-
Notifications
You must be signed in to change notification settings - Fork 161
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
Jaden/tipsetconversions #404
Conversation
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.
Approving because my suggested change is functionally the same, but I think it makes it a bit more readable
blockchain/blocks/src/tipset.rs
Outdated
pub fn new(blocks: Vec<Block>) -> Result<Self, Error> { | ||
verify_blocks(blocks.iter().map(Block::header))?; | ||
Ok(Self { blocks }) | ||
|
||
// sort blocks on creation to allow for more seamless conversions between FullTipset | ||
// and Tipset | ||
let mut sorted_blocks = blocks; | ||
sorted_blocks.sort_by_key(|block| { | ||
( | ||
block.header.ticket().vrfproof.clone(), | ||
block.header.cid().to_bytes(), | ||
) | ||
}); | ||
Ok(Self { | ||
blocks: sorted_blocks, | ||
}) |
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 can't add a suggestion, because a few lines are outside of the changes, but can simplify to:
pub fn new(mut blocks: Vec<Block>) -> Result<Self, Error> {
verify_blocks(blocks.iter().map(Block::header))?;
// sort blocks on creation to allow for more seamless conversions between FullTipset
// and Tipset
blocks.sort_by_key(|block| {
(
block.header.ticket().vrfproof.clone(),
block.header.cid().to_bytes(),
)
});
Ok(Self { blocks })
}
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 aren't we only sorting by the ticket anyway? Aren't those already unique? (I saw that Tipset::new
sorts by a tuple as well)
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.
Ah didn't catch that, will add that change and push commit.
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 is (or was) written into the spec to handle the secondary sorting. I'll try to find again, because quickly looking it is just referring to only sorting by ticket.
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.
If tickets are guaranteed to be unique then it will never hit the second tuple element — if not, then it's indeed needed for a canonical ordering
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.
The spec reads as follows:
The blocks in a tipset are canonically ordered by the lexicographic
ordering of the bytes in each block’s ticket, breaking ties with the bytes
of the CID of the block itself.
My interpretation of that is that we order based on ticket size and if ticket sizes are equal we check the cid of the block itself.
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.
Thanks @dutterbutter for finding :) Yeah the comparison can still be improved by not cloning the ticket and only comparing cid bytes when other matches (having some sort function) if you want to take that on now @flodesi
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.
My wording was a bit vague, I was questioning whether block.header.cid().to_bytes()
was needed there as well. But you raise a good point, Ticket
's ordering is defined by the ordering of its vrfproof
so leaving out .vrfproof
there will have no impact on the ordering whatsoever.
We unfortunately can't get rid of the .clone()
though because of a language limitation (StackOverflow)
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.
what I'm suggesting is not sorting by keys and just having a sort function, there should be no need to clone the ticket, only cids in the extremely rare case of a ticket match
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.
@flodesi If you call max_by
instead of max_by_key
, you get in two blocks which lets you compare the tickets without cloning them, and only compare the CIDs if necessary like Austin suggested.
Summary of changes
Changes introduced in this pull request:
FullTipset
toTipset
From
traits to convert fromFullTipset
toTipset
Reference issue to close (if applicable)
Closes #398