From ff12c1a12e2ecdfdffcba67a61c3313efe73c7ae Mon Sep 17 00:00:00 2001 From: Raushan Kumar Date: Tue, 27 Jan 2026 12:40:40 +0000 Subject: [PATCH 1/4] refactor: replace manual mocks with mockall in producer service --- .../services/producer/src/block_producer.rs | 50 +--- .../producer/src/block_producer/tests.rs | 93 ++----- crates/services/producer/src/mocks.rs | 261 +++++++++--------- crates/services/producer/src/ports.rs | 29 +- 4 files changed, 177 insertions(+), 256 deletions(-) diff --git a/crates/services/producer/src/block_producer.rs b/crates/services/producer/src/block_producer.rs index 2a791cca614..4e20937f2cf 100644 --- a/crates/services/producer/src/block_producer.rs +++ b/crates/services/producer/src/block_producer.rs @@ -1,61 +1,33 @@ use crate::{ Config, block_producer::gas_price::{ - ChainStateInfoProvider, - GasPriceProvider as GasPriceProviderConstraint, + ChainStateInfoProvider, GasPriceProvider as GasPriceProviderConstraint, }, - ports::{ - self, - BlockProducerDatabase, - RelayerBlockInfo, - }, -}; -use anyhow::{ - Context, - anyhow, -}; -use fuel_core_storage::transactional::{ - AtomicView, - Changes, - HistoricalView, + ports::{self, BlockProducerDatabase, RelayerBlockInfo}, }; +use anyhow::{Context, anyhow}; +use fuel_core_storage::transactional::{AtomicView, Changes, HistoricalView}; use fuel_core_types::{ blockchain::{ block::Block, header::{ - ApplicationHeader, - ConsensusHeader, - ConsensusParametersVersion, - PartialBlockHeader, - StateTransitionBytecodeVersion, + ApplicationHeader, ConsensusHeader, ConsensusParametersVersion, + PartialBlockHeader, StateTransitionBytecodeVersion, }, primitives::DaBlockHeight, }, fuel_tx::{ Transaction, - field::{ - InputContract, - MintGasPrice, - }, - }, - fuel_types::{ - BlockHeight, - Bytes32, + field::{InputContract, MintGasPrice}, }, + fuel_types::{BlockHeight, Bytes32}, services::{ block_producer::Components, - executor::{ - DryRunResult, - StorageReadReplayEvent, - UncommittedResult, - }, + executor::{DryRunResult, StorageReadReplayEvent, UncommittedResult}, }, tai64::Tai64, }; -use std::{ - future::Future, - sync::Arc, -}; +use std::{future::Future, sync::Arc}; use tokio::sync::Mutex; use tracing::debug; @@ -157,7 +129,7 @@ where height, previous_block: latest_height, } - .into()) + .into()); } let maybe_mint_tx = transactions_source.pop(); diff --git a/crates/services/producer/src/block_producer/tests.rs b/crates/services/producer/src/block_producer/tests.rs index c70c66722ea..4a1d7bbb6d6 100644 --- a/crates/services/producer/src/block_producer/tests.rs +++ b/crates/services/producer/src/block_producer/tests.rs @@ -1,63 +1,30 @@ #![allow(non_snake_case)] use crate::{ - Config, - Producer, + Config, Producer, block_producer::{ - Bytes32, - Error, - gas_price::{ - GasPriceProvider, - MockChainStateInfoProvider, - }, - }, - mocks::{ - FailingMockExecutor, - MockDb, - MockExecutor, - MockExecutorWithCapture, - MockRelayer, - MockTxPool, + Bytes32, Error, + gas_price::{GasPriceProvider, MockChainStateInfoProvider}, }, + mocks::{MockDb, MockExecutor, MockExecutorWithCapture, MockRelayer, MockTxPool}, }; use fuel_core_producer as _; use fuel_core_types::{ blockchain::{ - block::{ - Block, - CompressedBlock, - PartialFuelBlock, - }, - header::{ - ApplicationHeader, - ConsensusHeader, - PartialBlockHeader, - }, + block::{Block, CompressedBlock, PartialFuelBlock}, + header::{ApplicationHeader, ConsensusHeader, PartialBlockHeader}, primitives::DaBlockHeight, }, fuel_tx, - fuel_tx::{ - ConsensusParameters, - Mint, - Script, - Transaction, - field::InputContract, - }, + fuel_tx::{ConsensusParameters, Mint, Script, Transaction, field::InputContract}, fuel_types::BlockHeight, services::executor::Error as ExecutorError, tai64::Tai64, }; -use rand::{ - Rng, - SeedableRng, - rngs::StdRng, -}; +use rand::{Rng, SeedableRng, rngs::StdRng}; use std::{ collections::HashMap, - sync::{ - Arc, - Mutex, - }, + sync::{Arc, Mutex}, }; pub struct MockProducerGasPrice { @@ -518,9 +485,11 @@ mod produce_and_execute_block_txpool { #[tokio::test] async fn production_fails_on_execution_error() { - let ctx = TestContext::default_from_executor(FailingMockExecutor(Mutex::new( - Some(ExecutorError::TransactionIdCollision(Default::default())), - ))); + let ctx = TestContext::default_from_executor( + crate::mocks::create_failing_mock_executor( + ExecutorError::TransactionIdCollision(Default::default()), + ), + ); let producer = ctx.producer(); @@ -843,10 +812,7 @@ mod dry_run { } use fuel_core_types::fuel_tx::field::MintGasPrice; -use proptest::{ - prop_compose, - proptest, -}; +use proptest::{prop_compose, proptest}; prop_compose! { fn arb_block()(height in 1..255u8, da_height in 1..255u64, gas_price: u64, coinbase_recipient: [u8; 32], num_txs in 0..100u32) -> Block { @@ -1015,7 +981,7 @@ impl TestContext { } pub fn default_from_db(db: MockDb) -> Self { - let executor = MockExecutor(db.clone()); + let executor = crate::mocks::create_mock_executor(db.clone()); Self::default_from_db_and_executor(db, executor) } } @@ -1039,8 +1005,9 @@ impl TestContext { } pub fn default_from_db_and_executor(db: MockDb, executor: Executor) -> Self { - let txpool = MockTxPool::default(); - let relayer = MockRelayer::default(); + let txpool = crate::mocks::create_mock_txpool(vec![]); + let relayer = + crate::mocks::create_mock_relayer(DaBlockHeight::default(), HashMap::new()); let config = Config::default(); let gas_price = Some(0); Self { @@ -1229,13 +1196,10 @@ impl TestContextBuilder { fn build(self) -> TestContext { let block_gas_limit = self.block_gas_limit.unwrap_or_default(); - let mock_relayer = MockRelayer { - latest_block_height: self.latest_block_height, - latest_da_blocks_with_costs_and_transactions_number: self - .blocks_with_gas_costs_and_transactions_number - .clone(), - ..Default::default() - }; + let mock_relayer = crate::mocks::create_mock_relayer( + self.latest_block_height, + self.blocks_with_gas_costs_and_transactions_number.clone(), + ); let db = MockDb { blocks: self.pre_existing_blocks(), @@ -1253,13 +1217,10 @@ impl TestContextBuilder { fn build_with_executor(self, executor: Ex) -> TestContext { let block_gas_limit = self.block_gas_limit.unwrap_or_default(); - let mock_relayer = MockRelayer { - latest_block_height: self.latest_block_height, - latest_da_blocks_with_costs_and_transactions_number: self - .blocks_with_gas_costs_and_transactions_number - .clone(), - ..Default::default() - }; + let mock_relayer = crate::mocks::create_mock_relayer( + self.latest_block_height, + self.blocks_with_gas_costs_and_transactions_number.clone(), + ); let db = MockDb { blocks: self.pre_existing_blocks(), diff --git a/crates/services/producer/src/mocks.rs b/crates/services/producer/src/mocks.rs index 299a491ae62..f3a50e8f86a 100644 --- a/crates/services/producer/src/mocks.rs +++ b/crates/services/producer/src/mocks.rs @@ -1,46 +1,23 @@ use crate::ports::{ - BlockProducer, - BlockProducerDatabase, - DryRunner, - Relayer, - RelayerBlockInfo, - TxPool, + BlockProducer, BlockProducerDatabase, DryRunner, Relayer, RelayerBlockInfo, TxPool, }; use fuel_core_storage::{ - Result as StorageResult, - not_found, - transactional::{ - AtomicView, - Changes, - }, + Result as StorageResult, not_found, + transactional::{AtomicView, Changes}, }; use fuel_core_types::{ blockchain::{ - block::{ - Block, - CompressedBlock, - }, - header::{ - ConsensusParametersVersion, - StateTransitionBytecodeVersion, - }, + block::{Block, CompressedBlock}, + header::{ConsensusParametersVersion, StateTransitionBytecodeVersion}, primitives::DaBlockHeight, }, fuel_tx::Transaction, - fuel_types::{ - Address, - BlockHeight, - Bytes32, - ChainId, - }, + fuel_types::{BlockHeight, Bytes32, ChainId}, services::{ block_producer::Components, executor::{ - DryRunResult, - Error as ExecutorError, - ExecutionResult, - Result as ExecutorResult, - UncommittedResult, + DryRunResult, Error as ExecutorError, ExecutionResult, + Result as ExecutorResult, UncommittedResult, }, }, }; @@ -48,70 +25,142 @@ use std::{ borrow::Cow, collections::HashMap, ops::Deref, - sync::{ - Arc, - Mutex, - }, + sync::{Arc, Mutex}, }; -// TODO: Replace mocks with `mockall`. - -#[derive(Default, Clone)] -pub struct MockRelayer { - pub block_production_key: Address, - pub latest_block_height: DaBlockHeight, - pub latest_da_blocks_with_costs_and_transactions_number: - HashMap, -} +// Mockall-generated mocks for testing +#[cfg(feature = "test-helpers")] +use mockall::mock; -#[async_trait::async_trait] -impl Relayer for MockRelayer { - async fn wait_for_at_least_height( - &self, - _height: &DaBlockHeight, - ) -> anyhow::Result { - let highest = self.latest_block_height; - Ok(highest) - } +#[cfg(feature = "test-helpers")] +mock! { + pub Relayer {} - async fn get_cost_and_transactions_number_for_block( - &self, - height: &DaBlockHeight, - ) -> anyhow::Result { - let (gas_cost, tx_count) = self - .latest_da_blocks_with_costs_and_transactions_number - .get(height) - .cloned() - .unwrap_or_default(); - Ok(RelayerBlockInfo { gas_cost, tx_count }) + #[async_trait::async_trait] + impl Relayer for Relayer { + async fn wait_for_at_least_height( + &self, + height: &DaBlockHeight, + ) -> anyhow::Result; + + async fn get_cost_and_transactions_number_for_block( + &self, + height: &DaBlockHeight, + ) -> anyhow::Result; } } -#[derive(Default)] -pub struct MockTxPool(pub Vec); +// Re-export for backward compatibility during migration +#[cfg(feature = "test-helpers")] +pub use MockRelayer as MockRelayerLegacy; -impl TxPool for MockTxPool { - type TxSource = Vec; +// Helper function to create a MockRelayer with default behavior +#[cfg(feature = "test-helpers")] +pub fn create_mock_relayer( + latest_height: DaBlockHeight, + blocks_with_costs: HashMap, +) -> MockRelayer { + let mut mock = MockRelayer::new(); - async fn get_source(&self, _: u64, _: BlockHeight) -> anyhow::Result { - Ok(self.0.clone()) - } + // Default behavior: return the latest height + mock.expect_wait_for_at_least_height() + .returning(move |_| Ok(latest_height)); + + // Default behavior: return gas cost and tx count from the map + mock.expect_get_cost_and_transactions_number_for_block() + .returning(move |height| { + let (gas_cost, tx_count) = + blocks_with_costs.get(height).cloned().unwrap_or_default(); + Ok(RelayerBlockInfo { gas_cost, tx_count }) + }); + + mock } -#[derive(Default)] -pub struct MockExecutor(pub MockDb); +// MockTxPool with associated type +#[cfg(feature = "test-helpers")] +mock! { + pub TxPool {} -impl AsMut for MockDb { - fn as_mut(&mut self) -> &mut MockDb { - self + impl TxPool for TxPool { + type TxSource = Vec; + + async fn get_source(&self, gas_price: u64, block_height: BlockHeight) -> anyhow::Result>; } } -impl AsRef for MockDb { - fn as_ref(&self) -> &MockDb { - self +// Helper function to create a MockTxPool with default behavior +#[cfg(feature = "test-helpers")] +pub fn create_mock_txpool(transactions: Vec) -> MockTxPool { + let mut mock = MockTxPool::new(); + + // Default behavior: return the transactions + mock.expect_get_source() + .returning(move |_, _| Ok(transactions.clone())); + + mock +} + +// MockExecutor - BlockProducer implementation +#[cfg(feature = "test-helpers")] +mock! { + pub Executor {} + + impl BlockProducer> for Executor { + type Deadline = (); + + async fn produce_without_commit( + &self, + component: Components>, + deadline: (), + ) -> ExecutorResult>; } } +// Helper function to create a MockExecutor with default successful behavior +#[cfg(feature = "test-helpers")] +pub fn create_mock_executor(db: MockDb) -> MockExecutor { + let mut mock = MockExecutor::new(); + + // Default behavior: create a block and insert it into the database + mock.expect_produce_without_commit() + .returning(move |component, _| { + let block = arc_pool_tx_comp_to_block(&component); + // simulate executor inserting a block + let mut block_db = db.blocks.lock().unwrap(); + block_db.insert( + *block.header().height(), + block.compress(&ChainId::default()), + ); + Ok(UncommittedResult::new( + ExecutionResult { + block, + skipped_transactions: vec![], + tx_status: vec![], + events: vec![], + }, + Default::default(), + )) + }); + + mock +} + +// Helper function to create a failing MockExecutor +// This replaces the old FailingMockExecutor struct +#[cfg(feature = "test-helpers")] +pub fn create_failing_mock_executor(error: ExecutorError) -> MockExecutor { + let mut mock = MockExecutor::new(); + + // Set expectation to fail once, then succeed + mock.expect_produce_without_commit() + .times(1) + .return_once(move |_, _| Err(error)); + + mock +} + +// Helper functions for block creation (used by mocks) +#[cfg(feature = "test-helpers")] fn arc_pool_tx_comp_to_block(component: &Components>) -> Block { let transactions = component.transactions_source.clone(); Block::new( @@ -125,59 +174,15 @@ fn arc_pool_tx_comp_to_block(component: &Components>) -> Block .unwrap() } -impl BlockProducer> for MockExecutor { - type Deadline = (); - - async fn produce_without_commit( - &self, - component: Components>, - _: (), - ) -> ExecutorResult> { - let block = arc_pool_tx_comp_to_block(&component); - // simulate executor inserting a block - let mut block_db = self.0.blocks.lock().unwrap(); - block_db.insert( - *block.header().height(), - block.compress(&ChainId::default()), - ); - Ok(UncommittedResult::new( - ExecutionResult { - block, - skipped_transactions: vec![], - tx_status: vec![], - events: vec![], - }, - Default::default(), - )) +impl AsMut for MockDb { + fn as_mut(&mut self) -> &mut MockDb { + self } } -pub struct FailingMockExecutor(pub Mutex>); - -impl BlockProducer> for FailingMockExecutor { - type Deadline = (); - async fn produce_without_commit( - &self, - component: Components>, - _: (), - ) -> ExecutorResult> { - // simulate an execution failure - let mut err = self.0.lock().unwrap(); - match err.take() { - Some(err) => Err(err), - _ => { - let block = arc_pool_tx_comp_to_block(&component); - Ok(UncommittedResult::new( - ExecutionResult { - block, - skipped_transactions: vec![], - tx_status: vec![], - events: vec![], - }, - Default::default(), - )) - } - } +impl AsRef for MockDb { + fn as_ref(&self) -> &MockDb { + self } } diff --git a/crates/services/producer/src/ports.rs b/crates/services/producer/src/ports.rs index 50619c5b630..0bec56c0635 100644 --- a/crates/services/producer/src/ports.rs +++ b/crates/services/producer/src/ports.rs @@ -1,38 +1,21 @@ -use fuel_core_storage::{ - Result as StorageResult, - transactional::Changes, -}; +use fuel_core_storage::{Result as StorageResult, transactional::Changes}; use fuel_core_types::{ blockchain::{ - block::{ - Block, - CompressedBlock, - }, - header::{ - ConsensusParametersVersion, - StateTransitionBytecodeVersion, - }, + block::{Block, CompressedBlock}, + header::{ConsensusParametersVersion, StateTransitionBytecodeVersion}, primitives::DaBlockHeight, }, - fuel_tx::{ - Bytes32, - Transaction, - }, + fuel_tx::{Bytes32, Transaction}, fuel_types::BlockHeight, services::{ block_producer::Components, executor::{ - DryRunResult, - Result as ExecutorResult, - StorageReadReplayEvent, + DryRunResult, Result as ExecutorResult, StorageReadReplayEvent, UncommittedResult, }, }, }; -use std::{ - borrow::Cow, - future::Future, -}; +use std::{borrow::Cow, future::Future}; pub trait BlockProducerDatabase: Send + Sync { /// Returns the latest block height. From ef5ca910a2fd7eae5316b375fc961c4f1ac580e9 Mon Sep 17 00:00:00 2001 From: Raushan Kumar Date: Tue, 27 Jan 2026 13:20:33 +0000 Subject: [PATCH 2/4] fix: create_failing_mock_executor now handles subsequent calls correctly --- .../producer/src/block_producer/tests.rs | 2 ++ crates/services/producer/src/mocks.rs | 25 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/services/producer/src/block_producer/tests.rs b/crates/services/producer/src/block_producer/tests.rs index 4a1d7bbb6d6..cf0b9862088 100644 --- a/crates/services/producer/src/block_producer/tests.rs +++ b/crates/services/producer/src/block_producer/tests.rs @@ -485,9 +485,11 @@ mod produce_and_execute_block_txpool { #[tokio::test] async fn production_fails_on_execution_error() { + let db = TestContext::::default_db(); let ctx = TestContext::default_from_executor( crate::mocks::create_failing_mock_executor( ExecutorError::TransactionIdCollision(Default::default()), + db, ), ); diff --git a/crates/services/producer/src/mocks.rs b/crates/services/producer/src/mocks.rs index f3a50e8f86a..64c6c2aa310 100644 --- a/crates/services/producer/src/mocks.rs +++ b/crates/services/producer/src/mocks.rs @@ -147,15 +147,36 @@ pub fn create_mock_executor(db: MockDb) -> MockExecutor { // Helper function to create a failing MockExecutor // This replaces the old FailingMockExecutor struct +// Fails once with the provided error, then succeeds on subsequent calls #[cfg(feature = "test-helpers")] -pub fn create_failing_mock_executor(error: ExecutorError) -> MockExecutor { +pub fn create_failing_mock_executor(error: ExecutorError, db: MockDb) -> MockExecutor { let mut mock = MockExecutor::new(); - // Set expectation to fail once, then succeed + // First call: fail with the provided error mock.expect_produce_without_commit() .times(1) .return_once(move |_, _| Err(error)); + // Subsequent calls: succeed with standard executor logic + mock.expect_produce_without_commit() + .returning(move |component, _| { + let block = arc_pool_tx_comp_to_block(&component); + let mut block_db = db.blocks.lock().unwrap(); + block_db.insert( + *block.header().height(), + block.compress(&ChainId::default()), + ); + Ok(UncommittedResult::new( + ExecutionResult { + block, + skipped_transactions: vec![], + tx_status: vec![], + events: vec![], + }, + Default::default(), + )) + }); + mock } From a761a4c87cdb04e56d77ea8c0f8755cccc4d043c Mon Sep 17 00:00:00 2001 From: Raushan Kumar Date: Wed, 28 Jan 2026 11:30:33 +0000 Subject: [PATCH 3/4] style: apply nightly formatting --- .../services/producer/src/block_producer.rs | 48 ++++++++++++---- .../producer/src/block_producer/tests.rs | 55 +++++++++++++++---- crates/services/producer/src/mocks.rs | 43 ++++++++++++--- crates/services/producer/src/ports.rs | 29 ++++++++-- 4 files changed, 140 insertions(+), 35 deletions(-) diff --git a/crates/services/producer/src/block_producer.rs b/crates/services/producer/src/block_producer.rs index 4e20937f2cf..d599380d27f 100644 --- a/crates/services/producer/src/block_producer.rs +++ b/crates/services/producer/src/block_producer.rs @@ -1,33 +1,61 @@ use crate::{ Config, block_producer::gas_price::{ - ChainStateInfoProvider, GasPriceProvider as GasPriceProviderConstraint, + ChainStateInfoProvider, + GasPriceProvider as GasPriceProviderConstraint, }, - ports::{self, BlockProducerDatabase, RelayerBlockInfo}, + ports::{ + self, + BlockProducerDatabase, + RelayerBlockInfo, + }, +}; +use anyhow::{ + Context, + anyhow, +}; +use fuel_core_storage::transactional::{ + AtomicView, + Changes, + HistoricalView, }; -use anyhow::{Context, anyhow}; -use fuel_core_storage::transactional::{AtomicView, Changes, HistoricalView}; use fuel_core_types::{ blockchain::{ block::Block, header::{ - ApplicationHeader, ConsensusHeader, ConsensusParametersVersion, - PartialBlockHeader, StateTransitionBytecodeVersion, + ApplicationHeader, + ConsensusHeader, + ConsensusParametersVersion, + PartialBlockHeader, + StateTransitionBytecodeVersion, }, primitives::DaBlockHeight, }, fuel_tx::{ Transaction, - field::{InputContract, MintGasPrice}, + field::{ + InputContract, + MintGasPrice, + }, + }, + fuel_types::{ + BlockHeight, + Bytes32, }, - fuel_types::{BlockHeight, Bytes32}, services::{ block_producer::Components, - executor::{DryRunResult, StorageReadReplayEvent, UncommittedResult}, + executor::{ + DryRunResult, + StorageReadReplayEvent, + UncommittedResult, + }, }, tai64::Tai64, }; -use std::{future::Future, sync::Arc}; +use std::{ + future::Future, + sync::Arc, +}; use tokio::sync::Mutex; use tracing::debug; diff --git a/crates/services/producer/src/block_producer/tests.rs b/crates/services/producer/src/block_producer/tests.rs index cf0b9862088..3d5646cbec2 100644 --- a/crates/services/producer/src/block_producer/tests.rs +++ b/crates/services/producer/src/block_producer/tests.rs @@ -1,30 +1,62 @@ #![allow(non_snake_case)] use crate::{ - Config, Producer, + Config, + Producer, block_producer::{ - Bytes32, Error, - gas_price::{GasPriceProvider, MockChainStateInfoProvider}, + Bytes32, + Error, + gas_price::{ + GasPriceProvider, + MockChainStateInfoProvider, + }, + }, + mocks::{ + MockDb, + MockExecutor, + MockExecutorWithCapture, + MockRelayer, + MockTxPool, }, - mocks::{MockDb, MockExecutor, MockExecutorWithCapture, MockRelayer, MockTxPool}, }; use fuel_core_producer as _; use fuel_core_types::{ blockchain::{ - block::{Block, CompressedBlock, PartialFuelBlock}, - header::{ApplicationHeader, ConsensusHeader, PartialBlockHeader}, + block::{ + Block, + CompressedBlock, + PartialFuelBlock, + }, + header::{ + ApplicationHeader, + ConsensusHeader, + PartialBlockHeader, + }, primitives::DaBlockHeight, }, fuel_tx, - fuel_tx::{ConsensusParameters, Mint, Script, Transaction, field::InputContract}, + fuel_tx::{ + ConsensusParameters, + Mint, + Script, + Transaction, + field::InputContract, + }, fuel_types::BlockHeight, services::executor::Error as ExecutorError, tai64::Tai64, }; -use rand::{Rng, SeedableRng, rngs::StdRng}; +use rand::{ + Rng, + SeedableRng, + rngs::StdRng, +}; use std::{ collections::HashMap, - sync::{Arc, Mutex}, + sync::{ + Arc, + Mutex, + }, }; pub struct MockProducerGasPrice { @@ -814,7 +846,10 @@ mod dry_run { } use fuel_core_types::fuel_tx::field::MintGasPrice; -use proptest::{prop_compose, proptest}; +use proptest::{ + prop_compose, + proptest, +}; prop_compose! { fn arb_block()(height in 1..255u8, da_height in 1..255u64, gas_price: u64, coinbase_recipient: [u8; 32], num_txs in 0..100u32) -> Block { diff --git a/crates/services/producer/src/mocks.rs b/crates/services/producer/src/mocks.rs index 64c6c2aa310..c2d38247c29 100644 --- a/crates/services/producer/src/mocks.rs +++ b/crates/services/producer/src/mocks.rs @@ -1,23 +1,45 @@ use crate::ports::{ - BlockProducer, BlockProducerDatabase, DryRunner, Relayer, RelayerBlockInfo, TxPool, + BlockProducer, + BlockProducerDatabase, + DryRunner, + Relayer, + RelayerBlockInfo, + TxPool, }; use fuel_core_storage::{ - Result as StorageResult, not_found, - transactional::{AtomicView, Changes}, + Result as StorageResult, + not_found, + transactional::{ + AtomicView, + Changes, + }, }; use fuel_core_types::{ blockchain::{ - block::{Block, CompressedBlock}, - header::{ConsensusParametersVersion, StateTransitionBytecodeVersion}, + block::{ + Block, + CompressedBlock, + }, + header::{ + ConsensusParametersVersion, + StateTransitionBytecodeVersion, + }, primitives::DaBlockHeight, }, fuel_tx::Transaction, - fuel_types::{BlockHeight, Bytes32, ChainId}, + fuel_types::{ + BlockHeight, + Bytes32, + ChainId, + }, services::{ block_producer::Components, executor::{ - DryRunResult, Error as ExecutorError, ExecutionResult, - Result as ExecutorResult, UncommittedResult, + DryRunResult, + Error as ExecutorError, + ExecutionResult, + Result as ExecutorResult, + UncommittedResult, }, }, }; @@ -25,7 +47,10 @@ use std::{ borrow::Cow, collections::HashMap, ops::Deref, - sync::{Arc, Mutex}, + sync::{ + Arc, + Mutex, + }, }; // Mockall-generated mocks for testing #[cfg(feature = "test-helpers")] diff --git a/crates/services/producer/src/ports.rs b/crates/services/producer/src/ports.rs index 0bec56c0635..50619c5b630 100644 --- a/crates/services/producer/src/ports.rs +++ b/crates/services/producer/src/ports.rs @@ -1,21 +1,38 @@ -use fuel_core_storage::{Result as StorageResult, transactional::Changes}; +use fuel_core_storage::{ + Result as StorageResult, + transactional::Changes, +}; use fuel_core_types::{ blockchain::{ - block::{Block, CompressedBlock}, - header::{ConsensusParametersVersion, StateTransitionBytecodeVersion}, + block::{ + Block, + CompressedBlock, + }, + header::{ + ConsensusParametersVersion, + StateTransitionBytecodeVersion, + }, primitives::DaBlockHeight, }, - fuel_tx::{Bytes32, Transaction}, + fuel_tx::{ + Bytes32, + Transaction, + }, fuel_types::BlockHeight, services::{ block_producer::Components, executor::{ - DryRunResult, Result as ExecutorResult, StorageReadReplayEvent, + DryRunResult, + Result as ExecutorResult, + StorageReadReplayEvent, UncommittedResult, }, }, }; -use std::{borrow::Cow, future::Future}; +use std::{ + borrow::Cow, + future::Future, +}; pub trait BlockProducerDatabase: Send + Sync { /// Returns the latest block height. From 4f4f9abccf1893b174cd8035b3b1a74ea1748bcf Mon Sep 17 00:00:00 2001 From: Raushan Kumar Date: Wed, 28 Jan 2026 12:18:14 +0000 Subject: [PATCH 4/4] fix: use same db instance in failing mock executor test --- crates/services/producer/src/block_producer/tests.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/services/producer/src/block_producer/tests.rs b/crates/services/producer/src/block_producer/tests.rs index 3d5646cbec2..b2c9a95d0cd 100644 --- a/crates/services/producer/src/block_producer/tests.rs +++ b/crates/services/producer/src/block_producer/tests.rs @@ -518,12 +518,11 @@ mod produce_and_execute_block_txpool { #[tokio::test] async fn production_fails_on_execution_error() { let db = TestContext::::default_db(); - let ctx = TestContext::default_from_executor( - crate::mocks::create_failing_mock_executor( - ExecutorError::TransactionIdCollision(Default::default()), - db, - ), + let executor = crate::mocks::create_failing_mock_executor( + ExecutorError::TransactionIdCollision(Default::default()), + db.clone(), ); + let ctx = TestContext::default_from_db_and_executor(db, executor); let producer = ctx.producer();