Conversation
src/blocks/mod.rs
Outdated
|
|
||
| impl Display for Block { | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
| let work_render = if self.work.is_none() { |
There was a problem hiding this comment.
I prefer this for various reasons, especially because there is no need to do an unwrap (even though it's safe, it could not be in the future if edited incorrectly by someone else):
match &self.work {
Some(work_render) => work_render.to_string(),
None => "No work".to_string(),
}
src/blocks/mod.rs
Outdated
| } else { | ||
| self.signature.as_ref().unwrap().to_string() | ||
| }; | ||
| write!(f, "Block(Account: {}, Previous: {:?}, Balance: {}, Link: {:?}, Work: {}, Signature: {})", |
There was a problem hiding this comment.
I did, it probably reverted for some reason
There was a problem hiding this comment.
Btw, can we enforce this at CI level?
src/node/controller/messages.rs
Outdated
| BlockHolder::State(state_block) => { | ||
| let mut block = Block::from_state_block(&state_block); | ||
| let block_hash: &BlockHash = { | ||
| block.calc_hash().unwrap(); |
There was a problem hiding this comment.
Please use context()? or with_context()? instead of unwrap so we can handle problems gracefully instead of panicking.
There was a problem hiding this comment.
Ah right. Btw I'm starting to be more convinced about requiring a hash to create a valid block. The only reason we put it separately is in case it fails, but I'm quite sure that a hash can't fail per se, so if it fails it's a programming defect (unrecoverable error in Rust lingo). In other words, I don't think it makes sense to keep a block around incapable of having a hash.
There was a problem hiding this comment.
OK, if you're convinced go ahead!
src/node/controller/messages.rs
Outdated
| }; | ||
| // dbg!(state_block); | ||
|
|
||
| // # deduplication |
There was a problem hiding this comment.
I means important comment here! Just kidding, I'm going to delete all the comments before committing anyway.
src/node/controller/messages.rs
Outdated
|
|
||
| // # signature validation | ||
| let invalid_signature = || { | ||
| let valid_signature = block.verify_self_signature() |
There was a problem hiding this comment.
I think you can just do block.verify_signature().is_ok() or .is_err() to get a bool.
Does it need to be a closure?
There was a problem hiding this comment.
yes because otherwise it will be computed even if not necessary. On the other hand we could just use a different pattern. Remember the if else question in the discord? It was about this.
There was a problem hiding this comment.
I guess if it turns into the is_ok() variant, it won't be computed if the first if branch is true.
As in } else if block.verify_self_signature().is_err() {
There was a problem hiding this comment.
Sure, and for this example is fine because it can be reasonably turned into a one liner. I'm concerned whether it can be done for all. For example if the other checks are more elaborate they might not fit inline. I'll write a few more and see what's the result.
There was a problem hiding this comment.
I guess in that case the whole if statement could go into a function with early exits, similar to your initial example in chat?
There was a problem hiding this comment.
I don't think my first example would help. For reference it was:
if cond1 {
do_bla();
return Ok()
}
if cond2 {
do_bla2();
return Ok()
}
...
Now, if cond1 needs to lock the state and search the database for example, is not going to look pretty. This is why closures are a good way to group and name the checks on top of the ifs, whatever pattern we chose. I'm trying to think of other options but basically what we have to implement here is a very extensive flow diagram. Any other idea? Btw, in the ref implementation it's a big pile of nested ifs. It's quite legible to be honest but I think we can do much better. (ref code)
There was a problem hiding this comment.
Well let's just leave it at what you think is best. If we can find a nicer solution later, it shouldn't be a big deal to change.
src/node/controller/messages.rs
Outdated
| block.calc_hash().unwrap(); | ||
| let block_holder = BlockHolder::State(state_block); | ||
| controller.handle_publish(&test_header, Publish { block_holder }).await.unwrap(); | ||
| assert!(controller.state.lock().await.get_block_by_hash(block.hash().unwrap()).await.unwrap().is_none()) |
| #[derive(Debug)] | ||
| pub struct Publish(pub(crate) BlockHolder); | ||
| pub struct Publish { | ||
| pub(crate) block_holder: BlockHolder |
There was a problem hiding this comment.
publish.0 feels a bit weird, does this make it weirder? It helped me keep in mind I was working with a BlockHolder anyways.
There was a problem hiding this comment.
I think .0 is ok, although I do think it's a bit ugly. OK let's keep your change and see how it goes.
|
Thanks for the review! |
| let block = block; // give up mutability for safety | ||
|
|
||
| if Controller::block_existed(self, block_hash).await? { | ||
| tracing::info!("Block {} already exists!", block_hash); |
There was a problem hiding this comment.
Please just use the info! macro via a use tracing::info

This will address #59 (comment) but actually for the state block since no send blocks can be found alive. (I will also create an issue for that). The checks however are almost the same.