anvil_polkadot/substrate_node/impersonation.rs
1//! Support for "cheat codes" / bypass functions
2//! Same logic as for anvil, except the `H160` usage over `Address`.
3
4use std::collections::HashSet;
5use subxt::utils::H160;
6
7/// Manages user modifications that may affect the node's behavior
8///
9/// Contains the state of executed, non-eth standard cheat code RPC
10#[derive(Clone, Debug, Default)]
11pub(crate) struct ImpersonationManager {
12 /// All accounts that are currently impersonated
13 pub impersonated_accounts: HashSet<H160>,
14 /// If set to true will make the `is_impersonated` function always return true
15 pub auto_impersonate_accounts: bool,
16}
17
18impl ImpersonationManager {
19 /// Sets the account to impersonate
20 ///
21 /// This also accepts the actual code hash if the address is a contract to bypass EIP-3607
22 ///
23 /// Returns `true` if the account is already impersonated
24 pub fn impersonate(&mut self, addr: H160) -> bool {
25 trace!(target: "cheats", "Start impersonating {:?}", addr);
26 // When somebody **explicitly** impersonates an account we need to store it so we are able
27 // to return it from `eth_accounts`. That's why we do not simply call `is_impersonated()`
28 // which does not check that list when auto impersonation is enabled.
29 if self.impersonated_accounts.contains(&addr) {
30 // need to check if already impersonated, so we don't overwrite the code
31 return true;
32 }
33 self.impersonated_accounts.insert(addr)
34 }
35
36 /// Removes the account that from the impersonated set
37 pub fn stop_impersonating(&mut self, addr: &H160) {
38 trace!(target: "cheats", "Stop impersonating {:?}", addr);
39 self.impersonated_accounts.remove(addr);
40 }
41
42 /// Returns true if the `addr` is currently impersonated
43 pub fn is_impersonated(&self, addr: H160) -> bool {
44 if self.auto_impersonate_accounts() {
45 true
46 } else {
47 self.impersonated_accounts.contains(&addr)
48 }
49 }
50
51 /// Returns true is auto impersonation is enabled
52 pub fn auto_impersonate_accounts(&self) -> bool {
53 self.auto_impersonate_accounts
54 }
55
56 /// Sets the auto impersonation flag which if set to true will make the `is_impersonated`
57 /// function always return true
58 pub fn set_auto_impersonate_account(&mut self, enabled: bool) {
59 trace!(target: "cheats", "Auto impersonation set to {:?}", enabled);
60 self.auto_impersonate_accounts = enabled
61 }
62}