Skip to content
Merged
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
34 changes: 12 additions & 22 deletions anchor/common/qbft/src/msg_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use crate::{Round, WrappedQbftMessage};
/// Message container with strong typing and validation
#[derive(Default)]
pub struct MessageContainer {
/// Messages indexed by round and then by sender
messages: HashMap<Round, HashMap<OperatorId, WrappedQbftMessage>>,
/// Messages stored as a Vec per round to preserve insertion order
messages: HashMap<Round, Vec<WrappedQbftMessage>>,
/// Track which operators have sent messages for each round
senders_by_round: HashMap<Round, HashSet<OperatorId>>,
/// Track unique values per round
values_by_round: HashMap<Round, HashSet<Hash256>>,
/// The quorum size for the qbft instance
Expand All @@ -22,6 +24,7 @@ impl MessageContainer {
Self {
quorum_size,
messages: HashMap::new(),
senders_by_round: HashMap::new(),
values_by_round: HashMap::new(),
}
}
Expand All @@ -34,20 +37,12 @@ impl MessageContainer {
msg: &WrappedQbftMessage,
) -> bool {
// Check if we already have a message from this sender for this round
if self
.messages
.get(&round)
.and_then(|msgs| msgs.get(&sender))
.is_some()
{
return false; // Duplicate message
let senders = self.senders_by_round.entry(round).or_default();
if !senders.insert(sender) {
return false;
}

// Add message and track its value
self.messages
.entry(round)
.or_default()
.insert(sender, msg.clone());
self.messages.entry(round).or_default().push(msg.clone());

self.values_by_round
.entry(round)
Expand All @@ -64,7 +59,7 @@ impl MessageContainer {

// Count occurrences of each value
let mut value_counts: HashMap<Hash256, usize> = HashMap::new();
for msg in round_messages.values() {
for msg in round_messages {
*value_counts.entry(msg.qbft_message.root).or_default() += 1;
}

Expand All @@ -90,7 +85,7 @@ impl MessageContainer {
if let Some(hash) = self.has_quorum(round)
&& let Some(round_messages) = self.messages.get(&round)
{
for msg in round_messages.values() {
for msg in round_messages {
if msg.qbft_message.root == hash {
msgs.push(msg.clone());
}
Expand All @@ -101,14 +96,9 @@ impl MessageContainer {

/// Gets all messages for a specific round
pub fn get_messages_for_round(&self, round: Round) -> Vec<&WrappedQbftMessage> {
// If we have messages for this round in our container, return them all
// If not, return an empty vector
self.messages
.get(&round)
.map(|round_messages| {
// Convert the values of the HashMap into a Vec
round_messages.values().collect()
})
.map(|round_messages| round_messages.iter().collect())
.unwrap_or_default()
}
}
Loading