@@ -4,16 +4,20 @@ use super::{
44 block_builder:: BlockBuilder , l1_helpers:: L1Helper , setup_engine, tx_helpers:: TxHelper ,
55} ;
66use crate :: {
7- BlobProviderArgs , ChainOrchestratorArgs , ConsensusAlgorithm , ConsensusArgs , EngineDriverArgs ,
8- L1ProviderArgs , RollupNodeDatabaseArgs , RollupNodeGasPriceOracleArgs , RollupNodeNetworkArgs ,
9- RpcArgs , ScrollRollupNode , ScrollRollupNodeConfig , SequencerArgs , SignerArgs , TestArgs ,
7+ constants, BlobProviderArgs , ChainOrchestratorArgs , ConsensusAlgorithm , ConsensusArgs ,
8+ EngineDriverArgs , L1ProviderArgs , RollupNodeDatabaseArgs , RollupNodeGasPriceOracleArgs ,
9+ RollupNodeNetworkArgs , RpcArgs , ScrollRollupNode , ScrollRollupNodeConfig , SequencerArgs ,
10+ SignerArgs , TestArgs ,
1011} ;
1112
1213use alloy_eips:: BlockNumberOrTag ;
1314use alloy_primitives:: Address ;
14- use alloy_provider:: { Provider , ProviderBuilder } ;
15+ use alloy_provider:: { ext:: AnvilApi , layers:: CacheLayer , Provider , ProviderBuilder } ;
16+ use alloy_rpc_client:: RpcClient ;
17+ use alloy_rpc_types_anvil:: ReorgOptions ;
1518use alloy_rpc_types_eth:: Block ;
1619use alloy_signer_local:: PrivateKeySigner ;
20+ use alloy_transport:: layers:: RetryBackoffLayer ;
1721use reth_chainspec:: EthChainSpec ;
1822use reth_e2e_test_utils:: { wallet:: Wallet , NodeHelperType , TmpDB } ;
1923use reth_eth_wire_types:: BasicNetworkPrimitives ;
@@ -216,66 +220,46 @@ impl TestFixture {
216220 self . get_status ( 0 ) . await
217221 }
218222
219- /// Get the Anvil HTTP endpoint if Anvil was started.
220- pub fn anvil_endpoint ( & self ) -> Option < String > {
221- self . anvil . as_ref ( ) . map ( |a| a. http_endpoint ( ) )
223+ /// Get the Anvil HTTP provider with retry and cache layers.
224+ pub fn anvil_provider ( & self ) -> Option < impl Provider + Clone > {
225+ self . anvil . as_ref ( ) . map ( |anvil| {
226+ let retry_layer = RetryBackoffLayer :: new (
227+ constants:: L1_PROVIDER_MAX_RETRIES ,
228+ constants:: L1_PROVIDER_INITIAL_BACKOFF ,
229+ constants:: PROVIDER_COMPUTE_UNITS_PER_SECOND ,
230+ ) ;
231+ let client = RpcClient :: builder ( )
232+ . layer ( retry_layer)
233+ . http ( anvil. http_endpoint ( ) . parse ( ) . expect ( "failed to parse anvil http endpoint" ) ) ;
234+ let cache_layer = CacheLayer :: new ( constants:: L1_PROVIDER_CACHE_MAX_ITEMS ) ;
235+ ProviderBuilder :: new ( ) . layer ( cache_layer) . connect_client ( client)
236+ } )
222237 }
223238
224239 /// Generate Anvil blocks by calling `anvil_mine` RPC method.
225240 pub async fn anvil_mine_blocks ( & self , num_blocks : u64 ) -> eyre:: Result < ( ) > {
226- // Ensure Anvil is running
227- let anvil_endpoint =
228- self . anvil_endpoint ( ) . ok_or_else ( || eyre:: eyre!( "Anvil is not running" ) ) ?;
229-
230- // Create RPC client
231- let client = alloy_rpc_client:: RpcClient :: new_http ( anvil_endpoint. parse ( ) ?) ;
232-
233- // Mine blocks using anvil_mine RPC method
234- // Parameters: (num_blocks, interval_in_seconds)
235- let _: ( ) = client. request ( "anvil_mine" , ( num_blocks, 0 ) ) . await ?;
236-
237- Ok ( ( ) )
241+ let provider = self . anvil_provider ( ) . ok_or_else ( || eyre:: eyre!( "Anvil is not running" ) ) ?;
242+ Ok ( provider. anvil_mine ( Some ( num_blocks) , None ) . await ?)
238243 }
239244
240245 /// Inject a raw transaction to Anvil.
241246 pub async fn anvil_inject_tx (
242247 & self ,
243248 raw_tx : impl Into < alloy_primitives:: Bytes > ,
244249 ) -> eyre:: Result < alloy_primitives:: B256 > {
245- // Ensure Anvil is running
246- let anvil_endpoint =
247- self . anvil_endpoint ( ) . ok_or_else ( || eyre:: eyre!( "Anvil is not running" ) ) ?;
248-
249- // Create provider
250- let provider = ProviderBuilder :: new ( ) . connect_http ( anvil_endpoint. parse ( ) ?) ;
251-
252- // Send raw transaction
250+ let provider = self . anvil_provider ( ) . ok_or_else ( || eyre:: eyre!( "Anvil is not running" ) ) ?;
253251 let raw_tx_bytes = raw_tx. into ( ) ;
254252 let pending_tx = provider. send_raw_transaction ( & raw_tx_bytes) . await ?;
255-
256253 let tx_hash = * pending_tx. tx_hash ( ) ;
257254 tracing:: info!( "Sent raw transaction to Anvil: {:?}" , tx_hash) ;
258-
259255 Ok ( tx_hash)
260256 }
261257
262258 /// Reorg Anvil by a specific depth (number of blocks to rewind).
263259 pub async fn anvil_reorg ( & self , depth : u64 ) -> eyre:: Result < ( ) > {
264- // Ensure Anvil is running
265- let anvil_endpoint =
266- self . anvil_endpoint ( ) . ok_or_else ( || eyre:: eyre!( "Anvil is not running" ) ) ?;
267-
268- // Create RPC client
269- let client = alloy_rpc_client:: RpcClient :: new_http ( anvil_endpoint. parse ( ) ?) ;
270-
271- // Call anvil_reorg
272- // Parameters: (depth, transactions)
273- // - depth: number of blocks to rewind from current head
274- // - transactions: empty array means reorg without adding new transactions
275- let _: ( ) = client. request ( "anvil_reorg" , ( depth, Vec :: < String > :: new ( ) ) ) . await ?;
276-
260+ let provider = self . anvil_provider ( ) . ok_or_else ( || eyre:: eyre!( "Anvil is not running" ) ) ?;
261+ provider. anvil_reorg ( ReorgOptions { depth, tx_block_pairs : Vec :: new ( ) } ) . await ?;
277262 tracing:: info!( "Reorged Anvil by {} blocks" , depth) ;
278-
279263 Ok ( ( ) )
280264 }
281265}
@@ -523,7 +507,8 @@ impl TestFixtureBuilder {
523507 /// Enable Anvil with optional configuration.
524508 ///
525509 /// # Parameters
526- /// - `state_path`: Optional path to Anvil state file. Defaults to `./tests/testdata/anvil_state.json` if `None`.
510+ /// - `state_path`: Optional path to Anvil state file. Defaults to
511+ /// `./tests/testdata/anvil_state.json` if `None`.
527512 /// - `chain_id`: Optional chain ID for Anvil. If `None`, Anvil uses its default.
528513 /// - `block_time`: Optional block time in seconds. If `None`, Anvil uses its default.
529514 ///
@@ -545,8 +530,8 @@ impl TestFixtureBuilder {
545530 block_time : Option < u64 > ,
546531 ) -> Self {
547532 self . anvil_config . enabled = true ;
548- self . anvil_config . state_path = state_path
549- . or_else ( || Some ( PathBuf :: from ( "./tests/testdata/anvil_state.json" ) ) ) ;
533+ self . anvil_config . state_path =
534+ state_path . or_else ( || Some ( PathBuf :: from ( "./tests/testdata/anvil_state.json" ) ) ) ;
550535 self . anvil_config . chain_id = chain_id;
551536 self . anvil_config . block_time = block_time;
552537 self
0 commit comments