Skip to content

Commit f61b274

Browse files
committed
wire presim through flashpool
1 parent da1dabb commit f61b274

12 files changed

Lines changed: 259 additions & 172 deletions

File tree

crates/op-rbuilder/src/launcher.rs

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use std::sync::Arc;
2-
31
use eyre::Result;
4-
use futures::FutureExt;
52
use reth_optimism_rpc::OpEthApiBuilder;
63
use tracing::info;
74

@@ -11,24 +8,22 @@ use crate::{
118
BackrunBundleApiServer, BackrunBundleRpc, maintain_backrun_bundle_pool_future,
129
},
1310
builder::{BuilderConfig, FlashblocksServiceBuilder},
14-
metrics::{OpRBuilderMetrics, VERSION, record_flag_gauge_metrics},
11+
metrics::{VERSION, record_flag_gauge_metrics},
1512
monitor_tx_pool::monitor_tx_pool,
1613
pool::FlashpoolBuilder,
17-
presim::{TopOfBlockSimulator, maintain_pending_simulations, maintain_tip_state},
1814
revert_protection::{EthApiExtServer, RevertProtectionExt},
1915
};
2016
use moka::future::Cache;
2117
use reth::builder::{NodeBuilder, WithLaunchContext};
18+
use reth_chain_state::CanonStateSubscriptions;
2219
use reth_cli_commands::launcher::Launcher;
2320
use reth_db::mdbx::DatabaseEnv;
2421
use reth_optimism_chainspec::OpChainSpec;
2522
use reth_optimism_cli::chainspec::OpChainSpecParser;
26-
use reth_optimism_evm::OpEvmConfig;
2723
use reth_optimism_node::{
2824
OpNode,
2925
node::{OpAddOns, OpAddOnsBuilder, OpEngineValidatorBuilder},
3026
};
31-
use reth_provider::{CanonStateSubscriptions, ChainSpecProvider};
3227
use reth_transaction_pool::TransactionPool;
3328
pub fn launch() -> Result<()> {
3429
let cli = Cli::parsed();
@@ -100,18 +95,9 @@ impl Launcher<OpChainSpecParser, OpRbuilderArgs> for BuilderLauncher {
10095
let reverted_cache = Cache::builder().max_capacity(100).build();
10196
let reverted_cache_copy = reverted_cache.clone();
10297
let backrun_bundle_enabled = builder_args.backrun_bundle.backruns_enabled;
103-
let block_time_secs = builder_config.block_time.as_millis() as u64 / 1000;
10498
let backrun_bundle_pool = builder_config.backrun_bundle_pool.clone();
10599
let backrun_bundle_pool_maintain = backrun_bundle_pool.clone();
106100

107-
let simulator = if builder_args.pre_simulate_bundles {
108-
Some(Arc::new(TopOfBlockSimulator::new()))
109-
} else {
110-
None
111-
};
112-
let simulator_for_rpc = simulator.clone();
113-
let simulator_for_maintenance = simulator.clone();
114-
115101
let addons: OpAddOns<_, OpEthApiBuilder, OpEngineValidatorBuilder> =
116102
OpAddOnsBuilder::default()
117103
.with_sequencer(rollup_args.sequencer.clone())
@@ -140,7 +126,6 @@ impl Launcher<OpChainSpecParser, OpRbuilderArgs> for BuilderLauncher {
140126
provider,
141127
ctx.registry.eth_api().clone(),
142128
reverted_cache,
143-
simulator_for_rpc,
144129
);
145130

146131
ctx.modules
@@ -185,34 +170,6 @@ impl Launcher<OpChainSpecParser, OpRbuilderArgs> for BuilderLauncher {
185170
));
186171
}
187172

