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