From 03a17ac2acd4210feb9067c124ffefec4ee50fca Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Thu, 11 Jan 2024 16:01:06 +0100 Subject: [PATCH] consensus: fix_step_votes_registry --- consensus/src/proposal/step.rs | 7 +-- consensus/src/step_votes_reg.rs | 80 ++++++++++++++------------------- 2 files changed, 36 insertions(+), 51 deletions(-) diff --git a/consensus/src/proposal/step.rs b/consensus/src/proposal/step.rs index 296dd43cff..ceaae5dc2e 100644 --- a/consensus/src/proposal/step.rs +++ b/consensus/src/proposal/step.rs @@ -59,11 +59,8 @@ impl ProposalStep { cmp::min(config::RELAX_ITERATION_THRESHOLD, ctx.iteration); // Fetch failed certificates from sv_registry - let failed_certificates = ctx - .sv_registry - .lock() - .await - .get_nil_certificates(0, iteration as usize); + let failed_certificates = + ctx.sv_registry.lock().await.get_nil_certificates(iteration); if let Ok(msg) = self .bg diff --git a/consensus/src/step_votes_reg.rs b/consensus/src/step_votes_reg.rs index c7f4752a0b..e438769405 100644 --- a/consensus/src/step_votes_reg.rs +++ b/consensus/src/step_votes_reg.rs @@ -5,10 +5,10 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use crate::commons::RoundUpdate; -use crate::config::CONSENSUS_MAX_ITER; use node_data::ledger::StepVotes; use node_data::ledger::{to_str, Certificate}; use node_data::message::{payload, Message, Topics}; +use std::collections::HashMap; use std::fmt; use std::sync::Arc; use tokio::sync::Mutex; @@ -22,7 +22,7 @@ pub(crate) enum SvType { #[derive(Default, Clone, Copy)] struct CertificateInfo { /// represents candidate block hash - hash: Option<[u8; 32]>, + hash: [u8; 32], cert: Certificate, quorum_reached_validation: bool, @@ -31,12 +31,10 @@ struct CertificateInfo { impl fmt::Display for CertificateInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let hash = self.hash.unwrap_or_default(); - write!( f, "cert_info: hash: {}, validation: ({:?},{:?}), ratification: ({:?},{:?}) ", - to_str(&hash), + to_str(&self.hash), self.cert.validation, self.quorum_reached_validation, self.cert.ratification, @@ -49,19 +47,10 @@ impl CertificateInfo { pub(crate) fn add_sv( &mut self, iter: u8, - hash: [u8; 32], sv: StepVotes, svt: SvType, quorum_reached: bool, ) -> bool { - if let Some(h) = self.hash { - if h != hash { - return false; - } - } else { - self.hash = Some(hash); - } - match svt { SvType::Validation => { self.cert.validation = sv; @@ -94,33 +83,38 @@ impl CertificateInfo { fn is_ready(&self) -> bool { !self.cert.validation.is_empty() && !self.cert.ratification.is_empty() - && self.hash.is_some() && self.quorum_reached_validation && self.quorum_reached_ratification } /// Returns `true` if the certificate has empty hash - fn is_nil(&self) -> bool { - self.hash.map(|h| h == [0u8; 32]).unwrap_or_default() + fn is_nil_quorum(&self) -> bool { + self.hash == [0u8; 32] + && self.quorum_reached_ratification + && self.quorum_reached_validation } } pub type SafeCertificateInfoRegistry = Arc>; +#[derive(Default, Clone)] +struct CertInfo { + certs: HashMap<[u8; 32], CertificateInfo>, +} + pub struct CertInfoRegistry { ru: RoundUpdate, /// List of iterations certificates. Position in the array represents /// iteration number. - cert_list: [CertificateInfo; CONSENSUS_MAX_ITER as usize], + cert_list: HashMap, } impl CertInfoRegistry { pub(crate) fn new(ru: RoundUpdate) -> Self { Self { ru, - cert_list: [CertificateInfo::default(); - CONSENSUS_MAX_ITER as usize], + cert_list: HashMap::new(), } } @@ -135,20 +129,14 @@ impl CertInfoRegistry { svt: SvType, quorum_reached: bool, ) -> Option { - if iteration as usize >= self.cert_list.len() { - return None; - } - - let r = &mut self.cert_list[iteration as usize]; - if r.add_sv(iteration, hash, sv, svt, quorum_reached) { - return Some(Self::build_quorum_msg( - self.ru.clone(), - iteration, - *r, - )); - } - - None + let cert = self + .cert_list + .entry(iteration) + .or_insert(CertInfo::default()); + let cert = cert.certs.entry(hash).or_insert(CertificateInfo::default()); + let full_quorum = cert.add_sv(iteration, sv, svt, quorum_reached); + full_quorum + .then(|| Self::build_quorum_msg(self.ru.clone(), iteration, *cert)) } fn build_quorum_msg( @@ -160,7 +148,7 @@ impl CertInfoRegistry { pubkey_bls: ru.pubkey_bls.clone(), round: ru.round, iteration, - block_hash: result.hash.unwrap_or_default(), + block_hash: result.hash, topic: Topics::Quorum, }; @@ -177,18 +165,18 @@ impl CertInfoRegistry { pub(crate) fn get_nil_certificates( &mut self, - from: usize, - to: usize, + to: u8, ) -> Vec> { - let to = std::cmp::min(to, self.cert_list.len()); - let mut res = Vec::with_capacity(to - from); - - for item in &self.cert_list[from..to] { - if item.is_nil() { - res.push(Some(item.cert)); - } else { - res.push(None) - } + let mut res = Vec::with_capacity(to as usize); + + for iteration in 0u8..to { + res.push( + self.cert_list + .get(&iteration) + .and_then(|c| c.certs.get(&[0u8; 32])) + .filter(|ci| ci.is_nil_quorum()) + .map(|ci| ci.cert), + ); } res