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/message_receiver/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<E: types::EthSpec, S: SlotClock + 'static, D: DutiesProvider> MessageReceiv
let span = debug_span!("message_receiver", msg=%message_id);
let _enter = span.enter();

let result = receiver.validator.validate(&message.data, &topic_context, Some(propagation_source));
let result = receiver.validator.validate(&message.data, &topic_context);

let mut action = MessageAcceptance::from(&result);

Expand Down
5 changes: 0 additions & 5 deletions anchor/message_validator/src/consensus_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,6 @@ mod tests {
voluntary_exit_duty_count: expected_duty_count,
..Default::default()
}),
None,
);

assert_qbft_message_accepted(result, "Expected successful validation");
Expand Down Expand Up @@ -659,7 +658,6 @@ mod tests {
voluntary_exit_duty_count: 0,
..Default::default()
}),
None,
);

assert_validation_error(
Expand Down Expand Up @@ -717,7 +715,6 @@ mod tests {
voluntary_exit_duty_count: 0,
..Default::default()
}),
None,
);

assert_validation_error(
Expand Down Expand Up @@ -772,7 +769,6 @@ mod tests {
voluntary_exit_duty_count: 0,
..Default::default()
}),
None,
);

assert_validation_error(
Expand Down Expand Up @@ -2078,7 +2074,6 @@ mod tests {
voluntary_exit_duty_count: 0,
..Default::default()
}),
None,
)
}

Expand Down
22 changes: 9 additions & 13 deletions anchor/message_validator/src/duty_state.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::collections::{HashMap, HashSet};

