diff --git a/crates/fuel-core/src/schema/dap.rs b/crates/fuel-core/src/schema/dap.rs index 832d92a133..0232fa06f2 100644 --- a/crates/fuel-core/src/schema/dap.rs +++ b/crates/fuel-core/src/schema/dap.rs @@ -163,7 +163,7 @@ impl ConcreteStorage { let vm_database = VmStorage::new( storage.as_ref().clone(), - &block.header().consensus, + &block.header().consensus(), // TODO: Use a real coinbase address Default::default(), ); diff --git a/crates/services/consensus_module/poa/src/verifier.rs b/crates/services/consensus_module/poa/src/verifier.rs index 738c04f768..9da54343d4 100644 --- a/crates/services/consensus_module/poa/src/verifier.rs +++ b/crates/services/consensus_module/poa/src/verifier.rs @@ -62,7 +62,7 @@ pub fn verify_block_fields( ); ensure!( - header.consensus.application_hash == header.application.hash(), + header.consensus().application_hash == header.application().hash(), "The application hash mismatch." ); diff --git a/crates/services/sync/src/import.rs b/crates/services/sync/src/import.rs index c02f1d920a..bc21bc489a 100644 --- a/crates/services/sync/src/import.rs +++ b/crates/services/sync/src/import.rs @@ -552,7 +552,7 @@ where skip_all, fields( height = **block.entity.header().height(), - id = %block.entity.header().consensus.generated.application_hash + id = %block.entity.header().consensus().generated.application_hash ), err )] diff --git a/crates/services/sync/src/import/test_helpers.rs b/crates/services/sync/src/import/test_helpers.rs index 5a9d37ad47..583357262c 100644 --- a/crates/services/sync/src/import/test_helpers.rs +++ b/crates/services/sync/src/import/test_helpers.rs @@ -42,11 +42,11 @@ pub fn random_peer() -> PeerId { pub fn empty_header>(i: I) -> SealedBlockHeader { let mut header = BlockHeader::default(); let height = i.into(); - header.consensus.height = height; + header.consensus_mut().height = height; let transaction_tree = fuel_core_types::fuel_merkle::binary::root_calculator::MerkleRootCalculator::new( ); - header.application.generated.transactions_root = transaction_tree.root().into(); + header.application_mut().generated.transactions_root = transaction_tree.root().into(); let consensus = Consensus::default(); Sealed { diff --git a/crates/types/src/blockchain/block.rs b/crates/types/src/blockchain/block.rs index 521ad5516e..92a0212e6e 100644 --- a/crates/types/src/blockchain/block.rs +++ b/crates/types/src/blockchain/block.rs @@ -14,6 +14,7 @@ use super::{ }, }; use crate::{ + blockchain::header::BlockHeaderV1, fuel_tx::{ Transaction, TxId, @@ -227,7 +228,7 @@ impl From for PartialFuelBlock { match block { Block::V1(BlockV1 { header: - BlockHeader { + BlockHeader::V1(BlockHeaderV1 { application: ApplicationHeader { da_height, .. }, consensus: ConsensusHeader { @@ -237,7 +238,7 @@ impl From for PartialFuelBlock { .. }, .. - }, + }), transactions, }) => Self { header: PartialBlockHeader { diff --git a/crates/types/src/blockchain/header.rs b/crates/types/src/blockchain/header.rs index 284fcebcb4..4e48095bc9 100644 --- a/crates/types/src/blockchain/header.rs +++ b/crates/types/src/blockchain/header.rs @@ -20,12 +20,22 @@ use crate::{ }; use tai64::Tai64; +/// Version-able block header type +#[derive(Clone, Debug, derivative::Derivative)] +#[derivative(PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[non_exhaustive] +pub enum BlockHeader { + /// V1 BlockHeader + V1(BlockHeaderV1), +} + /// A fuel block header that has all the fields generated because it /// has been executed. #[derive(Clone, Debug, derivative::Derivative)] #[derivative(PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct BlockHeader { +pub struct BlockHeaderV1 { /// The application header. pub application: ApplicationHeader, /// The consensus header. @@ -37,6 +47,58 @@ pub struct BlockHeader { metadata: Option, } +impl From for BlockHeader { + fn from(v1: BlockHeaderV1) -> Self { + BlockHeader::V1(v1) + } +} + +impl BlockHeader { + /// Getter for consensus portion of header + pub fn consensus(&self) -> &ConsensusHeader { + match self { + BlockHeader::V1(v1) => &v1.consensus, + } + } + + /// Getter for application portion of header + pub fn application(&self) -> &ApplicationHeader { + match self { + BlockHeader::V1(v1) => &v1.application, + } + } + + /// Getter for metadata portion of header + pub fn metadata(&self) -> &Option { + match self { + BlockHeader::V1(v1) => &v1.metadata, + } + } + + /// Mutable getter for consensus portion of header + pub fn consensus_mut(&mut self) -> &mut ConsensusHeader { + match self { + BlockHeader::V1(v1) => &mut v1.consensus, + } + } + + /// Mutable getter for application portion of header + pub fn application_mut( + &mut self, + ) -> &mut ApplicationHeader { + match self { + BlockHeader::V1(v1) => &mut v1.application, + } + } + + /// Mutable getter for metadata portion of header + pub fn metadata_mut(&mut self) -> &mut Option { + match self { + BlockHeader::V1(v1) => &mut v1.metadata, + } + } +} + #[derive(Clone, Debug)] #[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] /// A partially complete fuel block header that doesn't not @@ -118,11 +180,12 @@ pub struct BlockHeaderMetadata { #[cfg(any(test, feature = "test-helpers"))] impl Default for BlockHeader { fn default() -> Self { - let mut default = Self { + let mut default: BlockHeader = BlockHeaderV1 { application: Default::default(), consensus: Default::default(), metadata: None, - }; + } + .into(); default.recalculate_metadata(); default } @@ -134,8 +197,8 @@ impl BlockHeader { /// The method should be used only for tests. pub fn new_block(height: BlockHeight, time: Tai64) -> Self { let mut default = Self::default(); - default.consensus.height = height; - default.consensus.time = time; + default.consensus_mut().height = height; + default.consensus_mut().time = time; default.recalculate_metadata(); default } @@ -189,9 +252,9 @@ impl PartialBlockHeader { impl BlockHeader { /// Re-generate the header metadata. pub fn recalculate_metadata(&mut self) { - let application_hash = self.application.hash(); - self.consensus.generated.application_hash = application_hash; - self.metadata = Some(BlockHeaderMetadata { id: self.hash() }); + let application_hash = self.application().hash(); + self.consensus_mut().generated.application_hash = application_hash; + *self.metadata_mut() = Some(BlockHeaderMetadata { id: self.hash() }); } /// Get the hash of the fuel header. @@ -201,14 +264,14 @@ impl BlockHeader { // and can't change its final hash on the fly. // // This assertion is a double-checks that this behavior is not changed. - debug_assert_eq!(self.consensus.application_hash, self.application.hash()); + debug_assert_eq!(self.consensus().application_hash, self.application().hash()); // This internally hashes the hash of the application header. - self.consensus.hash() + self.consensus().hash() } /// Get the cached fuel header hash. pub fn id(&self) -> BlockId { - if let Some(ref metadata) = self.metadata { + if let Some(ref metadata) = self.metadata() { metadata.id } else { self.hash() @@ -220,7 +283,7 @@ impl BlockHeader { // Generate the transaction merkle root. let transactions_root = generate_txns_root(transactions); - transactions_root == self.application.transactions_root + transactions_root == self.application().transactions_root } } @@ -263,7 +326,7 @@ impl PartialBlockHeader { }, }; - let mut header = BlockHeader { + let mut header: BlockHeader = BlockHeaderV1 { application, consensus: ConsensusHeader { prev_root: self.consensus.prev_root, @@ -275,7 +338,8 @@ impl PartialBlockHeader { }, }, metadata: None, - }; + } + .into(); // Cache the hash. header.recalculate_metadata(); @@ -340,7 +404,7 @@ impl core::ops::Deref for BlockHeader { type Target = ApplicationHeader; fn deref(&self) -> &Self::Target { - &self.application + &self.application() } } @@ -370,7 +434,7 @@ impl core::ops::Deref for ConsensusHeader { impl core::convert::AsRef> for BlockHeader { fn as_ref(&self) -> &ConsensusHeader { - &self.consensus + &self.consensus() } }