-
Notifications
You must be signed in to change notification settings - Fork 225
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
Handle empty block id #66
Handle empty block id #66
Conversation
@@ -34,7 +34,7 @@ impl block::ParseId for BlockId { | |||
|
|||
impl From<&block::Id> for BlockId { | |||
fn from(bid: &block::Id) -> Self { | |||
let bid_hash = bid.hash.as_bytes().unwrap().to_vec(); | |||
let bid_hash = bid.hash.as_bytes().unwrap_or(&[]).to_vec(); |
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.
This seems like a weird way of addressing the problem... doesn't it result in an invalid BlockId?
I'd suggest changing this whole impl to either:
impl From<&block::Id> for Option<BlockId>
or
impl TryFrom<&block::Id> for BlockId
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.
This is how golang tendermint handled this. I agree we should do better. But we have to handle the serialization identical to golang version to compute signing bytes, what do you think of that?
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 Rust I think it's more idiomatic to reflect the distinction using the type system
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 can also remove the Option
in the parts_header
field. I think when hash
is not empty, parts_header
can't be empty.
1c34c3b
to
54da372
Compare
I've changed |
1508abb
to
23b0a08
Compare
I've removed branch |
23b0a08
to
e6d188d
Compare
and correctly compute header hash when block id is empty. Represent empty Hash with Option
e6d188d
to
8b1d3dc
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.
Thanks!
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 for this, though it seems a bit unfortunate. I opened an issue on the Tendermint repo to consider if we should address this more fundamentally: tendermint/tendermint#4241
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.
To be honest I don't fully understand this. Why couldn't we somehow utilize the fact that Hash
is an enum with a Null
variant to deal with this? We changed all the header fields to Options but Options are themselves just enum types so I'd imagine we could do this more cleanly using the Hash
type with a Null variant ...
@ebuchman it's definitely another option (there and back again). It looks like In retrospect, I can see how |
#84 included this PR so that's why it was removed there too. I think for this case where we have these possibly null types where the possibility of being null is almost always only related to the first block (rather than normal operation) we could have a cleaner solution by encapsulating the possibility of null in the underlying types rather than in their wrappers. Still not sure, but it does seem it'd be a bit cleaner and simpler. |
|
Could go either way on that, but I don't frequently see |
Put a |
Would it be better to explicitly code the type of the first block without all the fields that will be empty and then use a |
Ok opened an issue: #101 |
I think it's only the deserialisation code needs some extra care here, other than that, |
What's the problem with all zero hashes then? It seems that's what rust version of cardano did: |
@yihuang IMO an all-zero hash is about the worst thing you can do... the outputs of digest functions are supposed to be random oracles, and all zeroes are anything but. The risk is an all-zero hash value is inadvertently included in something like a Merkle tree computation. |
Fix panic when dealing with empty block id in the first block.