188-
if let Some(simulator) = simulator_for_maintenance {
189-
let metrics = Arc::new(OpRBuilderMetrics::default());
190-
let chain_events = ctx.provider.canonical_state_stream();
191-
let evm_config = OpEvmConfig::optimism(ctx.provider.chain_spec());
192-
ctx.task_executor.spawn_task(
193-
maintain_tip_state(
194-
simulator.clone(),
195-
ctx.provider.clone(),
196-
evm_config,
197-
block_time_secs,
198-
metrics.clone(),
199-
chain_events,
200-
)
201-
.boxed(),
202-
);
203-
204-
let pending_events = ctx.pool.all_transactions_event_listener();
205-
ctx.task_executor.spawn_task(
206-
maintain_pending_simulations(
207-
simulator,
208-
ctx.pool.clone(),
209-
metrics,
210-
pending_events,
211-
)
212-
.boxed(),
213-
);
214-
}
215-
216173
Ok(())
217174
})
218175
.launch()

crates/op-rbuilder/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ pub mod launcher;
99
pub mod metrics;
1010
mod monitor_tx_pool;
1111
pub mod pool;
12-
pub mod presim;
1312
pub mod primitives;
1413
pub mod revert_protection;
1514
pub(crate) mod runtime_ext;

crates/op-rbuilder/src/metrics.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,6 @@ pub struct OpRBuilderMetrics {
159159
pub bundles_reverted: Histogram,
160160
/// Histogram of eth_sendBundle request duration
161161
pub bundle_receive_duration: Histogram,
162-
/// Number of bundles dropped by pre-simulation (reverted)
163-
pub bundle_pre_simulation_reverts: Counter,
164-
/// Number of bundles that passed pre-simulation
165-
pub bundle_pre_simulation_passes: Counter,
166-
/// Histogram of bundle pre-simulation duration
167-
pub bundle_pre_simulation_duration: Histogram,
168-
/// Number of updates to the tip state for the top of block simulator
169-
pub presim_tip_state_updates: Counter,
170-
/// Number of pending txs evicted due to failing top of block simulation
171-
pub presim_pending_evictions: Counter,
172162
/// Transactions rejected by per-tx DA size limit
173163
pub tx_da_size_exceeded_total: Counter,
174164
/// Transactions rejected by cumulative block DA limit
Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
1+
use std::sync::Arc;
2+
3+
use futures::FutureExt;
4+
use reth_chain_state::CanonStateSubscriptions;
15
use reth_evm::ConfigureEvm;
26
use reth_node_api::{FullNodeTypes, NodeTypes, PrimitivesTy, TxTy};
37
use reth_node_builder::{BuilderContext, components::PoolBuilder};
8+
use reth_optimism_chainspec::OpChainSpec;
9+
use reth_optimism_evm::OpEvmConfig;
410
use reth_optimism_forks::OpHardforks;
511
use reth_optimism_node::OpPoolBuilder;
6-
use reth_optimism_txpool::{OpPooledTx, OpTransactionPool};
7-
use reth_transaction_pool::{EthPoolTransaction, blobstore::DiskFileBlobStore};
12+
use reth_optimism_txpool::{OpPooledTx, OpTransactionPool, OpTransactionValidator};
13+
use reth_primitives_traits::{Block, NodePrimitives};
14+
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, NodePrimitivesProvider};
15+
use reth_transaction_pool::{
16+
EthPoolTransaction, TransactionPool, TransactionValidationTaskExecutor,
17+
blobstore::DiskFileBlobStore,
18+
};
819

9-
use crate::{args::OpRbuilderArgs, pool::Flashpool, tx::FBPooledTransaction};
20+
use crate::{
21+
args::OpRbuilderArgs,
22+
pool::{
23+
Flashpool,
24+
metrics::PoolMetrics,
25+
presim::{TopOfBlockSimulator, maintain_pending_simulations, maintain_tip_state},
26+
},
27+
tx::FBPooledTransaction,
28+
};
1029

1130
pub struct FlashpoolBuilder {
1231
op_pool_builder: OpPoolBuilder<FBPooledTransaction>,
32+
pre_simulate_bundles: bool,
33+
block_time_secs: u64,
1334
}
1435

