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://ethereum.reth.rs/rpc";
521
522 #[tokio::test]
523 async fn test_anvil_impersonate_account_stop_impersonating_account() {
524 let provider = ProviderBuilder::new()
525 .disable_recommended_fillers()
526 .with_simple_nonce_management()
527 .filler(GasFiller::default())
528 .filler(ChainIdFiller::default())
529 .connect_anvil();
530
531 let impersonate = Address::random();
532 let to = Address::random();
533 let val = U256::from(1337);
534 let funding = U256::from(1e18 as u64);
535
536 provider.anvil_set_balance(impersonate, funding).await.unwrap();
537
538 let balance = provider.get_balance(impersonate).await.unwrap();
539 assert_eq!(balance, funding);
540
541 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
542
543 let res = provider.send_transaction(tx.clone()).await;
544 res.unwrap_err();
545
546 provider.anvil_impersonate_account(impersonate).await.unwrap();
547 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
548
549 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
550 assert_eq!(res.from, impersonate);
551
552 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
553 assert_eq!(nonce, 1);
554
555 let balance = provider.get_balance(to).await.unwrap();
556 assert_eq!(balance, val);
557
558 provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
559 let res = provider.send_transaction(tx).await;
560 res.unwrap_err();
561 }
562
563 #[tokio::test]
564 async fn test_anvil_impersonated_send_with_config() {
565 let provider = ProviderBuilder::new()
566 .disable_recommended_fillers()
567 .with_simple_nonce_management()
568 .filler(GasFiller::default())
569 .filler(ChainIdFiller::default())
570 .connect_anvil();
571
572 let impersonate = Address::random();
573 let to = Address::random();
574 let val = U256::from(1337);
575 let funding = U256::from(1e18 as u64);
576
577 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
578
579 let config = ImpersonateConfig { fund_amount: Some(funding), stop_impersonate: true };
580
581 let pending = provider
582 .anvil_send_impersonated_transaction_with_config(tx.clone(), config)
583 .await
584 .expect("impersonated send failed");
585 let receipt = pending.get_receipt().await.unwrap();
586 assert_eq!(receipt.from, impersonate);
587
588 let recipient_balance = provider.get_balance(to).await.unwrap();
589 assert_eq!(recipient_balance, val);
590 }
591
592 #[tokio::test]
593 async fn test_anvil_auto_impersonate_account() {
594 let provider = ProviderBuilder::new()
595 .disable_recommended_fillers()
596 .with_simple_nonce_management()
597 .filler(GasFiller::default())
598 .filler(ChainIdFiller::default())
599 .connect_anvil();
600
601 let impersonate = Address::random();
602 let to = Address::random();
603 let val = U256::from(1337);
604 let funding = U256::from(1e18 as u64);
605
606 provider.anvil_set_balance(impersonate, funding).await.unwrap();
607
608 let balance = provider.get_balance(impersonate).await.unwrap();
609 assert_eq!(balance, funding);
610
611 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
612
613 let res = provider.send_transaction(tx.clone()).await;
614 res.unwrap_err();
615
616 provider.anvil_auto_impersonate_account(true).await.unwrap();
617
618 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
619 assert_eq!(res.from, impersonate);
620
621 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
622 assert_eq!(nonce, 1);
623
624 let balance = provider.get_balance(to).await.unwrap();
625 assert_eq!(balance, val);
626
627 provider.anvil_auto_impersonate_account(false).await.unwrap();
628 let res = provider.send_transaction(tx).await;
629 res.unwrap_err();
630
631 provider.anvil_impersonate_account(impersonate).await.unwrap();
632 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
633 }
634
635 #[tokio::test]
636 async fn test_anvil_get_auto_mine_set_auto_mine() {
637 let provider = ProviderBuilder::new().connect_anvil();
638
639 provider.anvil_set_auto_mine(false).await.unwrap();
640
641 let enabled = provider.anvil_get_auto_mine().await.unwrap();
642 assert!(!enabled);
643
644 provider.anvil_set_auto_mine(true).await.unwrap();
645
646 let enabled = provider.anvil_get_auto_mine().await.unwrap();
647 assert!(enabled);
648 }
649
650 #[tokio::test]
651 async fn test_anvil_mine() {
652 let provider = ProviderBuilder::new().connect_anvil();
653
654 let start_num = provider.get_block_number().await.unwrap();
655
656 provider.anvil_mine(Some(10), None).await.unwrap();
657
658 let num = provider.get_block_number().await.unwrap();
659
660 assert_eq!(num, start_num + 10);
661 }
662
663 #[tokio::test]
664 async fn test_anvil_set_interval_mining() {
665 let provider = ProviderBuilder::new().connect_anvil();
666
667 provider.anvil_set_interval_mining(1).await.unwrap();
668
669 let start_num = provider.get_block_number().await.unwrap();
670
671 tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
672
673 let num = provider.get_block_number().await.unwrap();
674
675 assert_eq!(num, start_num + 1);
676 }
677
678 #[tokio::test]
679 async fn test_anvil_drop_transaction() {
680 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
681
682 provider.anvil_set_auto_mine(false).await.unwrap();
683
684 let alice = provider.get_accounts().await.unwrap()[0];
685 let bob = provider.get_accounts().await.unwrap()[1];
686 let chain_id = provider.get_chain_id().await.unwrap();
687
688 let tx = TransactionRequest::default()
689 .with_from(alice)
690 .with_to(bob)
691 .with_nonce(0)
692 .with_chain_id(chain_id)
693 .with_value(U256::from(100))
694 .with_gas_limit(21_000)
695 .with_max_priority_fee_per_gas(1_000_000_000)
696 .with_max_fee_per_gas(20_000_000_000);
697
698 let tx_hash =
699 provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
700
701 let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
702
703 assert_eq!(res, Some(tx_hash));
704 }
705
706 #[tokio::test]
707 async fn test_anvil_drop_all_transactions() {
708 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
709
710 provider.anvil_set_auto_mine(false).await.unwrap();
711
712 let alice = provider.get_accounts().await.unwrap()[0];
713 let bob = provider.get_accounts().await.unwrap()[1];
714 let chain_id = provider.get_chain_id().await.unwrap();
715
716 let tx = TransactionRequest::default()
717 .with_from(alice)
718 .with_to(bob)
719 .with_nonce(0)
720 .with_chain_id(chain_id)
721 .with_value(U256::from(100))
722 .with_gas_limit(21_000)
723 .with_max_priority_fee_per_gas(1_000_000_000)
724 .with_max_fee_per_gas(20_000_000_000);
725
726 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
727
728 let tx = tx.clone().with_nonce(1);
729
730 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
731
732 provider.anvil_drop_all_transactions().await.unwrap();
733 }
734
735 #[tokio::test]
736 async fn test_anvil_reset() {
737 let provider = ProviderBuilder::new().connect_anvil();
738
739 let alice = Address::random();
740 let balance = U256::from(1e18 as u64);
741 provider.anvil_set_balance(alice, balance).await.unwrap();
742
743 let current_balance = provider.get_balance(alice).await.unwrap();
744 assert_eq!(current_balance, balance);
745
746 provider.anvil_reset(None).await.unwrap();
747
748 let reset_balance = provider.get_balance(alice).await.unwrap();
749 assert_eq!(reset_balance, U256::ZERO);
750 }
751
752 #[tokio::test]
753 async fn test_anvil_set_chain_id() {
754 let provider = ProviderBuilder::new().connect_anvil();
755
756 let chain_id = 1337;
757 provider.anvil_set_chain_id(chain_id).await.unwrap();
758
759 let new_chain_id = provider.get_chain_id().await.unwrap();
760 assert_eq!(new_chain_id, chain_id);
761 }
762
763 #[tokio::test]
764 async fn test_anvil_set_balance() {
765 let provider = ProviderBuilder::new().connect_anvil();
766
767 let address = Address::random();
768 let balance = U256::from(1337);
769 provider.anvil_set_balance(address, balance).await.unwrap();
770
771 let new_balance = provider.get_balance(address).await.unwrap();
772 assert_eq!(new_balance, balance);
773 }
774
775 #[tokio::test]
776 async fn test_anvil_set_code() {
777 let provider = ProviderBuilder::new().connect_anvil();
778
779 let address = Address::random();
780 provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
781
782 let code = provider.get_code_at(address).await.unwrap();
783 assert_eq!(code, Bytes::from("0xbeef"));
784 }
785
786 #[tokio::test]
787 async fn test_anvil_set_nonce() {
788 let provider = ProviderBuilder::new().connect_anvil();
789
790 let address = Address::random();
791 let nonce = 1337;
792 provider.anvil_set_nonce(address, nonce).await.unwrap();
793
794 let new_nonce = provider.get_transaction_count(address).await.unwrap();
795 assert_eq!(new_nonce, nonce);
796 }
797
798 #[tokio::test]
799 async fn test_anvil_set_storage_at() {
800 let provider = ProviderBuilder::new().connect_anvil();
801
802 let address = Address::random();
803 let slot = U256::from(1337);
804 let val = B256::from(U256::from(1337));
805 provider.anvil_set_storage_at(address, slot, val).await.unwrap();
806
807 let storage = provider.get_storage_at(address, slot).await.unwrap();
808 assert_eq!(B256::from(storage), val);
809 }
810
811 #[tokio::test]
812 async fn test_anvil_set_logging() {
813 let provider = ProviderBuilder::new().connect_anvil();
814
815 provider.anvil_set_logging(true).await.unwrap();
816 }
817
818 #[tokio::test]
819 async fn test_anvil_set_min_gas_price() {
820 let provider = ProviderBuilder::new().connect_anvil();
821
822 let gas = U256::from(1337);
823
824 if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
825 assert_eq!(
826 e.to_string(),
827 "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
828 );
829 }
830 }
831
832 #[tokio::test]
833 async fn test_anvil_set_next_block_base_fee_per_gas() {
834 let provider = ProviderBuilder::new().connect_anvil();
835
836 let basefee = 1337;
837 provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
838
839 provider.evm_mine(None).await.unwrap();
840
841 let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
842
843 assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
844 }
845
846 #[tokio::test]
847 async fn test_anvil_set_coinbase() {
848 let provider = ProviderBuilder::new().connect_anvil();
849
850 let coinbase = Address::random();
851 provider.anvil_set_coinbase(coinbase).await.unwrap();
852
853 provider.evm_mine(None).await.unwrap();
854
855 let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
856 assert_eq!(block.header.beneficiary, coinbase);
857 }
858
859 #[tokio::test]
860 async fn test_anvil_dump_state_load_state() {
861 let provider = ProviderBuilder::new().connect_anvil();
862
863 let state = provider.anvil_dump_state().await.unwrap();
864
865 assert!(!state.is_empty());
866
867 let res = provider.anvil_load_state(state).await.unwrap();
868
869 assert!(res);
870 }
871
872 #[tokio::test]
873 async fn test_anvil_node_info() {
874 let provider = ProviderBuilder::new().connect_anvil();
875
876 let latest_block =
877 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
878
879 provider.evm_mine(None).await.unwrap();
880
881 let node_info = provider.anvil_node_info().await.unwrap();
882
883 assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
884 }
885
886 #[tokio::test]
887 async fn test_anvil_metadata() {
888 let provider = ProviderBuilder::new().connect_anvil();
889
890 let client_version = provider.get_client_version().await.unwrap();
891 let chain_id = provider.get_chain_id().await.unwrap();
892
893 let metadata = provider.anvil_metadata().await.unwrap();
894
895 assert_eq!(metadata.client_version, client_version);
896 assert_eq!(metadata.chain_id, chain_id);
897 }
898
899 #[tokio::test]
900 async fn test_anvil_remove_pool_transactions() {
901 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
902
903 provider.anvil_set_auto_mine(false).await.unwrap();
904
905 let alice = provider.get_accounts().await.unwrap()[0];
906 let bob = provider.get_accounts().await.unwrap()[1];
907 let chain_id = provider.get_chain_id().await.unwrap();
908
909 let tx = TransactionRequest::default()
910 .with_from(alice)
911 .with_to(bob)
912 .with_nonce(0)
913 .with_chain_id(chain_id)
914 .with_value(U256::from(100))
915 .with_gas_limit(21_000)
916 .with_max_priority_fee_per_gas(1_000_000_000)
917 .with_max_fee_per_gas(20_000_000_000);
918
919 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
920
921 let tx = tx.clone().with_nonce(1);
922
923 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
924
925 provider.anvil_remove_pool_transactions(alice).await.unwrap();
926 }
927
928 #[tokio::test]
929 async fn test_anvil_snapshot_revert() {
930 let provider = ProviderBuilder::new().connect_anvil();
931
932 let snapshot_id = provider.anvil_snapshot().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().get_receipt().await.unwrap();
949
950 let tx = tx.clone().with_nonce(1);
951
952 provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
953
954 let tx_count = provider.get_transaction_count(alice).await.unwrap();
955 assert_eq!(tx_count, 2);
956
957 let res = provider.anvil_revert(snapshot_id).await.unwrap();
958 assert!(res);
959
960 let tx_count = provider.get_transaction_count(alice).await.unwrap();
961 assert_eq!(tx_count, 0);
962 }
963
964 #[tokio::test]
965 async fn test_anvil_increase_time() {
966 let provider = ProviderBuilder::new().connect_anvil();
967
968 let timestamp = provider
969 .get_block_by_number(BlockNumberOrTag::Latest)
970 .await
971 .unwrap()
972 .unwrap()
973 .header
974 .timestamp;
975
976 let seconds = provider.anvil_increase_time(1337).await.unwrap();
977
978 assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
979 }
980
981 #[tokio::test]
982 async fn test_anvil_set_next_block_timestamp() {
983 let provider = ProviderBuilder::new().connect_anvil();
984
985 let timestamp = provider
986 .get_block_by_number(BlockNumberOrTag::Latest)
987 .await
988 .unwrap()
989 .unwrap()
990 .header
991 .timestamp;
992
993 provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
994
995 provider.evm_mine(None).await.unwrap();
996
997 let latest_block =
998 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
999 assert_eq!(latest_block.header.timestamp, timestamp + 1337);
1000 }
1001
1002 #[tokio::test]
1003 async fn test_anvil_set_time() {
1004 let provider = ProviderBuilder::new().connect_anvil();
1005
1006 provider.anvil_set_time(0).await.unwrap();
1007
1008 let seconds = provider.anvil_set_time(1001).await.unwrap();
1009
1010 assert_eq!(seconds, 1001);
1011 }
1012
1013 #[tokio::test]
1014 async fn test_anvil_set_block_gas_limit() {
1015 let provider = ProviderBuilder::new().connect_anvil();
1016
1017 let block_gas_limit = 1337;
1018 assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
1019
1020 provider.evm_mine(None).await.unwrap();
1021
1022 let latest_block =
1023 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1024 assert_eq!(block_gas_limit, latest_block.header.gas_limit);
1025 }
1026
1027 #[tokio::test]
1028 async fn test_anvil_block_timestamp_interval() {
1029 let provider = ProviderBuilder::new().connect_anvil();
1030
1031 provider.anvil_set_block_timestamp_interval(1).await.unwrap();
1032
1033 let start_timestamp = provider
1034 .get_block_by_number(BlockNumberOrTag::Latest)
1035 .await
1036 .unwrap()
1037 .unwrap()
1038 .header
1039 .timestamp;
1040
1041 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1042
1043 provider.evm_mine(None).await.unwrap();
1044
1045 let latest_block =
1046 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1047
1048 assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
1049
1050 provider.anvil_remove_block_timestamp_interval().await.unwrap();
1051
1052 provider.evm_mine(None).await.unwrap();
1053
1054 let start_timestamp = provider
1055 .get_block_by_number(BlockNumberOrTag::Latest)
1056 .await
1057 .unwrap()
1058 .unwrap()
1059 .header
1060 .timestamp;
1061
1062 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1063
1064 let latest_block =
1065 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1066
1067 assert_eq!(latest_block.header.timestamp, start_timestamp);
1068 }
1069
1070 #[tokio::test]
1071 async fn test_evm_mine_single_block() {
1072 let provider = ProviderBuilder::new().connect_anvil();
1073
1074 let start_num = provider.get_block_number().await.unwrap();
1075
1076 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1077 provider.evm_mine(None).await.unwrap();
1078 let num = provider.get_block_number().await.unwrap();
1079 assert_eq!(num, start_num + idx as u64 + 1);
1080 }
1081
1082 let num = provider.get_block_number().await.unwrap();
1083 assert_eq!(num, start_num + 10);
1084 }
1085
1086 #[tokio::test]
1087 async fn test_evm_mine_with_configuration() {
1088 let provider = ProviderBuilder::new().connect_anvil();
1089
1090 let start_num = provider.get_block_number().await.unwrap();
1091
1092 provider
1093 .evm_mine(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1094 .await
1095 .unwrap();
1096
1097 let num = provider.get_block_number().await.unwrap();
1098 assert_eq!(num, start_num + 10);
1099 }
1100
1101 #[tokio::test]
1102 async fn test_anvil_mine_detailed_single_block() {
1103 let provider = ProviderBuilder::new().connect_anvil();
1104
1105 let start_num = provider.get_block_number().await.unwrap();
1106
1107 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1108 provider.anvil_mine_detailed(None).await.unwrap();
1109 let num = provider.get_block_number().await.unwrap();
1110 assert_eq!(num, start_num + idx as u64 + 1);
1111 }
1112
1113 let num = provider.get_block_number().await.unwrap();
1114 assert_eq!(num, start_num + 10);
1115 }
1116
1117 #[tokio::test]
1118 async fn test_anvil_mine_detailed_with_configuration() {
1119 let provider = ProviderBuilder::new().connect_anvil();
1120
1121 let start_num = provider.get_block_number().await.unwrap();
1122
1123 let blocks = provider
1124 .anvil_mine_detailed(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1125 .await
1126 .unwrap();
1127
1128 let num = provider.get_block_number().await.unwrap();
1129 assert_eq!(num, start_num + 10);
1130
1131 for (idx, block) in blocks.iter().enumerate() {
1132 assert_eq!(block.header.number, start_num + idx as u64 + 1);
1133 }
1134 }
1135
1136 #[tokio::test]
1137 async fn test_anvil_set_rpc_url() {
1138 let provider = ProviderBuilder::new().connect_anvil();
1139
1140 let url = "https://example.com".to_string();
1141 provider.anvil_set_rpc_url(url.clone()).await.unwrap();
1142 }
1143
1144 #[tokio::test]
1145 async fn test_anvil_reorg() {
1146 let provider = ProviderBuilder::new().connect_anvil();
1147
1148 provider.anvil_mine(Some(2), None).await.unwrap();
1150
1151 let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1152 provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1153
1154 let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1155
1156 assert_eq!(reorged_block.header.number, new_block.header.number);
1157 assert_ne!(reorged_block.header.hash, new_block.header.hash);
1158 }
1159
1160 #[tokio::test]
1161 #[ignore]
1162 async fn test_anvil_rollback() {
1163 let provider = ProviderBuilder::new().connect_anvil();
1164
1165 provider.anvil_mine(Some(2), None).await.unwrap();
1167
1168 let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1169
1170 provider.anvil_rollback(Some(1)).await.unwrap();
1171
1172 let new_head =
1173 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1174
1175 assert_eq!(target_height, new_head);
1176 }
1177
1178 #[tokio::test]
1179 async fn test_eth_send_unsigned_transaction() {
1180 let provider = ProviderBuilder::new().connect_anvil();
1181
1182 let alice = Address::random();
1183 let bob = Address::random();
1184 let chain_id = provider.get_chain_id().await.unwrap();
1185
1186 provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1187
1188 let tx = TransactionRequest::default()
1189 .with_from(alice)
1190 .with_to(bob)
1191 .with_nonce(0)
1192 .with_chain_id(chain_id)
1193 .with_value(U256::from(100))
1194 .with_gas_limit(21_000)
1195 .with_max_priority_fee_per_gas(1_000_000_000)
1196 .with_max_fee_per_gas(20_000_000_000);
1197
1198 let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1199
1200 provider.evm_mine(None).await.unwrap();
1201
1202 let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1203 assert_eq!(res.from, alice);
1204 assert_eq!(res.to, Some(bob));
1205 }
1206
1207 #[tokio::test]
1208 async fn test_anvil_get_blob_by_versioned_hash() {
1209 std::thread::Builder::new()
1210 .stack_size(16 * 1024 * 1024)
1211 .spawn(|| {
1212 let rt = tokio::runtime::Runtime::new().unwrap();
1213 rt.block_on(async {
1214 let provider = ProviderBuilder::new()
1215 .connect_anvil_with_wallet_and_config(|anvil| {
1216 anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1217 })
1218 .unwrap();
1219
1220 let accounts = provider.get_accounts().await.unwrap();
1221 let alice = accounts[0];
1222 let bob = accounts[1];
1223 let sidecar: SidecarBuilder<SimpleCoder> =
1224 SidecarBuilder::from_slice(b"Blobs are fun!");
1225 let sidecar = sidecar.build_4844().unwrap();
1226
1227 let tx = TransactionRequest::default()
1228 .with_from(alice)
1229 .with_to(bob)
1230 .with_blob_sidecar_4844(sidecar.clone());
1231
1232 let pending_tx = provider.send_transaction(tx).await.unwrap();
1233 let _receipt = pending_tx.get_receipt().await.unwrap();
1234 let hash = sidecar.versioned_hash_for_blob(0).unwrap();
1235
1236 let blob =
1237 provider.anvil_get_blob_by_versioned_hash(hash).await.unwrap().unwrap();
1238
1239 assert_eq!(blob, sidecar.blobs[0]);
1240 });
1241 })
1242 .unwrap()
1243 .join()
1244 .unwrap();
1245 }
1246
1247 #[tokio::test]
1248 async fn test_anvil_get_blobs_by_tx_hash() {
1249 std::thread::Builder::new()
1250 .stack_size(16 * 1024 * 1024)
1251 .spawn(|| {
1252 let rt = tokio::runtime::Runtime::new().unwrap();
1253 rt.block_on(async {
1254 let provider = ProviderBuilder::new()
1255 .connect_anvil_with_wallet_and_config(|anvil| {
1256 anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1257 })
1258 .unwrap();
1259
1260 let accounts = provider.get_accounts().await.unwrap();
1261 let alice = accounts[0];
1262 let bob = accounts[1];
1263 let sidecar: SidecarBuilder<SimpleCoder> =
1264 SidecarBuilder::from_slice(b"Blobs are fun!");
1265 let sidecar = sidecar.build_4844().unwrap();
1266
1267 let tx = TransactionRequest::default()
1268 .with_from(alice)
1269 .with_to(bob)
1270 .with_blob_sidecar_4844(sidecar.clone());
1271
1272 let pending_tx = provider.send_transaction(tx).await.unwrap();
1273 let receipt = pending_tx.get_receipt().await.unwrap();
1274 let tx_hash = receipt.transaction_hash;
1275
1276 let blobs =
1277 provider.anvil_get_blobs_by_tx_hash(tx_hash).await.unwrap().unwrap();
1278
1279 assert_eq!(blobs, sidecar.blobs);
1280 });
1281 })
1282 .unwrap()
1283 .join()
1284 .unwrap();
1285 }
1286
1287 #[tokio::test]
1288 async fn test_anvil_deal_erc20() {
1289 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1290
1291 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1292 let user = Address::random();
1293 let amount = U256::from(1e18 as u64);
1294
1295 provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1296
1297 sol! {
1298 function balanceOf(address owner) view returns (uint256);
1299 }
1300
1301 let balance_of_call = balanceOfCall::new((user,));
1302 let input = balanceOfCall::abi_encode(&balance_of_call);
1303
1304 let result = provider
1305 .call(TransactionRequest::default().with_to(dai).with_input(input))
1306 .await
1307 .unwrap();
1308 let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1309
1310 assert_eq!(balance, amount);
1311 }
1312
1313 #[tokio::test]
1314 async fn test_anvil_set_erc20_allowance() {
1315 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1316
1317 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1318 let owner = Address::random();
1319 let spender = Address::random();
1320 let amount = U256::from(1e18 as u64);
1321
1322 provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1323
1324 sol! {
1325 function allowance(address owner, address spender) view returns (uint256);
1326 }
1327
1328 let allowance_call = allowanceCall::new((owner, spender));
1329 let input = allowanceCall::abi_encode(&allowance_call);
1330
1331 let result = provider
1332 .call(TransactionRequest::default().with_to(dai).with_input(input))
1333 .await
1334 .unwrap();
1335 let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1336
1337 assert_eq!(allowance, amount);
1338 }
1339}