Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion anchor/common/qbft/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ where
qbft_message_type: msg_type,
height: *self.instance_height as u64,
round: data.round,
identifier: self.identifier.clone(),
identifier: self.identifier.clone().into(),
root: data.root,
data_round: data.data_round,
round_change_justification,
Expand Down
15 changes: 2 additions & 13 deletions anchor/common/ssv_types/src/consensus.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::message::*;
use crate::msgid::{MessageId, Role};
use crate::ValidatorIndex;
use sha2::{Digest, Sha256};
use ssz::{Decode, DecodeError, Encode};
Expand All @@ -8,7 +7,7 @@ use std::fmt::Debug;
use std::hash::Hash;
use tree_hash::{PackedEncoding, TreeHash, TreeHashType};
use tree_hash_derive::TreeHash;
use types::typenum::U13;
use types::typenum::{U13, U56};
use types::{
AggregateAndProof, AggregateAndProofBase, AggregateAndProofElectra, BeaconBlock,
BlindedBeaconBlock, Checkpoint, CommitteeIndex, EthSpec, Hash256, PublicKeyBytes, Signature,
Expand Down Expand Up @@ -52,23 +51,13 @@ pub struct QbftMessage {
pub qbft_message_type: QbftMessageType,
pub height: u64,
pub round: u64,
pub identifier: MessageId,
pub identifier: VariableList<u8, U56>, // TODO: address redundant typing due to ssz_max encoding in go-client
pub root: Hash256,
pub data_round: u64,
pub round_change_justification: Vec<SignedSSVMessage>, // always without full_data
pub prepare_justification: Vec<SignedSSVMessage>, // always without full_data
}

impl QbftMessage {
pub fn max_round(&self) -> Option<u64> {
self.identifier.role().and_then(|role| match role {
Role::Committee | Role::Aggregator => Some(12), // TODO: confirm max_round with ssvlabs
Role::Proposer | Role::SyncCommittee => Some(6), // as per https://github.com/ssvlabs/ssv/blob/main/message/validation/consensus_validation.go#L370
_ => None,
})
}
}

/// Different states the QBFT Message may represent
#[derive(Clone, Debug, PartialEq, PartialOrd, Copy)]
pub enum QbftMessageType {
Expand Down
23 changes: 20 additions & 3 deletions anchor/common/ssv_types/src/msgid.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::committee::CommitteeId;
use crate::domain_type::DomainType;
use derive_more::From;
use derive_more::{From, Into};
use ssz::{Decode, DecodeError, Encode};
use types::PublicKeyBytes;
use types::typenum::U56;
use types::{PublicKeyBytes, VariableList};

const MESSAGE_ID_LEN: usize = 56;

Expand Down Expand Up @@ -45,13 +46,23 @@ impl TryFrom<&[u8]> for Role {
}
}

impl Role {
pub fn max_round(self) -> Option<u64> {
match self {
Role::Committee | Role::Aggregator => Some(12), // TODO: confirm max_round with ssvlabs
Role::Proposer | Role::SyncCommittee => Some(6), // as per https://github.com/ssvlabs/ssv/blob/main/message/validation/consensus_validation.go#L370
_ => None,
}
}
}

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum DutyExecutor {
Committee(CommitteeId),
Validator(PublicKeyBytes),
}

#[derive(Debug, Clone, Hash, Eq, PartialEq, From)]
#[derive(Debug, Clone, Hash, Eq, PartialEq, From, Into)]
pub struct MessageId([u8; 56]);

impl MessageId {
Expand Down Expand Up @@ -108,6 +119,12 @@ impl TryFrom<&[u8]> for MessageId {
}
}

impl From<MessageId> for VariableList<u8, U56> {
fn from(value: MessageId) -> Self {
value.0.to_vec().into()
}
}

impl Encode for MessageId {
fn is_ssz_fixed_len() -> bool {
true
Expand Down
19 changes: 12 additions & 7 deletions anchor/message_validator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,12 @@ impl Validator {
return Err(ValidationFailure::UnexpectedConsensusMessage);
}

let max_round = match consensus_message.max_round() {
let max_round = match signed_ssv_message
.ssv_message()
.msg_id()
.role()
.and_then(Role::max_round)
{
Some(max_round) => max_round,
None => return Err(ValidationFailure::FailedToGetMaxRound),
};
Expand All @@ -262,9 +267,9 @@ impl Validator {
}

// Rule: consensus message must have the same identifier as the ssv message's identifier
if consensus_message.identifier != *signed_ssv_message.ssv_message().msg_id() {
if *consensus_message.identifier != *signed_ssv_message.ssv_message().msg_id().as_ref() {
return Err(ValidationFailure::MismatchedIdentifier {
got: hex::encode(&consensus_message.identifier),
got: hex::encode(&*consensus_message.identifier),
want: hex::encode(signed_ssv_message.ssv_message().msg_id()),
});
}
Expand Down Expand Up @@ -451,7 +456,7 @@ mod tests {
qbft_message_type: self.msg_type,
height: 1,
round: self.round,
identifier: self.msg_id.clone(),
identifier: self.msg_id.clone().into(),
root: Hash256::from([0u8; 32]),
data_round: 1,
round_change_justification: self.round_change_justification,
Expand Down Expand Up @@ -528,8 +533,8 @@ mod tests {
"Unexpected QbftMessageType in validated QbftMessage"
);
assert_eq!(
validated_qbft.identifier,
create_message_id_for_test(Role::Committee),
&*validated_qbft.identifier,
create_message_id_for_test(Role::Committee).as_ref(),
"Identifier mismatch after validation"
);
} else {
Expand Down Expand Up @@ -640,7 +645,7 @@ mod tests {
qbft_message_type: QbftMessageType::Proposal,
height: 1,
round: 1,
identifier: msg_id_b, // Mismatched ID
identifier: msg_id_b.into(), // Mismatched ID
root: Hash256::from([0u8; 32]),
data_round: 1,
round_change_justification: vec![],
Expand Down
Loading