From 54264827a71fce17badbcd5ac5a1eeee59337502 Mon Sep 17 00:00:00 2001 From: Brandon Vrooman Date: Mon, 22 Apr 2024 01:09:57 -0400 Subject: [PATCH 1/3] Test invalid block version --- crates/fuel-core/src/schema/block.rs | 1 + crates/types/src/blockchain/block.rs | 63 ++++++++++++++++++++++++++++ tests/tests/blocks.rs | 33 ++++++++++++++- 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/crates/fuel-core/src/schema/block.rs b/crates/fuel-core/src/schema/block.rs index b25b0d7fcd2..fe8e579cdf6 100644 --- a/crates/fuel-core/src/schema/block.rs +++ b/crates/fuel-core/src/schema/block.rs @@ -92,6 +92,7 @@ impl Block { async fn version(&self) -> Version { match self.0 { CompressedBlock::V1(_) => Version(1), + _ => Version(255), } } diff --git a/crates/types/src/blockchain/block.rs b/crates/types/src/blockchain/block.rs index b25cbb95a8a..8a79124e5d6 100644 --- a/crates/types/src/blockchain/block.rs +++ b/crates/types/src/blockchain/block.rs @@ -33,6 +33,8 @@ use crate::{ pub enum Block { /// V1 Block V1(BlockV1), + /// VUnknown + VUnknown(BlockV1), } #[cfg(any(test, feature = "test-helpers"))] @@ -125,6 +127,18 @@ impl Block { }; Block::V1(new_inner) } + Block::VUnknown(inner) => { + let transactions = inner + .transactions + .iter() + .map(|tx| tx.id(chain_id)) + .collect(); + let new_inner = BlockV1 { + header: inner.header.clone(), + transactions, + }; + Block::VUnknown(new_inner) + } } } } @@ -137,6 +151,10 @@ impl Block { header, transactions, }) => (header, transactions), + Block::VUnknown(BlockV1 { + header, + transactions, + }) => (header, transactions), } } } @@ -151,6 +169,10 @@ impl CompressedBlock { header: inner.header, transactions, }), + Block::VUnknown(inner) => Block::VUnknown(BlockV1 { + header: inner.header, + transactions, + }), } } } @@ -171,6 +193,7 @@ impl Block { pub fn transactions(&self) -> &[TransactionRepresentation] { match self { Block::V1(inner) => &inner.transactions, + Block::VUnknown(inner) => &inner.transactions, } } @@ -178,6 +201,7 @@ impl Block { pub fn header(&self) -> &BlockHeader { match self { Block::V1(inner) => &inner.header, + Block::VUnknown(inner) => &inner.header, } } @@ -191,6 +215,7 @@ impl Block { pub fn transactions_mut(&mut self) -> &mut Vec { match self { Block::V1(inner) => &mut inner.transactions, + Block::VUnknown(inner) => &mut inner.transactions, } } @@ -199,6 +224,7 @@ impl Block { pub fn header_mut(&mut self) -> &mut BlockHeader { match self { Block::V1(inner) => &mut inner.header, + Block::VUnknown(inner) => &mut inner.header, } } } @@ -273,6 +299,43 @@ impl From for PartialFuelBlock { }, transactions, }, + Block::VUnknown(BlockV1 { + header: + BlockHeader::V1(BlockHeaderV1 { + application: + ApplicationHeader { + da_height, + consensus_parameters_version, + state_transition_bytecode_version, + .. + }, + consensus: + ConsensusHeader { + prev_root, + height, + time, + .. + }, + .. + }), + transactions, + }) => Self { + header: PartialBlockHeader { + application: ApplicationHeader { + da_height, + consensus_parameters_version, + state_transition_bytecode_version, + generated: Empty {}, + }, + consensus: ConsensusHeader { + prev_root, + height, + time, + generated: Empty {}, + }, + }, + transactions, + }, } } } diff --git a/tests/tests/blocks.rs b/tests/tests/blocks.rs index b05d52178b9..38c445ceb76 100644 --- a/tests/tests/blocks.rs +++ b/tests/tests/blocks.rs @@ -29,7 +29,10 @@ use fuel_core_storage::{ }; use fuel_core_types::{ blockchain::{ - block::CompressedBlock, + block::{ + BlockV1, + CompressedBlock, + }, consensus::Consensus, }, fuel_tx::*, @@ -109,6 +112,34 @@ async fn block_by_height_returns_genesis_block() { )); } +#[tokio::test] +async fn block_by_height_returns_block_with_expected_values() { + let mut block = CompressedBlock::VUnknown(BlockV1::default()); + let height = 1.into(); + block.header_mut().set_block_height(height); + let mut db = Database::default(); + let srv = FuelService::from_database(db.clone(), Config::local_node()) + .await + .unwrap(); + let client = FuelClient::from(srv.bound_address); + + let mut transaction = db.write_transaction(); + transaction + .storage::() + .insert(&height, &block) + .unwrap(); + transaction + .storage::() + .insert(&height, &Consensus::PoA(Default::default())) + .unwrap(); + transaction.commit().unwrap(); + + client + .block_by_height(height) + .await + .expect_err("Block version expected to be invalid"); +} + #[tokio::test] async fn produce_block() { let config = Config::local_node(); From e38e5c8499613a5b0f60f236caea62d58d6fc931 Mon Sep 17 00:00:00 2001 From: Brandon Vrooman Date: Mon, 22 Apr 2024 01:16:30 -0400 Subject: [PATCH 2/3] Update insta tests --- ...block__tests__block_by_height_query_gql_output.snap | 10 ++-------- ...ma__block__tests__block_by_id_query_gql_output.snap | 10 ++-------- ...ock__tests__blocks_connection_query_gql_output.snap | 10 ++-------- ...__schema__chain__tests__chain_gql_query_output.snap | 10 ++-------- 4 files changed, 8 insertions(+), 32 deletions(-) diff --git a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_height_query_gql_output.snap b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_height_query_gql_output.snap index 790bed7164c..4a1795103be 100644 --- a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_height_query_gql_output.snap +++ b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_height_query_gql_output.snap @@ -5,18 +5,12 @@ expression: operation.query query($height: U32) { block(height: $height) { version { - __typename - ... on Version { - value - } + value } id header { version { - __typename - ... on Version { - value - } + value } id daHeight diff --git a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_id_query_gql_output.snap b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_id_query_gql_output.snap index 6311999334f..bd58fca0949 100644 --- a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_id_query_gql_output.snap +++ b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__block_by_id_query_gql_output.snap @@ -5,18 +5,12 @@ expression: operation.query query($id: BlockId) { block(id: $id) { version { - __typename - ... on Version { - value - } + value } id header { version { - __typename - ... on Version { - value - } + value } id daHeight diff --git a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__blocks_connection_query_gql_output.snap b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__blocks_connection_query_gql_output.snap index 38addfb7d7f..e13e05ff4cf 100644 --- a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__blocks_connection_query_gql_output.snap +++ b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__block__tests__blocks_connection_query_gql_output.snap @@ -8,18 +8,12 @@ query($after: String, $before: String, $first: Int, $last: Int) { cursor node { version { - __typename - ... on Version { - value - } + value } id header { version { - __typename - ... on Version { - value - } + value } id daHeight diff --git a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__chain__tests__chain_gql_query_output.snap b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__chain__tests__chain_gql_query_output.snap index cba1d1de02b..7fb92d4cc35 100644 --- a/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__chain__tests__chain_gql_query_output.snap +++ b/crates/client/src/client/schema/snapshots/fuel_core_client__client__schema__chain__tests__chain_gql_query_output.snap @@ -8,18 +8,12 @@ query { name latestBlock { version { - __typename - ... on Version { - value - } + value } id header { version { - __typename - ... on Version { - value - } + value } id daHeight From cb372996544e558e8bc8dab67b54508fbafad1ef Mon Sep 17 00:00:00 2001 From: Brandon Vrooman Date: Mon, 22 Apr 2024 01:59:33 -0400 Subject: [PATCH 3/3] Contrived tests --- crates/client/src/client/types/block.rs | 7 +++++ crates/fuel-core/src/schema/block.rs | 1 + crates/types/src/blockchain/block.rs | 19 +++++++++++++ crates/types/src/blockchain/header.rs | 13 +++++---- tests/tests/blocks.rs | 36 ++++++++++++++++++++++++- 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/crates/client/src/client/types/block.rs b/crates/client/src/client/types/block.rs index bbdfd489bea..e9d5005d633 100644 --- a/crates/client/src/client/types/block.rs +++ b/crates/client/src/client/types/block.rs @@ -152,6 +152,13 @@ impl TryFrom for Block { block_producer, }) } + 2 => Ok(Self { + id: BlockId::from([123u8; 32]), + header: value.header.try_into()?, + consensus: Consensus::Unknown, + transactions: vec![], + block_producer: None, + }), _ => Err(ConversionError::UnknownVariant("BlockVersion")), } } diff --git a/crates/fuel-core/src/schema/block.rs b/crates/fuel-core/src/schema/block.rs index fe8e579cdf6..e9afa8e6bbe 100644 --- a/crates/fuel-core/src/schema/block.rs +++ b/crates/fuel-core/src/schema/block.rs @@ -92,6 +92,7 @@ impl Block { async fn version(&self) -> Version { match self.0 { CompressedBlock::V1(_) => Version(1), + CompressedBlock::V2(_) => Version(2), _ => Version(255), } } diff --git a/crates/types/src/blockchain/block.rs b/crates/types/src/blockchain/block.rs index 8a79124e5d6..b77b89ba0fb 100644 --- a/crates/types/src/blockchain/block.rs +++ b/crates/types/src/blockchain/block.rs @@ -33,6 +33,8 @@ use crate::{ pub enum Block { /// V1 Block V1(BlockV1), + /// V2 Block + V2((BlockHeader, Vec)), /// VUnknown VUnknown(BlockV1), } @@ -127,6 +129,10 @@ impl Block { }; Block::V1(new_inner) } + Block::V2((header, txs)) => { + let txs = txs.iter().map(|tx| tx.id(chain_id)).collect(); + Block::V2((header.clone(), txs)) + } Block::VUnknown(inner) => { let transactions = inner .transactions @@ -151,6 +157,7 @@ impl Block { header, transactions, }) => (header, transactions), + Block::V2((header, txs)) => (header, txs), Block::VUnknown(BlockV1 { header, transactions, @@ -169,6 +176,7 @@ impl CompressedBlock { header: inner.header, transactions, }), + Block::V2((header, _txs)) => Block::V2((header, transactions)), Block::VUnknown(inner) => Block::VUnknown(BlockV1 { header: inner.header, transactions, @@ -193,6 +201,7 @@ impl Block { pub fn transactions(&self) -> &[TransactionRepresentation] { match self { Block::V1(inner) => &inner.transactions, + Block::V2(_) => &[], Block::VUnknown(inner) => &inner.transactions, } } @@ -201,6 +210,7 @@ impl Block { pub fn header(&self) -> &BlockHeader { match self { Block::V1(inner) => &inner.header, + Block::V2((header, _)) => header, Block::VUnknown(inner) => &inner.header, } } @@ -215,6 +225,7 @@ impl Block { pub fn transactions_mut(&mut self) -> &mut Vec { match self { Block::V1(inner) => &mut inner.transactions, + Block::V2((_, txs)) => txs, Block::VUnknown(inner) => &mut inner.transactions, } } @@ -224,6 +235,7 @@ impl Block { pub fn header_mut(&mut self) -> &mut BlockHeader { match self { Block::V1(inner) => &mut inner.header, + Block::V2((header, _)) => header, Block::VUnknown(inner) => &mut inner.header, } } @@ -299,6 +311,13 @@ impl From for PartialFuelBlock { }, transactions, }, + Block::V2((_header, txs)) => Self { + header: PartialBlockHeader { + application: Default::default(), + consensus: Default::default(), + }, + transactions: txs, + }, Block::VUnknown(BlockV1 { header: BlockHeader::V1(BlockHeaderV1 { diff --git a/crates/types/src/blockchain/header.rs b/crates/types/src/blockchain/header.rs index 1df21ef72e4..31f0daa8b5f 100644 --- a/crates/types/src/blockchain/header.rs +++ b/crates/types/src/blockchain/header.rs @@ -164,7 +164,8 @@ pub type StateTransitionBytecodeVersion = u32; #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +// #[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +#[derive(Default)] /// The fuel block application header. /// Contains everything except consensus related data. pub struct ApplicationHeader { @@ -185,7 +186,8 @@ pub struct ApplicationHeader { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +// #[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +#[derive(Default)] /// Concrete generated application header fields. /// These are generated once the full block has been run. pub struct GeneratedApplicationFields { @@ -219,7 +221,8 @@ pub struct ConsensusHeader { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +// #[cfg_attr(any(test, feature = "test-helpers"), derive(Default))] +#[derive(Default)] /// Concrete generated consensus header fields. /// These are generated once the full block has been run. pub struct GeneratedConsensusFields { @@ -235,7 +238,7 @@ pub struct BlockHeaderMetadata { id: BlockId, } -#[cfg(any(test, feature = "test-helpers"))] +// #[cfg(any(test, feature = "test-helpers"))] impl Default for BlockHeader { fn default() -> Self { let mut default: BlockHeader = BlockHeaderV1 { @@ -459,7 +462,7 @@ impl ConsensusHeader { } } -#[cfg(any(test, feature = "test-helpers"))] +// #[cfg(any(test, feature = "test-helpers"))] impl Default for ConsensusHeader where T: Default, diff --git a/tests/tests/blocks.rs b/tests/tests/blocks.rs index 38c445ceb76..ed070e67d2b 100644 --- a/tests/tests/blocks.rs +++ b/tests/tests/blocks.rs @@ -14,7 +14,10 @@ use fuel_core_client::client::{ PageDirection, PaginationRequest, }, - types::TransactionStatus, + types::{ + primitives::BlockId, + TransactionStatus, + }, FuelClient, }; use fuel_core_poa::Trigger; @@ -34,6 +37,7 @@ use fuel_core_types::{ CompressedBlock, }, consensus::Consensus, + header::BlockHeader, }, fuel_tx::*, secrecy::ExposeSecret, @@ -114,6 +118,36 @@ async fn block_by_height_returns_genesis_block() { #[tokio::test] async fn block_by_height_returns_block_with_expected_values() { + let mut block = CompressedBlock::V2((BlockHeader::default(), vec![])); + let height = 1.into(); + block.header_mut().set_block_height(height); + let mut db = Database::default(); + let srv = FuelService::from_database(db.clone(), Config::local_node()) + .await + .unwrap(); + let client = FuelClient::from(srv.bound_address); + + let mut transaction = db.write_transaction(); + transaction + .storage::() + .insert(&height, &block) + .unwrap(); + transaction + .storage::() + .insert(&height, &Consensus::PoA(Default::default())) + .unwrap(); + transaction.commit().unwrap(); + + let b = client + .block_by_height(height) + .await + .expect("Unable to get block") + .expect("Expected block"); + assert_eq!(b.id, BlockId::from([123u8; 32])); +} + +#[tokio::test] +async fn block_by_height_returns_err_unknown_version() { let mut block = CompressedBlock::VUnknown(BlockV1::default()); let height = 1.into(); block.header_mut().set_block_height(height);