use libp2p::PeerId;
use ssv_types::{
CommitteeId, Epoch, OperatorId, Slot,
consensus::{QbftMessage, QbftMessageType},
Expand Down Expand Up @@ -96,7 +95,6 @@ impl DutyState {
&mut self,
partial_signature_messages: &PartialSignatureMessages,
signer: &OperatorId,
received_from: Option<PeerId>,
) -> Result<(), ValidationFailure> {
let operator_state = self.get_or_create_operator(signer);
let message_slot = partial_signature_messages.slot;
Expand Down Expand Up @@ -130,7 +128,7 @@ impl DutyState {
// recipient's gossip duplicate cache expires, so repetition does not prove peer
// fault. Membership is checked before capacity so a recorded root stays IGNORE
// even when the set is full.
if seen_roots.contains_key(&root) {
if seen_roots.contains(&root) {
return Err(ValidationFailure::RelayedDuplicateMessage {
got: format!("{kind:?} root {root:?}"),
});
Expand All @@ -140,7 +138,7 @@ impl DutyState {
got: format!("{kind:?} distinct roots exceed cap {cap}"),
});
}
seen_roots.insert(root, received_from);
seen_roots.insert(root);
}

// Record the partial signature (only once)
Expand Down Expand Up @@ -288,19 +286,17 @@ pub(crate) struct SignerState {
/// first such packet: every role's ring entries share this struct, but only
/// `Role::ProposerPreferences` messages can ever populate it
/// (`partial_signature_type_matches_role`), so the other roles pay one pointer instead of
/// two inline maps.
/// two inline sets.
root_budgets: Option<Box<SigningRootBudgets>>,
}

/// Per-kind distinct-signing-root sets for the root-budgeted partial-signature kinds, each
/// accepted root mapped to its first deliverer (`None` = locally injected). The verdict for a
/// repeat is peer-agnostic Ignore (SIP-94 §7); the stored deliverer no longer affects
/// classification and is retained only because issue #1254 scopes the peer plumbing as
/// unchanged. The kinds are budgeted independently per SIP-94 §7: neither consumes the other.
/// Per-kind distinct-signing-root sets for the root-budgeted partial-signature kinds. The
/// verdict for a repeat is peer-agnostic Ignore (SIP-94 §7), so membership is all that is
/// tracked. The kinds are budgeted independently per SIP-94 §7: neither consumes the other.
#[derive(Debug, Clone, Default)]
struct SigningRootBudgets {
preferences: HashMap<Hash256, Option<PeerId>>,
request_auth: HashMap<Hash256, Option<PeerId>>,
preferences: HashSet<Hash256>,
request_auth: HashSet<Hash256>,
}

impl SignerState {
Expand All @@ -322,7 +318,7 @@ impl SignerState {
fn root_budget(
&mut self,
kind: PartialSignatureKind,
) -> Option<(&mut HashMap<Hash256, Option<PeerId>>, usize)> {
) -> Option<(&mut HashSet<Hash256>, usize)> {
match kind {
PartialSignatureKind::ProposerPreferences => Some((
&mut self.root_budgets.get_or_insert_default().preferences,
Expand Down
26 changes: 5 additions & 21 deletions anchor/message_validator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use database::NetworkState;
pub use duties_tracker::DutiesProvider;
use duties_tracker::DutyAssignment;
use fork::{Fork, ForkSchedule};
use libp2p::PeerId;
pub use libp2p::gossipsub::MessageAcceptance;
use openssl::{
hash::MessageDigest,
Expand Down Expand Up @@ -467,20 +466,11 @@ impl<S: SlotClock + 'static, D: DutiesProvider> Validator<S, D> {
/// The `topic_context` provides information about which topic the message was
/// received on, enabling validation of whether the message is on the correct
/// subnet for its committee based on the topic's fork.
pub fn validate(
&self,
message_data: &[u8],
topic_context: &TopicContext,
received_from: Option<PeerId>,
) -> ValidationResult {
pub fn validate(&self, message_data: &[u8], topic_context: &TopicContext) -> ValidationResult {
match SignedSSVMessage::from_ssz_bytes(message_data) {
Ok(signed_ssv_message) => {
trace!(msg = ?signed_ssv_message, "SignedSSVMessage deserialized");
match self.validate_decoded_message(
&signed_ssv_message,
topic_context,
received_from,
) {
match self.validate_decoded_message(&signed_ssv_message, topic_context) {
Ok(validated_message) => ValidationResult::Success(validated_message),
Err(failure) => {
ValidationResult::PostDecodeFailure(failure, signed_ssv_message)
Expand All @@ -497,7 +487,6 @@ impl<S: SlotClock + 'static, D: DutiesProvider> Validator<S, D> {
&self,
signed_ssv_message: &SignedSSVMessage,
topic_context: &TopicContext,
received_from: Option<PeerId>,
) -> Result<ValidatedMessage, ValidationFailure> {
let role = validate_structure_and_role(signed_ssv_message)?;
let ssv_message = signed_ssv_message.ssv_message();
Expand Down Expand Up @@ -572,7 +561,6 @@ impl<S: SlotClock + 'static, D: DutiesProvider> Validator<S, D> {
validation_context,
duty_state.value_mut(),
self.duties_provider.clone(),
received_from,
)
.map(|validated| ValidatedMessage::new(signed_ssv_message.clone(), validated))
}
Expand Down Expand Up @@ -785,20 +773,16 @@ fn validate_ssv_message(
validation_context: ValidationContext<impl SlotClock>,
duty_state: &mut DutyState,
duty_provider: Arc<impl DutiesProvider>,
received_from: Option<PeerId>,
) -> Result<ValidatedSSVMessage, ValidationFailure> {
let ssv_message = validation_context.signed_ssv_message.ssv_message();

match ssv_message.msg_type() {
MsgType::SSVConsensusMsgType => {
validate_consensus_message(validation_context, duty_state, duty_provider)
}
MsgType::SSVPartialSignatureMsgType => validate_partial_signature_message(
validation_context,
duty_state,
duty_provider,
received_from,
),
MsgType::SSVPartialSignatureMsgType => {
validate_partial_signature_message(validation_context, duty_state, duty_provider)
}
}
}

Expand Down
Loading
Loading