1536
impl FlashpoolBuilder {
@@ -22,26 +43,79 @@ impl FlashpoolBuilder {
2243
rollup_args.enable_tx_conditional || builder_args.enable_revert_protection,
2344
);
2445

25-
Self { op_pool_builder }
46+
Self {
47+
op_pool_builder,
48+
pre_simulate_bundles: builder_args.pre_simulate_bundles,
49+
block_time_secs: builder_args.chain_block_time / 1000,
50+
}
2651
}
2752
}
2853

2954
impl<Node, Evm> PoolBuilder<Node, Evm> for FlashpoolBuilder
3055
where
3156
Node: FullNodeTypes<Types: NodeTypes<ChainSpec: OpHardforks>>,
57+
Node::Provider: ChainSpecProvider<ChainSpec = OpChainSpec>
58+
+ BlockReaderIdExt<Header = alloy_consensus::Header>,
59+
<Node::Provider as NodePrimitivesProvider>::Primitives:
60+
NodePrimitives<Block: Block<Header = alloy_consensus::Header>>,
3261
FBPooledTransaction: EthPoolTransaction<Consensus = TxTy<Node::Types>> + OpPooledTx,
3362
Evm: ConfigureEvm<Primitives = PrimitivesTy<Node::Types>> + Clone + 'static,
3463
{
35-
type Pool =
36-
Flashpool<OpTransactionPool<Node::Provider, DiskFileBlobStore, Evm, FBPooledTransaction>>;
64+
type Pool = Flashpool<
65+
OpTransactionPool<Node::Provider, DiskFileBlobStore, Evm, FBPooledTransaction>,
66+
TransactionValidationTaskExecutor<
67+
OpTransactionValidator<Node::Provider, FBPooledTransaction, Evm>,
68+
>,
69+
>;
3770

3871
async fn build_pool(
3972
self,
4073
ctx: &BuilderContext<Node>,
4174
evm_config: Evm,
4275
) -> eyre::Result<Self::Pool> {
76+
let inner_pool = self.op_pool_builder.build_pool(ctx, evm_config).await?;
77+
let validator = inner_pool.validator().clone();
78+
let metrics = Arc::new(PoolMetrics::default());
79+
80+
let simulator = if self.pre_simulate_bundles {
81+
let simulator = Arc::new(TopOfBlockSimulator::new());
82+
83+
let chain_events = ctx.provider().canonical_state_stream();
84+
let op_evm_config = OpEvmConfig::optimism(ctx.provider().chain_spec());
85+
ctx.task_executor().spawn_task(
86+
maintain_tip_state(
87+
simulator.clone(),
88+
ctx.provider().clone(),
89+
op_evm_config,
90+
self.block_time_secs,
91+
metrics.clone(),
92+
chain_events,
93+
)
94+
.boxed(),
95+
);
96+
97+
let pending_events = inner_pool.all_transactions_event_listener();
98+
ctx.task_executor().spawn_task(
99+
maintain_pending_simulations(
100+
simulator.clone(),
101+
inner_pool.clone(),
102+
metrics.clone(),
103+
pending_events,
104+
)
105+
.boxed(),
106+
);
107+
108+
Some(simulator)
109+
} else {
110+
None
111+
};
112+
43113
Ok(Flashpool {
44-
inner: self.op_pool_builder.build_pool(ctx, evm_config).await?,
114+
inner: inner_pool,
115+
validator,
116+
simulator,
117+
task_executor: ctx.task_executor().clone(),
118+
metrics,
45119
})
46120
}
47121
}

crates/op-rbuilder/src/pool/delegate.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,27 @@ use reth_transaction_pool::{
1313
BestTransactionsAttributes, BlockInfo, GetPooledTransactionLimit, NewBlobSidecar,
1414
NewTransactionEvent, PoolResult, PoolSize, PoolTransaction, PropagatedTransactions,
1515
TransactionEvents, TransactionListenerKind, TransactionOrigin, TransactionPool,
16-
ValidPoolTransaction, blobstore::BlobStoreError,
16+
TransactionValidator, ValidPoolTransaction, blobstore::BlobStoreError,
1717
};
1818
use tokio::sync::mpsc::Receiver;
1919

