-
Notifications
You must be signed in to change notification settings - Fork 317
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
feat(storage-proofs): implement rational post #763
Conversation
f1f4886
to
c243861
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.
BLOCKING: This PR needs to generate and publish new Groth parameters.
Note: Breaking API Changes
generate_post
challenge_seed
parameter becomes&ChallengeSeed
generate_post
now accepts&[u64]
forfaults
generate_post
has new return typeverify_post
now accepts&[u8]
instead ofVec<Vec<u8>>
forproofs
verify_post
challenge_seed
parameter becomes&ChallengeSeed
verify_post
now accepts&[u64]
forfaults
SectorClass
dropsPoStProofPartitions
filecoin-proofs/src/api.rs
Outdated
|
||
let commitments: Vec<_> = challenges | ||
.iter() | ||
.map(|c| commitments_all[c.sector as usize]) |
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.
BLOCKING: Please use Vec::get
and early-return on a None
instead of indexing into the thing directly (which will panic if there is no value corresponding to the provided index).
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.
Counterpoint: derive_challenges
had damn well better make sure c.sector
is in range, and if it's not then we risk generating an invalid PoSt and need the moral equivalent of a panic (although I agree that should be caught and handled gracefully at the API boundary).
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.
We don't have any panic-recovery tooling yet, so this will unwind the stack and crash the Filecoin node. Until we build those tools, please avoid using panics.
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.
Good stuff, @dignifiedquire. Much simpler now…
filecoin-proofs/src/api.rs
Outdated
|
||
let commitments: Vec<_> = challenges | ||
.iter() | ||
.map(|c| commitments_all[c.sector as usize]) |
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.
Counterpoint: derive_challenges
had damn well better make sure c.sector
is in range, and if it's not then we risk generating an invalid PoSt and need the moral equivalent of a panic (although I agree that should be caught and handled gracefully at the API boundary).
filecoin-proofs/src/api.rs
Outdated
) | ||
.unwrap() | ||
} else { | ||
panic!("faults are not yet supported") |
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 think we should give ReplicaInfo
(or whatever you call it) a method which can convert it into a tree. We should pass those as private inputs, then only treeify them if the sector is challenged. This assumes there will be enough time to do that. This is a whole question I'm trying to get answers to now and will create an issue if necessary.
In any case, we can't hold all the trees in memory (and I think go-filecoin
) is currently blowing up because of this.
|
||
pub fn to_vec(&self) -> Vec<u8> { | ||
let mut out = Vec::new(); | ||
self.write(&mut out).expect("known allocation target"); |
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.
Why do you defile the holy MultiProof
so?
yes, will do once this PR is fully settled and approved |
6c40628
to
aa495ae
Compare
filecoin-proofs/src/api.rs
Outdated
let challenged_replicas: Vec<_> = challenges | ||
.iter() | ||
.map(|c| { | ||
if let Some(replica) = replicas.get(c.sector as usize) { |
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.
BLOCKING: replicas.get(c.sector as usize)
is going to index into replicas
by sector id. replicas
is a Vec
(i.e. not sector id-indexed data structure).
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.
How do I get the sector id from the the replica then?
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.
You'll need to extend ReplicaInfo
to include this information, e.g.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ReplicaInfo {
/// Path to the replica.
access: String,
/// The replica commitment.
commitment: Commitment,
sector_id: SectorId
}
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.
We should pause this thread until we're all on the same page regarding whether or not GeneratePoSt
should accept a SectorSet
(a sector id-indexed map) or an ordered list of sector ids.
storage-proofs/src/sector.rs
Outdated
use byteorder::ByteOrder; | ||
|
||
/// An ordered set of `SectorId`s. | ||
pub type SectorSet = BTreeSet<SectorId>; |
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.
Suggestion: Change the name of this type to something other than SectorSet
. SectorIdSet
would be fine by me.
Rationale: The protocol already specifies SectorSet
to be a map from sector id to replica commitment. Your type is not a map from sector id to replica commitment; I am certain that the name collision will cause some confusion in the future.
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.
changed to OrderedSectorSet
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.
BLOCKING: Please look into my questions about apparently conflating SectorId
with offset, even after changes to disentangle them. I made comments in a number of places to highlight the issue, and they should be taken as a group.
storage-proofs/src/rational_post.rs
Outdated
let challenged_sector = u64::from(challenge.sector); | ||
let challenged_leaf = challenge.leaf; | ||
|
||
let tree = priv_inputs.trees[challenged_sector as usize]; |
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.
challenged_sector
, which is the challenge.sector
, seems to be used as an index into the trees here, but the type of challenge.Sector
is SectorId
. This seems like a mismatch.
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.
fixed
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct Challenge { | ||
// The index of the sector into the sector list. | ||
pub sector: SectorId, |
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.
It it the index, or is it the Id?
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.
ID, forgot to update the comment
storage-proofs/src/rational_post.rs
Outdated
.iter() | ||
.zip(pub_inputs.commitments.iter()) | ||
.map(|(challenge, commitment)| { | ||
let challenged_sector = u64::from(challenge.sector); |
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.
Why are you turning a SectorId
into a u64
? It seems like this is defeating the type system and allowing you to look up a tree in an array by the integer value of its SectorId
.
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.
fixed
faults.insert(1.into()); | ||
let mut sectors = SectorSet::new(); | ||
sectors.insert(0.into()); | ||
sectors.insert(1.into()); |
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 think this test needs to be made more robust. It's not catching the fact that we're indexing into the trees using the SectorId
and not the calculated challenge offset.
I believe the test will break and expose this if you change line 297 to read sectors.insert(2.into());
.
We should also go further and add at least one more non-faulted sector and ensure that the test specifically validates that it has been selected correctly. In generally, we should avoid only inserting sectors whose SectorId
s are consecutive, starting from 0 — since this is very special case in which SectorId
and offset into an ordered set happen to be identical.
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.
fixed
d8d695b
to
a65d77a
Compare
* feat(add SectorId type and transforms) * fixup(clippy) * feat(implement Display for SectorId) * fixup(derive Ord) * fixup(revert sector_id field change to sector as per spec)
a65d77a
to
78419f6
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.
Nice work, but your tests are busted.
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.
LGTM
Some non-blocking thoughts to consider for future iterations (or not).
/// The replica commitment. | ||
commitment: Commitment, | ||
/// Is this sector marked as a fault? | ||
is_fault: bool, |
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.
Not necessary, but it might be nice to make this whole type be an Enum
with faulty and non-faulty variants — the faulty version omitting the access
. This would make it impossible to generate merkle trees from faulty sectors, potentially heading off some unpleasant failure modes we might accidentally stumble into if it's possible to do so.
|
||
if let Some(tree) = priv_inputs.trees.get(&challenge.sector) { | ||
if commitment != &tree.root() { | ||
return Err(Error::InvalidCommitment); |
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.
Not sure this is the right name for the error here. The commitment is valid by definition, right?
Follows the definition in filecoin-project/specs#332
PRs for other repos