From f9fc0602174c5400a15545d161aef6450af71a05 Mon Sep 17 00:00:00 2001 From: Aaryamann Challani <43716372+rymnc@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:57:00 +0530 Subject: [PATCH 1/4] fix(headers): move tx_id_commitment to application_headers --- Cargo.lock | 1 - bin/fuel-core/src/cli/snapshot.rs | 7 +- crates/chain-config/src/config/state.rs | 10 +- .../src/compressed_block_payload/v1.rs | 6 +- .../global_merkle_root/storage/src/update.rs | 4 +- crates/fuel-core/src/executor.rs | 10 +- crates/fuel-core/src/query/message/test.rs | 4 +- crates/fuel-core/src/schema/block.rs | 16 +- crates/fuel-core/src/schema/dap.rs | 4 +- .../src/service/adapters/consensus_module.rs | 2 +- .../adapters/consensus_parameters_provider.rs | 8 +- .../service/adapters/graphql_api/on_chain.rs | 2 +- crates/fuel-core/src/service/genesis.rs | 6 +- .../fuel-core/src/service/genesis/importer.rs | 4 +- crates/services/consensus_module/Cargo.toml | 8 + .../consensus_module/poa/src/verifier.rs | 15 +- .../poa/src/verifier/tests.rs | 36 +- .../consensus_module/src/block_verifier.rs | 2 +- .../src/block_verifier/tests.rs | 6 +- crates/services/executor/src/executor.rs | 4 +- .../src/common/l2_block_source.rs | 2 +- .../src/v0/uninitialized_task.rs | 2 +- .../src/v1/uninitialized_task.rs | 2 +- crates/services/p2p/Cargo.toml | 5 + crates/services/p2p/src/p2p_service.rs | 23 +- .../services/producer/src/block_producer.rs | 4 +- .../producer/src/block_producer/tests.rs | 32 +- crates/services/sync/src/import.rs | 2 +- .../upgradable-executor/src/executor.rs | 6 +- crates/types/Cargo.toml | 1 - crates/types/src/blockchain/block.rs | 36 +- crates/types/src/blockchain/header.rs | 577 +++++++++++------- crates/types/src/blockchain/header/v1.rs | 111 +++- crates/types/src/blockchain/header/v2.rs | 132 +++- 34 files changed, 724 insertions(+), 366 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6cd3197b138..d42cbfb4dd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4077,7 +4077,6 @@ dependencies = [ "bs58", "derivative", "derive_more 0.99.19", - "enum_dispatch", "fuel-vm 0.59.1", "k256", "rand", diff --git a/bin/fuel-core/src/cli/snapshot.rs b/bin/fuel-core/src/cli/snapshot.rs index 060dd9a87a2..34352a3b4d9 100644 --- a/bin/fuel-core/src/cli/snapshot.rs +++ b/bin/fuel-core/src/cli/snapshot.rs @@ -392,8 +392,9 @@ mod tests { .last_block_config() .cloned() .expect("Expects the last block config to be set"); - block.header_mut().application_mut().da_height = - last_block_config.da_block_height; + block + .header_mut() + .set_da_height(last_block_config.da_block_height); block .header_mut() .set_block_height(last_block_config.block_height); @@ -557,7 +558,7 @@ mod tests { fn given_block(&mut self) -> TableEntry { let mut block = CompressedBlock::default(); let height = self.rng.gen(); - block.header_mut().application_mut().da_height = self.rng.gen(); + block.header_mut().set_da_height(self.rng.gen()); block.header_mut().set_block_height(height); let _ = self .db diff --git a/crates/chain-config/src/config/state.rs b/crates/chain-config/src/config/state.rs index 06d4f605283..490a36b148f 100644 --- a/crates/chain-config/src/config/state.rs +++ b/crates/chain-config/src/config/state.rs @@ -105,13 +105,9 @@ impl LastBlockConfig { pub fn from_header(header: &BlockHeader, blocks_root: Bytes32) -> Self { Self { block_height: *header.height(), - da_block_height: header.application().da_height, - consensus_parameters_version: header - .application() - .consensus_parameters_version, - state_transition_version: header - .application() - .state_transition_bytecode_version, + da_block_height: header.da_height(), + consensus_parameters_version: header.consensus_parameters_version(), + state_transition_version: header.state_transition_bytecode_version(), blocks_root, } } diff --git a/crates/compression/src/compressed_block_payload/v1.rs b/crates/compression/src/compressed_block_payload/v1.rs index 51e0012a615..0b7d4ba0ff6 100644 --- a/crates/compression/src/compressed_block_payload/v1.rs +++ b/crates/compression/src/compressed_block_payload/v1.rs @@ -43,10 +43,10 @@ impl From<&BlockHeader> for CompressedBlockHeader { } = *header.consensus(); CompressedBlockHeader { application: ApplicationHeader { - da_height: header.da_height, - consensus_parameters_version: header.consensus_parameters_version, + da_height: header.da_height(), + consensus_parameters_version: header.consensus_parameters_version(), state_transition_bytecode_version: header - .state_transition_bytecode_version, + .state_transition_bytecode_version(), generated: Empty {}, }, consensus: ConsensusHeader { diff --git a/crates/fraud_proofs/global_merkle_root/storage/src/update.rs b/crates/fraud_proofs/global_merkle_root/storage/src/update.rs index d05eedc6b1a..74a7c680550 100644 --- a/crates/fraud_proofs/global_merkle_root/storage/src/update.rs +++ b/crates/fraud_proofs/global_merkle_root/storage/src/update.rs @@ -111,10 +111,10 @@ where storage: self, latest_state_transition_bytecode_version: block .header() - .state_transition_bytecode_version, + .state_transition_bytecode_version(), latest_consensus_parameters_version: block .header() - .consensus_parameters_version, + .consensus_parameters_version(), }; update_transaction.process_block(block)?; diff --git a/crates/fuel-core/src/executor.rs b/crates/fuel-core/src/executor.rs index b0439aaaad5..70a4ecaf06e 100644 --- a/crates/fuel-core/src/executor.rs +++ b/crates/fuel-core/src/executor.rs @@ -363,8 +363,8 @@ mod tests { assert!(skipped_transactions.is_empty()); assert_ne!( - start_block.header().transactions_root, - block.header().transactions_root + start_block.header().transactions_root(), + block.header().transactions_root() ); assert_eq!(block.transactions().len(), 11); assert!(block.transactions()[10].as_mint().is_some()); @@ -2712,7 +2712,7 @@ mod tests { .message_id() .to_bytes(), ); - assert_eq!(block.header().message_outbox_root.as_ref(), mt.root()); + assert_eq!(block.header().message_outbox_root().as_ref(), mt.root()); } #[test] @@ -2751,7 +2751,7 @@ mod tests { // Then let empty_root = empty_sum_sha256(); - assert_eq!(block.header().message_outbox_root.as_ref(), empty_root) + assert_eq!(block.header().message_outbox_root().as_ref(), empty_root) } #[test] @@ -3386,7 +3386,7 @@ mod tests { // then let expected = root_calculator.root().into(); - let actual = result.block.header().application().event_inbox_root; + let actual = result.block.header().event_inbox_root(); assert_eq!(actual, expected); } diff --git a/crates/fuel-core/src/query/message/test.rs b/crates/fuel-core/src/query/message/test.rs index 9aa7ee0799a..e718352d92d 100644 --- a/crates/fuel-core/src/query/message/test.rs +++ b/crates/fuel-core/src/query/message/test.rs @@ -202,8 +202,8 @@ async fn can_build_message_proof() { ) .unwrap(); assert_eq!( - proof.message_block_header.message_outbox_root, - message_block.header().message_outbox_root + proof.message_block_header.message_outbox_root(), + message_block.header().message_outbox_root() ); assert_eq!( proof.message_block_header.height(), diff --git a/crates/fuel-core/src/schema/block.rs b/crates/fuel-core/src/schema/block.rs index 98e35a7be6d..fc0688c2dca 100644 --- a/crates/fuel-core/src/schema/block.rs +++ b/crates/fuel-core/src/schema/block.rs @@ -188,42 +188,42 @@ impl Header { /// The layer 1 height of messages and events to include since the last layer 1 block number. async fn da_height(&self) -> U64 { - self.0.da_height.0.into() + self.0.da_height().0.into() } /// The version of the consensus parameters used to create this block. async fn consensus_parameters_version(&self) -> U32 { - self.0.consensus_parameters_version.into() + self.0.consensus_parameters_version().into() } /// The version of the state transition bytecode used to create this block. async fn state_transition_bytecode_version(&self) -> U32 { - self.0.state_transition_bytecode_version.into() + self.0.state_transition_bytecode_version().into() } /// Number of transactions in this block. async fn transactions_count(&self) -> U16 { - self.0.transactions_count.into() + self.0.transactions_count().into() } /// Number of message receipts in this block. async fn message_receipt_count(&self) -> U32 { - self.0.message_receipt_count.into() + self.0.message_receipt_count().into() } /// Merkle root of transactions. async fn transactions_root(&self) -> Bytes32 { - self.0.transactions_root.into() + self.0.transactions_root().into() } /// Merkle root of message receipts in this block. async fn message_outbox_root(&self) -> Bytes32 { - self.0.message_outbox_root.into() + self.0.message_outbox_root().into() } /// Merkle root of inbox events in this block. async fn event_inbox_root(&self) -> Bytes32 { - self.0.event_inbox_root.into() + self.0.event_inbox_root().into() } /// Fuel block height. diff --git a/crates/fuel-core/src/schema/dap.rs b/crates/fuel-core/src/schema/dap.rs index 808591fa0c3..0bbfb0be37b 100644 --- a/crates/fuel-core/src/schema/dap.rs +++ b/crates/fuel-core/src/schema/dap.rs @@ -220,10 +220,12 @@ impl ConcreteStorage { .get_current_block()? .ok_or(not_found!("Block for VMDatabase"))?; + let application_header = block.header().as_empty_application_header(); + let vm_database = VmStorage::new( view.into_transaction(), block.header().consensus(), - block.header().application(), + &application_header, // TODO: Use a real coinbase address Default::default(), ); diff --git a/crates/fuel-core/src/service/adapters/consensus_module.rs b/crates/fuel-core/src/service/adapters/consensus_module.rs index 484acaf4e8e..40d588d261e 100644 --- a/crates/fuel-core/src/service/adapters/consensus_module.rs +++ b/crates/fuel-core/src/service/adapters/consensus_module.rs @@ -40,7 +40,7 @@ impl VerifierAdapter { database: Database, ) -> Self { let block_height = *genesis_block.header().height(); - let da_block_height = genesis_block.header().da_height; + let da_block_height = genesis_block.header().da_height(); let config = VerifierConfig::new(consensus, block_height, da_block_height); Self { block_verifier: Arc::new(Verifier::new(config, database)), diff --git a/crates/fuel-core/src/service/adapters/consensus_parameters_provider.rs b/crates/fuel-core/src/service/adapters/consensus_parameters_provider.rs index 1553de47f64..db7c85f6bfe 100644 --- a/crates/fuel-core/src/service/adapters/consensus_parameters_provider.rs +++ b/crates/fuel-core/src/service/adapters/consensus_parameters_provider.rs @@ -124,8 +124,7 @@ impl RunnableTask for Task { .sealed_block .entity .header() - .application() - .consensus_parameters_version; + .consensus_parameters_version(); if new_version > *self.shared_state.latest_consensus_parameters_version.lock() { match self.shared_state.cache_consensus_parameters(new_version) { @@ -296,10 +295,7 @@ mod tests { version: ConsensusParametersVersion, ) -> SharedImportResult { let mut block = Block::default(); - block - .header_mut() - .application_mut() - .consensus_parameters_version = version; + block.header_mut().set_consensus_parameters_version(version); let sealed_block = SealedBlock { entity: block, consensus: Default::default(), diff --git a/crates/fuel-core/src/service/adapters/graphql_api/on_chain.rs b/crates/fuel-core/src/service/adapters/graphql_api/on_chain.rs index b3a6d860e76..9dc0c58a769 100644 --- a/crates/fuel-core/src/service/adapters/graphql_api/on_chain.rs +++ b/crates/fuel-core/src/service/adapters/graphql_api/on_chain.rs @@ -129,7 +129,7 @@ impl DatabaseContracts for OnChainIterableKeyValueView { impl DatabaseChain for OnChainIterableKeyValueView { fn da_height(&self) -> StorageResult { self.latest_compressed_block()? - .map(|block| block.header().da_height) + .map(|block| block.header().da_height()) .ok_or(not_found!("DaBlockHeight")) } } diff --git a/crates/fuel-core/src/service/genesis.rs b/crates/fuel-core/src/service/genesis.rs index e3d7bf3ff0a..0689bb4a57c 100644 --- a/crates/fuel-core/src/service/genesis.rs +++ b/crates/fuel-core/src/service/genesis.rs @@ -136,7 +136,7 @@ pub async fn execute_genesis_block( database_transaction_on_chain .storage_as_mut::() .insert( - &genesis_block.header().consensus_parameters_version, + &genesis_block.header().consensus_parameters_version(), &chain_config.consensus_parameters, )?; @@ -144,7 +144,7 @@ pub async fn execute_genesis_block( database_transaction_on_chain .storage_as_mut::() .insert( - &genesis_block.header().state_transition_bytecode_version, + &genesis_block.header().state_transition_bytecode_version(), &bytecode_root, )?; database_transaction_on_chain @@ -723,7 +723,7 @@ mod tests { .latest_block() .unwrap() .header() - .state_transition_bytecode_version; + .state_transition_bytecode_version(); last_block.blocks_root = view .block_header_merkle_root(&last_block.block_height) .unwrap(); diff --git a/crates/fuel-core/src/service/genesis/importer.rs b/crates/fuel-core/src/service/genesis/importer.rs index cb6206a976c..c7da7a9c747 100644 --- a/crates/fuel-core/src/service/genesis/importer.rs +++ b/crates/fuel-core/src/service/genesis/importer.rs @@ -179,7 +179,7 @@ impl SnapshotImporter { } let block_height = *self.genesis_block.header().height(); - let da_block_height = self.genesis_block.header().da_height; + let da_block_height = self.genesis_block.header().da_height(); let db = self.db.on_chain().clone(); let migration_name = migration_name::(); @@ -233,7 +233,7 @@ impl SnapshotImporter { } let block_height = *self.genesis_block.header().height(); - let da_block_height = self.genesis_block.header().da_height; + let da_block_height = self.genesis_block.header().da_height(); let db = self.db.off_chain().clone(); diff --git a/crates/services/consensus_module/Cargo.toml b/crates/services/consensus_module/Cargo.toml index bced45bbcf2..b8f1fd2c90c 100644 --- a/crates/services/consensus_module/Cargo.toml +++ b/crates/services/consensus_module/Cargo.toml @@ -19,3 +19,11 @@ fuel-core-types = { workspace = true, features = ["std"] } [dev-dependencies] fuel-core-types = { path = "../../types", features = ["test-helpers"] } test-case = { workspace = true } + +[features] +fault-proving = [ + "fuel-core-types/fault-proving", + "fuel-core-storage/fault-proving", + "fuel-core-poa/fault-proving", + "fuel-core-chain-config/fault-proving", +] diff --git a/crates/services/consensus_module/poa/src/verifier.rs b/crates/services/consensus_module/poa/src/verifier.rs index 3f25e72ca71..48006b53bfd 100644 --- a/crates/services/consensus_module/poa/src/verifier.rs +++ b/crates/services/consensus_module/poa/src/verifier.rs @@ -5,7 +5,10 @@ use fuel_core_types::{ blockchain::{ block::Block, consensus::poa::PoAConsensus, - header::BlockHeader, + header::{ + BlockHeader, + GetBlockHeaderFields, + }, }, fuel_tx::Input, }; @@ -61,7 +64,7 @@ pub fn verify_block_fields( let prev_header = database.block_header(&prev_height)?; ensure!( - header.da_height >= prev_header.da_height, + header.da_height() >= prev_header.da_height(), "The `da_height` of the next block can't be lower" ); @@ -70,8 +73,14 @@ pub fn verify_block_fields( "The `time` of the next block can't be lower" ); + let application_header_hash = match header { + BlockHeader::V1(header) => &header.application().hash(), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => &header.application().hash(), + }; + ensure!( - header.application_hash() == &header.application().hash(), + header.application_hash() == application_header_hash, "The application hash mismatch." ); diff --git a/crates/services/consensus_module/poa/src/verifier/tests.rs b/crates/services/consensus_module/poa/src/verifier/tests.rs index f8450bc9f93..8d45fb63213 100644 --- a/crates/services/consensus_module/poa/src/verifier/tests.rs +++ b/crates/services/consensus_module/poa/src/verifier/tests.rs @@ -4,9 +4,8 @@ use fuel_core_poa::ports::MockDatabase; use fuel_core_types::{ blockchain::header::{ ApplicationHeader, + BlockHeaderDataTestHelpers, ConsensusHeader, - GeneratedApplicationFields, - GeneratedConsensusFields, PartialBlockHeader, }, fuel_tx::Transaction, @@ -18,8 +17,7 @@ struct Input { block_header_merkle_root: [u8; 32], prev_header_time: Tai64, prev_header_da_height: u64, - ch: ConsensusHeader, - ah: ApplicationHeader, + bh: BlockHeader, txs: Vec, } @@ -51,8 +49,7 @@ fn correct() -> Input { block_header_merkle_root: [2u8; 32], prev_header_time: Tai64(2), prev_header_da_height: 2, - ch: *block_header.consensus(), - ah: *block_header.application(), + bh: block_header, txs, } } @@ -61,35 +58,35 @@ fn correct() -> Input { #[test_case( { let mut i = correct(); - i.ch.height = 0u32.into(); + i.bh.set_block_height(0u32.into()); i } => matches Err(_) ; "Height 0" )] #[test_case( { let mut i = correct(); - i.ch.prev_root = [3u8; 32].into(); + i.bh.set_previous_root([3u8; 32].into()); i } => matches Err(_) ; "genesis verify prev root mismatch should error" )] #[test_case( { let mut i = correct(); - i.ah.da_height = 1u64.into(); + i.bh.set_da_height(1u64.into()); i } => matches Err(_) ; "genesis verify da height lower then prev header should error" )] #[test_case( { let mut i = correct(); - i.ch.generated.application_hash = [0u8; 32].into(); + i.bh.set_application_hash([0u8; 32].into()); i } => matches Err(_) ; "genesis verify application hash mismatch should error" )] #[test_case( { let mut i = correct(); - i.ch.time = Tai64(1); + i.bh.set_time(Tai64(1)); i } => matches Err(_) ; "genesis verify time before prev header should error" )] @@ -105,8 +102,7 @@ fn test_verify_genesis_block_fields(input: Input) -> anyhow::Result<()> { block_header_merkle_root, prev_header_time, prev_header_da_height, - ch, - ah, + bh, txs, } = input; let mut d = MockDatabase::default(); @@ -119,8 +115,18 @@ fn test_verify_genesis_block_fields(input: Input) -> anyhow::Result<()> { Ok(h) }); let mut b = Block::default(); - b.header_mut().set_consensus_header(ch); - b.header_mut().set_application_header(ah); + b.header_mut().set_consensus_header(*bh.consensus()); + match (bh, b.header_mut()) { + (BlockHeader::V1(bh), BlockHeader::V1(ref mut h)) => { + h.set_application_header(*bh.application()) + } + #[cfg(feature = "fault-proving")] + (BlockHeader::V2(bh), BlockHeader::V2(ref mut h)) => { + h.set_application_header(*bh.application()) + } + #[cfg_attr(not(feature = "fault-proving"), allow(unreachable_patterns))] + _ => unreachable!(), + } *b.transactions_mut() = txs; verify_block_fields(&d, &b) } diff --git a/crates/services/consensus_module/src/block_verifier.rs b/crates/services/consensus_module/src/block_verifier.rs index bd47ec5d3b2..662ab9934aa 100644 --- a/crates/services/consensus_module/src/block_verifier.rs +++ b/crates/services/consensus_module/src/block_verifier.rs @@ -106,7 +106,7 @@ fn verify_genesis_block_fields( "The genesis time should be unix epoch time" ); ensure!( - header.da_height == expected_genesis_da_height, + header.da_height() == expected_genesis_da_height, "The genesis `da_height` is not as expected" ); ensure!( diff --git a/crates/services/consensus_module/src/block_verifier/tests.rs b/crates/services/consensus_module/src/block_verifier/tests.rs index 935f3514ffd..3f31c2e9005 100644 --- a/crates/services/consensus_module/src/block_verifier/tests.rs +++ b/crates/services/consensus_module/src/block_verifier/tests.rs @@ -26,7 +26,7 @@ use test_case::test_case; let mut h = BlockHeader::default(); h.set_previous_root(Bytes32::zeroed()); h.set_time(Tai64::UNIX_EPOCH); - h.application_mut().da_height = 1234u64.into(); + h.set_da_height(1234u64.into()); h }, 0, 1234 => matches Ok(_) ; "Correct header at `1234` da height" @@ -37,7 +37,7 @@ use test_case::test_case; h.set_previous_root(Bytes32::zeroed()); h.set_time(Tai64::UNIX_EPOCH); h.set_block_height(113u32.into()); - h.application_mut().da_height = 1234u64.into(); + h.set_da_height(1234u64.into()); h }, 113, 1234 => matches Ok(_) ; "Correct header at `113` height and at `1234` da height" @@ -67,7 +67,7 @@ use test_case::test_case; let mut h = BlockHeader::default(); h.set_previous_root(Bytes32::zeroed()); h.set_time(Tai64::UNIX_EPOCH); - h.application_mut().da_height = 1234u64.into(); + h.set_da_height(1234u64.into()); h }, 0, 0 => matches Err(_) ; "wrong header da height" diff --git a/crates/services/executor/src/executor.rs b/crates/services/executor/src/executor.rs index d4ce6102b17..22d03c51468 100644 --- a/crates/services/executor/src/executor.rs +++ b/crates/services/executor/src/executor.rs @@ -343,7 +343,7 @@ where self, block: &Block, ) -> ExecutorResult> { - let consensus_params_version = block.header().consensus_parameters_version; + let consensus_params_version = block.header().consensus_parameters_version(); let (block_executor, storage_tx) = self.into_executor(consensus_params_version)?; @@ -916,7 +916,7 @@ where .storage::() .get(&prev_block_height)? .ok_or(ExecutorError::PreviousBlockIsNotFound)?; - let previous_da_height = prev_block_header.header().da_height; + let previous_da_height = prev_block_header.header().da_height(); let Some(next_unprocessed_da_height) = previous_da_height.0.checked_add(1) else { return Err(ExecutorError::DaHeightExceededItsLimit) }; diff --git a/crates/services/gas_price_service/src/common/l2_block_source.rs b/crates/services/gas_price_service/src/common/l2_block_source.rs index d53a489bcbc..40490fb8382 100644 --- a/crates/services/gas_price_service/src/common/l2_block_source.rs +++ b/crates/services/gas_price_service/src/common/l2_block_source.rs @@ -69,7 +69,7 @@ where }), std::cmp::Ordering::Equal => Ok(BlockInfo::GenesisBlock), std::cmp::Ordering::Greater => { - let param_version = block.header().consensus_parameters_version; + let param_version = block.header().consensus_parameters_version(); let GasPriceSettings { gas_price_factor, diff --git a/crates/services/gas_price_service/src/v0/uninitialized_task.rs b/crates/services/gas_price_service/src/v0/uninitialized_task.rs index a32ea99c0e3..d0cb57c28ef 100644 --- a/crates/services/gas_price_service/src/v0/uninitialized_task.rs +++ b/crates/services/gas_price_service/src/v0/uninitialized_task.rs @@ -296,7 +296,7 @@ where let block = view .get_block(&height.into())? .ok_or(not_found!("FullBlock"))?; - let param_version = block.header().consensus_parameters_version; + let param_version = block.header().consensus_parameters_version(); let GasPriceSettings { gas_price_factor, diff --git a/crates/services/gas_price_service/src/v1/uninitialized_task.rs b/crates/services/gas_price_service/src/v1/uninitialized_task.rs index 35a1efdba53..85a0151093e 100644 --- a/crates/services/gas_price_service/src/v1/uninitialized_task.rs +++ b/crates/services/gas_price_service/src/v1/uninitialized_task.rs @@ -337,7 +337,7 @@ where let block = view .get_block(&height.into())? .ok_or(not_found!("FullBlock"))?; - let param_version = block.header().consensus_parameters_version; + let param_version = block.header().consensus_parameters_version(); let GasPriceSettings { gas_price_factor, diff --git a/crates/services/p2p/Cargo.toml b/crates/services/p2p/Cargo.toml index 158f16f836f..fac5d162870 100644 --- a/crates/services/p2p/Cargo.toml +++ b/crates/services/p2p/Cargo.toml @@ -72,3 +72,8 @@ version = "0.3.0" [features] test-helpers = ["fuel-core-types/test-helpers"] +fault-proving = [ + "fuel-core-types/fault-proving", + "fuel-core-storage/fault-proving", + "fuel-core-chain-config/fault-proving", +] diff --git a/crates/services/p2p/src/p2p_service.rs b/crates/services/p2p/src/p2p_service.rs index f40aa702e59..5b83ba6ee87 100644 --- a/crates/services/p2p/src/p2p_service.rs +++ b/crates/services/p2p/src/p2p_service.rs @@ -122,10 +122,10 @@ pub struct FuelP2PService { /// to the peer that requested it. inbound_requests_table: HashMap>, - /// NetworkCodec used as `` for encoding and decoding of Gossipsub messages + /// NetworkCodec used as `` for encoding and decoding of Gossipsub messages network_codec: PostcardCodec, - /// Stores additional p2p network info + /// Stores additional p2p network info network_metadata: NetworkMetadata, /// Whether or not metrics collection is enabled @@ -875,7 +875,10 @@ mod tests { poa::PoAConsensus, Consensus, }, - header::BlockHeader, + header::{ + BlockHeader, + GetBlockHeaderFields, + }, SealedBlockHeader, }, fuel_tx::{ @@ -1716,8 +1719,18 @@ mod tests { // Metadata gets skipped during serialization, so this is the fuzzy way to compare blocks fn eq_except_metadata(a: &SealedBlockHeader, b: &SealedBlockHeader) -> bool { - a.entity.application() == b.entity.application() - && a.entity.consensus() == b.entity.consensus() + let app_eq = match (&a.entity, &b.entity) { + (BlockHeader::V1(a), BlockHeader::V1(b)) => { + a.application() == b.application() + } + #[cfg(feature = "fault-proving")] + (BlockHeader::V2(a), BlockHeader::V2(b)) => { + a.application() == b.application() + } + #[cfg_attr(not(feature = "fault-proving"), allow(unreachable_patterns))] + _ => false, + }; + app_eq && a.entity.consensus() == b.entity.consensus() } async fn request_response_works_with(request_msg: RequestMessage) { diff --git a/crates/services/producer/src/block_producer.rs b/crates/services/producer/src/block_producer.rs index d8dd3bcf133..d3917b23227 100644 --- a/crates/services/producer/src/block_producer.rs +++ b/crates/services/producer/src/block_producer.rs @@ -125,7 +125,7 @@ where let block_time = predefined_block.header().consensus().time; - let da_height = predefined_block.header().application().da_height; + let da_height = predefined_block.header().da_height(); let view = self.view_provider.latest_view()?; @@ -522,7 +522,7 @@ where Ok(PreviousBlockInfo { prev_root, - da_height: previous_block.header().da_height, + da_height: previous_block.header().da_height(), }) } } diff --git a/crates/services/producer/src/block_producer/tests.rs b/crates/services/producer/src/block_producer/tests.rs index f6bd0427cf3..d65432a62c1 100644 --- a/crates/services/producer/src/block_producer/tests.rs +++ b/crates/services/producer/src/block_producer/tests.rs @@ -221,7 +221,7 @@ mod produce_and_execute_block_txpool { // Then let header = result.block.header(); assert_eq!( - header.consensus_parameters_version, + header.consensus_parameters_version(), consensus_parameters_version ); } @@ -279,7 +279,7 @@ mod produce_and_execute_block_txpool { // Then let header = result.block.header(); assert_eq!( - header.state_transition_bytecode_version, + header.state_transition_bytecode_version(), state_transition_bytecode_version ); } @@ -399,13 +399,7 @@ mod produce_and_execute_block_txpool { // then let expected = prev_da_height + 3; - let actual: u64 = res - .into_result() - .block - .header() - .application() - .da_height - .into(); + let actual: u64 = res.into_result().block.header().da_height().into(); assert_eq!(expected, actual); } @@ -445,13 +439,7 @@ mod produce_and_execute_block_txpool { // then let expected = prev_da_height + 3; - let actual: u64 = res - .into_result() - .block - .header() - .application() - .da_height - .into(); + let actual: u64 = res.into_result().block.header().da_height().into(); assert_eq!(expected, actual); } @@ -495,13 +483,7 @@ mod produce_and_execute_block_txpool { // then let expected = prev_da_height + i; - let actual: u64 = res - .into_result() - .block - .header() - .application() - .da_height - .into(); + let actual: u64 = res.into_result().block.header().da_height().into(); assert_eq!(expected, actual); } } @@ -754,7 +736,7 @@ fn ctx_for_block( executor: MockExecutorWithCapture, ) -> TestContext { let prev_height = block.header().height().pred().unwrap(); - let prev_da_height = block.header().da_height.as_u64() - 1; + let prev_da_height = block.header().da_height().as_u64() - 1; TestContextBuilder::new() .with_prev_height(prev_height) .with_prev_da_height(prev_da_height.into()) @@ -833,7 +815,7 @@ proptest! { let _ = rt.block_on(ctx.producer().produce_and_execute_predefined(&block)).unwrap(); // then - let expected_da_height = block.header().application().da_height; + let expected_da_height = block.header().da_height(); let captured = executor.captured.lock().unwrap(); let actual = captured.as_ref().unwrap().header_to_produce.application.da_height; assert_eq!(expected_da_height, actual); diff --git a/crates/services/sync/src/import.rs b/crates/services/sync/src/import.rs index f3d93359183..c535a78bee1 100644 --- a/crates/services/sync/src/import.rs +++ b/crates/services/sync/src/import.rs @@ -526,7 +526,7 @@ async fn await_da_height( consensus: &Arc, ) { let _ = consensus - .await_da_height(&header.entity.da_height) + .await_da_height(&header.entity.da_height()) .await .trace_err("Failed to wait for DA layer to sync"); } diff --git a/crates/services/upgradable-executor/src/executor.rs b/crates/services/upgradable-executor/src/executor.rs index 426c8479cf8..69af9042a3f 100644 --- a/crates/services/upgradable-executor/src/executor.rs +++ b/crates/services/upgradable-executor/src/executor.rs @@ -439,7 +439,7 @@ where block: &Block, options: ExecutionOptions, ) -> ExecutorResult> { - let block_version = block.header().state_transition_bytecode_version; + let block_version = block.header().state_transition_bytecode_version(); let native_executor_version = self.native_executor_version(); if block_version == native_executor_version { match &self.execution_strategy { @@ -475,7 +475,7 @@ where block: &Block, options: ExecutionOptions, ) -> ExecutorResult> { - let block_version = block.header().state_transition_bytecode_version; + let block_version = block.header().state_transition_bytecode_version(); let native_executor_version = self.native_executor_version(); if block_version == native_executor_version { self.native_validate_inner(block, options) @@ -572,7 +572,7 @@ where options: ExecutionOptions, ) -> ExecutorResult> { self.trace_block_version_warning( - block.header().state_transition_bytecode_version, + block.header().state_transition_bytecode_version(), ); let previous_block_height = block.header().height().pred(); diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index cbf9cd7753c..e7377efd0d2 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -24,7 +24,6 @@ derivative = { version = "2", default-features = false, optional = true, feature "use_core", ] } derive_more = { version = "0.99" } -enum_dispatch = { workspace = true } fuel-vm-private = { workspace = true, default-features = false, features = [ "alloc", ] } diff --git a/crates/types/src/blockchain/block.rs b/crates/types/src/blockchain/block.rs index 2d045d1e996..f8914aa33da 100644 --- a/crates/types/src/blockchain/block.rs +++ b/crates/types/src/blockchain/block.rs @@ -17,6 +17,7 @@ use crate::{ blockchain::header::{ BlockHeaderError, BlockHeaderV1, + GetBlockHeaderFields, }, fuel_tx::{ Transaction, @@ -116,12 +117,21 @@ impl Block { header: BlockHeader, transactions: Vec, ) -> Option { - header - .validate_transactions(&transactions) - .then_some(Block::V1(BlockV1 { - header, - transactions, - })) + match header { + BlockHeader::V1(ref header_v1) => header_v1 + .validate_transactions(&transactions) + .then_some(Block::V1(BlockV1 { + header, + transactions, + })), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(ref header_v2) => header_v2 + .validate_transactions(&transactions) + .then_some(Block::V1(BlockV1 { + header, + transactions, + })), + } } /// Compresses the fuel block and replaces transactions with hashes. @@ -178,8 +188,18 @@ impl Block { // identifier on the fly. // // This assertion is a double-checks that this behavior is not changed. - debug_assert_eq!(self.header().id(), self.header().hash()); - self.header().id() + let header = self.header(); + match header { + BlockHeader::V1(header_v1) => { + debug_assert_eq!(header_v1.id(), header_v1.hash()); + header_v1.id() + } + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header_v2) => { + debug_assert_eq!(header_v2.id(), header_v2.hash()); + header_v2.id() + } + } } /// Get the executed transactions. diff --git a/crates/types/src/blockchain/header.rs b/crates/types/src/blockchain/header.rs index 60a739dc9bb..360cf829dd6 100644 --- a/crates/types/src/blockchain/header.rs +++ b/crates/types/src/blockchain/header.rs @@ -24,24 +24,18 @@ use crate::{ MessageId, }, }; -use enum_dispatch::enum_dispatch; use tai64::Tai64; pub use v1::BlockHeaderV1; +use v1::GeneratedApplicationFieldsV1; #[cfg(feature = "fault-proving")] -pub use v2::{ - BlockHeaderV2, - FaultProvingHeader, -}; +pub use v2::BlockHeaderV2; +#[cfg(feature = "fault-proving")] +use v2::GeneratedApplicationFieldsV2; /// Version-able block header type #[derive(Clone, Debug, derivative::Derivative)] #[derivative(PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[enum_dispatch(GetBlockHeaderFields)] -#[cfg_attr( - any(test, feature = "test-helpers"), - enum_dispatch(BlockHeaderDataTestHelpers) -)] pub enum BlockHeader { /// V1 BlockHeader V1(BlockHeaderV1), @@ -51,12 +45,11 @@ pub enum BlockHeader { } /// Helpful methods for all variants of the block header. -#[enum_dispatch] -pub(crate) trait GetBlockHeaderFields { +pub trait GetBlockHeaderFields { /// Get the consensus portion of the header. fn consensus(&self) -> &ConsensusHeader; /// Get the application portion of the header. - fn application(&self) -> &ApplicationHeader; + fn application(&self) -> &ApplicationHeader; /// Get the metadata of the header. fn metadata(&self) -> &Option; /// Re-generate the header metadata. @@ -65,147 +58,294 @@ pub(crate) trait GetBlockHeaderFields { fn hash(&self) -> BlockId; /// Get the transaction ID Commitment fn tx_id_commitment(&self) -> Option; + /// Get the block ID + fn id(&self) -> BlockId; + /// Validate the transactions match the header. + fn validate_transactions(&self, transactions: &[Transaction]) -> bool; } -// reimplement GetBlockHeaderFields but with plain impl -// since both v1 and v2 support the fields, each function can just do -// GetBlockHeaderFields::fn(&self) impl BlockHeader { + /// Get the da height + pub fn da_height(&self) -> DaBlockHeight { + match self { + BlockHeader::V1(header) => header.application().da_height, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.application().da_height, + } + } + + /// Get the consensus parameters version + pub fn consensus_parameters_version(&self) -> ConsensusParametersVersion { + match self { + BlockHeader::V1(header) => header.application().consensus_parameters_version, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.application().consensus_parameters_version, + } + } + + /// Get the state transition bytecode version + pub fn state_transition_bytecode_version(&self) -> StateTransitionBytecodeVersion { + match self { + BlockHeader::V1(header) => { + header.application().state_transition_bytecode_version + } + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => { + header.application().state_transition_bytecode_version + } + } + } + /// Get the consensus portion of the header. pub fn consensus(&self) -> &ConsensusHeader { - GetBlockHeaderFields::consensus(self) + match self { + BlockHeader::V1(header) => header.consensus(), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.consensus(), + } } - /// Get the application portion of the header. - pub fn application(&self) -> &ApplicationHeader { - GetBlockHeaderFields::application(self) + /// Get the Block ID + pub fn id(&self) -> BlockId { + match self { + BlockHeader::V1(header) => header.id(), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.id(), + } } - /// Get the metadata of the header. - pub fn metadata(&self) -> &Option { - GetBlockHeaderFields::metadata(self) + /// Validate the transactions + pub fn validate_transactions(&self, transactions: &[Transaction]) -> bool { + match self { + BlockHeader::V1(header) => header.validate_transactions(transactions), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.validate_transactions(transactions), + } } - /// Re-generate the header metadata. + /// Recalculate the metadata pub fn recalculate_metadata(&mut self) { - GetBlockHeaderFields::recalculate_metadata(self) + match self { + BlockHeader::V1(header) => header.recalculate_metadata(), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.recalculate_metadata(), + } } - /// Get the hash of the fuel header. - pub fn hash(&self) -> BlockId { - GetBlockHeaderFields::hash(self) + /// Getter for the transactions root + pub fn transactions_root(&self) -> Bytes32 { + match self { + BlockHeader::V1(header) => header.application().transactions_root, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.application().transactions_root, + } } - /// Get the cached fuel header hash. - pub fn id(&self) -> BlockId { - if let Some(ref metadata) = self.metadata() { - metadata.id - } else { - self.hash() + /// Getter for the transactions count + pub fn transactions_count(&self) -> u16 { + match self { + BlockHeader::V1(header) => header.application().transactions_count, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.application().transactions_count, } } - /// Validate the transactions match the header. - pub fn validate_transactions(&self, transactions: &[Transaction]) -> bool { - let transactions_root = generate_txns_root(transactions); + /// Getter for the message receipt count + pub fn message_receipt_count(&self) -> u32 { + match self { + BlockHeader::V1(header) => header.application().message_receipt_count, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.application().message_receipt_count, + } + } - transactions_root == self.application().transactions_root - && transactions.len() == self.application().transactions_count as usize + /// Getter for the message outbox root + pub fn message_outbox_root(&self) -> Bytes32 { + match self { + BlockHeader::V1(header) => header.application().message_outbox_root, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.application().message_outbox_root, + } } - /// Getter for the tx id commitment + /// Getter for the event inbox root + pub fn event_inbox_root(&self) -> Bytes32 { + match self { + BlockHeader::V1(header) => header.application().event_inbox_root, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.application().event_inbox_root, + } + } + + /// Getter for the transaction ID commitment pub fn tx_id_commitment(&self) -> Option { - GetBlockHeaderFields::tx_id_commitment(self) + match self { + BlockHeader::V1(header) => header.tx_id_commitment(), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.tx_id_commitment(), + } } -} -/// Helpful test methods for all variants of the block header. -#[cfg(any(test, feature = "test-helpers"))] -#[enum_dispatch] -pub(crate) trait BlockHeaderDataTestHelpers { - /// Mutable getter for consensus portion of header - fn consensus_mut(&mut self) -> &mut ConsensusHeader; - /// Set the entire consensus header - fn set_consensus_header( - &mut self, - consensus: ConsensusHeader, - ); - /// Mutable getter for application portion of header - fn application_mut(&mut self) -> &mut ApplicationHeader; - /// Set the entire application header - fn set_application_header( - &mut self, - application: ApplicationHeader, - ); - /// Set the block height for the header - fn set_block_height(&mut self, height: BlockHeight); - /// Set the previous root for the header - fn set_previous_root(&mut self, root: Bytes32); - /// Set the time for the header - fn set_time(&mut self, time: Tai64); - /// Set the transaction root for the header - fn set_transaction_root(&mut self, root: Bytes32); - /// Set the DA height for the header - fn set_da_height(&mut self, da_height: DaBlockHeight); + /// Alias the application header into an empty one. + pub fn as_empty_application_header(&self) -> ApplicationHeader { + match self { + BlockHeader::V1(header) => ApplicationHeader { + da_height: header.application().da_height, + consensus_parameters_version: header + .application() + .consensus_parameters_version, + state_transition_bytecode_version: header + .application() + .state_transition_bytecode_version, + generated: Empty {}, + }, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => ApplicationHeader { + da_height: header.application().da_height, + consensus_parameters_version: header + .application() + .consensus_parameters_version, + state_transition_bytecode_version: header + .application() + .state_transition_bytecode_version, + generated: Empty {}, + }, + } + } } -/// Reimplement helpers so that its easy to import #[cfg(any(test, feature = "test-helpers"))] impl BlockHeader { - /// Mutable getter for consensus portion of header - pub fn consensus_mut(&mut self) -> &mut ConsensusHeader { - BlockHeaderDataTestHelpers::consensus_mut(self) + /// Set the time for the header + pub fn set_time(&mut self, time: Tai64) { + match self { + BlockHeader::V1(header) => header.set_time(time), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.set_time(time), + } } - /// Set the entire consensus header + /// Set the da height for the header + pub fn set_da_height(&mut self, da_height: DaBlockHeight) { + match self { + BlockHeader::V1(header) => header.set_da_height(da_height), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.set_da_height(da_height), + } + } + + /// Set the consensus header pub fn set_consensus_header( &mut self, consensus: ConsensusHeader, ) { - BlockHeaderDataTestHelpers::set_consensus_header(self, consensus) - } - - /// Mutable getter for application portion of header - pub fn application_mut( - &mut self, - ) -> &mut ApplicationHeader { - BlockHeaderDataTestHelpers::application_mut(self) + match self { + BlockHeader::V1(header) => header.set_consensus_header(consensus), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.set_consensus_header(consensus), + } } - /// Set the entire application header - pub fn set_application_header( - &mut self, - application: ApplicationHeader, - ) { - BlockHeaderDataTestHelpers::set_application_header(self, application) + /// Set the previous root for the header + pub fn set_previous_root(&mut self, root: Bytes32) { + match self { + BlockHeader::V1(header) => header.set_previous_root(root), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.set_previous_root(root), + } } /// Set the block height for the header pub fn set_block_height(&mut self, height: BlockHeight) { - BlockHeaderDataTestHelpers::set_block_height(self, height) - } - - /// Set the previous root for the header - pub fn set_previous_root(&mut self, root: Bytes32) { - BlockHeaderDataTestHelpers::set_previous_root(self, root) + match self { + BlockHeader::V1(header) => header.set_block_height(height), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.set_block_height(height), + } } - /// Set the time for the header - pub fn set_time(&mut self, time: Tai64) { - BlockHeaderDataTestHelpers::set_time(self, time) + /// Mutable getter for consensus portion of header + pub fn consensus_mut(&mut self) -> &mut ConsensusHeader { + match self { + BlockHeader::V1(header) => header.consensus_mut(), + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.consensus_mut(), + } } /// Set the transaction root for the header pub fn set_transaction_root(&mut self, root: Bytes32) { - BlockHeaderDataTestHelpers::set_transaction_root(self, root) + match self { + BlockHeader::V1(header) => { + header.set_transaction_root(root); + } + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => { + header.set_transaction_root(root); + } + } } - /// Set the DA height for the header - pub fn set_da_height(&mut self, da_height: DaBlockHeight) { - BlockHeaderDataTestHelpers::set_da_height(self, da_height) + /// Set the consensus parameters version + pub fn set_consensus_parameters_version( + &mut self, + version: ConsensusParametersVersion, + ) { + match self { + BlockHeader::V1(header) => { + header.set_consensus_parameters_version(version); + } + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => { + header.set_consensus_parameters_version(version); + } + } + } + + /// Set the application hash + pub fn set_application_hash(&mut self, hash: Bytes32) { + match self { + BlockHeader::V1(header) => { + header.set_application_hash(hash); + } + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => { + header.set_application_hash(hash); + } + } } } +/// Helpful test methods for all variants of the block header. +#[cfg(any(test, feature = "test-helpers"))] +pub trait BlockHeaderDataTestHelpers { + /// Mutable getter for consensus portion of header + fn consensus_mut(&mut self) -> &mut ConsensusHeader; + /// Set the entire consensus header + fn set_consensus_header( + &mut self, + consensus: ConsensusHeader, + ); + /// Mutable getter for application portion of header + fn application_mut(&mut self) -> &mut ApplicationHeader; + /// Set the entire application header + fn set_application_header(&mut self, application: ApplicationHeader); + /// Set the block height for the header + fn set_block_height(&mut self, height: BlockHeight); + /// Set the previous root for the header + fn set_previous_root(&mut self, root: Bytes32); + /// Set the time for the header + fn set_time(&mut self, time: Tai64); + /// Set the transaction root for the header + fn set_transaction_root(&mut self, root: Bytes32); + /// Set the DA height for the header + fn set_da_height(&mut self, da_height: DaBlockHeight); + /// Set the consensus parameters version + fn set_consensus_parameters_version(&mut self, version: ConsensusParametersVersion); + /// Set the application hash + fn set_application_hash(&mut self, hash: Bytes32); +} + #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default)] @@ -260,22 +400,24 @@ where } } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] -/// Concrete generated application header fields. -/// These are generated once the full block has been run. -pub struct GeneratedApplicationFields { - /// Number of transactions in this block. - pub transactions_count: u16, - /// Number of message receipts in this block. - pub message_receipt_count: u32, - /// Merkle root of transactions. - pub transactions_root: Bytes32, - /// Merkle root of message receipts in this block. - pub message_outbox_root: Bytes32, - /// Root hash of all imported events from L1 - pub event_inbox_root: Bytes32, +#[cfg(feature = "fault-proving")] +impl From<&ApplicationHeader> + for ApplicationHeader +{ + fn from(value: &ApplicationHeader) -> Self { + Self { + da_height: value.da_height, + consensus_parameters_version: value.consensus_parameters_version, + state_transition_bytecode_version: value.state_transition_bytecode_version, + generated: GeneratedApplicationFieldsV1 { + transactions_count: value.transactions_count, + message_receipt_count: value.message_receipt_count, + transactions_root: value.transactions_root, + message_outbox_root: value.message_outbox_root, + event_inbox_root: value.event_inbox_root, + }, + } + } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -315,9 +457,22 @@ pub struct BlockHeaderMetadata { #[cfg(any(test, feature = "test-helpers"))] impl Default for BlockHeader { fn default() -> Self { - let mut default: BlockHeader = BlockHeaderV1::default().into(); - default.recalculate_metadata(); - default + match () { + #[cfg(feature = "fault-proving")] + () => { + let mut default = BlockHeaderV2::default(); + default.recalculate_metadata(); + + BlockHeader::V2(default) + } + #[cfg(not(feature = "fault-proving"))] + () => { + let mut default = BlockHeaderV1::default(); + default.recalculate_metadata(); + + BlockHeader::V1(default) + } + } } } @@ -327,9 +482,19 @@ 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_mut().height = height; - default.consensus_mut().time = time; - default.recalculate_metadata(); + match default { + BlockHeader::V1(ref mut header) => { + header.consensus_mut().height = height; + header.consensus_mut().time = time; + header.recalculate_metadata(); + } + #[cfg(feature = "fault-proving")] + BlockHeader::V2(ref mut header) => { + header.consensus_mut().height = height; + header.consensus_mut().time = time; + header.recalculate_metadata(); + } + } default } } @@ -338,19 +503,35 @@ impl BlockHeader { impl BlockHeader { /// Merkle root of all previous block header hashes. pub fn prev_root(&self) -> &Bytes32 { - &self.as_ref().prev_root + match self { + BlockHeader::V1(header) => &header.consensus().prev_root, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => &header.consensus().prev_root, + } } /// Fuel block height. pub fn height(&self) -> &BlockHeight { - &self.as_ref().height + match self { + BlockHeader::V1(header) => &header.consensus().height, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => &header.consensus().height, + } } /// The block producer time. pub fn time(&self) -> Tai64 { - self.as_ref().time + match self { + BlockHeader::V1(header) => header.consensus().time, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => header.consensus().time, + } } /// The hash of the application header. pub fn application_hash(&self) -> &Bytes32 { - &self.as_ref().application_hash + match self { + BlockHeader::V1(header) => &header.consensus().application_hash, + #[cfg(feature = "fault-proving")] + BlockHeader::V2(header) => &header.consensus().application_hash, + } } /// The type of consensus this header is using. @@ -386,12 +567,17 @@ impl From<&BlockHeader> for PartialBlockHeader { time, .. } = *header.consensus(); + + let da_height = header.da_height(); + let consensus_parameters_version = header.consensus_parameters_version(); + let state_transition_bytecode_version = + header.state_transition_bytecode_version(); + PartialBlockHeader { application: ApplicationHeader { - da_height: header.da_height, - consensus_parameters_version: header.consensus_parameters_version, - state_transition_bytecode_version: header - .state_transition_bytecode_version, + da_height, + consensus_parameters_version, + state_transition_bytecode_version, generated: Empty {}, }, consensus: ConsensusHeader { @@ -448,26 +634,26 @@ impl PartialBlockHeader { .root() .into(); - let application = ApplicationHeader { - da_height: self.application.da_height, - consensus_parameters_version: self.application.consensus_parameters_version, - state_transition_bytecode_version: self - .application - .state_transition_bytecode_version, - generated: GeneratedApplicationFields { - transactions_count: u16::try_from(transactions.len()) - .map_err(|_| BlockHeaderError::TooManyTransactions)?, - message_receipt_count: u32::try_from(outbox_message_ids.len()) - .map_err(|_| BlockHeaderError::TooManyMessages)?, - transactions_root, - message_outbox_root, - event_inbox_root, - }, - }; - #[cfg(not(feature = "fault-proving"))] - let mut header: BlockHeader = BlockHeaderV1 { - application, + let mut header: BlockHeader = BlockHeader::V1(BlockHeaderV1 { + application: ApplicationHeader { + da_height: self.application.da_height, + consensus_parameters_version: self + .application + .consensus_parameters_version, + state_transition_bytecode_version: self + .application + .state_transition_bytecode_version, + generated: GeneratedApplicationFieldsV1 { + transactions_count: u16::try_from(transactions.len()) + .map_err(|_| BlockHeaderError::TooManyTransactions)?, + message_receipt_count: u32::try_from(outbox_message_ids.len()) + .map_err(|_| BlockHeaderError::TooManyMessages)?, + transactions_root, + message_outbox_root, + event_inbox_root, + }, + }, consensus: ConsensusHeader { prev_root: self.consensus.prev_root, height: self.consensus.height, @@ -478,12 +664,32 @@ impl PartialBlockHeader { }, }, metadata: None, - } - .into(); + }); #[cfg(feature = "fault-proving")] - let mut header: BlockHeader = BlockHeaderV2 { - application, + let mut header: BlockHeader = BlockHeader::V2(BlockHeaderV2 { + application: ApplicationHeader { + da_height: self.application.da_height, + consensus_parameters_version: self + .application + .consensus_parameters_version, + state_transition_bytecode_version: self + .application + .state_transition_bytecode_version, + generated: GeneratedApplicationFieldsV2 { + transactions_count: u16::try_from(transactions.len()) + .map_err(|_| BlockHeaderError::TooManyTransactions)?, + message_receipt_count: u32::try_from(outbox_message_ids.len()) + .map_err(|_| BlockHeaderError::TooManyMessages)?, + transactions_root, + message_outbox_root, + event_inbox_root, + tx_id_commitment: v2::generate_tx_id_commitment( + transactions, + chain_id, + ), + }, + }, consensus: ConsensusHeader { prev_root: self.consensus.prev_root, height: self.consensus.height, @@ -494,11 +700,7 @@ impl PartialBlockHeader { }, }, metadata: None, - fault_proving: FaultProvingHeader { - tx_id_commitment: v2::generate_tx_id_commitment(transactions, chain_id), - }, - } - .into(); + }); // Cache the hash. header.recalculate_metadata(); @@ -517,39 +719,6 @@ fn generate_txns_root(transactions: &[Transaction]) -> Bytes32 { transaction_tree.root().into() } -impl ApplicationHeader { - /// Hash the application header. - pub fn hash(&self) -> Bytes32 { - // Order matters and is the same as the spec. - let mut hasher = crate::fuel_crypto::Hasher::default(); - let Self { - da_height, - consensus_parameters_version, - state_transition_bytecode_version, - generated: - GeneratedApplicationFields { - transactions_count, - message_receipt_count, - transactions_root, - message_outbox_root, - event_inbox_root, - }, - } = self; - - hasher.input(da_height.to_be_bytes()); - hasher.input(consensus_parameters_version.to_be_bytes()); - hasher.input(state_transition_bytecode_version.to_be_bytes()); - - hasher.input(transactions_count.to_be_bytes()); - hasher.input(message_receipt_count.to_be_bytes()); - hasher.input(transactions_root.as_ref()); - hasher.input(message_outbox_root.as_ref()); - hasher.input(event_inbox_root.as_ref()); - - hasher.digest() - } -} - impl ConsensusHeader { /// Hash the consensus header. pub fn hash(&self) -> BlockId { @@ -586,14 +755,6 @@ where } } -impl core::ops::Deref for BlockHeader { - type Target = ApplicationHeader; - - fn deref(&self) -> &Self::Target { - self.application() - } -} - impl core::ops::Deref for PartialBlockHeader { type Target = ApplicationHeader; @@ -602,14 +763,6 @@ impl core::ops::Deref for PartialBlockHeader { } } -impl core::ops::Deref for ApplicationHeader { - type Target = GeneratedApplicationFields; - - fn deref(&self) -> &Self::Target { - &self.generated - } -} - impl core::ops::Deref for ConsensusHeader { type Target = GeneratedConsensusFields; @@ -618,12 +771,6 @@ impl core::ops::Deref for ConsensusHeader { } } -impl core::convert::AsRef> for BlockHeader { - fn as_ref(&self) -> &ConsensusHeader { - self.consensus() - } -} - impl core::convert::AsRef> for PartialBlockHeader { fn as_ref(&self) -> &ConsensusHeader { &self.consensus diff --git a/crates/types/src/blockchain/header/v1.rs b/crates/types/src/blockchain/header/v1.rs index cfa4d5fe999..85b5368a799 100644 --- a/crates/types/src/blockchain/header/v1.rs +++ b/crates/types/src/blockchain/header/v1.rs @@ -1,16 +1,19 @@ use crate::{ blockchain::{ header::{ + generate_txns_root, ApplicationHeader, BlockHeaderMetadata, ConsensusHeader, - GeneratedApplicationFields, GeneratedConsensusFields, GetBlockHeaderFields, }, primitives::BlockId, }, - fuel_tx::Bytes32, + fuel_tx::{ + Bytes32, + Transaction, + }, }; /// A fuel block header that has all the fields generated because it @@ -21,9 +24,9 @@ use crate::{ #[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] pub struct BlockHeaderV1 { /// The application header. - pub application: ApplicationHeader, + pub(crate) application: ApplicationHeader, /// The consensus header. - pub consensus: ConsensusHeader, + pub(crate) consensus: ConsensusHeader, /// The header metadata calculated during creation. /// The field is pub(crate) to enforce the use of the [`PartialBlockHeader::generate`] method. #[cfg_attr(feature = "serde", serde(skip))] @@ -31,12 +34,12 @@ pub struct BlockHeaderV1 { pub(crate) metadata: Option, } -impl GetBlockHeaderFields for BlockHeaderV1 { +impl GetBlockHeaderFields for BlockHeaderV1 { fn consensus(&self) -> &ConsensusHeader { &self.consensus } - fn application(&self) -> &ApplicationHeader { + fn application(&self) -> &ApplicationHeader { &self.application } @@ -60,10 +63,27 @@ impl GetBlockHeaderFields for BlockHeaderV1 { fn tx_id_commitment(&self) -> Option { None } + + fn id(&self) -> BlockId { + if let Some(ref metadata) = self.metadata() { + metadata.id + } else { + self.hash() + } + } + + fn validate_transactions(&self, transactions: &[Transaction]) -> bool { + let transactions_root = generate_txns_root(transactions); + + transactions_root == self.application().transactions_root + && transactions.len() == self.application().transactions_count as usize + } } #[cfg(any(test, feature = "test-helpers"))] -impl crate::blockchain::header::BlockHeaderDataTestHelpers for BlockHeaderV1 { +impl crate::blockchain::header::BlockHeaderDataTestHelpers + for BlockHeaderV1 +{ fn consensus_mut(&mut self) -> &mut ConsensusHeader { &mut self.consensus } @@ -75,13 +95,15 @@ impl crate::blockchain::header::BlockHeaderDataTestHelpers for BlockHeaderV1 { self.consensus = consensus; } - fn application_mut(&mut self) -> &mut ApplicationHeader { + fn application_mut( + &mut self, + ) -> &mut ApplicationHeader { &mut self.application } fn set_application_header( &mut self, - application: ApplicationHeader, + application: ApplicationHeader, ) { self.application = application; } @@ -110,4 +132,75 @@ impl crate::blockchain::header::BlockHeaderDataTestHelpers for BlockHeaderV1 { self.application_mut().da_height = da_height; self.recalculate_metadata(); } + + fn set_consensus_parameters_version( + &mut self, + version: super::ConsensusParametersVersion, + ) { + self.application_mut().consensus_parameters_version = version; + self.recalculate_metadata(); + } + + fn set_application_hash(&mut self, hash: Bytes32) { + self.consensus_mut().generated.application_hash = hash; + } +} + +/// Concrete generated application header fields. +/// These are generated once the full block has been run. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +pub struct GeneratedApplicationFieldsV1 { + /// Number of transactions in this block. + pub transactions_count: u16, + /// Number of message receipts in this block. + pub message_receipt_count: u32, + /// Merkle root of transactions. + pub transactions_root: Bytes32, + /// Merkle root of message receipts in this block. + pub message_outbox_root: Bytes32, + /// Root hash of all imported events from L1 + pub event_inbox_root: Bytes32, +} + +impl ApplicationHeader { + /// Hash the application header. + pub fn hash(&self) -> Bytes32 { + // Order matters and is the same as the spec. + let mut hasher = crate::fuel_crypto::Hasher::default(); + let Self { + da_height, + consensus_parameters_version, + state_transition_bytecode_version, + generated: + GeneratedApplicationFieldsV1 { + transactions_count, + message_receipt_count, + transactions_root, + message_outbox_root, + event_inbox_root, + }, + } = self; + + hasher.input(da_height.to_be_bytes()); + hasher.input(consensus_parameters_version.to_be_bytes()); + hasher.input(state_transition_bytecode_version.to_be_bytes()); + + hasher.input(transactions_count.to_be_bytes()); + hasher.input(message_receipt_count.to_be_bytes()); + hasher.input(transactions_root.as_ref()); + hasher.input(message_outbox_root.as_ref()); + hasher.input(event_inbox_root.as_ref()); + + hasher.digest() + } +} + +impl core::ops::Deref for ApplicationHeader { + type Target = GeneratedApplicationFieldsV1; + + fn deref(&self) -> &Self::Target { + &self.generated + } } diff --git a/crates/types/src/blockchain/header/v2.rs b/crates/types/src/blockchain/header/v2.rs index 30d82bafa40..cb812e7ec58 100644 --- a/crates/types/src/blockchain/header/v2.rs +++ b/crates/types/src/blockchain/header/v2.rs @@ -1,10 +1,10 @@ use crate::{ blockchain::{ header::{ + generate_txns_root, ApplicationHeader, BlockHeaderMetadata, ConsensusHeader, - GeneratedApplicationFields, GeneratedConsensusFields, GetBlockHeaderFields, }, @@ -37,15 +37,6 @@ pub(crate) fn generate_tx_id_commitment( hasher.digest() } -/// The fault proving header -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct FaultProvingHeader { - /// The transaction id commitment - pub tx_id_commitment: Bytes32, -} - /// A fuel block header that has all the fields generated because it /// has been executed. /// differences from V1: @@ -56,24 +47,22 @@ pub struct FaultProvingHeader { #[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] pub struct BlockHeaderV2 { /// The application header. - pub application: ApplicationHeader, + pub(crate) application: ApplicationHeader, /// The consensus header. - pub consensus: ConsensusHeader, + pub(crate) consensus: ConsensusHeader, /// The header metadata calculated during creation. /// The field is private to enforce the use of the [`PartialBlockHeader::generate`] method. #[cfg_attr(feature = "serde", serde(skip))] #[derivative(PartialEq = "ignore")] pub(crate) metadata: Option, - /// fault proving relevant data - pub fault_proving: FaultProvingHeader, } -impl GetBlockHeaderFields for BlockHeaderV2 { +impl GetBlockHeaderFields for BlockHeaderV2 { fn consensus(&self) -> &ConsensusHeader { &self.consensus } - fn application(&self) -> &ApplicationHeader { + fn application(&self) -> &ApplicationHeader { &self.application } @@ -91,20 +80,33 @@ impl GetBlockHeaderFields for BlockHeaderV2 { fn hash(&self) -> BlockId { debug_assert_eq!(&self.consensus.application_hash, &self.application().hash()); // This internally hashes the hash of the application header. - let consensus_header_hash = self.consensus().hash(); - let mut hasher = fuel_crypto::Hasher::default(); - hasher.input::<&Bytes32>(consensus_header_hash.as_ref()); - hasher.input(self.fault_proving.tx_id_commitment.as_ref()); - hasher.digest().into() + self.consensus().hash() } fn tx_id_commitment(&self) -> Option { - Some(self.fault_proving.tx_id_commitment) + Some(self.application().tx_id_commitment) + } + + fn id(&self) -> BlockId { + if let Some(ref metadata) = self.metadata() { + metadata.id + } else { + self.hash() + } + } + + fn validate_transactions(&self, transactions: &[Transaction]) -> bool { + let transactions_root = generate_txns_root(transactions); + + transactions_root == self.application().transactions_root + && transactions.len() == self.application().transactions_count as usize } } #[cfg(any(test, feature = "test-helpers"))] -impl crate::blockchain::header::BlockHeaderDataTestHelpers for BlockHeaderV2 { +impl crate::blockchain::header::BlockHeaderDataTestHelpers + for BlockHeaderV2 +{ fn consensus_mut(&mut self) -> &mut ConsensusHeader { &mut self.consensus } @@ -116,13 +118,15 @@ impl crate::blockchain::header::BlockHeaderDataTestHelpers for BlockHeaderV2 { self.consensus = consensus; } - fn application_mut(&mut self) -> &mut ApplicationHeader { + fn application_mut( + &mut self, + ) -> &mut ApplicationHeader { &mut self.application } fn set_application_header( &mut self, - application: ApplicationHeader, + application: ApplicationHeader, ) { self.application = application; } @@ -151,4 +155,82 @@ impl crate::blockchain::header::BlockHeaderDataTestHelpers for BlockHeaderV2 { self.application_mut().da_height = da_height; self.recalculate_metadata(); } + + fn set_consensus_parameters_version( + &mut self, + version: super::ConsensusParametersVersion, + ) { + self.application_mut().consensus_parameters_version = version; + self.recalculate_metadata(); + } + + fn set_application_hash(&mut self, hash: Bytes32) { + self.consensus_mut().generated.application_hash = hash; + } +} + +/// Concrete generated application header fields. +/// These are generated once the full block has been run. +/// contains the tx_id_commitment field +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +pub struct GeneratedApplicationFieldsV2 { + /// Number of transactions in this block. + pub transactions_count: u16, + /// Number of message receipts in this block. + pub message_receipt_count: u32, + /// Merkle root of transactions. + pub transactions_root: Bytes32, + /// Merkle root of message receipts in this block. + pub message_outbox_root: Bytes32, + /// Root hash of all imported events from L1 + pub event_inbox_root: Bytes32, + /// tx id commitment + pub tx_id_commitment: Bytes32, +} + +impl ApplicationHeader { + /// Hash the application header. + pub fn hash(&self) -> Bytes32 { + // Order matters and is the same as the spec. + let mut hasher = crate::fuel_crypto::Hasher::default(); + let Self { + da_height, + consensus_parameters_version, + state_transition_bytecode_version, + generated: + GeneratedApplicationFieldsV2 { + transactions_count, + message_receipt_count, + transactions_root, + message_outbox_root, + event_inbox_root, + tx_id_commitment, + }, + } = self; + + hasher.input(da_height.to_be_bytes()); + hasher.input(consensus_parameters_version.to_be_bytes()); + hasher.input(state_transition_bytecode_version.to_be_bytes()); + + hasher.input(transactions_count.to_be_bytes()); + hasher.input(message_receipt_count.to_be_bytes()); + hasher.input(transactions_root.as_ref()); + hasher.input(message_outbox_root.as_ref()); + hasher.input(event_inbox_root.as_ref()); + + // this is the only difference between the two versions + hasher.input(tx_id_commitment.as_ref()); + + hasher.digest() + } +} + +impl core::ops::Deref for ApplicationHeader { + type Target = GeneratedApplicationFieldsV2; + + fn deref(&self) -> &Self::Target { + &self.generated + } } From 44326fdf4feeb54fb9c36a53a880acff6032dba9 Mon Sep 17 00:00:00 2001 From: Aaryamann Challani <43716372+rymnc@users.noreply.github.com> Date: Sat, 8 Feb 2025 03:37:14 +0530 Subject: [PATCH 2/4] fix: changelog and comment --- CHANGELOG.md | 4 ++++ crates/types/src/blockchain/header/v2.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb7c2f9ca6c..2c5a2295870 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [2648](https://github.com/FuelLabs/fuel-core/pull/2648): Add feature-flagged field to block header `fault_proving_header` that contains a commitment to all transaction ids. +### Breaking + +- [2678](https://github.com/FuelLabs/fuel-core/pull/2678): Removed public accessors for `BlockHeader` fields and replaced with methods instead, moved `tx_id_commitment` to the application header of `BlockHeaderV2`. + ## [Version 0.41.6] ### Added diff --git a/crates/types/src/blockchain/header/v2.rs b/crates/types/src/blockchain/header/v2.rs index cb812e7ec58..dcef462fc44 100644 --- a/crates/types/src/blockchain/header/v2.rs +++ b/crates/types/src/blockchain/header/v2.rs @@ -186,7 +186,7 @@ pub struct GeneratedApplicationFieldsV2 { pub message_outbox_root: Bytes32, /// Root hash of all imported events from L1 pub event_inbox_root: Bytes32, - /// tx id commitment + /// TxID commitment pub tx_id_commitment: Bytes32, } From a019d2fadb89c1322bf87ba7ac8bcf98b15042a9 Mon Sep 17 00:00:00 2001 From: Aaryamann Challani <43716372+rymnc@users.noreply.github.com> Date: Sat, 8 Feb 2025 03:37:51 +0530 Subject: [PATCH 3/4] fix: changelog more --- CHANGELOG.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c5a2295870..a73af2f972f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] -### Added - -- [2648](https://github.com/FuelLabs/fuel-core/pull/2648): Add feature-flagged field to block header `fault_proving_header` that contains a commitment to all transaction ids. - ### Breaking +- [2648](https://github.com/FuelLabs/fuel-core/pull/2648): Add feature-flagged field to block header `fault_proving_header` that contains a commitment to all transaction ids. - [2678](https://github.com/FuelLabs/fuel-core/pull/2678): Removed public accessors for `BlockHeader` fields and replaced with methods instead, moved `tx_id_commitment` to the application header of `BlockHeaderV2`. ## [Version 0.41.6] From 28a816a64b6f5e4bae82f3b1941dd5ed6dad3932 Mon Sep 17 00:00:00 2001 From: Aaryamann Challani <43716372+rymnc@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:20:11 +0530 Subject: [PATCH 4/4] fix: remove tb --- .../consensus_module/poa/src/verifier.rs | 5 +- .../poa/src/verifier/tests.rs | 1 - crates/services/p2p/src/p2p_service.rs | 5 +- crates/types/src/blockchain/block.rs | 22 +++----- crates/types/src/blockchain/header.rs | 50 ----------------- crates/types/src/blockchain/header/v1.rs | 53 ++++++++++--------- crates/types/src/blockchain/header/v2.rs | 53 ++++++++++--------- 7 files changed, 66 insertions(+), 123 deletions(-) diff --git a/crates/services/consensus_module/poa/src/verifier.rs b/crates/services/consensus_module/poa/src/verifier.rs index 48006b53bfd..6e34f606719 100644 --- a/crates/services/consensus_module/poa/src/verifier.rs +++ b/crates/services/consensus_module/poa/src/verifier.rs @@ -5,10 +5,7 @@ use fuel_core_types::{ blockchain::{ block::Block, consensus::poa::PoAConsensus, - header::{ - BlockHeader, - GetBlockHeaderFields, - }, + header::BlockHeader, }, fuel_tx::Input, }; diff --git a/crates/services/consensus_module/poa/src/verifier/tests.rs b/crates/services/consensus_module/poa/src/verifier/tests.rs index 8d45fb63213..80d0e2936eb 100644 --- a/crates/services/consensus_module/poa/src/verifier/tests.rs +++ b/crates/services/consensus_module/poa/src/verifier/tests.rs @@ -4,7 +4,6 @@ use fuel_core_poa::ports::MockDatabase; use fuel_core_types::{ blockchain::header::{ ApplicationHeader, - BlockHeaderDataTestHelpers, ConsensusHeader, PartialBlockHeader, }, diff --git a/crates/services/p2p/src/p2p_service.rs b/crates/services/p2p/src/p2p_service.rs index 5b83ba6ee87..69d44912122 100644 --- a/crates/services/p2p/src/p2p_service.rs +++ b/crates/services/p2p/src/p2p_service.rs @@ -875,10 +875,7 @@ mod tests { poa::PoAConsensus, Consensus, }, - header::{ - BlockHeader, - GetBlockHeaderFields, - }, + header::BlockHeader, SealedBlockHeader, }, fuel_tx::{ diff --git a/crates/types/src/blockchain/block.rs b/crates/types/src/blockchain/block.rs index f8914aa33da..bcb7ad56f17 100644 --- a/crates/types/src/blockchain/block.rs +++ b/crates/types/src/blockchain/block.rs @@ -17,7 +17,6 @@ use crate::{ blockchain::header::{ BlockHeaderError, BlockHeaderV1, - GetBlockHeaderFields, }, fuel_tx::{ Transaction, @@ -117,21 +116,12 @@ impl Block { header: BlockHeader, transactions: Vec, ) -> Option { - match header { - BlockHeader::V1(ref header_v1) => header_v1 - .validate_transactions(&transactions) - .then_some(Block::V1(BlockV1 { - header, - transactions, - })), - #[cfg(feature = "fault-proving")] - BlockHeader::V2(ref header_v2) => header_v2 - .validate_transactions(&transactions) - .then_some(Block::V1(BlockV1 { - header, - transactions, - })), - } + header + .validate_transactions(&transactions) + .then_some(Block::V1(BlockV1 { + header, + transactions, + })) } /// Compresses the fuel block and replaces transactions with hashes. diff --git a/crates/types/src/blockchain/header.rs b/crates/types/src/blockchain/header.rs index 360cf829dd6..b5dcf3d848e 100644 --- a/crates/types/src/blockchain/header.rs +++ b/crates/types/src/blockchain/header.rs @@ -44,26 +44,6 @@ pub enum BlockHeader { V2(BlockHeaderV2), } -/// Helpful methods for all variants of the block header. -pub trait GetBlockHeaderFields { - /// Get the consensus portion of the header. - fn consensus(&self) -> &ConsensusHeader; - /// Get the application portion of the header. - fn application(&self) -> &ApplicationHeader; - /// Get the metadata of the header. - fn metadata(&self) -> &Option; - /// Re-generate the header metadata. - fn recalculate_metadata(&mut self); - /// Get the hash of the fuel header. - fn hash(&self) -> BlockId; - /// Get the transaction ID Commitment - fn tx_id_commitment(&self) -> Option; - /// Get the block ID - fn id(&self) -> BlockId; - /// Validate the transactions match the header. - fn validate_transactions(&self, transactions: &[Transaction]) -> bool; -} - impl BlockHeader { /// Get the da height pub fn da_height(&self) -> DaBlockHeight { @@ -316,36 +296,6 @@ impl BlockHeader { } } -/// Helpful test methods for all variants of the block header. -#[cfg(any(test, feature = "test-helpers"))] -pub trait BlockHeaderDataTestHelpers { - /// Mutable getter for consensus portion of header - fn consensus_mut(&mut self) -> &mut ConsensusHeader; - /// Set the entire consensus header - fn set_consensus_header( - &mut self, - consensus: ConsensusHeader, - ); - /// Mutable getter for application portion of header - fn application_mut(&mut self) -> &mut ApplicationHeader; - /// Set the entire application header - fn set_application_header(&mut self, application: ApplicationHeader); - /// Set the block height for the header - fn set_block_height(&mut self, height: BlockHeight); - /// Set the previous root for the header - fn set_previous_root(&mut self, root: Bytes32); - /// Set the time for the header - fn set_time(&mut self, time: Tai64); - /// Set the transaction root for the header - fn set_transaction_root(&mut self, root: Bytes32); - /// Set the DA height for the header - fn set_da_height(&mut self, da_height: DaBlockHeight); - /// Set the consensus parameters version - fn set_consensus_parameters_version(&mut self, version: ConsensusParametersVersion); - /// Set the application hash - fn set_application_hash(&mut self, hash: Bytes32); -} - #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default)] diff --git a/crates/types/src/blockchain/header/v1.rs b/crates/types/src/blockchain/header/v1.rs index 85b5368a799..5f3f62b01c7 100644 --- a/crates/types/src/blockchain/header/v1.rs +++ b/crates/types/src/blockchain/header/v1.rs @@ -6,7 +6,6 @@ use crate::{ BlockHeaderMetadata, ConsensusHeader, GeneratedConsensusFields, - GetBlockHeaderFields, }, primitives::BlockId, }, @@ -34,37 +33,38 @@ pub struct BlockHeaderV1 { pub(crate) metadata: Option, } -impl GetBlockHeaderFields for BlockHeaderV1 { - fn consensus(&self) -> &ConsensusHeader { +impl BlockHeaderV1 { + pub(crate) fn consensus(&self) -> &ConsensusHeader { &self.consensus } - fn application(&self) -> &ApplicationHeader { + /// Returns a reference to the application header. + pub fn application(&self) -> &ApplicationHeader { &self.application } - fn metadata(&self) -> &Option { + pub(crate) fn metadata(&self) -> &Option { &self.metadata } - fn recalculate_metadata(&mut self) { + pub(crate) fn recalculate_metadata(&mut self) { let application_hash = self.application().hash(); self.consensus.generated.application_hash = application_hash; let id = self.hash(); self.metadata = Some(BlockHeaderMetadata { id }); } - fn hash(&self) -> BlockId { + pub(crate) fn hash(&self) -> BlockId { debug_assert_eq!(&self.consensus.application_hash, &self.application().hash()); // This internally hashes the hash of the application header. self.consensus().hash() } - fn tx_id_commitment(&self) -> Option { + pub(crate) fn tx_id_commitment(&self) -> Option { None } - fn id(&self) -> BlockId { + pub(crate) fn id(&self) -> BlockId { if let Some(ref metadata) = self.metadata() { metadata.id } else { @@ -72,7 +72,7 @@ impl GetBlockHeaderFields for BlockHeaderV1 { } } - fn validate_transactions(&self, transactions: &[Transaction]) -> bool { + pub(crate) fn validate_transactions(&self, transactions: &[Transaction]) -> bool { let transactions_root = generate_txns_root(transactions); transactions_root == self.application().transactions_root @@ -81,59 +81,64 @@ impl GetBlockHeaderFields for BlockHeaderV1 { } #[cfg(any(test, feature = "test-helpers"))] -impl crate::blockchain::header::BlockHeaderDataTestHelpers - for BlockHeaderV1 -{ - fn consensus_mut(&mut self) -> &mut ConsensusHeader { +impl BlockHeaderV1 { + pub(crate) fn consensus_mut( + &mut self, + ) -> &mut ConsensusHeader { &mut self.consensus } - fn set_consensus_header( + pub(crate) fn set_consensus_header( &mut self, consensus: ConsensusHeader, ) { self.consensus = consensus; } - fn application_mut( + /// Returns a mutable reference to the application header. + pub fn application_mut( &mut self, ) -> &mut ApplicationHeader { &mut self.application } - fn set_application_header( + /// Sets the application header for the block. + pub fn set_application_header( &mut self, application: ApplicationHeader, ) { self.application = application; } - fn set_block_height(&mut self, height: crate::fuel_types::BlockHeight) { + pub(crate) fn set_block_height(&mut self, height: crate::fuel_types::BlockHeight) { self.consensus_mut().height = height; self.recalculate_metadata(); } - fn set_previous_root(&mut self, root: crate::fuel_tx::Bytes32) { + pub(crate) fn set_previous_root(&mut self, root: crate::fuel_tx::Bytes32) { self.consensus_mut().prev_root = root; self.recalculate_metadata(); } - fn set_time(&mut self, time: tai64::Tai64) { + pub(crate) fn set_time(&mut self, time: tai64::Tai64) { self.consensus_mut().time = time; self.recalculate_metadata(); } - fn set_transaction_root(&mut self, root: crate::fuel_tx::Bytes32) { + pub(crate) fn set_transaction_root(&mut self, root: crate::fuel_tx::Bytes32) { self.application_mut().generated.transactions_root = root; self.recalculate_metadata(); } - fn set_da_height(&mut self, da_height: crate::blockchain::primitives::DaBlockHeight) { + pub(crate) fn set_da_height( + &mut self, + da_height: crate::blockchain::primitives::DaBlockHeight, + ) { self.application_mut().da_height = da_height; self.recalculate_metadata(); } - fn set_consensus_parameters_version( + pub(crate) fn set_consensus_parameters_version( &mut self, version: super::ConsensusParametersVersion, ) { @@ -141,7 +146,7 @@ impl crate::blockchain::header::BlockHeaderDataTestHelpers, } -impl GetBlockHeaderFields for BlockHeaderV2 { - fn consensus(&self) -> &ConsensusHeader { +impl BlockHeaderV2 { + pub(crate) fn consensus(&self) -> &ConsensusHeader { &self.consensus } - fn application(&self) -> &ApplicationHeader { + /// Returns a reference to the application header. + pub fn application(&self) -> &ApplicationHeader { &self.application } - fn metadata(&self) -> &Option { + pub(crate) fn metadata(&self) -> &Option { &self.metadata } - fn recalculate_metadata(&mut self) { + pub(crate) fn recalculate_metadata(&mut self) { let application_hash = self.application().hash(); self.consensus.generated.application_hash = application_hash; let id = self.hash(); self.metadata = Some(BlockHeaderMetadata { id }); } - fn hash(&self) -> BlockId { + pub(crate) fn hash(&self) -> BlockId { debug_assert_eq!(&self.consensus.application_hash, &self.application().hash()); // This internally hashes the hash of the application header. self.consensus().hash() } - fn tx_id_commitment(&self) -> Option { + pub(crate) fn tx_id_commitment(&self) -> Option { Some(self.application().tx_id_commitment) } - fn id(&self) -> BlockId { + pub(crate) fn id(&self) -> BlockId { if let Some(ref metadata) = self.metadata() { metadata.id } else { @@ -95,7 +95,7 @@ impl GetBlockHeaderFields for BlockHeaderV2 { } } - fn validate_transactions(&self, transactions: &[Transaction]) -> bool { + pub(crate) fn validate_transactions(&self, transactions: &[Transaction]) -> bool { let transactions_root = generate_txns_root(transactions); transactions_root == self.application().transactions_root @@ -104,59 +104,64 @@ impl GetBlockHeaderFields for BlockHeaderV2 { } #[cfg(any(test, feature = "test-helpers"))] -impl crate::blockchain::header::BlockHeaderDataTestHelpers - for BlockHeaderV2 -{ - fn consensus_mut(&mut self) -> &mut ConsensusHeader { +impl BlockHeaderV2 { + pub(crate) fn consensus_mut( + &mut self, + ) -> &mut ConsensusHeader { &mut self.consensus } - fn set_consensus_header( + pub(crate) fn set_consensus_header( &mut self, consensus: ConsensusHeader, ) { self.consensus = consensus; } - fn application_mut( + /// Returns a mutable reference to the application header. + pub fn application_mut( &mut self, ) -> &mut ApplicationHeader { &mut self.application } - fn set_application_header( + /// Sets the application header. + pub fn set_application_header( &mut self, application: ApplicationHeader, ) { self.application = application; } - fn set_block_height(&mut self, height: crate::fuel_types::BlockHeight) { + pub(crate) fn set_block_height(&mut self, height: crate::fuel_types::BlockHeight) { self.consensus_mut().height = height; self.recalculate_metadata(); } - fn set_previous_root(&mut self, root: crate::fuel_tx::Bytes32) { + pub(crate) fn set_previous_root(&mut self, root: crate::fuel_tx::Bytes32) { self.consensus_mut().prev_root = root; self.recalculate_metadata(); } - fn set_time(&mut self, time: tai64::Tai64) { + pub(crate) fn set_time(&mut self, time: tai64::Tai64) { self.consensus_mut().time = time; self.recalculate_metadata(); } - fn set_transaction_root(&mut self, root: crate::fuel_tx::Bytes32) { + pub(crate) fn set_transaction_root(&mut self, root: crate::fuel_tx::Bytes32) { self.application_mut().generated.transactions_root = root; self.recalculate_metadata(); } - fn set_da_height(&mut self, da_height: crate::blockchain::primitives::DaBlockHeight) { + pub(crate) fn set_da_height( + &mut self, + da_height: crate::blockchain::primitives::DaBlockHeight, + ) { self.application_mut().da_height = da_height; self.recalculate_metadata(); } - fn set_consensus_parameters_version( + pub(crate) fn set_consensus_parameters_version( &mut self, version: super::ConsensusParametersVersion, ) { @@ -164,7 +169,7 @@ impl crate::blockchain::header::BlockHeaderDataTestHelpers