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/// Account overrides keyed by the address whose state should be changed for the call.
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/// Overrides one account while executing a call.
136///
137/// `state` and `state_diff` are alternative request fields; callers should set at most one, though
138/// this type does not enforce that constraint. `state` replaces the complete storage map, so
139/// unspecified slots read as zero, while `state_diff` changes only the listed slots. Storage keys
140/// and values are raw 32-byte EVM slot and value words.
141#[derive(Clone, Debug, Default, PartialEq, Eq)]
142#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
143#[cfg_attr(feature = "serde", serde(default, rename_all = "camelCase", deny_unknown_fields))]
144pub struct AccountOverride {
145    /// Fake balance to set for the account before executing the call, in wei.
146    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
147    pub balance: Option<U256>,
148    /// Fake nonce to set for the account before executing the call.
149    #[cfg_attr(
150        feature = "serde",
151        serde(
152            default,
153            skip_serializing_if = "Option::is_none",
154            with = "alloy_serde::quantity::opt"
155        )
156    )]
157    pub nonce: Option<u64>,
158    /// Fake EVM bytecode to inject into the account before executing the call.
159    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
160    pub code: Option<Bytes>,
161    /// Fake key-value mapping to override all slots in the account storage before executing the
162    /// call.
163    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
164    pub state: Option<B256HashMap<B256>>,
165    /// Fake key-value mapping to override individual slots in the account storage before executing
166    /// the call.
167    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
168    pub state_diff: Option<B256HashMap<B256>>,
169    /// Moves addresses precompile into the specified address. This move is done before the 'code'
170    /// override is set. When the specified address is not a precompile, the behaviour is undefined
171    /// and different clients might behave differently.
172    #[cfg_attr(
173        feature = "serde",
174        serde(
175            default,
176            skip_serializing_if = "Option::is_none",
177            rename = "movePrecompileToAddress",
178            alias = "MovePrecompileToAddress"
179        )
180    )]
181    pub move_precompile_to: Option<Address>,
182}
183
184impl AccountOverride {
185    /// Configures the bytecode override
186    pub fn with_code(mut self, code: impl Into<Bytes>) -> Self {
187        self.code = Some(code.into());
188        self
189    }
190
191    /// Convenience function that sets overrides the code with the EIP-7702 delegation designator
192    /// for `delegation_address`
193    pub fn with_7702_delegation_designator(self, delegation_address: Address) -> Self {
194        self.with_code(Bytes::from(
195            [&EIP7702_DELEGATION_DESIGNATOR, delegation_address.as_slice()].concat(),
196        ))
197    }
198
199    /// Configures the state overrides
200    pub fn with_state(mut self, state: impl IntoIterator<Item = (B256, B256)>) -> Self {
201        self.state = Some(state.into_iter().collect());
202        self
203    }
204
205    /// Configures the state diffs
206    pub fn with_state_diff(mut self, state_diff: impl IntoIterator<Item = (B256, B256)>) -> Self {
207        self.state_diff = Some(state_diff.into_iter().collect());
208        self
209    }
210
211    /// Configures the balance override
212    pub const fn with_balance(mut self, balance: U256) -> Self {
213        self.balance = Some(balance);
214        self
215    }
216
217    /// Configures the nonce override
218    pub const fn with_nonce(mut self, nonce: u64) -> Self {
219        self.nonce = Some(nonce);
220        self
221    }
222
223    /// Sets the bytecode override in place.
224    pub fn set_code(&mut self, code: impl Into<Bytes>) {
225        self.code = Some(code.into());
226    }
227
228    /// Sets the state overrides in place.
229    pub fn set_state(&mut self, state: impl IntoIterator<Item = (B256, B256)>) {
230        self.state = Some(state.into_iter().collect());
231    }
232
233    /// Sets the state diffs in place.
234    pub fn set_state_diff(&mut self, state_diff: impl IntoIterator<Item = (B256, B256)>) {
235        self.state_diff = Some(state_diff.into_iter().collect());
236    }
237
238    /// Sets the balance override in place.
239    pub const fn set_balance(&mut self, balance: U256) {
240        self.balance = Some(balance);
241    }
242
243    /// Sets the nonce override in place.
244    pub const fn set_nonce(&mut self, nonce: u64) {
245        self.nonce = Some(nonce);
246    }
247
248    /// Sets the move precompile address in place.
249    pub const fn set_move_precompile_to(&mut self, address: Address) {
250        self.move_precompile_to = Some(address);
251    }
252
253    /// Conditionally sets the bytecode override and returns self.
254    pub fn with_code_opt(mut self, code: Option<impl Into<Bytes>>) -> Self {
255        if let Some(code) = code {
256            self.code = Some(code.into());
257        }
258        self
259    }
260
261    /// Convenience function that sets overrides the code with the EIP-7702 delegation designator
262    /// for `delegation_address` if it is provided
263    pub fn with_7702_delegation_designator_opt(self, delegation_address: Option<Address>) -> Self {
264        if let Some(delegation_address) = delegation_address {
265            self.with_7702_delegation_designator(delegation_address)
266        } else {
267            self
268        }
269    }
270
271    /// Conditionally sets the balance override and returns self.
272    pub const fn with_balance_opt(mut self, balance: Option<U256>) -> Self {
273        if let Some(balance) = balance {
274            self.balance = Some(balance);
275        }
276        self
277    }
278
279    /// Conditionally sets the nonce override and returns self.
280    pub const fn with_nonce_opt(mut self, nonce: Option<u64>) -> Self {
281        if let Some(nonce) = nonce {
282            self.nonce = Some(nonce);
283        }
284        self
285    }
286
287    /// Conditionally sets the move precompile address and returns self.
288    pub const fn with_move_precompile_to_opt(mut self, address: Option<Address>) -> Self {
289        if let Some(address) = address {
290            self.move_precompile_to = Some(address);
291        }
292        self
293    }
294}
295
296/// Helper type that bundles various overrides for EVM Execution.
297///
298/// By `Default`, no overrides are included.
299#[derive(Debug, Clone, Default)]
300pub struct EvmOverrides {
301    /// Applies overrides to the state before execution.
302    pub state: Option<StateOverride>,
303    /// Applies overrides to the block before execution.
304    ///
305    /// This is a `Box` because less common and only available in debug trace endpoints.
306    pub block: Option<Box<BlockOverrides>>,
307}
308
309impl EvmOverrides {
310    /// Creates a new instance with the given overrides
311    pub const fn new(state: Option<StateOverride>, block: Option<Box<BlockOverrides>>) -> Self {
312        Self { state, block }
313    }
314
315    /// Creates a new instance with the given state overrides.
316    pub const fn state(state: Option<StateOverride>) -> Self {
317        Self { state, block: None }
318    }
319
320    /// Creates a new instance with the given block overrides.
321    pub const fn block(block: Option<Box<BlockOverrides>>) -> Self {
322        Self { state: None, block }
323    }
324
325    /// Returns `true` if the overrides contain state overrides.
326    pub const fn has_state(&self) -> bool {
327        self.state.is_some()
328    }
329
330    /// Returns `true` if the overrides contain block overrides.
331    pub const fn has_block(&self) -> bool {
332        self.block.is_some()
333    }
334
335    /// Adds state overrides to an existing instance.
336    pub fn with_state(mut self, state: StateOverride) -> Self {
337        self.state = Some(state);
338        self
339    }
340
341    /// Adds block overrides to an existing instance.
342    pub fn with_block(mut self, block: Box<BlockOverrides>) -> Self {
343        self.block = Some(block);
344        self
345    }
346}
347
348#[cfg(test)]
349mod tests {
350    use super::*;
351    use alloy_primitives::{address, map::B256HashMap, Bytes, B256, U256};
352    use similar_asserts::assert_eq;
353
354    #[test]
355    fn test_default_account_override() {
356        let acc_override = AccountOverride::default();
357        assert!(acc_override.balance.is_none());
358        assert!(acc_override.nonce.is_none());
359        assert!(acc_override.code.is_none());
360        assert!(acc_override.state.is_none());
361        assert!(acc_override.state_diff.is_none());
362    }
363
364    #[test]
365    #[cfg(feature = "serde")]
366    #[should_panic(expected = "invalid type")]
367    fn test_invalid_json_structure() {
368        let invalid_json = r#"{
369            "0x1234567890123456789012345678901234567890": {
370                "balance": true
371            }
372        }"#;
373
374        let _: StateOverride = serde_json::from_str(invalid_json).unwrap();
375    }
376
377    #[test]
378    #[cfg(feature = "serde")]
379    fn test_large_values_in_override() {
380        let large_values_json = r#"{
381            "0x1234567890123456789012345678901234567890": {
382                "balance": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
383                "nonce": "0xffffffffffffffff"
384            }
385        }"#;
386
387        let state_override: StateOverride = serde_json::from_str(large_values_json).unwrap();
388        let acc =
389            state_override.get(&address!("1234567890123456789012345678901234567890")).unwrap();
390        assert_eq!(acc.balance, Some(U256::MAX));
391        assert_eq!(acc.nonce, Some(u64::MAX));
392    }
393
394    #[test]
395    #[cfg(feature = "serde")]
396    fn test_state_override() {
397        let s = r#"{
398            "0x0000000000000000000000000000000000000124": {
399                "code": "0x6080604052348015600e575f80fd5b50600436106026575f3560e01c80632096525514602a575b5f80fd5b60306044565b604051901515815260200160405180910390f35b5f604e600242605e565b5f0360595750600190565b505f90565b5f82607757634e487b7160e01b5f52601260045260245ffd5b50069056fea2646970667358221220287f77a4262e88659e3fb402138d2ee6a7ff9ba86bae487a95aa28156367d09c64736f6c63430008140033"
400            }
401        }"#;
402        let state_override: StateOverride = serde_json::from_str(s).unwrap();
403        let acc =
404            state_override.get(&address!("0000000000000000000000000000000000000124")).unwrap();
405        assert!(acc.code.is_some());
406    }
407
408    #[test]
409    #[cfg(feature = "serde")]
410    fn test_state_override_state_diff() {
411        let s = r#"{
412                "0x1b5212AF6b76113afD94cD2B5a78a73B7d7A8222": {
413                    "balance": "0x39726378b58c400000",
414                    "stateDiff": {}
415                },
416                "0xdAC17F958D2ee523a2206206994597C13D831ec7": {
417                    "stateDiff": {
418                        "0xede27e4e7f3676edbf125879f17a896d6507958df3d57bda6219f1880cae8a41": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
419                    }
420                }
421            }"#;
422        let state_override: StateOverride = serde_json::from_str(s).unwrap();
423        let acc =
424            state_override.get(&address!("1b5212AF6b76113afD94cD2B5a78a73B7d7A8222")).unwrap();
425        assert!(acc.state_diff.is_some());
426    }
427
428    #[test]
429    fn test_set_code_in_place() {
430        let mut account_override = AccountOverride::default();
431        let code = Bytes::from(vec![0x60, 0x60, 0x60, 0x60]);
432        account_override.set_code(code.clone());
433        assert_eq!(account_override.code, Some(code));
434    }
435
436    #[test]
437    fn test_set_state_in_place() {
438        let mut account_override = AccountOverride::default();
439        let state: B256HashMap<B256> = vec![(B256::ZERO, B256::ZERO)].into_iter().collect();
440        account_override.set_state(state.clone());
441        assert_eq!(account_override.state, Some(state));
442    }
443
444    #[test]
445    fn test_set_state_diff_in_place() {
446        let mut account_override = AccountOverride::default();
447        let state_diff: B256HashMap<B256> = vec![(B256::ZERO, B256::ZERO)].into_iter().collect();
448        account_override.set_state_diff(state_diff.clone());
449        assert_eq!(account_override.state_diff, Some(state_diff));
450    }
451
452    #[test]
453    fn test_set_balance_in_place() {
454        let mut account_override = AccountOverride::default();
455        let balance = U256::from(1000);
456        account_override.set_balance(balance);
457        assert_eq!(account_override.balance, Some(balance));
458    }
459
460    #[test]
461    fn test_set_nonce_in_place() {
462        let mut account_override = AccountOverride::default();
463        let nonce = 42;
464        account_override.set_nonce(nonce);
465        assert_eq!(account_override.nonce, Some(nonce));
466    }
467
468    #[test]
469    fn test_set_move_precompile_to_in_place() {
470        let mut account_override = AccountOverride::default();
471        let address = address!("0000000000000000000000000000000000000001");
472        account_override.set_move_precompile_to(address);
473        assert_eq!(account_override.move_precompile_to, Some(address));
474    }
475
476    #[test]
477    fn test_evm_overrides_new() {
478        let state = StateOverride::default();
479        let block: Box<BlockOverrides> = Box::default();
480
481        let evm_overrides = EvmOverrides::new(Some(state.clone()), Some(block.clone()));
482
483        assert!(evm_overrides.has_state());
484        assert!(evm_overrides.has_block());
485        assert_eq!(evm_overrides.state.unwrap(), state);
486        assert_eq!(*evm_overrides.block.unwrap(), *block);
487    }
488
489    #[test]
490    fn test_evm_overrides_state() {
491        let state = StateOverride::default();
492        let evm_overrides = EvmOverrides::state(Some(state.clone()));
493
494        assert!(evm_overrides.has_state());
495        assert!(!evm_overrides.has_block());
496        assert_eq!(evm_overrides.state.unwrap(), state);
497    }
498
499    #[test]
500    fn test_evm_overrides_block() {
501        let block: Box<BlockOverrides> = Box::default();
502        let evm_overrides = EvmOverrides::block(Some(block.clone()));
503
504        assert!(!evm_overrides.has_state());
505        assert!(evm_overrides.has_block());
506        assert_eq!(*evm_overrides.block.unwrap(), *block);
507    }
508
509    #[test]
510    fn test_evm_overrides_with_state() {
511        let state = StateOverride::default();
512        let mut evm_overrides = EvmOverrides::default();
513
514        assert!(!evm_overrides.has_state());
515
516        evm_overrides = evm_overrides.with_state(state.clone());
517
518        assert!(evm_overrides.has_state());
519        assert_eq!(evm_overrides.state.unwrap(), state);
520    }
521
522    #[test]
523    fn test_evm_overrides_with_block() {
524        let block: Box<BlockOverrides> = Box::default();
525        let mut evm_overrides = EvmOverrides::default();
526
527        assert!(!evm_overrides.has_block());
528
529        evm_overrides = evm_overrides.with_block(block.clone());
530
531        assert!(evm_overrides.has_block());
532        assert_eq!(*evm_overrides.block.unwrap(), *block);
533    }
534}