diff --git a/crates/hotshot/examples/infra/mod.rs b/crates/hotshot/examples/infra/mod.rs index 5b9fd0e58e..9763c0696f 100644 --- a/crates/hotshot/examples/infra/mod.rs +++ b/crates/hotshot/examples/infra/mod.rs @@ -383,7 +383,6 @@ pub trait RunDA< memberships, networks_bundle, initializer, - TestInstanceState {}, ConsensusMetricsValue::default(), ) .await diff --git a/crates/hotshot/src/lib.rs b/crates/hotshot/src/lib.rs index 86ed946078..073c60ac29 100644 --- a/crates/hotshot/src/lib.rs +++ b/crates/hotshot/src/lib.rs @@ -195,13 +195,13 @@ impl> SystemContext { memberships: Memberships, networks: Networks, initializer: HotShotInitializer, - instance_state: TYPES::InstanceState, metrics: ConsensusMetricsValue, ) -> Result> { debug!("Creating a new hotshot"); let consensus_metrics = Arc::new(metrics); let anchored_leaf = initializer.inner; + let instance_state = initializer.instance_state; // insert to storage storage @@ -442,7 +442,6 @@ impl> SystemContext { memberships: Memberships, networks: Networks, initializer: HotShotInitializer, - instance_state: TYPES::InstanceState, metrics: ConsensusMetricsValue, ) -> Result< ( @@ -461,7 +460,6 @@ impl> SystemContext { memberships, networks, initializer, - instance_state, metrics, ) .await?; @@ -749,6 +747,9 @@ impl> ConsensusApi pub struct HotShotInitializer { /// the leaf specified initialization inner: Leaf, + + /// Instance-level state. + instance_state: TYPES::InstanceState, } impl HotShotInitializer { @@ -760,11 +761,15 @@ impl HotShotInitializer { ) -> Result> { Ok(Self { inner: Leaf::genesis(instance_state), + instance_state: instance_state.clone(), }) } - /// reload previous state based on most recent leaf - pub fn from_reload(anchor_leaf: Leaf) -> Self { - Self { inner: anchor_leaf } + /// reload previous state based on most recent leaf and the instance-level state. + pub fn from_reload(anchor_leaf: Leaf, instance_state: TYPES::InstanceState) -> Self { + Self { + inner: anchor_leaf, + instance_state, + } } } diff --git a/crates/task-impls/src/consensus.rs b/crates/task-impls/src/consensus.rs index 6b862f4063..9c35a62abe 100644 --- a/crates/task-impls/src/consensus.rs +++ b/crates/task-impls/src/consensus.rs @@ -594,9 +594,8 @@ impl, A: ConsensusApi + }; let Ok(state) = parent_state.validate_and_apply_header( &consensus.instance_state, - &proposal.data.block_header.clone(), &parent.block_header.clone(), - &view, + &proposal.data.block_header.clone(), ) else { error!("Block header doesn't extend the proposal",); return; @@ -1218,11 +1217,11 @@ impl, A: ConsensusApi + if let Some(commit_and_metadata) = &self.payload_commitment_and_metadata { let block_header = TYPES::BlockHeader::new( - commit_and_metadata.commitment, - commit_and_metadata.metadata.clone(), + state, &consensus.instance_state, &parent_header, - state, + commit_and_metadata.commitment, + commit_and_metadata.metadata.clone(), ); let leaf = Leaf { view_number: view, diff --git a/crates/testing/src/block_types.rs b/crates/testing/src/block_types.rs index b58a116932..c581f7726a 100644 --- a/crates/testing/src/block_types.rs +++ b/crates/testing/src/block_types.rs @@ -185,11 +185,11 @@ impl BlockHeader for TestBlockHeader { type State = TestValidatedState; fn new( - payload_commitment: VidCommitment, - _metadata: ::Metadata, + _parent_state: &Self::State, _instance_state: &::Instance, parent_header: &Self, - _parent_state: &Self::State, + payload_commitment: VidCommitment, + _metadata: ::Metadata, ) -> Self { Self { block_number: parent_header.block_number + 1, diff --git a/crates/testing/src/state_types.rs b/crates/testing/src/state_types.rs index 4241ab783f..7d2c6794b5 100644 --- a/crates/testing/src/state_types.rs +++ b/crates/testing/src/state_types.rs @@ -4,7 +4,6 @@ use commit::{Commitment, Committable}; use hotshot_types::{ data::{fake_commitment, BlockError, ViewNumber}, traits::{ - node_implementation::ConsensusTime, states::{InstanceState, TestableState, ValidatedState}, BlockPayload, }, @@ -18,7 +17,7 @@ use crate::block_types::{TestBlockHeader, TestBlockPayload}; pub use crate::node_types::TestTypes; /// Instance-level state implementation for testing purposes. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct TestInstanceState {} impl InstanceState for TestInstanceState {} @@ -28,8 +27,6 @@ impl InstanceState for TestInstanceState {} pub struct TestValidatedState { /// the block height block_height: u64, - /// the view number - view_number: ViewNumber, /// the previous state commitment prev_state_commitment: Commitment, } @@ -38,7 +35,6 @@ impl Committable for TestValidatedState { fn commit(&self) -> Commitment { commit::RawCommitmentBuilder::new("Test State Commit") .u64_field("block_height", self.block_height) - .u64_field("view_number", *self.view_number) .field("prev_state_commitment", self.prev_state_commitment) .finalize() } @@ -52,7 +48,6 @@ impl Default for TestValidatedState { fn default() -> Self { Self { block_height: 0, - view_number: ViewNumber::genesis(), prev_state_commitment: fake_commitment(), } } @@ -72,20 +67,11 @@ impl ValidatedState for TestValidatedState { fn validate_and_apply_header( &self, _instance: &Self::Instance, - _proposed_header: &Self::BlockHeader, _parent_header: &Self::BlockHeader, - view_number: &Self::Time, + _proposed_header: &Self::BlockHeader, ) -> Result { - if view_number == &ViewNumber::genesis() { - if &self.view_number != view_number { - return Err(BlockError::InvalidBlockHeader); - } - } else if self.view_number >= *view_number { - return Err(BlockError::InvalidBlockHeader); - } Ok(TestValidatedState { block_height: self.block_height + 1, - view_number: *view_number, prev_state_commitment: self.commit(), }) } diff --git a/crates/testing/src/task_helpers.rs b/crates/testing/src/task_helpers.rs index 9ca92cacdd..73068e94eb 100644 --- a/crates/testing/src/task_helpers.rs +++ b/crates/testing/src/task_helpers.rs @@ -113,7 +113,6 @@ pub async fn build_system_handle( memberships, networks_bundle, initializer, - TestInstanceState {}, ConsensusMetricsValue::default(), ) .await @@ -242,11 +241,11 @@ async fn build_quorum_proposal_and_signature( let mut parent_state = ::from_header(&parent_leaf.block_header); let block_header = TestBlockHeader::new( - payload_commitment, - (), + &parent_state, &TestInstanceState {}, &parent_leaf.block_header, - &parent_state, + payload_commitment, + (), ); // current leaf that can be re-assigned everytime when entering a new view let mut leaf = Leaf { @@ -271,12 +270,7 @@ async fn build_quorum_proposal_and_signature( // Only view 2 is tested, higher views are not tested for cur_view in 2..=view { let state_new_view = parent_state - .validate_and_apply_header( - &TestInstanceState {}, - &block_header, - &block_header, - &ViewNumber::new(cur_view - 1), - ) + .validate_and_apply_header(&TestInstanceState {}, &block_header, &block_header) .unwrap(); // save states for the previous view to pass all the qc checks // In the long term, we want to get rid of this, do not manually update consensus state diff --git a/crates/testing/src/test_runner.rs b/crates/testing/src/test_runner.rs index 6f7c466323..f1d4cf237b 100644 --- a/crates/testing/src/test_runner.rs +++ b/crates/testing/src/test_runner.rs @@ -321,7 +321,6 @@ where memberships, network_bundle, initializer, - TestInstanceState {}, ConsensusMetricsValue::default(), ) .await diff --git a/crates/types/src/traits/block_contents.rs b/crates/types/src/traits/block_contents.rs index 0feb0e1382..92785ed1b2 100644 --- a/crates/types/src/traits/block_contents.rs +++ b/crates/types/src/traits/block_contents.rs @@ -118,11 +118,11 @@ pub trait BlockHeader: /// Build a header with the payload commitment, metadata, instance-level state, parent header, /// and parent state. fn new( - payload_commitment: VidCommitment, - metadata: ::Metadata, + parent_state: &Self::State, instance_state: &::Instance, parent_header: &Self, - parent_state: &Self::State, + payload_commitment: VidCommitment, + metadata: ::Metadata, ) -> Self; /// Build the genesis header, payload, and metadata. diff --git a/crates/types/src/traits/states.rs b/crates/types/src/traits/states.rs index 3c1e58d828..0d7d5fe5ee 100644 --- a/crates/types/src/traits/states.rs +++ b/crates/types/src/traits/states.rs @@ -10,7 +10,7 @@ use serde::{de::DeserializeOwned, Serialize}; use std::{error::Error, fmt::Debug, hash::Hash}; /// Instance-level state, which allows us to fetch missing validated state. -pub trait InstanceState: Debug + Send + Sync {} +pub trait InstanceState: Clone + Debug + Send + Sync {} /// Abstraction over the state that blocks modify /// @@ -48,9 +48,8 @@ pub trait ValidatedState: fn validate_and_apply_header( &self, instance: &Self::Instance, - proposed_header: &Self::BlockHeader, parent_header: &Self::BlockHeader, - view_number: &Self::Time, + proposed_header: &Self::BlockHeader, ) -> Result; /// Construct the state with the given block header.