From bab1167bf6370ecd98d64cd3eca72642b5dd54fd Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 18 Dec 2024 15:09:05 +0100 Subject: [PATCH] wip --- consensus/src/consensus.rs | 2 ++ consensus/src/errors.rs | 10 +++++++++- consensus/src/operations.rs | 2 +- consensus/src/validation/step.rs | 21 ++++++++++++++------- node/src/chain/consensus.rs | 7 ++++--- node/src/vm.rs | 3 ++- rusk/src/lib/error.rs | 5 +++++ rusk/src/lib/node/rusk.rs | 8 ++++++-- rusk/src/lib/node/vm.rs | 22 +++++++++++++++++----- 9 files changed, 60 insertions(+), 20 deletions(-) diff --git a/consensus/src/consensus.rs b/consensus/src/consensus.rs index e5cab081e1..2343bd1a66 100644 --- a/consensus/src/consensus.rs +++ b/consensus/src/consensus.rs @@ -6,6 +6,7 @@ use std::cmp; use std::sync::Arc; +use std::time::Duration; use node_data::message::{AsyncQueue, Message, Payload}; use tokio::sync::{oneshot, Mutex}; @@ -106,6 +107,7 @@ impl Consensus { } }; + tokio::time::sleep(Duration::from_secs(1)).await; // Tear-down procedure abort(&mut handle).await; diff --git a/consensus/src/errors.rs b/consensus/src/errors.rs index 4e60ce4ecc..5a4603465c 100644 --- a/consensus/src/errors.rs +++ b/consensus/src/errors.rs @@ -70,7 +70,7 @@ impl From for ConsensusError { #[derive(Debug, Error)] pub enum OperationError { #[error("failed to call VST {0}")] - InvalidVST(anyhow::Error), + InvalidVST(VstError), #[error("failed to call EST {0}")] InvalidEST(anyhow::Error), #[error("failed to verify header {0}")] @@ -116,6 +116,14 @@ pub enum HeaderError { Storage(&'static str, anyhow::Error), } +#[derive(Debug, Error)] +pub enum VstError { + #[error("invalid previous block hash")] + PrevBlockHash, + #[error("Generic error in vst: {0}")] + Generic(String), +} + impl HeaderError { pub fn must_vote(&self) -> bool { match self { diff --git a/consensus/src/operations.rs b/consensus/src/operations.rs index 99246a0822..d02cedf9af 100644 --- a/consensus/src/operations.rs +++ b/consensus/src/operations.rs @@ -81,7 +81,7 @@ pub trait Operations: Send + Sync { prev_commit: StateRoot, blk: &Block, voters: &[Voter], - ) -> Result; + ) -> Result; async fn execute_state_transition( &self, diff --git a/consensus/src/validation/step.rs b/consensus/src/validation/step.rs index ae3b388821..2cfa9ec998 100644 --- a/consensus/src/validation/step.rs +++ b/consensus/src/validation/step.rs @@ -6,7 +6,6 @@ use std::sync::Arc; -use anyhow::anyhow; use node_data::bls::PublicKeyBytes; use node_data::ledger::{to_str, Block}; use node_data::message::payload::{Validation, Vote}; @@ -19,6 +18,7 @@ use tracing::{debug, error, info, Instrument}; use crate::commons::{Database, RoundUpdate}; use crate::config::is_emergency_iter; +use crate::errors::VstError; use crate::execution_ctx::ExecutionCtx; use crate::msg_handler::StepOutcome; use crate::operations::{Operations, Voter}; @@ -112,6 +112,13 @@ impl ValidationStep { .await { Ok(_) => Vote::Valid(header.hash), + Err(VstError::PrevBlockHash) => { + error!( + event = + "skip vote due to invalid_prev_block_hash", + ); + return; + } Err(err) => { error!(event = "failed_vst_call", ?err); Vote::Invalid(header.hash) @@ -165,7 +172,7 @@ impl ValidationStep { candidate: &Block, voters: &[Voter], executor: &Arc, - ) -> anyhow::Result<()> { + ) -> Result<(), VstError> { match executor .verify_state_transition(prev_commit, candidate, voters) .await @@ -176,23 +183,23 @@ impl ValidationStep { // ones we expect to have with the // current candidate block. if output.event_bloom != candidate.header().event_bloom { - return Err(anyhow!( + return Err(VstError::Generic(format!( "mismatch, event_bloom: {}, candidate_event_bloom: {}", hex::encode(output.event_bloom), hex::encode(candidate.header().event_bloom) - )); + ))); } if output.state_root != candidate.header().state_hash { - return Err(anyhow!( + return Err(VstError::Generic(format!( "mismatch, state_hash: {}, candidate_state_hash: {}", hex::encode(output.state_root), hex::encode(candidate.header().state_hash) - )); + ))); } } Err(err) => { - return Err(anyhow!("vm_err: {:?}", err)); + return Err(err); } }; diff --git a/node/src/chain/consensus.rs b/node/src/chain/consensus.rs index 13727e393f..e4e6eee572 100644 --- a/node/src/chain/consensus.rs +++ b/node/src/chain/consensus.rs @@ -10,7 +10,9 @@ use std::time::Duration; use async_trait::async_trait; use dusk_consensus::commons::{RoundUpdate, TimeoutSet}; use dusk_consensus::consensus::Consensus; -use dusk_consensus::errors::{ConsensusError, HeaderError, OperationError}; +use dusk_consensus::errors::{ + ConsensusError, HeaderError, OperationError, VstError, +}; use dusk_consensus::operations::{ CallParams, Operations, Output, VerificationOutput, Voter, }; @@ -318,13 +320,12 @@ impl Operations for Executor { prev_root: [u8; 32], blk: &Block, voters: &[Voter], - ) -> Result { + ) -> Result { info!("verifying state"); let vm = self.vm.read().await; vm.verify_state_transition(prev_root, blk, voters) - .map_err(OperationError::InvalidVST) } async fn execute_state_transition( diff --git a/node/src/vm.rs b/node/src/vm.rs index f43899a82a..c999335d1e 100644 --- a/node/src/vm.rs +++ b/node/src/vm.rs @@ -4,6 +4,7 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +use dusk_consensus::errors::VstError; use dusk_consensus::operations::{CallParams, VerificationOutput, Voter}; use dusk_consensus::user::provisioners::Provisioners; use dusk_consensus::user::stake::Stake; @@ -32,7 +33,7 @@ pub trait VMExecution: Send + Sync + 'static { prev_root: [u8; 32], blk: &Block, voters: &[Voter], - ) -> anyhow::Result; + ) -> Result; fn accept( &self, diff --git a/rusk/src/lib/error.rs b/rusk/src/lib/error.rs index 39ea449b83..fdacc66250 100644 --- a/rusk/src/lib/error.rs +++ b/rusk/src/lib/error.rs @@ -58,6 +58,8 @@ pub enum Error { InvalidCreditsCount(u64, usize), /// Memo too large MemoTooLarge(usize), + /// Chain tip different from the expected one + TipChanged, } impl std::error::Error for Error {} @@ -182,6 +184,9 @@ impl fmt::Display for Error { Error::MemoTooLarge(size) => { write!(f, "The memo size {size} is too large") } + Error::TipChanged => { + write!(f, "Chain tip different from the expected one") + } } } } diff --git a/rusk/src/lib/node/rusk.rs b/rusk/src/lib/node/rusk.rs index 98201dddd1..d9cef1d1fd 100644 --- a/rusk/src/lib/node/rusk.rs +++ b/rusk/src/lib/node/rusk.rs @@ -7,7 +7,7 @@ use std::path::Path; use std::sync::{mpsc, Arc, LazyLock}; use std::time::{Duration, Instant}; -use std::{fs, io}; +use std::{fs, io, thread}; use execution_core::stake::StakeKeys; use execution_core::transfer::PANIC_NONCE_NOT_READY; @@ -271,6 +271,7 @@ impl Rusk { slashing: Vec, voters: &[Voter], ) -> Result<(Vec, VerificationOutput)> { + thread::sleep(Duration::from_secs(1)); let session = self.new_block_session(block_height, prev_commit)?; accept( @@ -479,7 +480,10 @@ impl Rusk { block_height: u64, commit: [u8; 32], ) -> Result { - let mut session = self._session(block_height, Some(commit))?; + let mut session = self._session(block_height, None)?; + if session.root() != commit { + return Err(Error::TipChanged); + } let _: CallReceipt<()> = session .call(STAKE_CONTRACT, "before_state_transition", &(), u64::MAX) .expect("before_state_transition to success"); diff --git a/rusk/src/lib/node/vm.rs b/rusk/src/lib/node/vm.rs index 649944ccfe..d8c0b67cde 100644 --- a/rusk/src/lib/node/vm.rs +++ b/rusk/src/lib/node/vm.rs @@ -6,6 +6,7 @@ mod query; +use dusk_consensus::errors::VstError; use node_data::events::contract::ContractEvent; use tracing::info; @@ -48,13 +49,18 @@ impl VMExecution for Rusk { prev_commit: [u8; 32], blk: &Block, voters: &[Voter], - ) -> anyhow::Result { + ) -> Result { info!("Received verify_state_transition request"); let generator = blk.header().generator_bls_pubkey; - let generator = BlsPublicKey::from_slice(&generator.0) - .map_err(|e| anyhow::anyhow!("Error in from_slice {e:?}"))?; + let generator = + BlsPublicKey::from_slice(&generator.0).map_err(|e| { + VstError::Generic(format!("Error in from_slice {e:?}")) + })?; + // .map_err(|e| anyhow::anyhow!("Error in from_slice {e:?}"))?; - let slashing = Slash::from_block(blk)?; + let slashing = Slash::from_block(blk).map_err(|e| { + VstError::Generic(format!("Error in from_block {e:?}")) + })?; let (_, verification_output) = self .verify_transactions( @@ -67,7 +73,13 @@ impl VMExecution for Rusk { slashing, voters, ) - .map_err(|inner| anyhow::anyhow!("Cannot verify txs: {inner}!!"))?; + .map_err(|inner| { + if let crate::Error::TipChanged = inner { + VstError::PrevBlockHash + } else { + VstError::Generic(format!("Cannot verify txs: {inner}!!")) + } + })?; Ok(verification_output) }