Skip to main content

alloy_rpc_types_eth/
state.rs

1//! bindings for state overrides in eth_call
2
3use crate::BlockOverrides;
4use alloc::boxed::Box;
5use alloy_eips::eip7702::constants::EIP7702_DELEGATION_DESIGNATOR;
6use alloy_primitives::{
7    map::{AddressHashMap, B256HashMap},
8    Address, Bytes, B256, U256,
9};
10
11/// A builder type for [`StateOverride`].
12#[derive(Clone, Debug, Default, PartialEq, Eq)]
13pub struct StateOverridesBuilder {
14    overrides: StateOverride,
15}
16
17impl StateOverridesBuilder {
18    /// Create a new StateOverridesBuilder.
19    pub const fn new(map: AddressHashMap<AccountOverride>) -> Self {
20        Self { overrides: map }
21    }
22
23    /// Creates a new [`StateOverridesBuilder`] with the given capacity.
24    pub fn with_capacity(capacity: usize) -> Self {
25        Self::new(StateOverride::with_capacity_and_hasher(capacity, Default::default()))
26    }
27
28    /// Adds an account override for a specific address.
29    pub fn append(mut self, address: Address, account_override: AccountOverride) -> Self {
30        self.overrides.insert(address, account_override);
31        self
32    }
33
34    /// Helper `append` function that appends an optional override.
35    pub fn append_opt<F>(self, f: F) -> Self
36    where
37        F: FnOnce() -> Option<(Address, AccountOverride)>,
38    {
39        if let Some((add, acc)) = f() {
40            self.append(add, acc)
41        } else {
42            self
43        }
44    }
45
46    /// Apply a function to the builder, returning the modified builder.
47    pub fn apply<F>(self, f: F) -> Self
48    where
49        F: FnOnce(Self) -> Self,
50    {
51        f(self)
52    }
53
54    /// Adds multiple account overrides from an iterator.
55    pub fn extend<I>(mut self, account_overrides: I) -> Self
56    where
57        I: IntoIterator<Item = (Address, AccountOverride)>,
58    {
59        self.overrides.extend(account_overrides);
60        self
61    }
62
63    /// Get the underlying `StateOverride`.
64    pub fn build(self) -> StateOverride {
65        self.overrides
66    }
67
68    /// Configures an account override with a balance.
69    pub fn with_balance(mut self, address: Address, balance: U256) -> Self {
70        self.overrides.entry(address).or_default().set_balance(balance);
71        self
72    }
73
74    /// Configures an account override with a nonce.
75    pub fn with_nonce(mut self, address: Address, nonce: u64) -> Self {
76        self.overrides.entry(address).or_default().set_nonce(nonce);
77        self
78    }
79
80    /// Configures an account override with bytecode.
81    pub fn with_code(mut self, address: Address, code: impl Into<Bytes>) -> Self {
82        self.overrides.entry(address).or_default().set_code(code);
83        self
84    }
85
86    /// Convenience function that sets overrides the `address` code with the EIP-7702 delegation
87    /// designator for `delegation_address`
88    pub fn with_7702_delegation_designator(
89        self,
90        address: Address,
91        delegation_address: Address,
92    ) -> Self {
93        self.with_code(
94            address,
95            Bytes::from([&EIP7702_DELEGATION_DESIGNATOR, delegation_address.as_slice()].concat()),
96        )
97    }
98
99    /// Configures an account override with state overrides.
100    pub fn with_state(
101        mut self,
102        address: Address,
103        state: impl IntoIterator<Item = (B256, B256)>,
104    ) -> Self {
105        self.overrides.entry(address).or_default().set_state(state);
106        self
107    }
108
109    /// Configures an account override with state diffs.
110    pub fn with_state_diff(
111        mut self,
112        address: Address,
113        state_diff: impl IntoIterator<Item = (B256, B256)>,
114    ) -> Self {
115        self.overrides.entry(address).or_default().set_state_diff(state_diff);
116        self
117    }
118}
119
120impl FromIterator<(Address, AccountOverride)> for StateOverridesBuilder {
121    fn from_iter<T: IntoIterator<Item = (Address, AccountOverride)>>(iter: T) -> Self {
122        Self::new(StateOverride::from_iter(iter))
123    }
124}
125
126/// A set of account overrides
127pub type StateOverride = AddressHashMap<AccountOverride>;
128
129/// Allows converting `StateOverridesBuilder` directly into `StateOverride`.
130impl From<StateOverridesBuilder> for StateOverride {
131    fn from(builder: StateOverridesBuilder) -> Self {
132        builder.overrides
133    }
134}
135/// Custom account override used in call
136#[derive(Clone, Debug, Default, PartialEq, Eq)]
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138#[cfg_attr(feature = "serde", serde(default, rename_all = "camelCase", deny_unknown_fields))]
139pub struct AccountOverride {
140    /// Fake balance to set for the account before executing the call.
141    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
142    pub balance: Option<U256>,
143    /// Fake nonce to set for the account before executing the call.
144    #[cfg_attr(
145        feature = "serde",
146        serde(
147            default,
148            skip_serializing_if = "Option::is_none",
149            with = "alloy_serde::quantity::opt"
150        )
151    )]
152    pub nonce: Option<u64>,
153    /// Fake EVM bytecode to inject into the account before executing the call.
154    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
155    pub code: Option<Bytes>,
156    /// Fake key-value mapping to override all slots in the account storage before executing the
157    /// call.
158    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
159    pub state: Option<B256HashMap<B256>>,
160    /// Fake key-value mapping to override individual slots in the account storage before executing
161    /// the call.
162    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
163    pub state_diff: Option<B256HashMap<B256>>,
164    /// Moves addresses precompile into the specified address. This move is done before the 'code'
165    /// override is set. When the specified address is not a precompile, the behaviour is undefined
166    /// and different clients might behave differently.
167    #[cfg_attr(
168        feature = "serde",
169        serde(
170            default,
171            skip_serializing_if = "Option::is_none",
172            rename = "movePrecompileToAddress",
173            alias = "MovePrecompileToAddress"
174        )
175    )]
176    pub move_precompile_to: Option<Address>,
177}
178
179impl AccountOverride {
180    /// Configures the bytecode override
181    pub fn with_code(mut self, code: impl Into<Bytes>) -> Self {
182        self.code = Some(code.into());
183        self
184    }
185
186    /// Convenience function that sets overrides the code with the EIP-7702 delegation designator
187    /// for `delegation_address`
188    pub fn with_7702_delegation_designator(self, delegation_address: Address) -> Self {
189        self.with_code(Bytes::from(
190            [&EIP7702_DELEGATION_DESIGNATOR, delegation_address.as_slice()].concat(),
191        ))
192    }
193
194    /// Configures the state overrides
195    pub fn with_state(mut self, state: impl IntoIterator<Item = (B256, B256)>) -> Self {
196        self.state = Some(state.into_iter().collect());
197        self
198    }
199
200    /// Configures the state diffs
201    pub fn with_state_diff(mut self, state_diff: impl IntoIterator<Item = (B256, B256)>) -> Self {
202        self.state_diff = Some(state_diff.into_iter().collect());
203        self
204    }
205
206    /// Configures the balance override
207    pub const fn with_balance(mut self, balance: U256) -> Self {
208        self.balance = Some(balance);
209        self
210    }
211
212    /// Configures the nonce override
213    pub const fn with_nonce(mut self, nonce: u64) -> Self {
214        self.nonce = Some(nonce);
215        self
216    }
217
218    /// Sets the bytecode override in place.
219    pub fn set_code(&mut self, code: impl Into<Bytes>) {
220        self.code = Some(code.into());
221    }
222
223    /// Sets the state overrides in place.
224    pub fn set_state(&mut self, state: impl IntoIterator<Item = (B256, B256)>) {
225        self.state = Some(state.into_iter().collect());
226    }
227
228    /// Sets the state diffs in place.
229    pub fn set_state_diff(&mut self, state_diff: impl IntoIterator<Item = (B256, B256)>) {
230        self.state_diff = Some(state_diff.into_iter().collect());
231    }
232
233    /// Sets the balance override in place.
234    pub const fn set_balance(&mut self, balance: U256) {
235        self.balance = Some(balance);
236    }
237
238    /// Sets the nonce override in place.
239    pub const fn set_nonce(&mut self, nonce: u64) {
240        self.nonce = Some(nonce);
241    }
242
243    /// Sets the move precompile address in place.
244    pub const fn set_move_precompile_to(&mut self, address: Address) {
245        self.move_precompile_to = Some(address);
246    }
247
248    /// Conditionally sets the bytecode override and returns self.
249    pub fn with_code_opt(mut self, code: Option<impl Into<Bytes>>) -> Self {
250        if let Some(code) = code {
251            self.code = Some(code.into());
252        }
253        self
254    }
255
256    /// Convenience function that sets overrides the code with the EIP-7702 delegation designator
257    /// for `delegation_address` if it is provided
258    pub fn with_7702_delegation_designator_opt(self, delegation_address: Option<Address>) -> Self {
259        if let Some(delegation_address) = delegation_address {
260            self.with_7702_delegation_designator(delegation_address)
261        } else {
262            self
263        }
264    }
265
266    /// Conditionally sets the balance override and returns self.
267    pub const fn with_balance_opt(mut self, balance: Option<U256>) -> Self {
268        if let Some(balance) = balance {
269            self.balance = Some(balance);
270        }
271        self
272    }
273
274    /// Conditionally sets the nonce override and returns self.
275    pub const fn with_nonce_opt(mut self, nonce: Option<u64>) -> Self {
276        if let Some(nonce) = nonce {
277            self.nonce = Some(nonce);
278        }
279        self
280    }
281
282    /// Conditionally sets the move precompile address and returns self.
283    pub const fn with_move_precompile_to_opt(mut self, address: Option<Address>) -> Self {
284        if let Some(address) = address {
285            self.move_precompile_to = Some(address);
286        }
287        self
288    }
289}
290
291/// Helper type that bundles various overrides for EVM Execution.
292///
293/// By `Default`, no overrides are included.
294#[derive(Debug, Clone, Default)]
295pub struct EvmOverrides {
296    /// Applies overrides to the state before execution.
297    pub state: Option<StateOverride>,
298    /// Applies overrides to the block before execution.
299    ///
300    /// This is a `Box` because less common and only available in debug trace endpoints.
301    pub block: Option<Box<BlockOverrides>>,
302}
303
304impl EvmOverrides {
305    /// Creates a new instance with the given overrides
306    pub const fn new(state: Option<StateOverride>, block: Option<Box<BlockOverrides>>) -> Self {
307        Self { state, block }
308    }
309
310    /// Creates a new instance with the given state overrides.
311    pub const fn state(state: Option<StateOverride>) -> Self {
312        Self { state, block: None }
313    }
314
315    /// Creates a new instance with the given block overrides.
316    pub const fn block(block: Option<Box<BlockOverrides>>) -> Self {
317        Self { state: None, block }
318    }
319
320    /// Returns `true` if the overrides contain state overrides.
321    pub const fn has_state(&self) -> bool {
322        self.state.is_some()
323    }
324
325    /// Returns `true` if the overrides contain block overrides.
326    pub const fn has_block(&self) -> bool {
327        self.block.is_some()
328    }
329
330    /// Adds state overrides to an existing instance.
331    pub fn with_state(mut self, state: StateOverride) -> Self {
332        self.state = Some(state);
333        self
334    }
335
336    /// Adds block overrides to an existing instance.
337    pub fn with_block(mut self, block: Box<BlockOverrides>) -> Self {
338        self.block = Some(block);
339        self
340    }
341}
342
343#[cfg(test)]
344mod tests {
345    use super::*;
346    use alloy_primitives::{address, map::B256HashMap, Bytes, B256, U256};
347    use similar_asserts::assert_eq;
348
349    #[test]
350    fn test_default_account_override() {
351        let acc_override = AccountOverride::default();
352        assert!(acc_override.balance.is_none());
353        assert!(acc_override.nonce.is_none());
354        assert!(acc_override.code.is_none());
355        assert!(acc_override.state.is_none());
356        assert!(acc_override.state_diff.is_none());
357    }
358
359    #[test]
360    #[cfg(feature = "serde")]
361    #[should_panic(expected = "invalid type")]
362    fn test_invalid_json_structure() {
363        let invalid_json = r#"{
364            "0x1234567890123456789012345678901234567890": {
365                "balance": true
366            }
367        }"#;
368
369        let _: StateOverride = serde_json::from_str(invalid_json).unwrap();
370    }
371
372    #[test]
373    #[cfg(feature = "serde")]
374    fn test_large_values_in_override() {
375        let large_values_json = r#"{
376            "0x1234567890123456789012345678901234567890": {
377                "balance": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
378                "nonce": "0xffffffffffffffff"
379            }
380        }"#;
381
382        let state_override: StateOverride = serde_json::from_str(large_values_json).unwrap();
383        let acc =
384            state_override.get(&address!("1234567890123456789012345678901234567890")).unwrap();
385        assert_eq!(acc.balance, Some(U256::MAX));
386        assert_eq!(acc.nonce, Some(u64::MAX));
387    }
388
389    #[test]
390    #[cfg(feature = "serde")]
391    fn test_state_override() {
392        let s = r#"{
393            "0x0000000000000000000000000000000000000124": {
394                "code": "0x6080604052348015600e575f80fd5b50600436106026575f3560e01c80632096525514602a575b5f80fd5b60306044565b604051901515815260200160405180910390f35b5f604e600242605e565b5f0360595750600190565b505f90565b5f82607757634e487b7160e01b5f52601260045260245ffd5b50069056fea2646970667358221220287f77a4262e88659e3fb402138d2ee6a7ff9ba86bae487a95aa28156367d09c64736f6c63430008140033"
395            }
396        }"#;
397        let state_override: StateOverride = serde_json::from_str(s).unwrap();
398        let acc =
399            state_override.get(&address!("0000000000000000000000000000000000000124")).unwrap();
400        assert!(acc.code.is_some());
401    }
402
403    #[test]
404    #[cfg(feature = "serde")]
405    fn test_state_override_state_diff() {
406        let s = r#"{
407                "0x1b5212AF6b76113afD94cD2B5a78a73B7d7A8222": {
408                    "balance": "0x39726378b58c400000",
409                    "stateDiff": {}
410                },
411                "0xdAC17F958D2ee523a2206206994597C13D831ec7": {
412                    "stateDiff": {
413                        "0xede27e4e7f3676edbf125879f17a896d6507958df3d57bda6219f1880cae8a41": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
414                    }
415                }
416            }"#;
417        let state_override: StateOverride = serde_json::from_str(s).unwrap();
418        let acc =
419            state_override.get(&address!("1b5212AF6b76113afD94cD2B5a78a73B7d7A8222")).unwrap();
420        assert!(acc.state_diff.is_some());
421    }
422
423    #[test]
424    fn test_set_code_in_place() {
425        let mut account_override = AccountOverride::default();
426        let code = Bytes::from(vec![0x60, 0x60, 0x60, 0x60]);
427        account_override.set_code(code.clone());
428        assert_eq!(account_override.code, Some(code));
429    }
430
431    #[test]
432    fn test_set_state_in_place() {
433        let mut account_override = AccountOverride::default();
434        let state: B256HashMap<B256> = vec![(B256::ZERO, B256::ZERO)].into_iter().collect();
435        account_override.set_state(state.clone());
436        assert_eq!(account_override.state, Some(state));
437    }
438
439    #[test]
440    fn test_set_state_diff_in_place() {
441        let mut account_override = AccountOverride::default();
442        let state_diff: B256HashMap<B256> = vec![(B256::ZERO, B256::ZERO)].into_iter().collect();
443        account_override.set_state_diff(state_diff.clone());
444        assert_eq!(account_override.state_diff, Some(state_diff));
445    }
446
447    #[test]
448    fn test_set_balance_in_place() {
449        let mut account_override = AccountOverride::default();
450        let balance = U256::from(1000);
451        account_override.set_balance(balance);
452        assert_eq!(account_override.balance, Some(balance));
453    }
454
455    #[test]
456    fn test_set_nonce_in_place() {
457        let mut account_override = AccountOverride::default();
458        let nonce = 42;
459        account_override.set_nonce(nonce);
460        assert_eq!(account_override.nonce, Some(nonce));
461    }
462
463    #[test]
464    fn test_set_move_precompile_to_in_place() {
465        let mut account_override = AccountOverride::default();
466        let address = address!("0000000000000000000000000000000000000001");
467        account_override.set_move_precompile_to(address);
468        assert_eq!(account_override.move_precompile_to, Some(address));
469    }
470
471    #[test]
472    fn test_evm_overrides_new() {
473        let state = StateOverride::default();
474        let block: Box<BlockOverrides> = Box::default();
475
476        let evm_overrides = EvmOverrides::new(Some(state.clone()), Some(block.clone()));
477
478        assert!(evm_overrides.has_state());
479        assert!(evm_overrides.has_block());
480        assert_eq!(evm_overrides.state.unwrap(), state);
481        assert_eq!(*evm_overrides.block.unwrap(), *block);
482    }
483
484    #[test]
485    fn test_evm_overrides_state() {
486        let state = StateOverride::default();
487        let evm_overrides = EvmOverrides::state(Some(state.clone()));
488
489        assert!(evm_overrides.has_state());
490        assert!(!evm_overrides.has_block());
491        assert_eq!(evm_overrides.state.unwrap(), state);
492    }
493
494    #[test]
495    fn test_evm_overrides_block() {
496        let block: Box<BlockOverrides> = Box::default();
497        let evm_overrides = EvmOverrides::block(Some(block.clone()));
498
499        assert!(!evm_overrides.has_state());
500        assert!(evm_overrides.has_block());
501        assert_eq!(*evm_overrides.block.unwrap(), *block);
502    }
503
504    #[test]
505    fn test_evm_overrides_with_state() {
506        let state = StateOverride::default();
507        let mut evm_overrides = EvmOverrides::default();
508
509        assert!(!evm_overrides.has_state());
510
511        evm_overrides = evm_overrides.with_state(state.clone());
512
513        assert!(evm_overrides.has_state());
514        assert_eq!(evm_overrides.state.unwrap(), state);
515    }
516
517    #[test]
518    fn test_evm_overrides_with_block() {
519        let block: Box<BlockOverrides> = Box::default();
520        let mut evm_overrides = EvmOverrides::default();
521
522        assert!(!evm_overrides.has_block());
523
524        evm_overrides = evm_overrides.with_block(block.clone());
525
526        assert!(evm_overrides.has_block());
527        assert_eq!(*evm_overrides.block.unwrap(), *block);
528    }
529}