diff --git a/CHANGELOG.md b/CHANGELOG.md index d967f8d4e88..5ff096beffc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - [2113](https://github.com/FuelLabs/fuel-core/pull/2113): Modify the way the gas price service and shared algo is initialized to have some default value based on best guess instead of `None`, and initialize service before graphql. +- [2112](https://github.com/FuelLabs/fuel-core/pull/2112): Alter the way the sealed blocks are fetched with a given height. + ## [Version 0.34.0] diff --git a/bin/fuel-core/src/cli/run/p2p.rs b/bin/fuel-core/src/cli/run/p2p.rs index f8b5797c214..5ebeb312de1 100644 --- a/bin/fuel-core/src/cli/run/p2p.rs +++ b/bin/fuel-core/src/cli/run/p2p.rs @@ -62,7 +62,7 @@ pub struct P2PArgs { #[clap(long = "max-block-size", default_value = MAX_RESPONSE_SIZE_STR, env)] pub max_block_size: usize, - /// Max number of headers in a single headers request response + /// Max number of blocks/headers in a single headers request response #[clap(long = "max-headers-per-request", default_value = "100", env)] pub max_headers_per_request: u32, @@ -76,7 +76,7 @@ pub struct P2PArgs { #[clap(long = "reserved-nodes", value_delimiter = ',', env)] pub reserved_nodes: Vec, - /// With this set to `true` you create a guarded node that is only ever connected to trusted, reserved nodes. + /// With this set to `true` you create a guarded node that is only ever connected to trusted, reserved nodes. #[clap(long = "reserved-nodes-only-mode", env)] pub reserved_nodes_only_mode: bool, diff --git a/crates/fuel-core/src/database/block.rs b/crates/fuel-core/src/database/block.rs index 6c886ca2b10..c6295e62017 100644 --- a/crates/fuel-core/src/database/block.rs +++ b/crates/fuel-core/src/database/block.rs @@ -63,10 +63,7 @@ impl OnChainIterableKeyValueView { } /// Retrieve the full block and all associated transactions - pub(crate) fn get_full_block( - &self, - height: &BlockHeight, - ) -> StorageResult> { + pub fn get_full_block(&self, height: &BlockHeight) -> StorageResult> { let db_block = self.storage::().get(height)?; if let Some(block) = db_block { // fetch all the transactions diff --git a/crates/fuel-core/src/database/sealed_block.rs b/crates/fuel-core/src/database/sealed_block.rs index 23bfe717fe9..4b25d929afc 100644 --- a/crates/fuel-core/src/database/sealed_block.rs +++ b/crates/fuel-core/src/database/sealed_block.rs @@ -18,7 +18,6 @@ use fuel_core_types::{ consensus::{ Consensus, Genesis, - Sealed, }, SealedBlock, SealedBlockHeader, @@ -36,10 +35,11 @@ impl OnChainIterableKeyValueView { height: &BlockHeight, ) -> StorageResult> { // combine the block and consensus metadata into a sealed fuel block type - let block = self.get_full_block(height)?; let consensus = self.storage::().get(height)?; - if let (Some(block), Some(consensus)) = (block, consensus) { + if let Some(consensus) = consensus { + let block = self.get_full_block(height)?.ok_or(not_found!(FuelBlocks))?; + let sealed_block = SealedBlock { entity: block, consensus: consensus.into_owned(), @@ -96,10 +96,14 @@ impl OnChainIterableKeyValueView { &self, height: &BlockHeight, ) -> StorageResult> { - let header = self.storage::().get(height)?; let consensus = self.storage::().get(height)?; - if let (Some(header), Some(consensus)) = (header, consensus) { + if let Some(consensus) = consensus { + let header = self + .storage::() + .get(height)? + .ok_or(not_found!(FuelBlocks))?; // This shouldn't happen if a block has been sealed + let sealed_block = SealedBlockHeader { entity: header.into_owned().header().clone(), consensus: consensus.into_owned(), @@ -120,8 +124,8 @@ impl OnChainIterableKeyValueView { .map(BlockHeight::from) .map(|block_height| { let transactions = self - .get_sealed_block_by_height(&block_height)? - .map(|Sealed { entity: block, .. }| block.into_inner().1) + .get_full_block(&block_height)? + .map(|block| block.into_inner().1) .map(Transactions); Ok(transactions) }) diff --git a/crates/services/p2p/src/config.rs b/crates/services/p2p/src/config.rs index a05f7c4a51d..355e9e70db0 100644 --- a/crates/services/p2p/src/config.rs +++ b/crates/services/p2p/src/config.rs @@ -46,7 +46,7 @@ const REQ_RES_TIMEOUT: Duration = Duration::from_secs(20); /// - `nginx.ingress.kubernetes.io/proxy-body-size` pub const MAX_RESPONSE_SIZE: usize = 18 * 1024 * 1024; -/// Maximum number of headers per request. +/// Maximum number of blocks per request. pub const MAX_HEADERS_PER_REQUEST: u32 = 100; #[derive(Clone, Debug)] diff --git a/crates/services/p2p/src/service.rs b/crates/services/p2p/src/service.rs index 13c103b0ecf..7d1dd9b8ae6 100644 --- a/crates/services/p2p/src/service.rs +++ b/crates/services/p2p/src/service.rs @@ -437,6 +437,24 @@ where let response_channel = self.request_sender.clone(); match request_message { RequestMessage::Transactions(range) => { + let max_len = self + .max_headers_per_request + .try_into() + .expect("u32 should always fit into usize"); + if range.len() > max_len { + tracing::error!( + requested_length = range.len(), + max_len, + "Requested range of blocks is too big" + ); + let response = None; + let _ = self.p2p_service.send_response_msg( + request_id, + ResponseMessage::Transactions(response), + ); + return Ok(()) + } + let view = self.view_provider.latest_view()?; let result = self.database_processor.spawn(move || { if instant.elapsed() > timeout { @@ -479,8 +497,11 @@ where .try_into() .expect("u32 should always fit into usize"); if range.len() > max_len { - tracing::error!("Requested range of sealed headers is too big. Requested length: {:?}, Max length: {:?}", range.len(), max_len); - // TODO: Return helpful error message to requester. https://github.com/FuelLabs/fuel-core/issues/1311 + tracing::error!( + requested_length = range.len(), + max_len, + "Requested range of sealed headers is too big" + ); // TODO: Return helpful error message to requester. https://github.com/FuelLabs/fuel-core/issues/1311 let response = None; let _ = self.p2p_service.send_response_msg( request_id, diff --git a/tests/tests/poa.rs b/tests/tests/poa.rs index b8f5554749f..6f8c2b93dc6 100644 --- a/tests/tests/poa.rs +++ b/tests/tests/poa.rs @@ -182,11 +182,10 @@ async fn starting_node_with_predefined_nodes_produces_these_predefined_blocks( let predefined_blocks: Vec<_> = (1..=BLOCK_TO_PRODUCE) .map(|block_height| { let block_height = block_height as u32; - let sealed_block = on_chain_view - .get_sealed_block_by_height(&block_height.into()) + on_chain_view + .get_full_block(&block_height.into()) + .unwrap() .unwrap() - .unwrap(); - sealed_block.entity }) .collect(); assert_eq!(predefined_blocks.len(), BLOCK_TO_PRODUCE); @@ -216,11 +215,10 @@ async fn starting_node_with_predefined_nodes_produces_these_predefined_blocks( let blocks_from_new_node: Vec<_> = (1..=BLOCK_TO_PRODUCE) .map(|block_height| { let block_height = block_height as u32; - let sealed_block = on_chain_view - .get_sealed_block_by_height(&block_height.into()) + on_chain_view + .get_full_block(&block_height.into()) + .unwrap() .unwrap() - .unwrap(); - sealed_block.entity }) .collect(); assert_eq!(predefined_blocks, blocks_from_new_node); diff --git a/tests/tests/state_rewind.rs b/tests/tests/state_rewind.rs index 2770132f56d..c49be565914 100644 --- a/tests/tests/state_rewind.rs +++ b/tests/tests/state_rewind.rs @@ -97,11 +97,10 @@ async fn validate_block_at_any_height__only_transfers() -> anyhow::Result<()> { for i in 0..TOTAL_BLOCKS { let height_to_execute = rng.gen_range(1..last_block_height); - let sealed_block = view - .get_sealed_block_by_height(&height_to_execute.into()) + let block = view + .get_full_block(&height_to_execute.into()) .unwrap() .unwrap(); - let block = sealed_block.entity; // When tracing::info!("Validating block {i} at height {}", height_to_execute);