From 90fa9c397cce6478d67c513cf4801fb0915653d1 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 28 Apr 2024 06:21:42 -0400 Subject: [PATCH] Set participation upon participation instead of constantly recalculating --- coordinator/tributary/tendermint/src/lib.rs | 1 + .../tributary/tendermint/src/message_log.rs | 47 +++++++++---------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/coordinator/tributary/tendermint/src/lib.rs b/coordinator/tributary/tendermint/src/lib.rs index 145c5188..777b2f00 100644 --- a/coordinator/tributary/tendermint/src/lib.rs +++ b/coordinator/tributary/tendermint/src/lib.rs @@ -1003,6 +1003,7 @@ impl TendermintMachine { // If it's been more than 60s, rebroadcast our own messages () = rebroadcast_future => { + log::trace!("rebroadcast future hit within tendermint machine"); let key = message_tape_key(self.genesis); let messages = self.db.get(key).unwrap_or(vec![]); let mut messages = messages.as_slice(); diff --git a/coordinator/tributary/tendermint/src/message_log.rs b/coordinator/tributary/tendermint/src/message_log.rs index 716f6d64..f39a45ca 100644 --- a/coordinator/tributary/tendermint/src/message_log.rs +++ b/coordinator/tributary/tendermint/src/message_log.rs @@ -7,12 +7,19 @@ use crate::{ext::*, RoundNumber, Step, DataFor, SignedMessageFor, Evidence}; type RoundLog = HashMap<::ValidatorId, HashMap>>; pub(crate) struct MessageLog { weights: Arc, + round_participation: HashMap, + participation: HashMap<(RoundNumber, Step), u64>, pub(crate) log: HashMap>, } impl MessageLog { pub(crate) fn new(weights: Arc) -> MessageLog { - MessageLog { weights, log: HashMap::new() } + MessageLog { + weights, + round_participation: HashMap::new(), + participation: HashMap::new(), + log: HashMap::new(), + } } // Returns true if it's a new message @@ -35,54 +42,44 @@ impl MessageLog { return Ok(false); } + // Since we have a new message, update the participation + let sender_weight = self.weights.weight(msg.sender); + if msgs.is_empty() { + *self.round_participation.entry(msg.round).or_insert_with(|| 0) += sender_weight; + } + *self.participation.entry((msg.round, step)).or_insert_with(|| 0) += sender_weight; + msgs.insert(step, signed); Ok(true) } - // For a given round, return the participating weight for this step, and the weight agreeing with - // the data. - pub(crate) fn message_instances(&self, round: RoundNumber, data: &DataFor) -> (u64, u64) { - let mut participating = 0; + // For a given round, return the weight agreeing with the data + fn message_instances(&self, round: RoundNumber, data: &DataFor) -> u64 { let mut weight = 0; - let Some(log) = self.log.get(&round) else { return (0, 0) }; + let Some(log) = self.log.get(&round) else { return 0 }; for (participant, msgs) in log { if let Some(msg) = msgs.get(&data.step()) { let validator_weight = self.weights.weight(*participant); - participating += validator_weight; if data == &msg.msg.data { weight += validator_weight; } } } - (participating, weight) + weight } // Get the participation in a given round pub(crate) fn round_participation(&self, round: RoundNumber) -> u64 { - let mut weight = 0; - if let Some(round) = self.log.get(&round) { - for participant in round.keys() { - weight += self.weights.weight(*participant); - } - }; - weight + *self.round_participation.get(&round).unwrap_or(&0) } // Check if a supermajority of nodes have participated on a specific step pub(crate) fn has_participation(&self, round: RoundNumber, step: Step) -> bool { - let mut participating = 0; - let Some(log) = self.log.get(&round) else { return false }; - for (participant, msgs) in log { - if msgs.get(&step).is_some() { - participating += self.weights.weight(*participant); - } - } - participating >= self.weights.threshold() + *self.participation.get(&(round, step)).unwrap_or(&0) >= self.weights.threshold() } // Check if consensus has been reached on a specific piece of data pub(crate) fn has_consensus(&self, round: RoundNumber, data: &DataFor) -> bool { - let (_, weight) = self.message_instances(round, data); - weight >= self.weights.threshold() + self.message_instances(round, data) >= self.weights.threshold() } }