diff --git a/src/consensus/coins.rs b/src/consensus/coins.rs index a76ccf65c..896298626 100644 --- a/src/consensus/coins.rs +++ b/src/consensus/coins.rs @@ -39,7 +39,9 @@ fn get_frequency() -> Float10 { /// Calculate nodes total stake for specific epoch and slot. fn total_stake(epoch: u64, slot: u64) -> u64 { - (epoch * *EPOCH_LENGTH + slot + 1) * *REWARD + // TODO: fix this + //(epoch * *EPOCH_LENGTH + slot + 1) * *REWARD + *REWARD } /// Generate epoch competing coins. diff --git a/src/consensus/state.rs b/src/consensus/state.rs index 173482516..fbdca5e84 100644 --- a/src/consensus/state.rs +++ b/src/consensus/state.rs @@ -38,7 +38,7 @@ use crate::{ tx::Transaction, util::time::Timestamp, zk::circuit::LeadContract, - Result, + Error, Result, }; /// This struct represents the information required by the consensus algorithm @@ -52,8 +52,6 @@ pub struct ConsensusState { pub proposals: Vec, /// Validators currently participating in the consensus pub participants: BTreeMap, - /// Validators to be added on the next slot as participants - pub pending_participants: Vec, /// Last slot participants where refreshed pub refreshed: u64, /// Current epoch @@ -72,7 +70,6 @@ impl ConsensusState { genesis_block, proposals: vec![], participants: BTreeMap::new(), - pending_participants: vec![], refreshed: 0, epoch: 0, coins: vec![], @@ -445,28 +442,28 @@ impl ValidatorState { } None => return Ok(None), } - + let leader = self.consensus.participants.get(&proposal.block.metadata.address); if leader.is_none() { warn!( "receive_proposal(): Received proposal from unknown node: ({})", proposal.block.metadata.address ); - return Ok(None) + return Err(Error::UnknownNodeError) } let leader = leader.unwrap(); - let public_inputs = &leader.coins[current as usize][proposal.block.metadata.winning_index]; + let public_inputs = &leader.coins[self.relative_slot(current) as usize][proposal.block.metadata.winning_index]; if public_inputs != &proposal.block.metadata.public_inputs { warn!("receive_proposal(): Received proposal public inputs are invalid."); - return Ok(None) + return Err(Error::InvalidPublicInputsError) } match proposal.block.metadata.proof.verify(&self.verifying_key, &public_inputs) { Ok(_) => info!("receive_proposal(): Proof veryfied succsessfully!"), Err(e) => { error!("receive_proposal(): Error during leader proof verification: {}", e); - return Ok(None) + return Err(Error::LeaderProofVerificationError); } } @@ -478,7 +475,7 @@ impl ValidatorState { "receive_proposal(): Proposer ({}) signature could not be verified", proposal.block.metadata.address ); - return Ok(None) + return Err(Error::InvalidSignatureError) } debug!("receive_proposal(): Starting state transition validation"); @@ -491,7 +488,7 @@ impl ValidatorState { } Err(e) => { warn!("receive_proposal(): State transition fail: {}", e); - return Ok(None) + return Err(Error::StateTransitionError) } } @@ -661,38 +658,18 @@ impl ValidatorState { Ok(finalized) } - /// Append a new participant to the pending participants list. + /// Append a new participant to the participants list. pub fn append_participant(&mut self, participant: Participant) -> bool { - if self.consensus.pending_participants.contains(&participant) { - return false + if let Some(p) = self.consensus.participants.get(&participant.address) { + if p == &participant { + return false + } } - // TODO: [PLACEHOLDER] don't blintly trust the public inputs/validate them - - self.consensus.pending_participants.push(participant); + self.consensus.participants.insert(participant.address, participant); true } - /// Utility function to reset the current consensus state. - pub fn reset_consensus_state(&mut self) -> Result<()> { - let genesis_ts = self.consensus.genesis_ts; - let genesis_block = self.consensus.genesis_block; - - let consensus = ConsensusState { - genesis_ts, - genesis_block, - proposals: vec![], - participants: BTreeMap::new(), - pending_participants: vec![], - refreshed: 0, - epoch: 0, - coins: vec![], - }; - - self.consensus = consensus; - Ok(()) - } - // ========================== // State transition functions // ========================== diff --git a/src/consensus/task/consensus_sync.rs b/src/consensus/task/consensus_sync.rs index 09c754632..92ddb98e2 100644 --- a/src/consensus/task/consensus_sync.rs +++ b/src/consensus/task/consensus_sync.rs @@ -43,8 +43,7 @@ pub async fn consensus_sync_task(p2p: P2pPtr, state: ValidatorStatePtr) -> Resul break } } else { - warn!("Node is not connected to other nodes, resetting consensus state."); - state.write().await.reset_consensus_state()?; + warn!("Node is not connected to other nodes"); } info!("Consensus state synced!"); diff --git a/src/error.rs b/src/error.rs index 6413f69db..569d83a13 100644 --- a/src/error.rs +++ b/src/error.rs @@ -192,6 +192,21 @@ pub enum Error { #[error("JSON-RPC error: {0}")] JsonRpcError(String), + + #[error("Received proposal from unknown node")] + UnknownNodeError, + + #[error("Public inputs are invalid")] + InvalidPublicInputsError, + + #[error("Error during leader proof verification")] + LeaderProofVerificationError, + + #[error("Signature could not be verified")] + InvalidSignatureError, + + #[error("State transition failed")] + StateTransitionError, // =============== // Database errors