referrerpolicy=no-referrer-when-downgrade

pallet_revive/evm/api/
state_overrides.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10//  http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18use super::Bytes;
19use alloc::collections::BTreeMap;
20use ethereum_types::*;
21use pallet_revive_types::runtime_api::*;
22
23/// A mapping from account addresses to their state overrides, used to temporarily modify account
24/// state during `eth_call` and similar simulation methods without affecting on-chain data.
25///
26/// Each entry maps an [`Address`] to a [`StateOverride`] that specifies which parts of the
27/// account's state to replace for the duration of the call.
28///
29/// Conforms to the [Geth state override set specification](https://geth.ethereum.org/docs/interacting-with-geth/rpc/objects#state-override-set).
30#[derive(Debug, Default, Clone, Eq, PartialEq)]
31pub struct StateOverrideSet(pub BTreeMap<Address, StateOverride>);
32
33impl core::ops::Deref for StateOverrideSet {
34	type Target = BTreeMap<Address, StateOverride>;
35
36	fn deref(&self) -> &Self::Target {
37		&self.0
38	}
39}
40
41impl core::ops::DerefMut for StateOverrideSet {
42	fn deref_mut(&mut self) -> &mut Self::Target {
43		&mut self.0
44	}
45}
46
47impl From<StateOverrideSetV1> for StateOverrideSet {
48	fn from(value: StateOverrideSetV1) -> Self {
49		Self(
50			value
51				.0
52				.into_iter()
53				.map(|(address, overrides)| (address, overrides.into()))
54				.collect(),
55		)
56	}
57}
58
59/// Specifies how an account's storage should be overridden during a simulated call.
60///
61/// The Geth state override specification mandates that `state` and `stateDiff` are mutually
62/// exclusive. This enum encodes that constraint at the type level.
63#[derive(Debug, Clone, Eq, PartialEq)]
64pub enum StorageOverride {
65	/// Completely replaces the account's storage with the provided mapping. Any existing slots
66	/// not present in the mapping are effectively zeroed out.
67	State(BTreeMap<H256, H256>),
68	/// Patches individual storage slots without affecting the rest of the account's storage.
69	/// Only the specified slots are modified; all other existing slots remain unchanged.
70	StateDiff(BTreeMap<H256, H256>),
71}
72
73impl From<StorageOverrideV1> for StorageOverride {
74	fn from(value: StorageOverrideV1) -> Self {
75		match value {
76			StorageOverrideV1::State(state) => Self::State(state),
77			StorageOverrideV1::StateDiff(state_diff) => Self::StateDiff(state_diff),
78		}
79	}
80}
81
82/// Per-account state overrides applied during `eth_call` and similar simulation methods.
83///
84/// All fields are optional. Only the fields that are set will be overridden; the rest of the
85/// account's state is read from the chain as normal.
86///
87/// Conforms to the [Geth state override object specification](https://geth.ethereum.org/docs/interacting-with-geth/rpc/objects#state-override-set).
88#[derive(Debug, Default, Clone, Eq, PartialEq)]
89pub struct StateOverride {
90	/// Fake balance to set for the account before executing the call.
91	pub balance: Option<U256>,
92	/// Fake nonce to set for the account before executing the call.
93	pub nonce: Option<U256>,
94	/// Fake EVM bytecode to inject into the account before executing the call.
95	pub code: Option<Bytes>,
96	/// Storage override specifying either a full replacement or a partial diff. These two modes
97	/// are mutually exclusive per the Geth specification.
98	pub storage: Option<StorageOverride>,
99	/// Moves the precompile at the account's address to the specified address. Useful for
100	/// overriding a precompile's code with custom logic while still being able to invoke the
101	/// original precompile at a different address.
102	pub move_precompile_to_address: Option<Address>,
103}
104
105impl From<StateOverrideV1> for StateOverride {
106	fn from(value: StateOverrideV1) -> Self {
107		Self {
108			balance: value.balance,
109			nonce: value.nonce,
110			code: value.code,
111			storage: value.storage.map(Into::into),
112			move_precompile_to_address: value.move_precompile_to_address,
113		}
114	}
115}