2020
use crate::{pool::Flashpool, tx::FBPooledTransaction};
2121

22-
impl<P: TransactionPool<Transaction = FBPooledTransaction>> TransactionPool for Flashpool<P> {
22+
impl<
23+
P: TransactionPool<Transaction = FBPooledTransaction> + 'static,
24+
V: TransactionValidator<Transaction = FBPooledTransaction> + Clone,
25+
> TransactionPool for Flashpool<P, V>
26+
{
2327
type Transaction = FBPooledTransaction;
2428

29+
fn add_transaction(
30+
&self,
31+
origin: TransactionOrigin,
32+
transaction: Self::Transaction,
33+
) -> impl Future<Output = PoolResult<AddedTransactionOutcome>> + Send {
34+
self.add_transaction_override(origin, transaction)
35+
}
36+
2537
delegate! {
2638
to self.inner {
2739
fn pool_size(&self) -> PoolSize;
@@ -31,11 +43,7 @@ impl<P: TransactionPool<Transaction = FBPooledTransaction>> TransactionPool for
3143
origin: TransactionOrigin,
3244
transaction: Self::Transaction,
3345
) -> impl Future<Output = PoolResult<TransactionEvents>> + Send;
34-
fn add_transaction(
35-
&self,
36-
origin: TransactionOrigin,
37-
transaction: Self::Transaction,
38-
) -> impl Future<Output = PoolResult<AddedTransactionOutcome>> + Send;
46+
3947
fn add_transactions_with_origins(
4048
&self,
4149
transactions: impl IntoIterator<Item = (TransactionOrigin, Self::Transaction)> + Send,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use metrics::{Counter, Histogram, counter};
2+
use reth_metrics::Metrics;
3+
4+
#[derive(Metrics, Clone)]
5+
#[metrics(scope = "op_rbuilder.pool")]
6+
pub(super) struct PoolMetrics {
7+
/// Histogram of bundle pre-simulation duration
8+
pub presim_duration: Histogram,
9+
/// Number of updates to the tip state for the top of block simulator
10+
pub presim_tip_state_updates: Counter,
11+
/// Number of pending txs evicted due to failing top of block simulation
12+
pub presim_pending_evictions: Counter,
13+
}
14+
15+
pub(super) fn increment_presim_count(sim_result: &eyre::Result<bool>) {
16+
let label = match sim_result {
17+
Ok(true) => "passed",
18+
Ok(false) => "reverted",
19+
Err(_) => "failed",
20+
};
21+
counter!("op_rbuilder.pool.presim_count", "result" => label).increment(1);
22+
}

crates/op-rbuilder/src/pool/mod.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
11
mod builder;
22
mod delegate;
3+
mod metrics;
4+
mod overrides;
5+
mod presim;
36

47
pub use builder::FlashpoolBuilder;
58

6-
use reth_transaction_pool::TransactionPool;
9+
use std::sync::Arc;
710

8-
use crate::tx::FBPooledTransaction;
11+
use reth_tasks::TaskExecutor;
12+
13+
use crate::pool::{metrics::PoolMetrics, presim::TopOfBlockSimulator};
914

1015
#[derive(Debug, Clone)]
11-
pub struct Flashpool<P: TransactionPool<Transaction = FBPooledTransaction>> {
16+
pub struct Flashpool<P, V> {
17+
/// The reth transaction pool we're wrapping around
1218
inner: P,
19+
20+
/// The transaction validator
21+
validator: V,
22+
23+
/// Optional pre-simulator: when present, revert-protected txs are simulated
24+
/// before being added to the pool; those that would revert are rejected.
25+
simulator: Option<Arc<TopOfBlockSimulator>>,
26+
27+
/// Task executor for spawning presim tasks
28+
task_executor: TaskExecutor,
29+
30+
/// Metrics
31+
metrics: Arc<PoolMetrics>,
1332
}

0 commit comments

Comments
 (0)