-
Notifications
You must be signed in to change notification settings - Fork 315
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
Synthetic PoRep #1701
Synthetic PoRep #1701
Conversation
1abe7a5
to
8864b73
Compare
8864b73
to
f5e8ca8
Compare
@@ -89,12 +89,25 @@ impl<'a, 'c, Tree: 'static + MerkleTreeTrait, G: 'static + Hasher> ProofScheme<' | |||
return Ok(false); | |||
}; | |||
|
|||
// If the caller attempts to verify the empty set of synthetic vanilla proofs, return early | |||
// (without error) as the synthetic prover validated the synthetic proofs prior to writing | |||
// them to disk. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IDK in what code paths it is used, but I could see it being useful as a step before running the prover.
In this, the randomness should be available to verify just the 180 selected challenges.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In production this code path should not be hit; it's here just in case the prover runs the verification method prior to randomness being set. The synthetic prover verifies all synthetic proofs prior to writing them to disk, so the selected 180 proofs should always be valid prior to this method's invocation. I could add proof re-verification in prove_layers
when the selected synthetic proofs are read from disk?
f89fe3a
to
27d3003
Compare
27d3003
to
d4a6479
Compare
ed45920
to
5ef8262
Compare
1ca5c6a
to
9789d77
Compare
9789d77
to
4d12385
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've only reviewed some of the synthetic proofs serialization as I was interested in it for other reasons.
let has_sub_path = SubTreeArity::to_usize() != 0; | ||
let has_top_path = TopTreeArity::to_usize() != 0; | ||
let base_path_len = path.len() - has_sub_path as usize - has_top_path as usize; | ||
|
||
let mut path = path.drain(..); | ||
|
||
let base_path = (&mut path) | ||
.take(base_path_len) | ||
.map(PathElement::from) | ||
.collect::<Vec<_>>() | ||
.into(); | ||
|
||
if !has_sub_path { | ||
return MerkleProof { | ||
data: ProofData::Single(SingleProof { | ||
leaf, | ||
root, | ||
path: base_path, | ||
}), | ||
}; | ||
} | ||
|
||
let sub_path = path | ||
.next() | ||
.map(|elem| InclusionPath::from(vec![PathElement::from(elem)])) | ||
.expect("path should not be empty"); | ||
|
||
if !has_top_path { | ||
return MerkleProof { | ||
data: ProofData::Sub(SubProof { | ||
leaf, | ||
root, | ||
base_proof: base_path, | ||
sub_proof: sub_path, | ||
}), | ||
}; | ||
} | ||
|
||
let top_path = path | ||
.next() | ||
.map(|elem| InclusionPath::from(vec![PathElement::from(elem)])) | ||
.expect("path should not be empty"); | ||
|
||
MerkleProof { | ||
data: ProofData::Top(TopProof { | ||
leaf, | ||
root, | ||
base_proof: base_path, | ||
sub_proof: sub_path, | ||
top_proof: top_path, | ||
}), | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this code a bit hard to follow. Here's my version:
if SubTreeArity::to_usize() == 0 {
let base_path = path.into_iter().map(PathElement::from).collect::<Vec<_>>();
MerkleProof {
data: ProofData::Single(SingleProof {
leaf,
root,
path: base_path.into(),
}),
}
} else if TopTreeArity::to_usize() == 0 {
let sub_elem = path.pop().expect("path should not be empty");
let base_path = path.into_iter().map(PathElement::from).collect::<Vec<_>>();
MerkleProof {
data: ProofData::Sub(SubProof {
leaf,
root,
base_proof: base_path.into(),
sub_proof: vec![PathElement::from(sub_elem)].into(),
}),
}
} else {
let sub_elem = path.pop().expect("path should not be empty");
let top_elem = path.pop().expect("path should not be empty");
let base_path = path.into_iter().map(PathElement::from).collect::<Vec<_>>();
MerkleProof {
data: ProofData::Top(TopProof {
leaf,
root,
base_proof: base_path.into(),
sub_proof: vec![PathElement::from(sub_elem)].into(),
top_proof: vec![PathElement::from(top_elem)].into(),
}),
}
}
}
It contains more repitition than yours , but I find it easier to follow. @DrPeterVanNostrand What do thou think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, this can be changed.
let has_exp_parents = (layer_index != 0) as usize; | ||
let layer_parents = num_drg_parents + has_exp_parents * num_exp_parents; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Casting a boolean into a usize is pretty C-like. I'd prefer having it in a more type-safe way. What about:
let layer_parents = if layer_index == 0 {
num_drg_parents
} else {
num_drg_parents + num_exp_parents
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, sounds good.
/// | ||
/// 1) root_d (32 bytes) | ||
/// 2) root_c (32 bytes) | ||
/// 3) root_r (32 bytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would call it root_r_last
for extra clarity (also in the code).
any reason to wait on landing the PR, as the test has ✅ ? |
We'll have it merged sooner than later, but as it is now, all of synthetic-porep is in feature branches across all of the repos. We didn't plan to cut a release until the SN work was complete (it's complete, but we're waiting on a release; @vmx has a meeting on that today and may have a solid update there). After that, we're going to start thinking about our next release scheduling |
Thanks! why don’t we decouple the releases for synthetic PoRep and SN changes? From lotus perspective, they will be introduced in two separate releases, one in a mandatory consensus breaking release, the other in an optional feature release. Would be great if we can minimize the changes in proof libraries for the mandatory release (or external dependencies in general!). (@rjan90 could you please follow up here after teams sync with SN and align with proof team on code landing/freeze expectations?) |
feat: temporarily allow testing against 16k sectors more like 32g
feat: wire synthetic porep to several existing benchmarks feat: add new porep bench allowing isolated synth proof generation
feat: revert rust-toolchain to previous feat: revert cuda default to opencl for fil-proofs-tooling
…oved feat: wire in synthetic porep tests to sector upgrade tests feat: special case tree_d/tree_c in t_aux cache when not needed (synporep)
f3e90a2
to
fc054cd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't had a fully in-depth review, but @DrPeterVanNostrand and @cryptonemo worked on it together, no open questions are left => approval.
No description provided.