diff --git a/src/consensus/proto/protocol_proposal.rs b/src/consensus/proto/protocol_proposal.rs index e4b5ef7d0..adc7d1ead 100644 --- a/src/consensus/proto/protocol_proposal.rs +++ b/src/consensus/proto/protocol_proposal.rs @@ -80,26 +80,13 @@ impl ProtocolProposal { let proposal_copy = (*proposal).clone(); - let mut state = self.state.write().await; - // Verify we have the proposal already - match state.find_proposal(&proposal_copy.block.header.headerhash()) { - Ok(p) => { - if let Some(_) = p { - debug!("ProtocolProposal::handle_receive_proposal(): Proposal already received."); - continue - } - } - Err(e) => { - error!( - "ProtocolProposal::handle_receive_proposal(): find_proposal() failed: {}", - e - ); - continue - } - }; + if self.state.read().await.proposal_exists(&proposal_copy.block.header.headerhash()) { + debug!("ProtocolProposal::handle_receive_proposal(): Proposal already received."); + continue + } - if let Err(e) = state.receive_proposal(&proposal_copy).await { + if let Err(e) = self.state.write().await.receive_proposal(&proposal_copy).await { error!( "ProtocolProposal::handle_receive_proposal(): receive_proposal error: {}", e diff --git a/src/consensus/state.rs b/src/consensus/state.rs index 5c5baad61..ea8e18265 100644 --- a/src/consensus/state.rs +++ b/src/consensus/state.rs @@ -461,6 +461,12 @@ impl ValidatorState { None => return Ok(None), } + // Check if proposal extends any existing fork chains + let index = self.find_extended_chain_index(&proposal)?; + if index == -2 { + return Err(Error::ExtendedChainIndexNotFoundError) + } + let leader = self.consensus.participants.get(&proposal.block.metadata.address); if leader.is_none() { warn!( @@ -513,11 +519,6 @@ impl ValidatorState { // TODO: [PLACEHOLDER] Add rewards validation - let index = self.find_extended_chain_index(&proposal)?; - if index == -2 { - return Ok(None) - } - let mut to_broadcast = vec![]; match index { -1 => { @@ -553,22 +554,16 @@ impl ValidatorState { return Ok(index as i64) } - if proposal.block.header.previous == last.block.header.previous && - proposal.block.header.slot == last.block.header.slot - { - debug!("find_extended_chain_index(): Proposal already received"); - return Ok(-2) - } - if proposal.block.header.previous == last.block.header.previous && proposal.block.header.slot > last.block.header.slot { fork = Some(chain.clone()); + break } } if let Some(mut chain) = fork { - debug!("Proposal to fork a forkchain was received."); + debug!("find_extended_chain_index(): Proposal to fork a forkchain was received."); chain.proposals.pop(); // removing last block to create the fork if !chain.proposals.is_empty() { // if len is 0 we will verify against blockchain last block @@ -587,20 +582,17 @@ impl ValidatorState { } /// Search the chains we're holding for the given proposal. - pub fn find_proposal( - &mut self, - input_proposal: &blake3::Hash, - ) -> Result> { - for (index, chain) in &mut self.consensus.proposals.iter_mut().enumerate() { - for proposal in chain.proposals.iter_mut().rev() { + pub fn proposal_exists(&self, input_proposal: &blake3::Hash) -> bool { + for chain in self.consensus.proposals.iter() { + for proposal in chain.proposals.iter() { let proposal_hash = proposal.block.header.headerhash(); if input_proposal == &proposal_hash { - return Ok(Some((proposal, index as i64))) + return true } } } - Ok(None) + false } /// Remove provided transactions vector from unconfirmed_txs if they exist. diff --git a/src/error.rs b/src/error.rs index 9742b0f19..9498b25d8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -226,6 +226,9 @@ pub enum Error { #[error("State transition failed")] StateTransitionError, + #[error("Check if proposal extends any existing fork chains failed")] + ExtendedChainIndexNotFoundError, + // =============== // Database errors // =============== diff --git a/src/net/p2p.rs b/src/net/p2p.rs index 526ae6e51..b9a60fe3c 100644 --- a/src/net/p2p.rs +++ b/src/net/p2p.rs @@ -491,9 +491,10 @@ impl P2p { *self.discovery.lock().await = false; } - /// Retrieves a random connected channel + /// Retrieves a random connected channel, exluding seeds pub async fn random_channel(self: Arc) -> Option> { - let channels_map = self.channels().lock().await; + let mut channels_map = self.channels().lock().await.clone(); + channels_map.retain(|c, _| !self.settings.seeds.contains(&c)); let mut values = channels_map.values(); if values.len() == 0 { diff --git a/src/zk/circuit/lead_contract.rs b/src/zk/circuit/lead_contract.rs index 391815aa4..b56fe6857 100644 --- a/src/zk/circuit/lead_contract.rs +++ b/src/zk/circuit/lead_contract.rs @@ -116,24 +116,42 @@ const LEAD_Y_COMMIT_BASE_OFFSET: usize = 3; #[derive(Default, Debug)] pub struct LeadContract { - pub path: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, /// path of coin1 commitment - pub sk: Value, /// coin secret key - pub root_sk: Value, /// root to secret key - pub path_sk: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, /// path to the secret key rooted by `root_sk` - pub coin_timestamp: Value, /// $\tau$ or coin index - pub coin_nonce: Value, /// coin nonce $\rho_{c1}$ - pub coin1_blind: Value, /// coin blind r - pub coin1_sn: Value, /// coin serial number - pub value: Value, /// coin value - pub coin2_blind: Value, /// coin2 blind r2 - pub coin2_commit: Value, /// coin2 commitment - pub cm_pos: Value, /// coin position in the merkle tree - pub slot: Value, /// slot index - pub mau_rho: Value, /// random value derived from eta used for constraining \rho - pub mau_y: Value, /// random value derived from eta used for calculating y - pub root_cm: Value, /// root to commitment in the mekle tree - pub sigma1: Value, /// first coefficient in 1-term T (target function) approximation - pub sigma2: Value, /// second coefficient in 2-term T (target function) approximation + pub path: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, + /// path of coin1 commitment + pub sk: Value, + /// coin secret key + pub root_sk: Value, + /// root to secret key + pub path_sk: Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, + /// path to the secret key rooted by `root_sk` + pub coin_timestamp: Value, + /// $\tau$ or coin index + pub coin_nonce: Value, + /// coin nonce $\rho_{c1}$ + pub coin1_blind: Value, + /// coin blind r + pub coin1_sn: Value, + /// coin serial number + pub value: Value, + /// coin value + pub coin2_blind: Value, + /// coin2 blind r2 + pub coin2_commit: Value, + /// coin2 commitment + pub cm_pos: Value, + /// coin position in the merkle tree + pub slot: Value, + /// slot index + pub mau_rho: Value, + /// random value derived from eta used for constraining \rho + pub mau_y: Value, + /// random value derived from eta used for calculating y + pub root_cm: Value, + /// root to commitment in the mekle tree + pub sigma1: Value, + /// first coefficient in 1-term T (target function) approximation + pub sigma2: Value, + /// second coefficient in 2-term T (target function) approximation /// constrained nonce $\rho$ pub rho: Value, //pub eta : Option,