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