1use crate::{PendingTransactionBuilder, Provider};
4use alloy_consensus::Blob;
5use alloy_network::{Network, TransactionBuilder};
6use alloy_primitives::{Address, Bytes, TxHash, B256, U128, U256, U64};
7use alloy_rpc_types_anvil::{Forking, Metadata, MineOptions, NodeInfo, ReorgOptions};
8use alloy_transport::{TransportError, TransportResult};
9use futures::try_join;
10
11#[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 async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()>;
21
22 async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()>;
24
25 async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()>;
27
28 async fn anvil_send_impersonated_transaction_with_config(
32 &self,
33 request: N::TransactionRequest,
34 config: ImpersonateConfig,
35 ) -> TransportResult<PendingTransactionBuilder<N>>;
36
37 async fn anvil_get_auto_mine(&self) -> TransportResult<bool>;
39
40 async fn anvil_set_auto_mine(&self, enable_automine: bool) -> TransportResult<()>;
43
44 async fn anvil_mine(
46 &self,
47 num_blocks: Option<u64>,
48 interval: Option<u64>,
49 ) -> TransportResult<()>;
50
51 async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()>;
53
54 async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>>;
56
57 async fn anvil_drop_all_transactions(&self) -> TransportResult<()>;
59
60 async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()>;
64
65 async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()>;
67
68 async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()>;
70
71 async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()>;
73
74 async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()>;
76
77 async fn anvil_set_storage_at(
79 &self,
80 address: Address,
81 slot: U256,
82 val: B256,
83 ) -> TransportResult<bool>;
84
85 async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()>;
87
88 async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()>;
90
91 async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()>;
93
94 async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()>;
96
97 async fn anvil_dump_state(&self) -> TransportResult<Bytes>;
100
101 async fn anvil_dump_state_with_history(&self) -> TransportResult<Bytes>;
109
110 async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool>;
113
114 async fn anvil_node_info(&self) -> TransportResult<NodeInfo>;
116
117 async fn anvil_metadata(&self) -> TransportResult<Metadata>;
119
120 async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()>;
122
123 async fn anvil_snapshot(&self) -> TransportResult<U256>;
125
126 async fn anvil_revert(&self, id: U256) -> TransportResult<bool>;
129
130 async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64>;
132
133 async fn anvil_set_next_block_timestamp(&self, timestamp: u64) -> TransportResult<()>;
135
136 async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64>;
139
140 async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool>;
142
143 async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()>;
145
146 async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool>;
148
149 async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String>;
152
153 async fn anvil_mine_detailed(
156 &self,
157 opts: Option<MineOptions>,
158 ) -> TransportResult<Vec<N::BlockResponse>>;
159
160 async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()>;
162
163 async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()>;
165
166 async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()>;
168
169 async fn anvil_get_blob_by_versioned_hash(
171 &self,
172 versioned_hash: B256,
173 ) -> TransportResult<Option<Blob>>;
174
175 async fn anvil_get_blobs_by_tx_hash(
177 &self,
178 tx_hash: TxHash,
179 ) -> TransportResult<Option<Vec<Blob>>>;
180
181 async fn eth_send_unsigned_transaction(
183 &self,
184 request: N::TransactionRequest,
185 ) -> TransportResult<TxHash>;
186
187 async fn eth_send_transaction_sync(
189 &self,
190 request: N::TransactionRequest,
191 ) -> TransportResult<N::ReceiptResponse>;
192
193 async fn eth_send_raw_transaction_sync(
195 &self,
196 request: Bytes,
197 ) -> TransportResult<N::ReceiptResponse>;
198
199 async fn anvil_send_impersonated_transaction(
201 &self,
202 request: N::TransactionRequest,
203 ) -> TransportResult<TxHash>;
204
205 async fn anvil_deal_erc20(
207 &self,
208 address: Address,
209 token_address: Address,
210 balance: U256,
211 ) -> TransportResult<()>;
212
213 async fn anvil_set_erc20_allowance(
215 &self,
216 owner: Address,
217 spender: Address,
218 token: Address,
219 allowance: U256,
220 ) -> TransportResult<()>;
221}
222
223#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
224#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
225impl<N, P> AnvilApi<N> for P
226where
227 N: Network,
228 P: Provider<N>,
229{
230 async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()> {
231 self.client().request("anvil_impersonateAccount", (address,)).await
232 }
233
234 async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()> {
235 self.client().request("anvil_stopImpersonatingAccount", (address,)).await
236 }
237
238 async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()> {
239 self.client().request("anvil_autoImpersonateAccount", (enabled,)).await
240 }
241
242 async fn anvil_get_auto_mine(&self) -> TransportResult<bool> {
243 self.client().request_noparams("anvil_getAutomine").await
244 }
245
246 async fn anvil_set_auto_mine(&self, enabled: bool) -> TransportResult<()> {
247 self.client().request("anvil_setAutomine", (enabled,)).await
248 }
249
250 async fn anvil_mine(
251 &self,
252 num_blocks: Option<u64>,
253 interval: Option<u64>,
254 ) -> TransportResult<()> {
255 self.client()
256 .request("anvil_mine", (num_blocks.map(U64::from), interval.map(U64::from)))
257 .await
258 }
259
260 async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()> {
261 self.client().request("anvil_setIntervalMining", (secs,)).await
262 }
263
264 async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>> {
265 self.client().request("anvil_dropTransaction", (tx_hash,)).await
266 }
267
268 async fn anvil_drop_all_transactions(&self) -> TransportResult<()> {
269 self.client().request_noparams("anvil_dropAllTransactions").await
270 }
271
272 async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()> {
273 self.client().request("anvil_reset", (forking,)).await
274 }
275
276 async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()> {
277 self.client().request("anvil_setChainId", (chain_id,)).await
278 }
279
280 async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()> {
281 self.client().request("anvil_setBalance", (address, balance)).await
282 }
283
284 async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()> {
285 self.client().request("anvil_setCode", (address, code)).await
286 }
287
288 async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()> {
289 self.client().request("anvil_setNonce", (address, U64::from(nonce))).await
290 }
291
292 async fn anvil_set_storage_at(
293 &self,
294 address: Address,
295 slot: U256,
296 val: B256,
297 ) -> TransportResult<bool> {
298 self.client().request("anvil_setStorageAt", (address, slot, val)).await
299 }
300
301 async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()> {
302 self.client().request("anvil_setLoggingEnabled", (enable,)).await
303 }
304
305 async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()> {
306 self.client().request("anvil_setMinGasPrice", (U128::from(gas),)).await
307 }
308
309 async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()> {
310 self.client().request("anvil_setNextBlockBaseFeePerGas", (U128::from(basefee),)).await
311 }
312
313 async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()> {
314 self.client().request("anvil_setCoinbase", (address,)).await
315 }
316
317 async fn anvil_dump_state(&self) -> TransportResult<Bytes> {
318 self.client().request_noparams("anvil_dumpState").await
319 }
320
321 async fn anvil_dump_state_with_history(&self) -> TransportResult<Bytes> {
322 self.client().request("anvil_dumpState", (true,)).await
323 }
324
325 async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool> {
326 self.client().request("anvil_loadState", (buf,)).await
327 }
328
329 async fn anvil_node_info(&self) -> TransportResult<NodeInfo> {
330 self.client().request_noparams("anvil_nodeInfo").await
331 }
332
333 async fn anvil_metadata(&self) -> TransportResult<Metadata> {
334 self.client().request_noparams("anvil_metadata").await
335 }
336
337 async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()> {
338 self.client().request("anvil_removePoolTransactions", (address,)).await
339 }
340
341 async fn anvil_snapshot(&self) -> TransportResult<U256> {
342 self.client().request_noparams("evm_snapshot").await
343 }
344
345 async fn anvil_revert(&self, id: U256) -> TransportResult<bool> {
346 self.client().request("evm_revert", (id,)).await
347 }
348
349 async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64> {
350 self.client().request("evm_increaseTime", (U64::from(seconds),)).await
351 }
352
353 async fn anvil_set_next_block_timestamp(&self, seconds: u64) -> TransportResult<()> {
354 self.client().request("evm_setNextBlockTimestamp", (seconds,)).await
355 }
356
357 async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64> {
358 self.client().request("evm_setTime", (timestamp,)).await
359 }
360
361 async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool> {
362 self.client().request("evm_setBlockGasLimit", (U64::from(gas_limit),)).await
363 }
364
365 async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()> {
366 self.client().request("anvil_setBlockTimestampInterval", (seconds,)).await
367 }
368
369 async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool> {
370 self.client().request_noparams("anvil_removeBlockTimestampInterval").await
371 }
372
373 async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String> {
374 self.client().request("evm_mine", (opts,)).await
375 }
376
377 async fn anvil_mine_detailed(
378 &self,
379 opts: Option<MineOptions>,
380 ) -> TransportResult<Vec<N::BlockResponse>> {
381 self.client().request("evm_mine_detailed", (opts,)).await
382 }
383
384 async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()> {
385 self.client().request("anvil_setRpcUrl", (url,)).await
386 }
387
388 async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()> {
389 self.client().request("anvil_reorg", options).await
390 }
391
392 async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()> {
393 self.client().request("anvil_rollback", (depth,)).await
394 }
395
396 async fn anvil_get_blob_by_versioned_hash(&self, hash: B256) -> TransportResult<Option<Blob>> {
397 self.client().request("anvil_getBlobByHash", (hash,)).await
398 }
399
400 async fn anvil_get_blobs_by_tx_hash(&self, hash: TxHash) -> TransportResult<Option<Vec<Blob>>> {
401 self.client().request("anvil_getBlobsByTransactionHash", (hash,)).await
402 }
403
404 async fn eth_send_unsigned_transaction(
405 &self,
406 request: N::TransactionRequest,
407 ) -> TransportResult<TxHash> {
408 self.client().request("eth_sendUnsignedTransaction", (request,)).await
409 }
410
411 async fn eth_send_transaction_sync(
412 &self,
413 request: N::TransactionRequest,
414 ) -> TransportResult<N::ReceiptResponse> {
415 self.client().request("eth_sendTransactionSync", (request,)).await
416 }
417
418 async fn eth_send_raw_transaction_sync(
419 &self,
420 request: Bytes,
421 ) -> TransportResult<N::ReceiptResponse> {
422 self.client().request("eth_sendRawTransactionSync", (request,)).await
423 }
424
425 async fn anvil_send_impersonated_transaction(
426 &self,
427 request: N::TransactionRequest,
428 ) -> TransportResult<TxHash> {
429 self.client().request("eth_sendTransaction", (request,)).await
430 }
431
432 async fn anvil_deal_erc20(
433 &self,
434 address: Address,
435 token_address: Address,
436 balance: U256,
437 ) -> TransportResult<()> {
438 self.client().request("anvil_dealERC20", (address, token_address, balance)).await
439 }
440
441 async fn anvil_set_erc20_allowance(
442 &self,
443 owner: Address,
444 spender: Address,
445 token: Address,
446 allowance: U256,
447 ) -> TransportResult<()> {
448 self.client().request("anvil_setERC20Allowance", (owner, spender, token, allowance)).await
449 }
450
451 async fn anvil_send_impersonated_transaction_with_config(
452 &self,
453 request: N::TransactionRequest,
454 config: ImpersonateConfig,
455 ) -> TransportResult<PendingTransactionBuilder<N>> {
456 let from = request.from().ok_or_else(|| {
457 TransportError::from(alloy_transport::TransportErrorKind::Custom(
458 "TransactionRequest must have a `from` address set.".to_string().into(),
459 ))
460 })?;
461
462 let impersonate_future = self.anvil_impersonate_account(from);
463
464 if let Some(amount) = config.fund_amount {
465 let fund_future = self.anvil_set_balance(from, amount);
466 try_join!(fund_future, impersonate_future)?;
467 } else {
468 impersonate_future.await?;
469 }
470
471 let tx_hash = self.anvil_send_impersonated_transaction(request).await;
472
473 if config.stop_impersonate {
474 let stop_result = self.anvil_stop_impersonating_account(from).await;
475 if tx_hash.is_ok() {
476 stop_result?;
477 }
478 }
479
480 let pending = PendingTransactionBuilder::new(self.root().clone(), tx_hash?);
481 Ok(pending)
482 }
483}
484
485#[derive(Debug, Clone)]
488pub struct ImpersonateConfig {
489 pub fund_amount: Option<U256>,
491 pub stop_impersonate: bool,
493}
494
495impl Default for ImpersonateConfig {
496 fn default() -> Self {
497 Self { fund_amount: None, stop_impersonate: true }
498 }
499}
500
501impl ImpersonateConfig {
502 pub const fn keep_impersonate(mut self) -> Self {
504 self.stop_impersonate = false;
505 self
506 }
507
508 pub const fn stop_impersonate(mut self) -> Self {
510 self.stop_impersonate = true;
511 self
512 }
513
514 pub const fn fund(mut self, amount: U256) -> Self {
516 self.fund_amount = Some(amount);
517 self
518 }
519
520 pub const fn no_fund(mut self) -> Self {
522 self.fund_amount = None;
523 self
524 }
525}
526
527#[cfg(test)]
528mod tests {
529 use super::*;
530 use crate::{
531 fillers::{ChainIdFiller, GasFiller},
532 ProviderBuilder,
533 };
534 use alloy_consensus::{BlockHeader, SidecarBuilder, SimpleCoder};
535 use alloy_eips::BlockNumberOrTag;
536 use alloy_network::{AnyNetwork, TransactionBuilder, TransactionBuilder4844};
537 use alloy_network_primitives::BlockResponse as _;
538 use alloy_primitives::{address, B256};
539 use alloy_rpc_types_eth::TransactionRequest;
540 use alloy_sol_types::{sol, SolCall};
541 use alloy_transport::mock::Asserter;
542
543 const FORK_URL: &str = "https://ethereum.reth.rs/rpc";
544
545 #[tokio::test]
546 async fn test_anvil_impersonate_account_stop_impersonating_account() {
547 let provider = ProviderBuilder::new()
548 .disable_recommended_fillers()
549 .with_simple_nonce_management()
550 .filler(GasFiller::default())
551 .filler(ChainIdFiller::default())
552 .connect_anvil();
553
554 let impersonate = Address::random();
555 let to = Address::random();
556 let val = U256::from(1337);
557 let funding = U256::from(1e18 as u64);
558
559 provider.anvil_set_balance(impersonate, funding).await.unwrap();
560
561 let balance = provider.get_balance(impersonate).await.unwrap();
562 assert_eq!(balance, funding);
563
564 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
565
566 let res = provider.send_transaction(tx.clone()).await;
567 res.unwrap_err();
568
569 provider.anvil_impersonate_account(impersonate).await.unwrap();
570 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
571
572 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
573 assert_eq!(res.from, impersonate);
574
575 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
576 assert_eq!(nonce, 1);
577
578 let balance = provider.get_balance(to).await.unwrap();
579 assert_eq!(balance, val);
580
581 provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
582 let res = provider.send_transaction(tx).await;
583 res.unwrap_err();
584 }
585
586 #[tokio::test]
587 async fn test_anvil_impersonated_send_with_config() {
588 let provider = ProviderBuilder::new()
589 .disable_recommended_fillers()
590 .with_simple_nonce_management()
591 .filler(GasFiller::default())
592 .filler(ChainIdFiller::default())
593 .connect_anvil();
594
595 let impersonate = Address::random();
596 let to = Address::random();
597 let val = U256::from(1337);
598 let funding = U256::from(1e18 as u64);
599
600 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
601
602 let config = ImpersonateConfig { fund_amount: Some(funding), stop_impersonate: true };
603
604 let pending = provider
605 .anvil_send_impersonated_transaction_with_config(tx.clone(), config)
606 .await
607 .expect("impersonated send failed");
608 let receipt = pending.get_receipt().await.unwrap();
609 assert_eq!(receipt.from, impersonate);
610
611 let recipient_balance = provider.get_balance(to).await.unwrap();
612 assert_eq!(recipient_balance, val);
613 }
614
615 #[tokio::test]
616 async fn test_anvil_impersonated_send_stops_on_send_error() {
617 let asserter = Asserter::new();
618 let provider = ProviderBuilder::new().connect_mocked_client(asserter.clone());
619
620 asserter.push_success(&());
621 asserter.push_failure_msg("send failed");
622 asserter.push_success(&());
623
624 let tx = TransactionRequest::default().with_from(Address::random());
625 let err = provider
626 .anvil_send_impersonated_transaction_with_config(tx, ImpersonateConfig::default())
627 .await
628 .unwrap_err();
629
630 assert!(err.to_string().contains("send failed"));
631 assert!(asserter.read_q().is_empty(), "stop impersonation response should be consumed");
632 }
633
634 #[tokio::test]
635 async fn test_anvil_auto_impersonate_account() {
636 let provider = ProviderBuilder::new()
637 .disable_recommended_fillers()
638 .with_simple_nonce_management()
639 .filler(GasFiller::default())
640 .filler(ChainIdFiller::default())
641 .connect_anvil();
642
643 let impersonate = Address::random();
644 let to = Address::random();
645 let val = U256::from(1337);
646 let funding = U256::from(1e18 as u64);
647
648 provider.anvil_set_balance(impersonate, funding).await.unwrap();
649
650 let balance = provider.get_balance(impersonate).await.unwrap();
651 assert_eq!(balance, funding);
652
653 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
654
655 let res = provider.send_transaction(tx.clone()).await;
656 res.unwrap_err();
657
658 provider.anvil_auto_impersonate_account(true).await.unwrap();
659
660 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
661 assert_eq!(res.from, impersonate);
662
663 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
664 assert_eq!(nonce, 1);
665
666 let balance = provider.get_balance(to).await.unwrap();
667 assert_eq!(balance, val);
668
669 provider.anvil_auto_impersonate_account(false).await.unwrap();
670 let res = provider.send_transaction(tx).await;
671 res.unwrap_err();
672
673 provider.anvil_impersonate_account(impersonate).await.unwrap();
674 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
675 }
676
677 #[tokio::test]
678 async fn test_anvil_get_auto_mine_set_auto_mine() {
679 let provider = ProviderBuilder::new().connect_anvil();
680
681 provider.anvil_set_auto_mine(false).await.unwrap();
682
683 let enabled = provider.anvil_get_auto_mine().await.unwrap();
684 assert!(!enabled);
685
686 provider.anvil_set_auto_mine(true).await.unwrap();
687
688 let enabled = provider.anvil_get_auto_mine().await.unwrap();
689 assert!(enabled);
690 }
691
692 #[tokio::test]
693 async fn test_anvil_mine() {
694 let provider = ProviderBuilder::new().connect_anvil();
695
696 let start_num = provider.get_block_number().await.unwrap();
697
698 provider.anvil_mine(Some(10), None).await.unwrap();
699
700 let num = provider.get_block_number().await.unwrap();
701
702 assert_eq!(num, start_num + 10);
703 }
704
705 #[tokio::test]
706 async fn test_anvil_set_interval_mining() {
707 let provider = ProviderBuilder::new().connect_anvil();
708
709 provider.anvil_set_interval_mining(1).await.unwrap();
710
711 let start_num = provider.get_block_number().await.unwrap();
712
713 tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
714
715 let num = provider.get_block_number().await.unwrap();
716
717 assert_eq!(num, start_num + 1);
718 }
719
720 #[tokio::test]
721 async fn test_anvil_drop_transaction() {
722 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
723
724 provider.anvil_set_auto_mine(false).await.unwrap();
725
726 let alice = provider.get_accounts().await.unwrap()[0];
727 let bob = provider.get_accounts().await.unwrap()[1];
728 let chain_id = provider.get_chain_id().await.unwrap();
729
730 let tx = TransactionRequest::default()
731 .with_from(alice)
732 .with_to(bob)
733 .with_nonce(0)
734 .with_chain_id(chain_id)
735 .with_value(U256::from(100))
736 .with_gas_limit(21_000)
737 .with_max_priority_fee_per_gas(1_000_000_000)
738 .with_max_fee_per_gas(20_000_000_000);
739
740 let tx_hash =
741 provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
742
743 let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
744
745 assert_eq!(res, Some(tx_hash));
746 }
747
748 #[tokio::test]
749 async fn test_anvil_drop_all_transactions() {
750 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
751
752 provider.anvil_set_auto_mine(false).await.unwrap();
753
754 let alice = provider.get_accounts().await.unwrap()[0];
755 let bob = provider.get_accounts().await.unwrap()[1];
756 let chain_id = provider.get_chain_id().await.unwrap();
757
758 let tx = TransactionRequest::default()
759 .with_from(alice)
760 .with_to(bob)
761 .with_nonce(0)
762 .with_chain_id(chain_id)
763 .with_value(U256::from(100))
764 .with_gas_limit(21_000)
765 .with_max_priority_fee_per_gas(1_000_000_000)
766 .with_max_fee_per_gas(20_000_000_000);
767
768 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
769
770 let tx = tx.clone().with_nonce(1);
771
772 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
773
774 provider.anvil_drop_all_transactions().await.unwrap();
775 }
776
777 #[tokio::test]
778 async fn test_anvil_reset() {
779 let provider = ProviderBuilder::new().connect_anvil();
780
781 let alice = Address::random();
782 let balance = U256::from(1e18 as u64);
783 provider.anvil_set_balance(alice, balance).await.unwrap();
784
785 let current_balance = provider.get_balance(alice).await.unwrap();
786 assert_eq!(current_balance, balance);
787
788 provider.anvil_reset(None).await.unwrap();
789
790 let reset_balance = provider.get_balance(alice).await.unwrap();
791 assert_eq!(reset_balance, U256::ZERO);
792 }
793
794 #[tokio::test]
795 async fn test_anvil_set_chain_id() {
796 let provider = ProviderBuilder::new().connect_anvil();
797
798 let chain_id = 1337;
799 provider.anvil_set_chain_id(chain_id).await.unwrap();
800
801 let new_chain_id = provider.get_chain_id().await.unwrap();
802 assert_eq!(new_chain_id, chain_id);
803 }
804
805 #[tokio::test]
806 async fn test_anvil_set_balance() {
807 let provider = ProviderBuilder::new().connect_anvil();
808
809 let address = Address::random();
810 let balance = U256::from(1337);
811 provider.anvil_set_balance(address, balance).await.unwrap();
812
813 let new_balance = provider.get_balance(address).await.unwrap();
814 assert_eq!(new_balance, balance);
815 }
816
817 #[tokio::test]
818 async fn test_anvil_set_code() {
819 let provider = ProviderBuilder::new().connect_anvil();
820
821 let address = Address::random();
822 provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
823
824 let code = provider.get_code_at(address).await.unwrap();
825 assert_eq!(code, Bytes::from("0xbeef"));
826 }
827
828 #[tokio::test]
829 async fn test_anvil_set_nonce() {
830 let provider = ProviderBuilder::new().connect_anvil();
831
832 let address = Address::random();
833 let nonce = 1337;
834 provider.anvil_set_nonce(address, nonce).await.unwrap();
835
836 let new_nonce = provider.get_transaction_count(address).await.unwrap();
837 assert_eq!(new_nonce, nonce);
838 }
839
840 #[tokio::test]
841 async fn test_anvil_set_storage_at() {
842 let provider = ProviderBuilder::new().connect_anvil();
843
844 let address = Address::random();
845 let slot = U256::from(1337);
846 let val = B256::from(U256::from(1337));
847 provider.anvil_set_storage_at(address, slot, val).await.unwrap();
848
849 let storage = provider.get_storage_at(address, slot).await.unwrap();
850 assert_eq!(B256::from(storage), val);
851 }
852
853 #[tokio::test]
854 async fn test_anvil_set_logging() {
855 let provider = ProviderBuilder::new().connect_anvil();
856
857 provider.anvil_set_logging(true).await.unwrap();
858 }
859
860 #[tokio::test]
861 async fn test_anvil_set_min_gas_price() {
862 let provider = ProviderBuilder::new().connect_anvil();
863
864 let gas = U256::from(1337);
865
866 if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
867 assert_eq!(
868 e.to_string(),
869 "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
870 );
871 }
872 }
873
874 #[tokio::test]
875 async fn test_anvil_set_next_block_base_fee_per_gas() {
876 let provider = ProviderBuilder::new().connect_anvil();
877
878 let basefee = 1337;
879 provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
880
881 provider.evm_mine(None).await.unwrap();
882
883 let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
884
885 assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
886 }
887
888 #[tokio::test]
889 async fn test_anvil_set_coinbase() {
890 let provider = ProviderBuilder::new().connect_anvil();
891
892 let coinbase = Address::random();
893 provider.anvil_set_coinbase(coinbase).await.unwrap();
894
895 provider.evm_mine(None).await.unwrap();
896
897 let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
898 assert_eq!(block.header.beneficiary, coinbase);
899 }
900
901 #[tokio::test]
902 async fn test_anvil_dump_state_load_state() {
903 let provider = ProviderBuilder::new().connect_anvil();
904
905 let state = provider.anvil_dump_state().await.unwrap();
906
907 assert!(!state.is_empty());
908
909 let res = provider.anvil_load_state(state).await.unwrap();
910
911 assert!(res);
912 }
913
914 #[tokio::test]
915 async fn test_anvil_dump_state_with_history() {
916 let provider = ProviderBuilder::new().connect_anvil();
917
918 let state = provider.anvil_dump_state_with_history().await.unwrap();
919
920 assert!(!state.is_empty());
921
922 let res = provider.anvil_load_state(state).await.unwrap();
923
924 assert!(res);
925 }
926
927 #[tokio::test]
928 async fn test_anvil_node_info() {
929 let provider = ProviderBuilder::new().connect_anvil();
930
931 let latest_block =
932 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
933
934 provider.evm_mine(None).await.unwrap();
935
936 let node_info = provider.anvil_node_info().await.unwrap();
937
938 assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
939 }
940
941 #[tokio::test]
942 async fn test_anvil_metadata() {
943 let provider = ProviderBuilder::new().connect_anvil();
944
945 let client_version = provider.get_client_version().await.unwrap();
946 let chain_id = provider.get_chain_id().await.unwrap();
947
948 let metadata = provider.anvil_metadata().await.unwrap();
949
950 assert_eq!(metadata.client_version, client_version);
951 assert_eq!(metadata.chain_id, chain_id);
952 }
953
954 #[tokio::test]
955 async fn test_anvil_remove_pool_transactions() {
956 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
957
958 provider.anvil_set_auto_mine(false).await.unwrap();
959
960 let alice = provider.get_accounts().await.unwrap()[0];
961 let bob = provider.get_accounts().await.unwrap()[1];
962 let chain_id = provider.get_chain_id().await.unwrap();
963
964 let tx = TransactionRequest::default()
965 .with_from(alice)
966 .with_to(bob)
967 .with_nonce(0)
968 .with_chain_id(chain_id)
969 .with_value(U256::from(100))
970 .with_gas_limit(21_000)
971 .with_max_priority_fee_per_gas(1_000_000_000)
972 .with_max_fee_per_gas(20_000_000_000);
973
974 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
975
976 let tx = tx.clone().with_nonce(1);
977
978 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
979
980 provider.anvil_remove_pool_transactions(alice).await.unwrap();
981 }
982
983 #[tokio::test]
984 async fn test_anvil_snapshot_revert() {
985 let provider = ProviderBuilder::new().connect_anvil();
986
987 let snapshot_id = provider.anvil_snapshot().await.unwrap();
988
989 let alice = provider.get_accounts().await.unwrap()[0];
990 let bob = provider.get_accounts().await.unwrap()[1];
991 let chain_id = provider.get_chain_id().await.unwrap();
992
993 let tx = TransactionRequest::default()
994 .with_from(alice)
995 .with_to(bob)
996 .with_nonce(0)
997 .with_chain_id(chain_id)
998 .with_value(U256::from(100))
999 .with_gas_limit(21_000)
1000 .with_max_priority_fee_per_gas(1_000_000_000)
1001 .with_max_fee_per_gas(20_000_000_000);
1002
1003 provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
1004
1005 let tx = tx.clone().with_nonce(1);
1006
1007 provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
1008
1009 let tx_count = provider.get_transaction_count(alice).await.unwrap();
1010 assert_eq!(tx_count, 2);
1011
1012 let res = provider.anvil_revert(snapshot_id).await.unwrap();
1013 assert!(res);
1014
1015 let tx_count = provider.get_transaction_count(alice).await.unwrap();
1016 assert_eq!(tx_count, 0);
1017 }
1018
1019 #[tokio::test]
1020 async fn test_anvil_increase_time() {
1021 let provider = ProviderBuilder::new().connect_anvil();
1022
1023 let timestamp = provider
1024 .get_block_by_number(BlockNumberOrTag::Latest)
1025 .await
1026 .unwrap()
1027 .unwrap()
1028 .header
1029 .timestamp;
1030
1031 let seconds = provider.anvil_increase_time(1337).await.unwrap();
1032
1033 assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
1034 }
1035
1036 #[tokio::test]
1037 async fn test_anvil_set_next_block_timestamp() {
1038 let provider = ProviderBuilder::new().connect_anvil();
1039
1040 let timestamp = provider
1041 .get_block_by_number(BlockNumberOrTag::Latest)
1042 .await
1043 .unwrap()
1044 .unwrap()
1045 .header
1046 .timestamp;
1047
1048 provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
1049
1050 provider.evm_mine(None).await.unwrap();
1051
1052 let latest_block =
1053 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1054 assert_eq!(latest_block.header.timestamp, timestamp + 1337);
1055 }
1056
1057 #[tokio::test]
1058 async fn test_anvil_set_time() {
1059 let provider = ProviderBuilder::new().connect_anvil();
1060
1061 provider.anvil_set_time(0).await.unwrap();
1062
1063 let seconds = provider.anvil_set_time(1001).await.unwrap();
1064
1065 assert_eq!(seconds, 1001);
1066 }
1067
1068 #[tokio::test]
1069 async fn test_anvil_set_block_gas_limit() {
1070 let provider = ProviderBuilder::new().connect_anvil();
1071
1072 let block_gas_limit = 1337;
1073 assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
1074
1075 provider.evm_mine(None).await.unwrap();
1076
1077 let latest_block =
1078 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1079 assert_eq!(block_gas_limit, latest_block.header.gas_limit);
1080 }
1081
1082 #[tokio::test]
1083 async fn test_anvil_block_timestamp_interval() {
1084 let provider = ProviderBuilder::new().connect_anvil();
1085
1086 provider.anvil_set_block_timestamp_interval(1).await.unwrap();
1087
1088 let start_timestamp = provider
1089 .get_block_by_number(BlockNumberOrTag::Latest)
1090 .await
1091 .unwrap()
1092 .unwrap()
1093 .header
1094 .timestamp;
1095
1096 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1097
1098 provider.evm_mine(None).await.unwrap();
1099
1100 let latest_block =
1101 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1102
1103 assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
1104
1105 provider.anvil_remove_block_timestamp_interval().await.unwrap();
1106
1107 provider.evm_mine(None).await.unwrap();
1108
1109 let start_timestamp = provider
1110 .get_block_by_number(BlockNumberOrTag::Latest)
1111 .await
1112 .unwrap()
1113 .unwrap()
1114 .header
1115 .timestamp;
1116
1117 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1118
1119 let latest_block =
1120 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1121
1122 assert_eq!(latest_block.header.timestamp, start_timestamp);
1123 }
1124
1125 #[tokio::test]
1126 async fn test_evm_mine_single_block() {
1127 let provider = ProviderBuilder::new().connect_anvil();
1128
1129 let start_num = provider.get_block_number().await.unwrap();
1130
1131 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1132 provider.evm_mine(None).await.unwrap();
1133 let num = provider.get_block_number().await.unwrap();
1134 assert_eq!(num, start_num + idx as u64 + 1);
1135 }
1136
1137 let num = provider.get_block_number().await.unwrap();
1138 assert_eq!(num, start_num + 10);
1139 }
1140
1141 #[tokio::test]
1142 async fn test_evm_mine_with_configuration() {
1143 let provider = ProviderBuilder::new().connect_anvil();
1144
1145 let start_num = provider.get_block_number().await.unwrap();
1146
1147 provider
1148 .evm_mine(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1149 .await
1150 .unwrap();
1151
1152 let num = provider.get_block_number().await.unwrap();
1153 assert_eq!(num, start_num + 10);
1154 }
1155
1156 #[tokio::test]
1157 async fn test_anvil_mine_detailed_single_block() {
1158 let provider = ProviderBuilder::new().connect_anvil();
1159
1160 let start_num = provider.get_block_number().await.unwrap();
1161
1162 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1163 provider.anvil_mine_detailed(None).await.unwrap();
1164 let num = provider.get_block_number().await.unwrap();
1165 assert_eq!(num, start_num + idx as u64 + 1);
1166 }
1167
1168 let num = provider.get_block_number().await.unwrap();
1169 assert_eq!(num, start_num + 10);
1170 }
1171
1172 #[tokio::test]
1173 async fn test_anvil_mine_detailed_with_configuration() {
1174 let provider = ProviderBuilder::new().connect_anvil();
1175
1176 let start_num = provider.get_block_number().await.unwrap();
1177
1178 let blocks = provider
1179 .anvil_mine_detailed(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1180 .await
1181 .unwrap();
1182
1183 let num = provider.get_block_number().await.unwrap();
1184 assert_eq!(num, start_num + 10);
1185
1186 for (idx, block) in blocks.iter().enumerate() {
1187 assert_eq!(block.header().number(), start_num + idx as u64 + 1);
1188 }
1189 }
1190
1191 #[tokio::test]
1192 async fn test_anvil_mine_detailed_with_any_network() {
1193 let provider = ProviderBuilder::new().network::<AnyNetwork>().connect_anvil();
1194
1195 let start_num = provider.get_block_number().await.unwrap();
1196
1197 let blocks = provider
1198 .anvil_mine_detailed(Some(MineOptions::Options { timestamp: None, blocks: Some(2) }))
1199 .await
1200 .unwrap();
1201
1202 assert_eq!(blocks.len(), 2);
1203 for (idx, block) in blocks.iter().enumerate() {
1204 assert_eq!(block.header().number(), start_num + idx as u64 + 1);
1205 }
1206 }
1207
1208 #[tokio::test]
1209 async fn test_anvil_set_rpc_url() {
1210 let provider = ProviderBuilder::new().connect_anvil();
1211
1212 let url = "https://example.com".to_string();
1213 provider.anvil_set_rpc_url(url.clone()).await.unwrap();
1214 }
1215
1216 #[tokio::test]
1217 async fn test_anvil_reorg() {
1218 let provider = ProviderBuilder::new().connect_anvil();
1219
1220 provider.anvil_mine(Some(2), None).await.unwrap();
1222
1223 let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1224 provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1225
1226 let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1227
1228 assert_eq!(reorged_block.header.number, new_block.header.number);
1229 assert_ne!(reorged_block.header.hash, new_block.header.hash);
1230 }
1231
1232 #[tokio::test]
1233 #[ignore]
1234 async fn test_anvil_rollback() {
1235 let provider = ProviderBuilder::new().connect_anvil();
1236
1237 provider.anvil_mine(Some(2), None).await.unwrap();
1239
1240 let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1241
1242 provider.anvil_rollback(Some(1)).await.unwrap();
1243
1244 let new_head =
1245 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1246
1247 assert_eq!(target_height, new_head);
1248 }
1249
1250 #[tokio::test]
1251 async fn test_eth_send_unsigned_transaction() {
1252 let provider = ProviderBuilder::new().connect_anvil();
1253
1254 let alice = Address::random();
1255 let bob = Address::random();
1256 let chain_id = provider.get_chain_id().await.unwrap();
1257
1258 provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1259
1260 let tx = TransactionRequest::default()
1261 .with_from(alice)
1262 .with_to(bob)
1263 .with_nonce(0)
1264 .with_chain_id(chain_id)
1265 .with_value(U256::from(100))
1266 .with_gas_limit(21_000)
1267 .with_max_priority_fee_per_gas(1_000_000_000)
1268 .with_max_fee_per_gas(20_000_000_000);
1269
1270 let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1271
1272 provider.evm_mine(None).await.unwrap();
1273
1274 let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1275 assert_eq!(res.from, alice);
1276 assert_eq!(res.to, Some(bob));
1277 }
1278
1279 #[tokio::test]
1280 async fn test_anvil_get_blob_by_versioned_hash() {
1281 std::thread::Builder::new()
1282 .stack_size(16 * 1024 * 1024)
1283 .spawn(|| {
1284 let rt = tokio::runtime::Runtime::new().unwrap();
1285 rt.block_on(async {
1286 let provider = ProviderBuilder::new()
1287 .connect_anvil_with_wallet_and_config(|anvil| {
1288 anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1289 })
1290 .unwrap();
1291
1292 let accounts = provider.get_accounts().await.unwrap();
1293 let alice = accounts[0];
1294 let bob = accounts[1];
1295 let sidecar: SidecarBuilder<SimpleCoder> =
1296 SidecarBuilder::from_slice(b"Blobs are fun!");
1297 let sidecar = sidecar.build_4844().unwrap();
1298
1299 let tx = TransactionRequest::default()
1300 .with_from(alice)
1301 .with_to(bob)
1302 .with_blob_sidecar_4844(sidecar.clone());
1303
1304 let pending_tx = provider.send_transaction(tx).await.unwrap();
1305 let _receipt = pending_tx.get_receipt().await.unwrap();
1306 let hash = sidecar.versioned_hash_for_blob(0).unwrap();
1307
1308 let blob =
1309 provider.anvil_get_blob_by_versioned_hash(hash).await.unwrap().unwrap();
1310
1311 assert_eq!(blob, sidecar.blobs[0]);
1312 });
1313 })
1314 .unwrap()
1315 .join()
1316 .unwrap();
1317 }
1318
1319 #[tokio::test]
1320 async fn test_anvil_get_blobs_by_tx_hash() {
1321 std::thread::Builder::new()
1322 .stack_size(16 * 1024 * 1024)
1323 .spawn(|| {
1324 let rt = tokio::runtime::Runtime::new().unwrap();
1325 rt.block_on(async {
1326 let provider = ProviderBuilder::new()
1327 .connect_anvil_with_wallet_and_config(|anvil| {
1328 anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1329 })
1330 .unwrap();
1331
1332 let accounts = provider.get_accounts().await.unwrap();
1333 let alice = accounts[0];
1334 let bob = accounts[1];
1335 let sidecar: SidecarBuilder<SimpleCoder> =
1336 SidecarBuilder::from_slice(b"Blobs are fun!");
1337 let sidecar = sidecar.build_4844().unwrap();
1338
1339 let tx = TransactionRequest::default()
1340 .with_from(alice)
1341 .with_to(bob)
1342 .with_blob_sidecar_4844(sidecar.clone());
1343
1344 let pending_tx = provider.send_transaction(tx).await.unwrap();
1345 let receipt = pending_tx.get_receipt().await.unwrap();
1346 let tx_hash = receipt.transaction_hash;
1347
1348 let blobs =
1349 provider.anvil_get_blobs_by_tx_hash(tx_hash).await.unwrap().unwrap();
1350
1351 assert_eq!(blobs, sidecar.blobs);
1352 });
1353 })
1354 .unwrap()
1355 .join()
1356 .unwrap();
1357 }
1358
1359 #[tokio::test]
1360 async fn test_anvil_deal_erc20() {
1361 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1362
1363 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1364 let user = Address::random();
1365 let amount = U256::from(1e18 as u64);
1366
1367 provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1368
1369 sol! {
1370 function balanceOf(address owner) view returns (uint256);
1371 }
1372
1373 let balance_of_call = balanceOfCall::new((user,));
1374 let input = balanceOfCall::abi_encode(&balance_of_call);
1375
1376 let result = provider
1377 .call(TransactionRequest::default().with_to(dai).with_input(input))
1378 .await
1379 .unwrap();
1380 let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1381
1382 assert_eq!(balance, amount);
1383 }
1384
1385 #[tokio::test]
1386 async fn test_anvil_set_erc20_allowance() {
1387 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1388
1389 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1390 let owner = Address::random();
1391 let spender = Address::random();
1392 let amount = U256::from(1e18 as u64);
1393
1394 provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1395
1396 sol! {
1397 function allowance(address owner, address spender) view returns (uint256);
1398 }
1399
1400 let allowance_call = allowanceCall::new((owner, spender));
1401 let input = allowanceCall::abi_encode(&allowance_call);
1402
1403 let result = provider
1404 .call(TransactionRequest::default().with_to(dai).with_input(input))
1405 .await
1406 .unwrap();
1407 let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1408
1409 assert_eq!(allowance, amount);
1410 }
1411}