Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Empty Sector Update proofs (for SnapDeals) #1519

Merged
merged 74 commits into from
Dec 13, 2021

Conversation

cryptonemo
Copy link
Collaborator

No description provided.

@cryptonemo
Copy link
Collaborator Author

Important note: while all tests are passing locally, I have verified that the empty_sector_update_circuit* tests are failing on CI because they top out around 42GB RAM, and so they are killed in the CI environment. This is an issue that can be addressed separately, as it does not affect production immediately and is otherwise acceptable for initial integration work.

pub comm_r_old: Option<Fr>,
pub comm_d_new: Option<Fr>,
pub comm_r_new: Option<Fr>,
pub h_select: Option<Fr>,
Copy link

@Kubuxu Kubuxu Oct 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DrPeterVanNostrand this is not critical so we should figure out anything else there is. Could we pack k and h_select into one input? AFAIK proof-verification significantly scales with the number of public inputs, so this could be a measurable improvement.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I will do it today.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, but a final review would be appreciated. I added one public-input for the packed k and h_select, then perform a binary decomposition on that public-input, then take the first 4 bits of that as partition_bits and the next 6 bits as h_select_bits.

let input_index_without_k = node_index & remove_k_from_node_index_mask;
let high =
input_index_without_k >> (node_index_bit_len - partition_bit_len - h);
let rho: Fr = <TreeRHasher as Hasher>::Function::hash2(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid computing this hash on a per-node basis, the core reason why we hash only the high bits is to avoid 2^30 hash computations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that I've made the change, but a second review would be beneficial.


/// Encodes data into an existing replica.
/// Returns tuple of (comm_r_new, comm_r_last_new, comm_d_new)
#[allow(clippy::too_many_arguments)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should document what happens to the old replica & gurantees

staged_data_path: &Path,
h: usize,
) -> Result<(TreeRDomain, TreeRDomain, TreeDDomain)> {
// Sanity check all input path types.
Copy link
Contributor

@qy3u qy3u Oct 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be also ensure that the new_replica_path (and cache path) not equal to the old one here?

@DrPeterVanNostrand DrPeterVanNostrand force-pushed the empty-sector-update branch 2 times, most recently from eb21db7 to 6d79e6d Compare October 12, 2021 18:34
@cryptonemo cryptonemo mentioned this pull request Oct 13, 2021
9 tasks
cryptonemo and others added 24 commits December 9, 2021 07:47
style: clippy updates
style: rust fmt
* feat: re-factor tree_r_last building for external re-use
* reduce conversions in encode (@dignifiedquire)
* feat: use an enum return type to avoid transmute (unsafe)
* fix: keep new crate version consistent with latest release
* fix: add doc and additional type check
* feat: wrap settings for tree builders in a method
This check was loosened since lotus may pad the data file
feat: add and expose an API to prove sector updates with vanilla proofs
From the lotus side, additional data may be stored after the nodes we
want in the tree, so using a different builder method will allow that
to happen without a panic
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
Copy link
Contributor

@vmx vmx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done a general Rust review, I didn't really get into the algorithms.

)]
struct Opt {
#[structopt(long, help = "Only cache PoSt groth params.")]
only_post: bool,
#[structopt(long, help = "Only cache EmptySectorUpdate groth params.")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--only-sector-update and --only-post are mutually exclusive. If you add a group = "sectortype" to each of them, you'll get an error message like this if you specify both:

error: The argument '--only-post' cannot be used with one or more of the other specified argument


impl From<HSelect> for u64 {
fn from(x: HSelect) -> Self {
x.0 as u64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a general note for new future code (no need to change it). as can also be lossy. Hence I think u64::from(x.0) should be preferred. See https://stackoverflow.com/questions/48795329/what-is-the-difference-between-fromfrom-and-as-in-rust for more information.

@@ -0,0 +1,16 @@
// Update Proof Partitions are the number of partitions used in the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a doc comment (three slashes).

Comment on lines +149 to +151
match self.raw {
Some(..) => {}
None => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick (no need to change): I'd fine a if self.raw.is_none() { … } clearer.

@@ -171,6 +171,9 @@ where
}
}

// Note: This method verifies that the tree can be build with the size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a doc comment (three slashes).

where
TreeR: MerkleTreeTrait<Hasher = TreeRHasher>,
{
pub _tree_r: PhantomData<TreeR>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this pub? I don't see a reason why PhantomData should every need public acces.

Comment on lines +122 to +142
pub struct PublicInputs {
pub k: usize,
pub comm_r_old: TreeRDomain,
pub comm_d_new: TreeDDomain,
pub comm_r_new: TreeRDomain,
// The number of high bits to take from each challenge's bits. Used to verify replica encoding
// in the vanilla proof. `h` is only a public-input for the vanilla proof; the circuit takes
// `h_select` as a public-input rather than `h`.
pub h: usize,
}

pub struct PrivateInputs {
pub comm_c: TreeRDomain,
pub tree_r_old_config: StoreConfig,
// Path to old replica.
pub old_replica_path: PathBuf,
pub tree_d_new_config: StoreConfig,
pub tree_r_new_config: StoreConfig,
// Path to new replica.
pub replica_path: PathBuf,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do all members (also for the PublicParams above) need to be public? I try to keep as much out of the public API as possible. Once somrthing is in the public API, it's tricky to get it out again. E.g. If you want to change a type (let's say you change from PathBuf to Path) and it's public, it's a breaking change and you have to be very careful about it.

@cryptonemo cryptonemo merged commit 415f9d2 into master Dec 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants