Skip to content

Commit

Permalink
backtesting fix.
Browse files Browse the repository at this point in the history
roothash not used in backtesting.
  • Loading branch information
ZanCorDX committed Jan 15, 2025
1 parent 9846e76 commit 112edc3
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 36 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/rbuilder/src/backtest/backtest_build_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ where
result
};

let provider_factory = config.base_config().create_provider_factory()?;
let provider_factory = config.base_config().create_provider_factory(true)?;
let chain_spec = config.base_config().chain_spec()?;

let mut profits = Vec::new();
Expand Down
21 changes: 6 additions & 15 deletions crates/rbuilder/src/backtest/build_block/backtest_build_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
use ahash::HashMap;
use alloy_primitives::utils::format_ether;
use reth_db::Database;
use reth_provider::{BlockReader, DatabaseProviderFactory, StateProviderFactory};

use crate::{
backtest::{
Expand All @@ -18,6 +16,7 @@ use crate::{
building::{builders::BacktestSimulateBlockInput, BlockBuildingContext},
live_builder::cli::LiveBuilderConfig,
primitives::{Order, OrderId, SimulatedOrder},
provider::StateProviderFactory,
};
use clap::Parser;
use std::path::PathBuf;
Expand All @@ -42,14 +41,10 @@ pub struct BuildBlockCfg {

/// Provides all the orders needed to simulate the construction of a block.
/// It also provides the needed context to execute those orders.
pub trait OrdersSource<ConfigType, DBType, ProviderType>
pub trait OrdersSource<ConfigType, ProviderType>
where
ConfigType: LiveBuilderConfig,
DBType: Database + Clone + 'static,
ProviderType: DatabaseProviderFactory<DB = DBType, Provider: BlockReader>
+ StateProviderFactory
+ Clone
+ 'static,
ProviderType: StateProviderFactory + Clone + 'static,
{
fn config(&self) -> &ConfigType;
/// Orders available to build blocks with their time of arrival.
Expand All @@ -67,18 +62,14 @@ where
fn print_custom_stats(&self, provider: ProviderType) -> eyre::Result<()>;
}

pub async fn run_backtest_build_block<ConfigType, OrdersSourceType, DBType, ProviderType>(
pub async fn run_backtest_build_block<ConfigType, OrdersSourceType, ProviderType>(
build_block_cfg: BuildBlockCfg,
orders_source: OrdersSourceType,
) -> eyre::Result<()>
where
ConfigType: LiveBuilderConfig,
DBType: Database + Clone + 'static,
ProviderType: DatabaseProviderFactory<DB = DBType, Provider: BlockReader>
+ StateProviderFactory
+ Clone
+ 'static,
OrdersSourceType: OrdersSource<ConfigType, DBType, ProviderType>,
ProviderType: StateProviderFactory + Clone + 'static,
OrdersSourceType: OrdersSource<ConfigType, ProviderType>,
{
let config = orders_source.config();
config.base_config().setup_tracing_subscriber()?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
},
BlockData, HistoricalDataStorage, OrdersWithTimestamp,
},
building::BlockBuildingContext,
building::{builders::mock_block_building_helper::MockRootHasher, BlockBuildingContext},
live_builder::{base_config::load_config_toml_and_env, cli::LiveBuilderConfig},
utils::{timestamp_as_u64, ProviderFactoryReopener},
};
Expand Down Expand Up @@ -84,7 +84,6 @@ impl<ConfigType: LiveBuilderConfig> LandedBlockFromDBOrdersSource<ConfigType> {
impl<ConfigType: LiveBuilderConfig>
OrdersSource<
ConfigType,
Arc<DatabaseEnv>,
ProviderFactoryReopener<NodeTypesWithDBAdapter<EthereumNode, Arc<DatabaseEnv>>>,
> for LandedBlockFromDBOrdersSource<ConfigType>
{
Expand All @@ -100,7 +99,7 @@ impl<ConfigType: LiveBuilderConfig>
&self,
) -> eyre::Result<ProviderFactoryReopener<NodeTypesWithDBAdapter<EthereumNode, Arc<DatabaseEnv>>>>
{
self.config.base_config().create_provider_factory()
self.config.base_config().create_provider_factory(true)
}

fn create_block_building_context(&self) -> eyre::Result<BlockBuildingContext> {
Expand All @@ -113,6 +112,7 @@ impl<ConfigType: LiveBuilderConfig>
signer.address,
self.block_data.winning_bid_trace.proposer_fee_recipient,
Some(signer),
Arc::new(MockRootHasher {}),
))
}

Expand Down
24 changes: 11 additions & 13 deletions crates/rbuilder/src/backtest/build_block/synthetic_orders.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use std::sync::Arc;

use clap::{command, Parser};
use reth_db::{test_utils::TempDatabase, DatabaseEnv};
use reth_provider::{providers::BlockchainProvider2, test_utils::MockNodeTypesWithDB};
use reth_provider::test_utils::MockNodeTypesWithDB;
use revm_primitives::B256;
use uuid::Uuid;

Expand All @@ -14,6 +11,7 @@ use crate::{
},
live_builder::{base_config::load_config_toml_and_env, cli::LiveBuilderConfig},
primitives::{Bundle, MempoolTx, Metadata, Order, TransactionSignedEcRecoveredWithBlobs},
provider::state_provider_factory_from_provider_factory::StateProviderFactoryFromProviderFactory,
};

use super::backtest_build_block::{run_backtest_build_block, BuildBlockCfg, OrdersSource};
Expand Down Expand Up @@ -112,11 +110,8 @@ impl<ConfigType: LiveBuilderConfig> SyntheticOrdersSource<ConfigType> {
}

impl<ConfigType: LiveBuilderConfig>
OrdersSource<
ConfigType,
Arc<TempDatabase<DatabaseEnv>>,
BlockchainProvider2<MockNodeTypesWithDB>,
> for SyntheticOrdersSource<ConfigType>
OrdersSource<ConfigType, StateProviderFactoryFromProviderFactory<MockNodeTypesWithDB>>
for SyntheticOrdersSource<ConfigType>
{
fn available_orders(&self) -> Vec<OrdersWithTimestamp> {
self.orders.clone()
Expand All @@ -126,10 +121,13 @@ impl<ConfigType: LiveBuilderConfig>
0
}

fn create_provider_factory(&self) -> eyre::Result<BlockchainProvider2<MockNodeTypesWithDB>> {
Ok(BlockchainProvider2::new(
fn create_provider_factory(
&self,
) -> eyre::Result<StateProviderFactoryFromProviderFactory<MockNodeTypesWithDB>> {
Ok(StateProviderFactoryFromProviderFactory::new(
self.test_chain_state.provider_factory().clone(),
)?)
None,
))
}

fn create_block_building_context(&self) -> eyre::Result<BlockBuildingContext> {
Expand All @@ -138,7 +136,7 @@ impl<ConfigType: LiveBuilderConfig>

fn print_custom_stats(
&self,
_provider: BlockchainProvider2<MockNodeTypesWithDB>,
_provider: StateProviderFactoryFromProviderFactory<MockNodeTypesWithDB>,
) -> eyre::Result<()> {
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion crates/rbuilder/src/backtest/redistribute/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ where
let mut historical_data_storage =
HistoricalDataStorage::new_from_path(&config.base_config().backtest_fetch_output_file)
.await?;
let provider = config.base_config().create_provider_factory()?;
let provider = config.base_config().create_provider_factory(true)?;
let mut csv_writer = cli
.csv
.map(|path| -> io::Result<_> { CSVResultWriter::new(path) })
Expand Down
2 changes: 1 addition & 1 deletion crates/rbuilder/src/bin/debug-bench-machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async fn main() -> eyre::Result<()> {

let chain_spec = config.base_config().chain_spec()?;

let provider_factory = config.base_config().create_provider_factory()?;
let provider_factory = config.base_config().create_provider_factory(false)?;

let last_block = provider_factory.last_block_number()?;

Expand Down
8 changes: 7 additions & 1 deletion crates/rbuilder/src/live_builder/base_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,10 @@ impl BaseConfig {
}

/// Open reth db and DB should be opened once per process but it can be cloned and moved to different threads.
/// skip_root_hash -> will create a mock roothasher. Used on backtesting since reth can't compute roothashes on the past.
pub fn create_provider_factory(
&self,
skip_root_hash: bool,
) -> eyre::Result<ProviderFactoryReopener<NodeTypesWithDBAdapter<EthereumNode, Arc<DatabaseEnv>>>>
{
create_provider_factory(
Expand All @@ -240,7 +242,11 @@ impl BaseConfig {
self.reth_static_files_path.as_deref(),
self.chain_spec()?,
false,
Some(self.live_root_hash_config()?),
if skip_root_hash {
None
} else {
Some(self.live_root_hash_config()?)
},
)
}

Expand Down
2 changes: 1 addition & 1 deletion crates/rbuilder/src/live_builder/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ where
config.base_config().log_enable_dynamic,
)
.await?;
let provider = config.base_config().create_provider_factory()?;
let provider = config.base_config().create_provider_factory(false)?;
let builder = config.new_builder(provider, cancel.clone()).await?;

let ctrlc = tokio::spawn(async move {
Expand Down
1 change: 1 addition & 0 deletions crates/rbuilder/src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use tokio::sync::broadcast;
use tokio_util::sync::CancellationToken;

pub mod reth_prov;
pub mod state_provider_factory_from_provider_factory;

/// Main trait to interact with the chain data.
/// Allows to create different backends for chain data access without implementing lots of interfaces as would happen with reth_provider::StateProviderFactory
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use alloy_consensus::Header;
use alloy_primitives::{BlockHash, BlockNumber};
use reth_errors::ProviderResult;
use reth_node_api::NodeTypesWithDB;
use reth_provider::{
providers::ProviderNodeTypes, BlockHashReader, BlockNumReader, HeaderProvider, ProviderFactory,
StateProviderBox,
};
use revm_primitives::B256;

use crate::{
building::builders::mock_block_building_helper::MockRootHasher, roothash::RootHashConfig,
utils::RootHasherImpl,
};

use super::{RootHasher, StateProviderFactory};

/// StateProviderFactory based on a ProviderFactory.
#[derive(Clone)]
pub struct StateProviderFactoryFromProviderFactory<N: NodeTypesWithDB> {
provider: ProviderFactory<N>,
root_hash_config: Option<RootHashConfig>,
}

impl<N: NodeTypesWithDB> StateProviderFactoryFromProviderFactory<N> {
/// root_hash_config None -> no roothash (MockRootHasher)
pub fn new(provider: ProviderFactory<N>, root_hash_config: Option<RootHashConfig>) -> Self {
Self {
provider,
root_hash_config,
}
}
}

impl<N: NodeTypesWithDB + ProviderNodeTypes + Clone> StateProviderFactory
for StateProviderFactoryFromProviderFactory<N>
{
fn latest(&self) -> ProviderResult<StateProviderBox> {
self.provider.latest()
}

fn history_by_block_number(&self, block: BlockNumber) -> ProviderResult<StateProviderBox> {
self.provider.history_by_block_number(block)
}

fn history_by_block_hash(&self, block: BlockHash) -> ProviderResult<StateProviderBox> {
self.provider.history_by_block_hash(block)
}

fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
self.provider.header(block_hash)
}

fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>> {
self.provider.block_hash(number)
}

fn best_block_number(&self) -> ProviderResult<BlockNumber> {
self.provider.best_block_number()
}

fn header_by_number(&self, num: u64) -> ProviderResult<Option<Header>> {
self.provider.header_by_number(num)
}

fn last_block_number(&self) -> ProviderResult<BlockNumber> {
self.provider.last_block_number()
}

fn root_hasher(&self, parent_hash: B256) -> Box<dyn RootHasher> {
if let Some(root_hash_config) = &self.root_hash_config {
Box::new(RootHasherImpl::new(
parent_hash,
root_hash_config.clone(),
self.provider.clone(),
))
} else {
Box::new(MockRootHasher {})
}
}
}

0 comments on commit 112edc3

Please sign in to comment.