-
Notifications
You must be signed in to change notification settings - Fork 251
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
Remove 'NodeHandler::public_key_of' function and some unwraps #39
Conversation
pub fn propose(&mut self, hash: &Hash) -> Option<&mut ProposeState> { | ||
self.proposes.get_mut(hash) | ||
pub fn propose(&self, hash: &Hash) -> Option<&ProposeState> { | ||
self.proposes.get(hash) | ||
} |
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 if we need mutable ProposeState
, then the method should be named propose_mut
, but for now it is not needed.
return; | ||
} | ||
}; | ||
|
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 see here a lot of boilerplate code. Can you think about simplify it?
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 don't like this either, but I can not see how to elegantly get rid of it. This code can not be moved in a separate function because it should return Option
and in the call site there will be matching with early return, so we are not going to win anything.
Any ideas how to deal with this?
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.
As I understand correctly the problem is in error handling at all.
there so many functions like: fn handle_SOMETHING(...) -> ()
with body:
if some_bad_case {
error!("ERROR MESSAGE");
return;
}
we probably could replace it by
// in mod consensus
enum Error {
Propose(ProposeError),
Commit(CommitError),
...
}
enum ProposeError {
WrongLeader{actual: ValidatorId, expected: ValidatorId} ,
WrongValidator{actual: ValidatorId},
}
and handling errors like this should be trivial:
let validator_id = msg.validator();
let key = self.state.public_key_of(validator_id).ok_or(WrongValidator{actual: validator_id})?
We should consider some way to work with errors.
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 like the idea, although new error kinds seems like relatively big change, so I propose to perform such changes as a separate pull request. Could you please create an issue?
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.
@alekseysidorov already used crate derive_error https://github.com/rushmorem/derive-error in exonum/exonum-btc-anchoring
for chaining error kinds.
Though, https://crates.io/crates/error-chain is a lot more widely spread and involves more capabilities.
@defuz we should choose, what tool to use for chaining errors project wide (in core and services repos).
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.
@gisochre
Error chain may allocate memory in heap for traces. And it may be too complex for our use cases.
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.
@gisochre @alekseysidorov Personally I prefer derive-error. At least, I understand what it does. Macros from error-chain looks like black implicit magic.
error!("Incorrect prevote validator: {:?}", prevote); | ||
return; | ||
} | ||
}; |
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.
Here similarly
None => { | ||
error!("Invalid validator id: propose = {:?}", state.message()); | ||
return; | ||
} |
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.
And here.
return; | ||
} | ||
}; | ||
|
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.
And here
I am not satisfied with the approach of solving this problem. In all cases, you just trying to handle error which will never happen. All methods which calling match self.state.public_key_of(msg.validator()) {
// incorrect signature of message
Some(public_key) => {
if !msg.verify(public_key) {
error!("Received message with incorrect signature msg={:?}", msg);
return;
}
}
// incorrect validator id
None => {
error!("Received message from incorrect msg={:?}", msg);
return;
}
} Calling |
Still I would like to refactor error handling. |
Change votes response format
API testing
Closes #28