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