Stateless QBFT consensus message semantic validation#171
Stateless QBFT consensus message semantic validation#171diegomrsantos merged 26 commits intosigp:unstablefrom
Conversation
91d58e5 to
2b07331
Compare
f1038ee to
4b08b92
Compare
|
This is based on #160, as soon as it gets merged, I'll remove the common code and make it ready for review. But feel free to take a look in the mean time. |
4b08b92 to
a41c6cb
Compare
c34cd52 to
1b40fa0
Compare
0e902a6 to
e5158db
Compare
|
@jking-aus @dknopik @Zacholme7 Sorry for the big PR. I can move the tests to a new one if necessary. |
| let committee_id = match signed_ssv_message.ssv_message().msg_id().duty_executor() { | ||
| Some(DutyExecutor::Committee(id)) => id, | ||
| _ => return Err(ValidationFailure::NonExistentCommitteeID), | ||
| }; |
There was a problem hiding this comment.
This is incomplete, I'm not handling the validator case. But this PR is already quite big, I will handle it in my next one which is coming soon.
…ion and VoluntaryExit) fix max_round
| hash | ||
| } | ||
|
|
||
| #[cfg(test)] |
There was a problem hiding this comment.
The tests could be greatly simplified if it's possible to call the validation functions without creating a validator. It's an interesting idea that I'll explore in a new PR.
Zacholme7
left a comment
There was a problem hiding this comment.
This is awesome, thanks for doing this. Have a few comments.
|
|
||
| pub struct WatchableNetworkState { | ||
| state_rx: watch::Receiver<NetworkState>, | ||
| } | ||
|
|
||
| impl WatchableNetworkState { | ||
| pub fn new(state_rx: watch::Receiver<NetworkState>) -> Self { | ||
| Self { state_rx } | ||
| } | ||
| } | ||
|
|
||
| impl NetworkStateService for WatchableNetworkState { | ||
| fn get_cluster_members(&self, committee_id: &CommitteeId) -> Option<IndexSet<OperatorId>> { | ||
| let db_state = self.state_rx.borrow(); | ||
| db_state | ||
| .multi_state | ||
| .clusters | ||
| .get_all_by(committee_id) | ||
| .and_then(|clusters| clusters.first().cloned()) | ||
| .map(|cluster| cluster.cluster_members) | ||
| } | ||
| } |
There was a problem hiding this comment.
Why is this needed?
Can get_cluster_members just be defined on the network state and then use state() and watch() on the database to get access to NetworkState?
There was a problem hiding this comment.
You mean why the trait is needed? If so, it's much easier to use it in the tests then recreating the whole NetworkState. But after talking to @dknopik, there might be an easier solution if we extract the validation to functions that can be called without a validator instance. I'll explore this design in a new PR.
| self.identifier.role().and_then(|role| match role { | ||
| Role::Committee | Role::Aggregator => Some(12), | ||
| Role::Proposer | Role::SyncCommittee => Some(6), | ||
| _ => None, |
There was a problem hiding this comment.
this may be obvious and I'm not getting it but why are we hardcoding 12 and 6 as max rounds? is that ssv spec? 2secs per round and 2 slot window?
There was a problem hiding this comment.
I copied it from here https://github.com/ssvlabs/ssv/blob/main/message/validation/consensus_validation.go#L370
There was a problem hiding this comment.
all good we need to match them on this or we won't timeout at the same time. I would like to ask them where they're pulling this number from because I would assume it's just a guess like follow distance. I will just add an inline comment saying where it's from.
There was a problem hiding this comment.
This is used only for validation, maybe I shouldn't have added it here.
There was a problem hiding this comment.
I can move it to the validator if you think it's better.
# Conflicts: # anchor/client/src/lib.rs # anchor/message_validator/src/lib.rs
…antos/anchor into qbft-message-validation
Issue Addressed
#161
Proposed Changes
Add an initial validation for QBFT consensus messages that doesn't depend on the consensus state.
Additional Info
Validation using consensus state is coming in the next PR.