alloy_provider/ext/
anvil.rs

1//! This module extends the Ethereum JSON-RPC provider with the Anvil namespace's RPC methods.
2
3use crate::{PendingTransactionBuilder, Provider};
4use alloy_network::{Network, TransactionBuilder};
5use alloy_primitives::{Address, Bytes, TxHash, B256, U128, U256, U64};
6use alloy_rpc_types_anvil::{Forking, Metadata, MineOptions, NodeInfo, ReorgOptions};
7use alloy_rpc_types_eth::Block;
8use alloy_transport::{TransportError, TransportResult};
9use futures::try_join;
10
11/// Anvil namespace rpc interface that gives access to several non-standard RPC methods.
12#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
13#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
14pub trait AnvilApi<N: Network>: Send + Sync {
15    // Not implemented:
16    // - anvil_enable_traces: Not implemented in the Anvil RPC API.
17    // - anvil_set_block: Not implemented / wired correctly in the Anvil RPC API.
18
19    /// Send transactions impersonating specific account and contract addresses.
20    async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()>;
21
22    /// Stops impersonating an account if previously set with `anvil_impersonateAccount`.
23    async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()>;
24
25    /// If set to true will make every account impersonated.
26    async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()>;
27
28    /// Impersonates the `from` address in the given transaction request, optionally funds the
29    /// sender, sends the transaction, and optionally stops impersonating after execution based
30    /// on the provided config.
31    async fn anvil_send_impersonated_transaction_with_config(
32        &self,
33        request: N::TransactionRequest,
34        config: ImpersonateConfig,
35    ) -> TransportResult<PendingTransactionBuilder<N>>;
36
37    /// Returns true if auto mining is enabled, and false.
38    async fn anvil_get_auto_mine(&self) -> TransportResult<bool>;
39
40    /// Enables or disables, based on the single boolean argument, the automatic mining of new
41    /// blocks with each new transaction submitted to the network.
42    async fn anvil_set_auto_mine(&self, enable_automine: bool) -> TransportResult<()>;
43
44    /// Mines a series of blocks.
45    async fn anvil_mine(
46        &self,
47        num_blocks: Option<u64>,
48        interval: Option<u64>,
49    ) -> TransportResult<()>;
50
51    /// Sets the mining behavior to interval with the given interval (seconds).
52    async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()>;
53
54    /// Removes transactions from the pool.
55    async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>>;
56
57    /// Removes all transactions from the pool.
58    async fn anvil_drop_all_transactions(&self) -> TransportResult<()>;
59
60    /// Reset the fork to a fresh forked state, and optionally update the fork config.
61    ///
62    /// If `forking` is `None` then this will disable forking entirely.
63    async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()>;
64
65    /// Sets the chain ID.
66    async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()>;
67
68    /// Modifies the balance of an account.
69    async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()>;
70
71    /// Sets the code of a contract.
72    async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()>;
73
74    /// Sets the nonce of an address.
75    async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()>;
76
77    /// Writes a single slot of the account's storage.
78    async fn anvil_set_storage_at(
79        &self,
80        address: Address,
81        slot: U256,
82        val: B256,
83    ) -> TransportResult<bool>;
84
85    /// Enable or disable logging.
86    async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()>;
87
88    /// Set the minimum gas price for the node.
89    async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()>;
90
91    /// Sets the base fee of the next block.
92    async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()>;
93
94    /// Sets the coinbase address.
95    async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()>;
96
97    /// Create a buffer that represents all state on the chain, which can be loaded to separate
98    /// process by calling `anvil_loadState`
99    async fn anvil_dump_state(&self) -> TransportResult<Bytes>;
100
101    /// Append chain state buffer to current chain. Will overwrite any conflicting addresses or
102    /// storage.
103    async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool>;
104
105    /// Retrieves the Anvil node configuration params.
106    async fn anvil_node_info(&self) -> TransportResult<NodeInfo>;
107
108    /// Retrieves metadata about the Anvil instance.
109    async fn anvil_metadata(&self) -> TransportResult<Metadata>;
110
111    /// Removes all transactions from the pool for a specific address.
112    async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()>;
113
114    /// Snapshot the state of the blockchain at the current block.
115    async fn anvil_snapshot(&self) -> TransportResult<U256>;
116
117    /// Revert the state of the blockchain to a previous snapshot.
118    /// Takes a single parameter, which is the snapshot id to revert to.
119    async fn anvil_revert(&self, id: U256) -> TransportResult<bool>;
120
121    /// Jump forward in time by the given amount of time, in seconds.
122    async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64>;
123
124    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block.
125    async fn anvil_set_next_block_timestamp(&self, timestamp: u64) -> TransportResult<()>;
126
127    /// Sets the specific timestamp and returns the number of seconds between the given timestamp
128    /// and the current time.
129    async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64>;
130
131    /// Set the next block gas limit.
132    async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool>;
133
134    /// Sets an interval for the block timestamp.
135    async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()>;
136
137    /// Unsets the interval for the block timestamp.
138    async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool>;
139
140    /// Mine blocks, instantly.
141    /// This will mine the blocks regardless of the configured mining mode.
142    async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String>;
143
144    /// Mine blocks, instantly and return the mined blocks.
145    /// This will mine the blocks regardless of the configured mining mode.
146    async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>>;
147
148    /// Sets the backend rpc url.
149    async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()>;
150
151    /// Reorg the chain
152    async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()>;
153
154    /// Rollback the chain  
155    async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()>;
156
157    /// Execute a transaction regardless of signature status.
158    async fn eth_send_unsigned_transaction(
159        &self,
160        request: N::TransactionRequest,
161    ) -> TransportResult<TxHash>;
162
163    /// Executes a transaction and waits for it to be mined, returning the receipt.
164    async fn eth_send_transaction_sync(
165        &self,
166        request: N::TransactionRequest,
167    ) -> TransportResult<N::ReceiptResponse>;
168
169    /// Sends a raw transaction and waits for it to be mined, returning the receipt.
170    async fn eth_send_raw_transaction_sync(
171        &self,
172        request: Bytes,
173    ) -> TransportResult<N::ReceiptResponse>;
174
175    /// Sets impersonated transaction
176    async fn anvil_send_impersonated_transaction(
177        &self,
178        request: N::TransactionRequest,
179    ) -> TransportResult<TxHash>;
180
181    /// Modifies the ERC20 balance of an account.
182    async fn anvil_deal_erc20(
183        &self,
184        address: Address,
185        token_address: Address,
186        balance: U256,
187    ) -> TransportResult<()>;
188
189    /// Modifies the ERC20 allowance of an account.
190    async fn anvil_set_erc20_allowance(
191        &self,
192        owner: Address,
193        spender: Address,
194        token: Address,
195        allowance: U256,
196    ) -> TransportResult<()>;
197}
198
199#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
200#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
201impl<N, P> AnvilApi<N> for P
202where
203    N: Network,
204    P: Provider<N>,
205{
206    async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()> {
207        self.client().request("anvil_impersonateAccount", (address,)).await
208    }
209
210    async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()> {
211        self.client().request("anvil_stopImpersonatingAccount", (address,)).await
212    }
213
214    async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()> {
215        self.client().request("anvil_autoImpersonateAccount", (enabled,)).await
216    }
217
218    async fn anvil_get_auto_mine(&self) -> TransportResult<bool> {
219        self.client().request_noparams("anvil_getAutomine").await
220    }
221
222    async fn anvil_set_auto_mine(&self, enabled: bool) -> TransportResult<()> {
223        self.client().request("anvil_setAutomine", (enabled,)).await
224    }
225
226    async fn anvil_mine(
227        &self,
228        num_blocks: Option<u64>,
229        interval: Option<u64>,
230    ) -> TransportResult<()> {
231        self.client()
232            .request("anvil_mine", (num_blocks.map(U64::from), interval.map(U64::from)))
233            .await
234    }
235
236    async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()> {
237        self.client().request("anvil_setIntervalMining", (secs,)).await
238    }
239
240    async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>> {
241        self.client().request("anvil_dropTransaction", (tx_hash,)).await
242    }
243
244    async fn anvil_drop_all_transactions(&self) -> TransportResult<()> {
245        self.client().request_noparams("anvil_dropAllTransactions").await
246    }
247
248    async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()> {
249        self.client().request("anvil_reset", (forking,)).await
250    }
251
252    async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()> {
253        self.client().request("anvil_setChainId", (chain_id,)).await
254    }
255
256    async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()> {
257        self.client().request("anvil_setBalance", (address, balance)).await
258    }
259
260    async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()> {
261        self.client().request("anvil_setCode", (address, code)).await
262    }
263
264    async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()> {
265        self.client().request("anvil_setNonce", (address, U64::from(nonce))).await
266    }
267
268    async fn anvil_set_storage_at(
269        &self,
270        address: Address,
271        slot: U256,
272        val: B256,
273    ) -> TransportResult<bool> {
274        self.client().request("anvil_setStorageAt", (address, slot, val)).await
275    }
276
277    async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()> {
278        self.client().request("anvil_setLoggingEnabled", (enable,)).await
279    }
280
281    async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()> {
282        self.client().request("anvil_setMinGasPrice", (U128::from(gas),)).await
283    }
284
285    async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()> {
286        self.client().request("anvil_setNextBlockBaseFeePerGas", (U128::from(basefee),)).await
287    }
288
289    async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()> {
290        self.client().request("anvil_setCoinbase", (address,)).await
291    }
292
293    async fn anvil_dump_state(&self) -> TransportResult<Bytes> {
294        self.client().request_noparams("anvil_dumpState").await
295    }
296
297    async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool> {
298        self.client().request("anvil_loadState", (buf,)).await
299    }
300
301    async fn anvil_node_info(&self) -> TransportResult<NodeInfo> {
302        self.client().request_noparams("anvil_nodeInfo").await
303    }
304
305    async fn anvil_metadata(&self) -> TransportResult<Metadata> {
306        self.client().request_noparams("anvil_metadata").await
307    }
308
309    async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()> {
310        self.client().request("anvil_removePoolTransactions", (address,)).await
311    }
312
313    async fn anvil_snapshot(&self) -> TransportResult<U256> {
314        self.client().request_noparams("evm_snapshot").await
315    }
316
317    async fn anvil_revert(&self, id: U256) -> TransportResult<bool> {
318        self.client().request("evm_revert", (id,)).await
319    }
320
321    async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64> {
322        self.client().request("evm_increaseTime", (U64::from(seconds),)).await
323    }
324
325    async fn anvil_set_next_block_timestamp(&self, seconds: u64) -> TransportResult<()> {
326        self.client().request("evm_setNextBlockTimestamp", (seconds,)).await
327    }
328
329    async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64> {
330        self.client().request("evm_setTime", (timestamp,)).await
331    }
332
333    async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool> {
334        self.client().request("evm_setBlockGasLimit", (U64::from(gas_limit),)).await
335    }
336
337    async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()> {
338        self.client().request("anvil_setBlockTimestampInterval", (seconds,)).await
339    }
340
341    async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool> {
342        self.client().request_noparams("anvil_removeBlockTimestampInterval").await
343    }
344
345    async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String> {
346        self.client().request("evm_mine", (opts,)).await
347    }
348
349    async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>> {
350        self.client().request("evm_mine_detailed", (opts,)).await
351    }
352
353    async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()> {
354        self.client().request("anvil_setRpcUrl", (url,)).await
355    }
356
357    async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()> {
358        self.client().request("anvil_reorg", options).await
359    }
360
361    async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()> {
362        self.client().request("anvil_rollback", (depth,)).await
363    }
364
365    async fn eth_send_unsigned_transaction(
366        &self,
367        request: N::TransactionRequest,
368    ) -> TransportResult<TxHash> {
369        self.client().request("eth_sendUnsignedTransaction", (request,)).await
370    }
371
372    async fn eth_send_transaction_sync(
373        &self,
374        request: N::TransactionRequest,
375    ) -> TransportResult<N::ReceiptResponse> {
376        self.client().request("eth_sendTransactionSync", (request,)).await
377    }
378
379    async fn eth_send_raw_transaction_sync(
380        &self,
381        request: Bytes,
382    ) -> TransportResult<N::ReceiptResponse> {
383        self.client().request("eth_sendRawTransactionSync", (request,)).await
384    }
385
386    async fn anvil_send_impersonated_transaction(
387        &self,
388        request: N::TransactionRequest,
389    ) -> TransportResult<TxHash> {
390        self.client().request("eth_sendTransaction", (request,)).await
391    }
392
393    async fn anvil_deal_erc20(
394        &self,
395        address: Address,
396        token_address: Address,
397        balance: U256,
398    ) -> TransportResult<()> {
399        self.client().request("anvil_dealERC20", (address, token_address, balance)).await
400    }
401
402    async fn anvil_set_erc20_allowance(
403        &self,
404        owner: Address,
405        spender: Address,
406        token: Address,
407        allowance: U256,
408    ) -> TransportResult<()> {
409        self.client().request("anvil_setERC20Allowance", (owner, spender, token, allowance)).await
410    }
411
412    async fn anvil_send_impersonated_transaction_with_config(
413        &self,
414        request: N::TransactionRequest,
415        config: ImpersonateConfig,
416    ) -> TransportResult<PendingTransactionBuilder<N>> {
417        let from = request.from().ok_or_else(|| {
418            TransportError::from(alloy_transport::TransportErrorKind::Custom(
419                "TransactionRequest must have a `from` address set.".to_string().into(),
420            ))
421        })?;
422
423        let impersonate_future = self.anvil_impersonate_account(from);
424
425        if let Some(amount) = config.fund_amount {
426            let fund_future = self.anvil_set_balance(from, amount);
427            try_join!(fund_future, impersonate_future)?;
428        } else {
429            impersonate_future.await?;
430        }
431
432        let tx_hash = self.anvil_send_impersonated_transaction(request).await?;
433        let pending = PendingTransactionBuilder::new(self.root().clone(), tx_hash);
434
435        if config.stop_impersonate {
436            self.anvil_stop_impersonating_account(from).await?;
437        }
438
439        Ok(pending)
440    }
441}
442
443/// Configuration for impersonated transactions, including optional funding and whether to stop
444/// impersonation.
445#[derive(Debug, Clone)]
446pub struct ImpersonateConfig {
447    /// Optional amount of ETH to fund the impersonated account.
448    pub fund_amount: Option<U256>,
449    /// Whether to stop impersonating after the transaction is sent.
450    pub stop_impersonate: bool,
451}
452
453impl Default for ImpersonateConfig {
454    fn default() -> Self {
455        Self { fund_amount: None, stop_impersonate: true }
456    }
457}
458
459impl ImpersonateConfig {
460    /// Set the impersonation to continue after the transaction.
461    pub const fn keep_impersonate(mut self) -> Self {
462        self.stop_impersonate = false;
463        self
464    }
465
466    /// Set the impersonation to stop after the transaction.
467    pub const fn stop_impersonate(mut self) -> Self {
468        self.stop_impersonate = true;
469        self
470    }
471
472    /// Set the funding amount for the impersonated account.
473    pub const fn fund(mut self, amount: U256) -> Self {
474        self.fund_amount = Some(amount);
475        self
476    }
477
478    /// Clear the funding amount.
479    pub const fn no_fund(mut self) -> Self {
480        self.fund_amount = None;
481        self
482    }
483}
484
485#[cfg(test)]
486mod tests {
487    use super::*;
488    use crate::{
489        fillers::{ChainIdFiller, GasFiller},
490        ProviderBuilder,
491    };
492    use alloy_eips::BlockNumberOrTag;
493    use alloy_network::TransactionBuilder;
494    use alloy_primitives::{address, B256};
495    use alloy_rpc_types_eth::TransactionRequest;
496    use alloy_sol_types::{sol, SolCall};
497
498    // use alloy_node_bindings::Anvil; (to be used in `test_anvil_reset`)
499    const FORK_URL: &str = "https://reth-ethereum.ithaca.xyz/rpc";
500
501    #[tokio::test]
502    async fn test_anvil_impersonate_account_stop_impersonating_account() {
503        let provider = ProviderBuilder::new()
504            .disable_recommended_fillers()
505            .with_simple_nonce_management()
506            .filler(GasFiller)
507            .filler(ChainIdFiller::default())
508            .connect_anvil();
509
510        let impersonate = Address::random();
511        let to = Address::random();
512        let val = U256::from(1337);
513        let funding = U256::from(1e18 as u64);
514
515        provider.anvil_set_balance(impersonate, funding).await.unwrap();
516
517        let balance = provider.get_balance(impersonate).await.unwrap();
518        assert_eq!(balance, funding);
519
520        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
521
522        let res = provider.send_transaction(tx.clone()).await;
523        res.unwrap_err();
524
525        provider.anvil_impersonate_account(impersonate).await.unwrap();
526        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
527
528        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
529        assert_eq!(res.from, impersonate);
530
531        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
532        assert_eq!(nonce, 1);
533
534        let balance = provider.get_balance(to).await.unwrap();
535        assert_eq!(balance, val);
536
537        provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
538        let res = provider.send_transaction(tx).await;
539        res.unwrap_err();
540    }
541
542    #[tokio::test]
543    async fn test_anvil_impersonated_send_with_config() {
544        let provider = ProviderBuilder::new()
545            .disable_recommended_fillers()
546            .with_simple_nonce_management()
547            .filler(GasFiller)
548            .filler(ChainIdFiller::default())
549            .connect_anvil();
550
551        let impersonate = Address::random();
552        let to = Address::random();
553        let val = U256::from(1337);
554        let funding = U256::from(1e18 as u64);
555
556        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
557
558        let config = ImpersonateConfig { fund_amount: Some(funding), stop_impersonate: true };
559
560        let pending = provider
561            .anvil_send_impersonated_transaction_with_config(tx.clone(), config)
562            .await
563            .expect("impersonated send failed");
564        let receipt = pending.get_receipt().await.unwrap();
565        assert_eq!(receipt.from, impersonate);
566
567        let recipient_balance = provider.get_balance(to).await.unwrap();
568        assert_eq!(recipient_balance, val);
569    }
570
571    #[tokio::test]
572    async fn test_anvil_auto_impersonate_account() {
573        let provider = ProviderBuilder::new()
574            .disable_recommended_fillers()
575            .with_simple_nonce_management()
576            .filler(GasFiller)
577            .filler(ChainIdFiller::default())
578            .connect_anvil();
579
580        let impersonate = Address::random();
581        let to = Address::random();
582        let val = U256::from(1337);
583        let funding = U256::from(1e18 as u64);
584
585        provider.anvil_set_balance(impersonate, funding).await.unwrap();
586
587        let balance = provider.get_balance(impersonate).await.unwrap();
588        assert_eq!(balance, funding);
589
590        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
591
592        let res = provider.send_transaction(tx.clone()).await;
593        res.unwrap_err();
594
595        provider.anvil_auto_impersonate_account(true).await.unwrap();
596
597        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
598        assert_eq!(res.from, impersonate);
599
600        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
601        assert_eq!(nonce, 1);
602
603        let balance = provider.get_balance(to).await.unwrap();
604        assert_eq!(balance, val);
605
606        provider.anvil_auto_impersonate_account(false).await.unwrap();
607        let res = provider.send_transaction(tx).await;
608        res.unwrap_err();
609
610        provider.anvil_impersonate_account(impersonate).await.unwrap();
611        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
612    }
613
614    #[tokio::test]
615    async fn test_anvil_get_auto_mine_set_auto_mine() {
616        let provider = ProviderBuilder::new().connect_anvil();
617
618        provider.anvil_set_auto_mine(false).await.unwrap();
619
620        let enabled = provider.anvil_get_auto_mine().await.unwrap();
621        assert!(!enabled);
622
623        provider.anvil_set_auto_mine(true).await.unwrap();
624
625        let enabled = provider.anvil_get_auto_mine().await.unwrap();
626        assert!(enabled);
627    }
628
629    #[tokio::test]
630    async fn test_anvil_mine() {
631        let provider = ProviderBuilder::new().connect_anvil();
632
633        let start_num = provider.get_block_number().await.unwrap();
634
635        provider.anvil_mine(Some(10), None).await.unwrap();
636
637        let num = provider.get_block_number().await.unwrap();
638
639        assert_eq!(num, start_num + 10);
640    }
641
642    #[tokio::test]
643    async fn test_anvil_set_interval_mining() {
644        let provider = ProviderBuilder::new().connect_anvil();
645
646        provider.anvil_set_interval_mining(1).await.unwrap();
647
648        let start_num = provider.get_block_number().await.unwrap();
649
650        tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
651
652        let num = provider.get_block_number().await.unwrap();
653
654        assert_eq!(num, start_num + 1);
655    }
656
657    #[tokio::test]
658    async fn test_anvil_drop_transaction() {
659        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
660
661        provider.anvil_set_auto_mine(false).await.unwrap();
662
663        let alice = provider.get_accounts().await.unwrap()[0];
664        let bob = provider.get_accounts().await.unwrap()[1];
665        let chain_id = provider.get_chain_id().await.unwrap();
666
667        let tx = TransactionRequest::default()
668            .with_from(alice)
669            .with_to(bob)
670            .with_nonce(0)
671            .with_chain_id(chain_id)
672            .with_value(U256::from(100))
673            .with_gas_limit(21_000)
674            .with_max_priority_fee_per_gas(1_000_000_000)
675            .with_max_fee_per_gas(20_000_000_000);
676
677        let tx_hash =
678            provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
679
680        let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
681
682        assert_eq!(res, Some(tx_hash));
683    }
684
685    #[tokio::test]
686    async fn test_anvil_drop_all_transactions() {
687        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
688
689        provider.anvil_set_auto_mine(false).await.unwrap();
690
691        let alice = provider.get_accounts().await.unwrap()[0];
692        let bob = provider.get_accounts().await.unwrap()[1];
693        let chain_id = provider.get_chain_id().await.unwrap();
694
695        let tx = TransactionRequest::default()
696            .with_from(alice)
697            .with_to(bob)
698            .with_nonce(0)
699            .with_chain_id(chain_id)
700            .with_value(U256::from(100))
701            .with_gas_limit(21_000)
702            .with_max_priority_fee_per_gas(1_000_000_000)
703            .with_max_fee_per_gas(20_000_000_000);
704
705        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
706
707        let tx = tx.clone().with_nonce(1);
708
709        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
710
711        provider.anvil_drop_all_transactions().await.unwrap();
712    }
713
714    // TODO: Fix this test, `chain_id` is not being set correctly.
715    // #[tokio::test]
716    // async fn test_anvil_reset() {
717    //     let fork1 = Anvil::default().chain_id(777).spawn();
718    //     let fork2 = Anvil::default().chain_id(888).spawn();
719
720    //     let provider = ProviderBuilder::new()
721    //         .connect_anvil_with_config(|config| config.fork(fork1.endpoint_url().to_string()));
722
723    //     let chain_id = provider.get_chain_id().await.unwrap();
724    //     assert_eq!(chain_id, 777);
725
726    //     provider
727    //         .anvil_reset(Some(Forking {
728    //             json_rpc_url: Some(fork2.endpoint_url().to_string()),
729    //             block_number: Some(0),
730    //         }))
731    //         .await
732    //         .unwrap();
733
734    //     let chain_id = provider.get_chain_id().await.unwrap();
735    //     assert_eq!(chain_id, 888);
736    // }
737
738    #[tokio::test]
739    async fn test_anvil_set_chain_id() {
740        let provider = ProviderBuilder::new().connect_anvil();
741
742        let chain_id = 1337;
743        provider.anvil_set_chain_id(chain_id).await.unwrap();
744
745        let new_chain_id = provider.get_chain_id().await.unwrap();
746        assert_eq!(new_chain_id, chain_id);
747    }
748
749    #[tokio::test]
750    async fn test_anvil_set_balance() {
751        let provider = ProviderBuilder::new().connect_anvil();
752
753        let address = Address::random();
754        let balance = U256::from(1337);
755        provider.anvil_set_balance(address, balance).await.unwrap();
756
757        let new_balance = provider.get_balance(address).await.unwrap();
758        assert_eq!(new_balance, balance);
759    }
760
761    #[tokio::test]
762    async fn test_anvil_set_code() {
763        let provider = ProviderBuilder::new().connect_anvil();
764
765        let address = Address::random();
766        provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
767
768        let code = provider.get_code_at(address).await.unwrap();
769        assert_eq!(code, Bytes::from("0xbeef"));
770    }
771
772    #[tokio::test]
773    async fn test_anvil_set_nonce() {
774        let provider = ProviderBuilder::new().connect_anvil();
775
776        let address = Address::random();
777        let nonce = 1337;
778        provider.anvil_set_nonce(address, nonce).await.unwrap();
779
780        let new_nonce = provider.get_transaction_count(address).await.unwrap();
781        assert_eq!(new_nonce, nonce);
782    }
783
784    #[tokio::test]
785    async fn test_anvil_set_storage_at() {
786        let provider = ProviderBuilder::new().connect_anvil();
787
788        let address = Address::random();
789        let slot = U256::from(1337);
790        let val = B256::from(U256::from(1337));
791        provider.anvil_set_storage_at(address, slot, val).await.unwrap();
792
793        let storage = provider.get_storage_at(address, slot).await.unwrap();
794        assert_eq!(B256::from(storage), val);
795    }
796
797    #[tokio::test]
798    async fn test_anvil_set_logging() {
799        let provider = ProviderBuilder::new().connect_anvil();
800
801        provider.anvil_set_logging(true).await.unwrap();
802    }
803
804    #[tokio::test]
805    async fn test_anvil_set_min_gas_price() {
806        let provider = ProviderBuilder::new().connect_anvil();
807
808        let gas = U256::from(1337);
809
810        if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
811            assert_eq!(
812                e.to_string(),
813                "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
814            );
815        }
816    }
817
818    #[tokio::test]
819    async fn test_anvil_set_next_block_base_fee_per_gas() {
820        let provider = ProviderBuilder::new().connect_anvil();
821
822        let basefee = 1337;
823        provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
824
825        provider.evm_mine(None).await.unwrap();
826
827        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
828
829        assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
830    }
831
832    #[tokio::test]
833    async fn test_anvil_set_coinbase() {
834        let provider = ProviderBuilder::new().connect_anvil();
835
836        let coinbase = Address::random();
837        provider.anvil_set_coinbase(coinbase).await.unwrap();
838
839        provider.evm_mine(None).await.unwrap();
840
841        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
842        assert_eq!(block.header.beneficiary, coinbase);
843    }
844
845    #[tokio::test]
846    async fn test_anvil_dump_state_load_state() {
847        let provider = ProviderBuilder::new().connect_anvil();
848
849        let state = provider.anvil_dump_state().await.unwrap();
850
851        assert!(!state.is_empty());
852
853        let res = provider.anvil_load_state(state).await.unwrap();
854
855        assert!(res);
856    }
857
858    #[tokio::test]
859    async fn test_anvil_node_info() {
860        let provider = ProviderBuilder::new().connect_anvil();
861
862        let latest_block =
863            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
864
865        provider.evm_mine(None).await.unwrap();
866
867        let node_info = provider.anvil_node_info().await.unwrap();
868
869        assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
870    }
871
872    #[tokio::test]
873    async fn test_anvil_metadata() {
874        let provider = ProviderBuilder::new().connect_anvil();
875
876        let client_version = provider.get_client_version().await.unwrap();
877        let chain_id = provider.get_chain_id().await.unwrap();
878
879        let metadata = provider.anvil_metadata().await.unwrap();
880
881        assert_eq!(metadata.client_version, client_version);
882        assert_eq!(metadata.chain_id, chain_id);
883    }
884
885    #[tokio::test]
886    async fn test_anvil_remove_pool_transactions() {
887        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
888
889        provider.anvil_set_auto_mine(false).await.unwrap();
890
891        let alice = provider.get_accounts().await.unwrap()[0];
892        let bob = provider.get_accounts().await.unwrap()[1];
893        let chain_id = provider.get_chain_id().await.unwrap();
894
895        let tx = TransactionRequest::default()
896            .with_from(alice)
897            .with_to(bob)
898            .with_nonce(0)
899            .with_chain_id(chain_id)
900            .with_value(U256::from(100))
901            .with_gas_limit(21_000)
902            .with_max_priority_fee_per_gas(1_000_000_000)
903            .with_max_fee_per_gas(20_000_000_000);
904
905        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
906
907        let tx = tx.clone().with_nonce(1);
908
909        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
910
911        provider.anvil_remove_pool_transactions(alice).await.unwrap();
912    }
913
914    #[tokio::test]
915    async fn test_anvil_snapshot_revert() {
916        let provider = ProviderBuilder::new().connect_anvil();
917
918        let snapshot_id = provider.anvil_snapshot().await.unwrap();
919
920        let alice = provider.get_accounts().await.unwrap()[0];
921        let bob = provider.get_accounts().await.unwrap()[1];
922        let chain_id = provider.get_chain_id().await.unwrap();
923
924        let tx = TransactionRequest::default()
925            .with_from(alice)
926            .with_to(bob)
927            .with_nonce(0)
928            .with_chain_id(chain_id)
929            .with_value(U256::from(100))
930            .with_gas_limit(21_000)
931            .with_max_priority_fee_per_gas(1_000_000_000)
932            .with_max_fee_per_gas(20_000_000_000);
933
934        provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
935
936        let tx = tx.clone().with_nonce(1);
937
938        provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
939
940        let tx_count = provider.get_transaction_count(alice).await.unwrap();
941        assert_eq!(tx_count, 2);
942
943        let res = provider.anvil_revert(snapshot_id).await.unwrap();
944        assert!(res);
945
946        let tx_count = provider.get_transaction_count(alice).await.unwrap();
947        assert_eq!(tx_count, 0);
948    }
949
950    #[tokio::test]
951    async fn test_anvil_increase_time() {
952        let provider = ProviderBuilder::new().connect_anvil();
953
954        let timestamp = provider
955            .get_block_by_number(BlockNumberOrTag::Latest)
956            .await
957            .unwrap()
958            .unwrap()
959            .header
960            .timestamp;
961
962        let seconds = provider.anvil_increase_time(1337).await.unwrap();
963
964        assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
965    }
966
967    #[tokio::test]
968    async fn test_anvil_set_next_block_timestamp() {
969        let provider = ProviderBuilder::new().connect_anvil();
970
971        let timestamp = provider
972            .get_block_by_number(BlockNumberOrTag::Latest)
973            .await
974            .unwrap()
975            .unwrap()
976            .header
977            .timestamp;
978
979        provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
980
981        provider.evm_mine(None).await.unwrap();
982
983        let latest_block =
984            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
985        assert_eq!(latest_block.header.timestamp, timestamp + 1337);
986    }
987
988    #[tokio::test]
989    async fn test_anvil_set_time() {
990        let provider = ProviderBuilder::new().connect_anvil();
991
992        provider.anvil_set_time(0).await.unwrap();
993
994        let seconds = provider.anvil_set_time(1001).await.unwrap();
995
996        assert_eq!(seconds, 1);
997    }
998
999    #[tokio::test]
1000    async fn test_anvil_set_block_gas_limit() {
1001        let provider = ProviderBuilder::new().connect_anvil();
1002
1003        let block_gas_limit = 1337;
1004        assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
1005
1006        provider.evm_mine(None).await.unwrap();
1007
1008        let latest_block =
1009            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1010        assert_eq!(block_gas_limit, latest_block.header.gas_limit);
1011    }
1012
1013    #[tokio::test]
1014    async fn test_anvil_block_timestamp_interval() {
1015        let provider = ProviderBuilder::new().connect_anvil();
1016
1017        provider.anvil_set_block_timestamp_interval(1).await.unwrap();
1018
1019        let start_timestamp = provider
1020            .get_block_by_number(BlockNumberOrTag::Latest)
1021            .await
1022            .unwrap()
1023            .unwrap()
1024            .header
1025            .timestamp;
1026
1027        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1028
1029        provider.evm_mine(None).await.unwrap();
1030
1031        let latest_block =
1032            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1033
1034        assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
1035
1036        provider.anvil_remove_block_timestamp_interval().await.unwrap();
1037
1038        provider.evm_mine(None).await.unwrap();
1039
1040        let start_timestamp = provider
1041            .get_block_by_number(BlockNumberOrTag::Latest)
1042            .await
1043            .unwrap()
1044            .unwrap()
1045            .header
1046            .timestamp;
1047
1048        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1049
1050        let latest_block =
1051            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1052
1053        assert_eq!(latest_block.header.timestamp, start_timestamp);
1054    }
1055
1056    #[tokio::test]
1057    async fn test_evm_mine_single_block() {
1058        let provider = ProviderBuilder::new().connect_anvil();
1059
1060        let start_num = provider.get_block_number().await.unwrap();
1061
1062        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1063            provider.evm_mine(None).await.unwrap();
1064            let num = provider.get_block_number().await.unwrap();
1065            assert_eq!(num, start_num + idx as u64 + 1);
1066        }
1067
1068        let num = provider.get_block_number().await.unwrap();
1069        assert_eq!(num, start_num + 10);
1070    }
1071
1072    // TODO: Fix this test, only a single block is being mined regardless of the `blocks` parameter.
1073    // #[tokio::test]
1074    // async fn test_evm_mine_with_configuration() {
1075    //     let provider = ProviderBuilder::new().connect_anvil();
1076
1077    //     let start_num = provider.get_block_number().await.unwrap();
1078
1079    //     provider
1080    //         .evm_mine(Some(MineOptions::Options { timestamp: Some(100), blocks: Some(10) }))
1081    //         .await
1082    //         .unwrap();
1083
1084    //     let num = provider.get_block_number().await.unwrap();
1085    //     assert_eq!(num, start_num + 10);
1086    // }
1087
1088    #[tokio::test]
1089    async fn test_anvil_mine_detailed_single_block() {
1090        let provider = ProviderBuilder::new().connect_anvil();
1091
1092        let start_num = provider.get_block_number().await.unwrap();
1093
1094        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1095            provider.anvil_mine_detailed(None).await.unwrap();
1096            let num = provider.get_block_number().await.unwrap();
1097            assert_eq!(num, start_num + idx as u64 + 1);
1098        }
1099
1100        let num = provider.get_block_number().await.unwrap();
1101        assert_eq!(num, start_num + 10);
1102    }
1103
1104    // TODO: Fix this test, only a single block is being mined regardless of the `blocks` parameter.
1105    // #[tokio::test]
1106    // async fn test_anvil_mine_detailed_with_configuration() {
1107    //     let provider = ProviderBuilder::new().connect_anvil();
1108
1109    //     let start_num = provider.get_block_number().await.unwrap();
1110
1111    //     let blocks = provider
1112    //         .anvil_mine_detailed(Some(MineOptions::Options {
1113    //             timestamp: Some(100),
1114    //             blocks: Some(10),
1115    //         }))
1116    //         .await
1117    //         .unwrap();
1118
1119    //     let num = provider.get_block_number().await.unwrap();
1120    //     assert_eq!(num, start_num + 10);
1121
1122    //     for (idx, block) in blocks.iter().enumerate() {
1123    //         assert_eq!(block.header.number, Some(start_num + idx as u64 + 1));
1124    //     }
1125    // }
1126
1127    #[tokio::test]
1128    async fn test_anvil_set_rpc_url() {
1129        let provider = ProviderBuilder::new().connect_anvil();
1130
1131        let url = "https://example.com".to_string();
1132        provider.anvil_set_rpc_url(url.clone()).await.unwrap();
1133    }
1134
1135    #[tokio::test]
1136    async fn test_anvil_reorg() {
1137        let provider = ProviderBuilder::new().connect_anvil();
1138
1139        // Mine two blocks
1140        provider.anvil_mine(Some(2), None).await.unwrap();
1141
1142        let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1143        provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1144
1145        let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1146
1147        assert_eq!(reorged_block.header.number, new_block.header.number);
1148        assert_ne!(reorged_block.header.hash, new_block.header.hash);
1149    }
1150
1151    #[tokio::test]
1152    #[ignore]
1153    async fn test_anvil_rollback() {
1154        let provider = ProviderBuilder::new().connect_anvil();
1155
1156        // Mine two blocks
1157        provider.anvil_mine(Some(2), None).await.unwrap();
1158
1159        let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1160
1161        provider.anvil_rollback(Some(1)).await.unwrap();
1162
1163        let new_head =
1164            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1165
1166        assert_eq!(target_height, new_head);
1167    }
1168
1169    #[tokio::test]
1170    async fn test_eth_send_unsigned_transaction() {
1171        let provider = ProviderBuilder::new().connect_anvil();
1172
1173        let alice = Address::random();
1174        let bob = Address::random();
1175        let chain_id = provider.get_chain_id().await.unwrap();
1176
1177        provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1178
1179        let tx = TransactionRequest::default()
1180            .with_from(alice)
1181            .with_to(bob)
1182            .with_nonce(0)
1183            .with_chain_id(chain_id)
1184            .with_value(U256::from(100))
1185            .with_gas_limit(21_000)
1186            .with_max_priority_fee_per_gas(1_000_000_000)
1187            .with_max_fee_per_gas(20_000_000_000);
1188
1189        let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1190
1191        provider.evm_mine(None).await.unwrap();
1192
1193        let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1194        assert_eq!(res.from, alice);
1195        assert_eq!(res.to, Some(bob));
1196    }
1197
1198    #[tokio::test]
1199    async fn test_anvil_deal_erc20() {
1200        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1201
1202        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1203        let user = Address::random();
1204        let amount = U256::from(1e18 as u64);
1205
1206        provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1207
1208        sol! {
1209            function balanceOf(address owner) view returns (uint256);
1210        }
1211
1212        let balance_of_call = balanceOfCall::new((user,));
1213        let input = balanceOfCall::abi_encode(&balance_of_call);
1214
1215        let result = provider
1216            .call(TransactionRequest::default().with_to(dai).with_input(input))
1217            .await
1218            .unwrap();
1219        let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1220
1221        assert_eq!(balance, amount);
1222    }
1223
1224    #[tokio::test]
1225    async fn test_anvil_set_erc20_allowance() {
1226        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1227
1228        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1229        let owner = Address::random();
1230        let spender = Address::random();
1231        let amount = U256::from(1e18 as u64);
1232
1233        provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1234
1235        sol! {
1236            function allowance(address owner, address spender) view returns (uint256);
1237        }
1238
1239        let allowance_call = allowanceCall::new((owner, spender));
1240        let input = allowanceCall::abi_encode(&allowance_call);
1241
1242        let result = provider
1243            .call(TransactionRequest::default().with_to(dai).with_input(input))
1244            .await
1245            .unwrap();
1246        let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1247
1248        assert_eq!(allowance, amount);
1249    }
1250}