referrerpolicy=no-referrer-when-downgrade

pallet_revive/
exec.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 crate::{
19	AccountInfo, AccountInfoOf, BalanceOf, BalanceWithDust, Code, CodeInfo, CodeInfoOf,
20	CodeRemoved, Config, ContractInfo, Error, Event, ImmutableData, ImmutableDataOf, LOG_TARGET,
21	Pallet as Contracts, RuntimeCosts, TrieId,
22	access_list::{AccessEntry, AccessList, StorageAccessKind, StorageOp},
23	address::{self, AddressMapper},
24	deposit_payment::Deposit as _,
25	evm::{block_storage, fees::InfoT as _, transfer_with_dust},
26	limits,
27	metering::{ChargedAmount, Diff, FrameMeter, ResourceMeter, State, Token, TransactionMeter},
28	precompiles::{All as AllPrecompiles, Instance as PrecompileInstance, Precompiles},
29	primitives::{ExecConfig, ExecReturnValue, StorageDeposit},
30	runtime_decl_for_revive_api::{Decode, Encode, TypeInfo},
31	storage::{AccountIdOrAddress, WriteOutcome},
32	tracing::if_tracing,
33	transient_storage::TransientStorage,
34};
35use alloc::{
36	collections::{BTreeMap, BTreeSet},
37	vec::Vec,
38};
39use core::{cmp, fmt::Debug, marker::PhantomData, mem, ops::ControlFlow};
40use frame_support::{
41	Blake2_128Concat, BoundedVec, DebugNoBound, StorageHasher,
42	crypto::ecdsa::ECDSAExt,
43	dispatch::DispatchResult,
44	ensure,
45	storage::{TransactionOutcome, with_transaction},
46	traits::{
47		Time,
48		fungible::{Balanced as _, Inspect, Mutate},
49		tokens::Preservation,
50	},
51	weights::Weight,
52};
53use frame_system::{
54	Pallet as System, RawOrigin,
55	pallet_prelude::{BlockNumberFor, OriginFor},
56};
57use sp_core::{
58	ConstU32, Get, H160, H256, U256,
59	ecdsa::Public as ECDSAPublic,
60	sr25519::{Public as SR25519Public, Signature as SR25519Signature},
61};
62use sp_io::{crypto::secp256k1_ecdsa_recover_compressed, hashing::blake2_256};
63use sp_runtime::{
64	DispatchError, SaturatedConversion,
65	traits::{BadOrigin, Saturating, TrailingZeroInput, Zero},
66};
67
68#[cfg(test)]
69mod tests;
70
71#[cfg(test)]
72pub mod mock_ext;
73
74pub type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
75pub type MomentOf<T> = <<T as Config>::Time as Time>::Moment;
76pub type ExecResult = Result<ExecReturnValue, ExecError>;
77
78/// Type for variable sized storage key. Used for transparent hashing.
79type VarSizedKey = BoundedVec<u8, ConstU32<{ limits::STORAGE_KEY_BYTES }>>;
80
81const FRAME_ALWAYS_EXISTS_ON_INSTANTIATE: &str = "The return value is only `None` if no contract exists at the specified address. This cannot happen on instantiate or delegate; qed";
82
83/// Code hash of existing account without code (keccak256 hash of empty data).
84pub const EMPTY_CODE_HASH: H256 =
85	H256(sp_core::hex2array!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
86
87/// Combined key type for both fixed and variable sized storage keys.
88#[derive(Debug)]
89pub enum Key {
90	/// Variant for fixed sized keys.
91	Fix([u8; 32]),
92	/// Variant for variable sized keys.
93	Var(VarSizedKey),
94}
95
96impl Key {
97	/// Reference to the raw unhashed key.
98	pub fn unhashed(&self) -> &[u8] {
99		match self {
100			Key::Fix(v) => v.as_ref(),
101			Key::Var(v) => v.as_ref(),
102		}
103	}
104
105	/// The hashed key that has be used as actual key to the storage trie.
106	pub fn hash(&self) -> Vec<u8> {
107		match self {
108			Key::Fix(v) => blake2_256(v.as_slice()).to_vec(),
109			Key::Var(v) => Blake2_128Concat::hash(v.as_slice()),
110		}
111	}
112
113	pub fn from_fixed(v: [u8; 32]) -> Self {
114		Self::Fix(v)
115	}
116
117	pub fn try_from_var(v: Vec<u8>) -> Result<Self, ()> {
118		VarSizedKey::try_from(v).map(Self::Var).map_err(|_| ())
119	}
120}
121
122/// Level of reentrancy protection.
123///
124/// This needs to be specifed when a contract makes a message call. This way the calling contract
125/// can specify the level of re-entrancy protection while the callee (and it's recursive callees) is
126/// executing.
127#[derive(Copy, Clone, PartialEq, Debug)]
128pub enum ReentrancyProtection {
129	/// Don't activate reentrancy protection
130	AllowReentry,
131	/// Activate strict reentrancy protection. The direct callee and none of its own recursive
132	/// callees must be the calling contract.
133	Strict,
134	/// Activate reentrancy protection where the direct callee can be the same contract as the
135	/// caller but none of the recursive callees of the callee must be the caller.
136	///
137	/// This is used for calls that transfer value but restrict gas so that the callee only has a
138	/// stipend gas amount. In Ethereum that is not sufficient for the callee to make another call.
139	/// However, due to gas scale differences that guarantee does not automatically hold in revive
140	/// and we enforce it explicitly here.
141	AllowNext,
142}
143
144/// Origin of the error.
145///
146/// Call or instantiate both called into other contracts and pass through errors happening
147/// in those to the caller. This enum is for the caller to distinguish whether the error
148/// happened during the execution of the callee or in the current execution context.
149#[derive(Copy, Clone, PartialEq, Eq, Debug, codec::Decode, codec::Encode)]
150pub enum ErrorOrigin {
151	/// Caller error origin.
152	///
153	/// The error happened in the current execution context rather than in the one
154	/// of the contract that is called into.
155	Caller,
156	/// The error happened during execution of the called contract.
157	Callee,
158}
159
160/// Error returned by contract execution.
161#[derive(Copy, Clone, PartialEq, Eq, Debug, codec::Decode, codec::Encode)]
162pub struct ExecError {
163	/// The reason why the execution failed.
164	pub error: DispatchError,
165	/// Origin of the error.
166	pub origin: ErrorOrigin,
167}
168
169impl<T: Into<DispatchError>> From<T> for ExecError {
170	fn from(error: T) -> Self {
171		Self { error: error.into(), origin: ErrorOrigin::Caller }
172	}
173}
174
175/// The type of origins supported by the revive pallet.
176#[derive(Clone, Encode, Decode, PartialEq, TypeInfo, DebugNoBound)]
177pub enum Origin<T: Config> {
178	Root,
179	Signed(T::AccountId),
180}
181
182impl<T: Config> Origin<T> {
183	/// Creates a new Signed Caller from an AccountId.
184	pub fn from_account_id(account_id: T::AccountId) -> Self {
185		Origin::Signed(account_id)
186	}
187
188	/// Creates a new Origin from a `RuntimeOrigin`.
189	pub fn from_runtime_origin(o: OriginFor<T>) -> Result<Self, DispatchError> {
190		match o.into() {
191			Ok(RawOrigin::Root) => Ok(Self::Root),
192			Ok(RawOrigin::Signed(t)) => Ok(Self::Signed(t)),
193			_ => Err(BadOrigin.into()),
194		}
195	}
196
197	/// Returns the AccountId of a Signed Origin or an error if the origin is Root.
198	pub fn account_id(&self) -> Result<&T::AccountId, DispatchError> {
199		match self {
200			Origin::Signed(id) => Ok(id),
201			Origin::Root => Err(DispatchError::RootNotAllowed),
202		}
203	}
204
205	/// Make sure that this origin is mapped.
206	///
207	/// We require an origin to be mapped in order to be used in a `Stack`. Otherwise
208	/// [`Stack::caller`] returns an address that can't be reverted to the original address.
209	fn ensure_mapped(&self) -> DispatchResult {
210		match self {
211			Self::Root => Ok(()),
212			Self::Signed(account_id) if T::AddressMapper::is_mapped(account_id) => Ok(()),
213			Self::Signed(_) => Err(<Error<T>>::AccountUnmapped.into()),
214		}
215	}
216}
217
218/// Argument passed by a contact to describe the amount of resources allocated to a cross contact
219/// call.
220#[derive(DebugNoBound)]
221pub enum CallResources<T: Config> {
222	/// Resources are not limited
223	NoLimits,
224	/// Resources encoded using their actual values.
225	WeightDeposit { weight: Weight, deposit_limit: BalanceOf<T> },
226	/// Resources encoded as unified ethereum gas.
227	Ethereum { gas: BalanceOf<T>, add_stipend: bool },
228}
229
230impl<T: Config> CallResources<T> {
231	/// Creates a new `CallResources` with weight and deposit limits.
232	pub fn from_weight_and_deposit(weight: Weight, deposit_limit: U256) -> Self {
233		Self::WeightDeposit {
234			weight,
235			deposit_limit: deposit_limit.saturated_into::<BalanceOf<T>>(),
236		}
237	}
238
239	/// Creates a new `CallResources` from Ethereum gas limits.
240	pub fn from_ethereum_gas(gas: U256, add_stipend: bool) -> Self {
241		Self::Ethereum { gas: gas.saturated_into::<BalanceOf<T>>(), add_stipend }
242	}
243}
244
245impl<T: Config> Default for CallResources<T> {
246	fn default() -> Self {
247		Self::WeightDeposit { weight: Default::default(), deposit_limit: Default::default() }
248	}
249}
250
251/// Stored inside the `Stack` for each contract that is scheduled for termination.
252struct TerminateArgs<T: Config> {
253	/// Where to send the free balance of the terminated contract.
254	beneficiary: T::AccountId,
255	/// The storage child trie of the contract that needs to be deleted.
256	trie_id: TrieId,
257	/// The code referenced by the contract. Will be deleted if refcount drops to zero.
258	code_hash: H256,
259	/// Triggered by the EVM opcode.
260	only_if_same_tx: bool,
261}
262
263/// Environment functions only available to host functions.
264pub trait Ext: PrecompileWithInfoExt {
265	/// Execute code in the current frame.
266	///
267	/// Returns the code size of the called contract.
268	fn delegate_call(
269		&mut self,
270		call_resources: &CallResources<Self::T>,
271		address: H160,
272		input_data: Vec<u8>,
273	) -> Result<(), ExecError>;
274
275	/// Register the contract for destruction at the end of the call stack.
276	///
277	/// Transfer all funds to `beneficiary`.
278	/// Contract is deleted only if it was created in the same call stack.
279	///
280	/// This function will fail if called from constructor.
281	fn terminate_if_same_tx(&mut self, beneficiary: &H160) -> Result<CodeRemoved, DispatchError>;
282
283	/// Returns the code hash of the contract being executed.
284	#[allow(dead_code)]
285	fn own_code_hash(&mut self) -> &H256;
286
287	/// This query is free as it does not need to load the immutable data from storage.
288	/// Useful when we need a constant time lookup of the length.
289	/// For foreign code (delegate call, EIP-7702 delegated EOA) returns the `IMMUTABLE_BYTES` cap.
290	fn immutable_data_len(&mut self) -> u32;
291
292	/// Returns the immutable data of the current contract.
293	///
294	/// Returns `Err(InvalidImmutableAccess)` if called from a constructor.
295	fn get_immutable_data(&mut self) -> Result<ImmutableData, DispatchError>;
296
297	/// Set the immutable data of the current contract.
298	///
299	/// Returns `Err(InvalidImmutableAccess)` if not called from a constructor.
300	///
301	/// Note: Requires &mut self to access the contract info.
302	fn set_immutable_data(&mut self, data: ImmutableData) -> Result<(), DispatchError>;
303}
304
305/// Environment functions which are available to pre-compiles with `HAS_CONTRACT_INFO = true`.
306pub trait PrecompileWithInfoExt: PrecompileExt {
307	/// Instantiate a contract from the given code.
308	///
309	/// Returns the original code size of the called contract.
310	/// The newly created account will be associated with `code`. `value` specifies the amount of
311	/// value transferred from the caller to the newly created account.
312	fn instantiate(
313		&mut self,
314		limits: &CallResources<Self::T>,
315		code: Code,
316		value: U256,
317		input_data: Vec<u8>,
318		salt: Option<&[u8; 32]>,
319	) -> Result<H160, ExecError>;
320}
321
322/// Environment functions which are available to all pre-compiles.
323pub trait PrecompileExt: sealing::Sealed {
324	type T: Config;
325
326	/// Charges the weight meter with the given weight.
327	fn charge(&mut self, weight: Weight) -> Result<ChargedAmount, DispatchError> {
328		self.frame_meter_mut().charge_weight_token(RuntimeCosts::Precompile(weight))
329	}
330
331	/// Reconcile an earlier gas charge with the actual weight consumed.
332	/// This updates the current weight meter to reflect the real cost of the token.
333	fn adjust_gas(&mut self, charged: ChargedAmount, actual_weight: Weight) {
334		self.frame_meter_mut()
335			.adjust_weight(charged, RuntimeCosts::Precompile(actual_weight));
336	}
337
338	/// Charges the weight meter with the given token or halts execution if not enough weight is
339	/// left.
340	#[inline]
341	fn charge_or_halt<Tok: Token<Self::T>>(
342		&mut self,
343		token: Tok,
344	) -> ControlFlow<crate::vm::evm::Halt, ChargedAmount> {
345		self.frame_meter_mut().charge_or_halt(token)
346	}
347
348	/// Call (possibly transferring some amount of funds) into the specified account.
349	fn call(
350		&mut self,
351		call_resources: &CallResources<Self::T>,
352		to: &H160,
353		value: U256,
354		input_data: Vec<u8>,
355		reentrancy: ReentrancyProtection,
356		read_only: bool,
357	) -> Result<(), ExecError>;
358
359	/// Returns the transient storage entry of the executing account for the given `key`.
360	///
361	/// Returns `None` if the `key` wasn't previously set by `set_transient_storage` or
362	/// was deleted.
363	fn get_transient_storage(&self, key: &Key) -> Option<Vec<u8>>;
364
365	/// Returns `Some(len)` (in bytes) if a transient storage item exists at `key`.
366	///
367	/// Returns `None` if the `key` wasn't previously set by `set_transient_storage` or
368	/// was deleted.
369	fn get_transient_storage_size(&self, key: &Key) -> Option<u32>;
370
371	/// Sets the transient storage entry for the given key to the specified value. If `value` is
372	/// `None` then the storage entry is deleted.
373	fn set_transient_storage(
374		&mut self,
375		key: &Key,
376		value: Option<Vec<u8>>,
377		take_old: bool,
378	) -> Result<WriteOutcome, DispatchError>;
379
380	/// Returns the caller.
381	fn caller(&self) -> Origin<Self::T>;
382
383	/// Returns the caller of the caller.
384	fn caller_of_caller(&self) -> Origin<Self::T>;
385
386	/// Return the origin of the whole call stack.
387	fn origin(&self) -> &Origin<Self::T>;
388
389	/// Returns the account id for the given `address`.
390	fn to_account_id(&self, address: &H160) -> AccountIdOf<Self::T>;
391
392	/// Returns the code hash of the contract for the given `address`.
393	/// If not a contract but account exists then `keccak_256([])` is returned, otherwise `zero`.
394	fn code_hash(&self, address: &H160) -> H256;
395
396	/// Returns the code size of the contract at the given `address` or zero.
397	fn code_size(&self, address: &H160) -> u64;
398
399	/// Check if the caller of the current contract is the origin of the whole call stack.
400	fn caller_is_origin(&self, use_caller_of_caller: bool) -> bool;
401
402	/// Check if the caller is origin, and this origin is root.
403	fn caller_is_root(&self, use_caller_of_caller: bool) -> bool;
404
405	/// Check if the origin of the whole call stack is root.
406	///
407	/// Unlike [`Self::caller_is_root`], this does not require the caller to be the origin: any
408	/// number of intermediate frames may sit between this contract and the original dispatch.
409	fn origin_is_root(&self) -> bool;
410
411	/// Returns a reference to the account id of the current contract.
412	fn account_id(&self) -> &AccountIdOf<Self::T>;
413
414	/// Returns a reference to the [`H160`] address of the current contract.
415	fn address(&self) -> H160 {
416		<Self::T as Config>::AddressMapper::to_address(self.account_id())
417	}
418
419	/// Returns the balance of the current contract.
420	///
421	/// The `value_transferred` is already added.
422	fn balance(&self) -> U256;
423
424	/// Returns the balance of the supplied account.
425	///
426	/// The `value_transferred` is already added.
427	fn balance_of(&self, address: &H160) -> U256;
428
429	/// Returns the value transferred along with this call.
430	fn value_transferred(&self) -> U256;
431
432	/// Returns the timestamp of the current block in seconds.
433	fn now(&self) -> U256;
434
435	/// Returns the minimum balance that is required for creating an account.
436	fn minimum_balance(&self) -> U256;
437
438	/// Deposit an event with the given topics.
439	///
440	/// There should not be any duplicates in `topics`.
441	fn deposit_event(&mut self, topics: Vec<H256>, data: Vec<u8>);
442
443	/// Returns the current block number.
444	fn block_number(&self) -> U256;
445
446	/// Returns the block hash at the given `block_number` or `None` if
447	/// `block_number` isn't within the range of the previous 256 blocks.
448	fn block_hash(&self, block_number: U256) -> Option<H256>;
449
450	/// Returns the author of the current block.
451	fn block_author(&self) -> H160;
452
453	/// Returns the block gas limit.
454	fn gas_limit(&self) -> u64;
455
456	/// Returns the chain id.
457	fn chain_id(&self) -> u64;
458
459	/// Get an immutable reference to the nested resource meter of the frame.
460	#[deprecated(note = "Renamed to `frame_meter`; this alias will be removed in future versions")]
461	fn gas_meter(&self) -> &FrameMeter<Self::T>;
462
463	/// Get a mutable reference to the nested resource meter of the frame.
464	#[deprecated(
465		note = "Renamed to `frame_meter_mut`; this alias will be removed in future versions"
466	)]
467	fn gas_meter_mut(&mut self) -> &mut FrameMeter<Self::T>;
468
469	/// Get an immutable reference to the nested resource meter of the frame.
470	fn frame_meter(&self) -> &FrameMeter<Self::T>;
471
472	/// Get a mutable reference to the nested resource meter of the frame.
473	fn frame_meter_mut(&mut self) -> &mut FrameMeter<Self::T>;
474
475	/// Recovers ECDSA compressed public key based on signature and message hash.
476	fn ecdsa_recover(&self, signature: &[u8; 65], message_hash: &[u8; 32]) -> Result<[u8; 33], ()>;
477
478	/// Verify a sr25519 signature.
479	fn sr25519_verify(&self, signature: &[u8; 64], message: &[u8], pub_key: &[u8; 32]) -> bool;
480
481	/// Returns Ethereum address from the ECDSA compressed public key.
482	fn ecdsa_to_eth_address(&self, pk: &[u8; 33]) -> Result<[u8; 20], DispatchError>;
483
484	/// Tests sometimes need to modify and inspect the contract info directly.
485	#[cfg(any(test, feature = "runtime-benchmarks"))]
486	fn contract_info(&mut self) -> &mut ContractInfo<Self::T>;
487
488	/// Get a mutable reference to the transient storage.
489	/// Useful in benchmarks when it is sometimes necessary to modify and inspect the transient
490	/// storage directly.
491	#[cfg(any(feature = "runtime-benchmarks", test))]
492	fn transient_storage(&mut self) -> &mut TransientStorage<Self::T>;
493
494	/// Check if running in read-only context.
495	fn is_read_only(&self) -> bool;
496
497	/// Check if running as a delegate call.
498	fn is_delegate_call(&self) -> bool;
499
500	/// Returns an immutable reference to the output of the last executed call frame.
501	fn last_frame_output(&self) -> &ExecReturnValue;
502
503	/// Returns a mutable reference to the output of the last executed call frame.
504	fn last_frame_output_mut(&mut self) -> &mut ExecReturnValue;
505
506	/// Copies a slice of the contract's code at `address` into the provided buffer.
507	///
508	/// EVM CODECOPY semantics:
509	/// - If `buf.len()` = 0: Nothing happens
510	/// - If `code_offset` >= code size: `len` bytes of zero are written to memory
511	/// - If `code_offset + buf.len()` extends beyond code: Available code copied, remaining bytes
512	///   are filled with zeros
513	fn copy_code_slice(&mut self, buf: &mut [u8], address: &H160, code_offset: usize);
514
515	/// Register the caller of the current contract for destruction.
516	/// Destruction happens at the end of the call stack.
517	/// This is supposed to be used by the terminate precompile.
518	///
519	/// Transfer all funds to `beneficiary`.
520	/// Contract is deleted at the end of the call stack.
521	///
522	/// This function will fail if called from constructor.
523	fn terminate_caller(&mut self, beneficiary: &H160) -> Result<(), DispatchError>;
524
525	/// Returns the effective gas price of this transaction.
526	fn effective_gas_price(&self) -> U256;
527
528	/// The amount of gas left in eth gas units.
529	fn gas_left(&self) -> u64;
530
531	/// Returns the storage entry of the executing account by the given `key`.
532	///
533	/// Returns `None` if the `key` wasn't previously set by `set_storage` or
534	/// was deleted.
535	fn get_storage(&mut self, key: &Key) -> Option<Vec<u8>>;
536
537	/// Returns `Some(len)` (in bytes) if a storage item exists at `key`.
538	///
539	/// Returns `None` if the `key` wasn't previously set by `set_storage` or
540	/// was deleted.
541	fn get_storage_size(&mut self, key: &Key) -> Option<u32>;
542
543	/// Sets the storage entry by the given key to the specified value. If `value` is `None` then
544	/// the storage entry is deleted.
545	fn set_storage(
546		&mut self,
547		key: &Key,
548		value: Option<Vec<u8>>,
549		take_old: bool,
550	) -> Result<WriteOutcome, DispatchError>;
551
552	/// Checks if `key` was already accessed in this transaction and inserts it
553	/// otherwise, so subsequent accesses to the same slot bill as hot. Returns
554	/// the slot's [`StorageAccessKind`]. `op` is the operation being performed:
555	/// a write upgrades a slot that had only paid for a read. When
556	/// `transient` is true, skips the access list and returns the `Transient`
557	/// variant.
558	fn touch_storage_access(
559		&mut self,
560		transient: bool,
561		key: &Key,
562		op: StorageOp,
563	) -> StorageAccessKind;
564
565	/// Non-mutating sibling of `touch_storage_access`: prices the access without
566	/// warming the slot.
567	fn peek_storage_access(&self, transient: bool, key: &Key) -> StorageAccessKind;
568
569	/// Charges `diff` from the meter.
570	fn charge_storage(&mut self, diff: &Diff) -> DispatchResult;
571}
572
573/// Describes the different functions that can be exported by an [`Executable`].
574#[derive(
575	Copy,
576	Clone,
577	PartialEq,
578	Eq,
579	Debug,
580	codec::Decode,
581	codec::Encode,
582	codec::MaxEncodedLen,
583	scale_info::TypeInfo,
584)]
585pub enum ExportedFunction {
586	/// The constructor function which is executed on deployment of a contract.
587	Constructor,
588	/// The function which is executed when a contract is called.
589	Call,
590}
591
592/// A trait that represents something that can be executed.
593///
594/// In the on-chain environment this would be represented by a vm binary module. This trait exists
595/// in order to be able to mock the vm logic for testing.
596pub trait Executable<T: Config>: Sized {
597	/// Load the executable from storage.
598	///
599	/// # Note
600	/// Charges size base load weight from the weight meter.
601	fn from_storage<S: State>(
602		code_hash: H256,
603		meter: &mut ResourceMeter<T, S>,
604	) -> Result<Self, DispatchError>;
605
606	/// Load the executable from EVM bytecode
607	fn from_evm_init_code(code: Vec<u8>, owner: AccountIdOf<T>) -> Result<Self, DispatchError>;
608
609	/// Execute the specified exported function and return the result.
610	///
611	/// When the specified function is `Constructor` the executable is stored and its
612	/// refcount incremented.
613	///
614	/// # Note
615	///
616	/// This functions expects to be executed in a storage transaction that rolls back
617	/// all of its emitted storage changes.
618	fn execute<E: Ext<T = T>>(
619		self,
620		ext: &mut E,
621		function: ExportedFunction,
622		input_data: Vec<u8>,
623	) -> ExecResult;
624
625	/// The code info of the executable.
626	fn code_info(&self) -> &CodeInfo<T>;
627
628	/// The raw code of the executable.
629	fn code(&self) -> &[u8];
630
631	/// The code hash of the executable.
632	fn code_hash(&self) -> &H256;
633}
634
635/// The complete call stack of a contract execution.
636///
637/// The call stack is initiated by either a signed origin or one of the contract RPC calls.
638/// This type implements `Ext` and by that exposes the business logic of contract execution to
639/// the runtime module which interfaces with the contract (the vm contract blob) itself.
640pub struct Stack<'a, T: Config, E> {
641	/// The origin that initiated the call stack. It could either be a Signed plain account that
642	/// holds an account id or Root.
643	///
644	/// # Note
645	///
646	/// Please note that it is possible that the id of a Signed origin belongs to a contract rather
647	/// than a plain account when being called through one of the contract RPCs where the
648	/// client can freely choose the origin. This usually makes no sense but is still possible.
649	origin: Origin<T>,
650	/// The resource meter that tracks all resource usage before the first frame starts.
651	transaction_meter: &'a mut TransactionMeter<T>,
652	/// The timestamp at the point of call stack instantiation.
653	timestamp: MomentOf<T>,
654	/// The block number at the time of call stack instantiation.
655	block_number: BlockNumberFor<T>,
656	/// The actual call stack. One entry per nested contract called/instantiated.
657	/// This does **not** include the [`Self::first_frame`].
658	frames: BoundedVec<Frame<T>, ConstU32<{ limits::CALL_STACK_DEPTH }>>,
659	/// Statically guarantee that each call stack has at least one frame.
660	first_frame: Frame<T>,
661	/// Transient storage used to store data, which is kept for the duration of a transaction.
662	transient_storage: TransientStorage<T>,
663	/// Per-transaction cold/hot access list for storage slots (EIP-2929 style).
664	access_list: AccessList,
665	/// Global behavior determined by the creater of this stack.
666	exec_config: &'a ExecConfig<T>,
667	/// No executable is held by the struct but influences its behaviour.
668	_phantom: PhantomData<E>,
669}
670
671/// Represents one entry in the call stack.
672///
673/// For each nested contract call or instantiate one frame is created. It holds specific
674/// information for the said call and caches the in-storage `ContractInfo` data structure.
675struct Frame<T: Config> {
676	/// The address of the executing contract.
677	account_id: T::AccountId,
678	/// The cached in-storage data of the contract.
679	contract_info: CachedContract<T>,
680	/// The EVM balance transferred by the caller as part of the call.
681	value_transferred: U256,
682	/// Determines whether this is a call or instantiate frame.
683	entry_point: ExportedFunction,
684	/// The resource meter that tracks all resource usage of this frame.
685	frame_meter: FrameMeter<T>,
686	/// If `false` the contract enabled its defense against reentrance attacks.
687	allows_reentry: bool,
688	/// If `true` subsequent calls cannot modify storage.
689	read_only: bool,
690	/// The delegate call info of the currently executing frame which was spawned by
691	/// `delegate_call`.
692	delegate: Option<DelegateInfo<T>>,
693	/// The address where the code (and immutable data) originates from.
694	///
695	/// For regular contracts, this equals the contract's own address.
696	/// For delegated accounts (EIP-7702), this is the delegation target's address.
697	/// For explicit delegate_call, this is the callee's address.
698	code_address: H160,
699	/// The output of the last executed call frame.
700	last_frame_output: ExecReturnValue,
701	/// The set of contracts that were created during this call stack.
702	contracts_created: BTreeSet<T::AccountId>,
703	/// The set of contracts that are registered for destruction at the end of this call stack.
704	contracts_to_be_destroyed: BTreeMap<T::AccountId, TerminateArgs<T>>,
705}
706
707/// This structure is used to represent the arguments in a delegate call frame in order to
708/// distinguish who delegated the call and where it was delegated to.
709#[derive(Clone, DebugNoBound)]
710pub struct DelegateInfo<T: Config> {
711	/// The caller of the contract.
712	pub caller: Origin<T>,
713	/// The address of the contract the call was delegated to.
714	pub callee: H160,
715}
716
717/// When calling an address it can either lead to execution of contract code or a pre-compile.
718enum ExecutableOrPrecompile<T: Config, E: Executable<T>, Env> {
719	/// Contract code.
720	Executable(E),
721	/// Code inside the runtime (so called pre-compile).
722	Precompile { instance: PrecompileInstance<Env>, _phantom: PhantomData<T> },
723}
724
725impl<T: Config, E: Executable<T>, Env> ExecutableOrPrecompile<T, E, Env> {
726	fn as_executable(&self) -> Option<&E> {
727		if let Self::Executable(executable) = self { Some(executable) } else { None }
728	}
729
730	fn is_pvm(&self) -> bool {
731		match self {
732			Self::Executable(e) => e.code_info().is_pvm(),
733			_ => false,
734		}
735	}
736
737	fn as_precompile(&self) -> Option<&PrecompileInstance<Env>> {
738		if let Self::Precompile { instance, .. } = self { Some(instance) } else { None }
739	}
740
741	#[cfg(any(feature = "runtime-benchmarks", test))]
742	fn into_executable(self) -> Option<E> {
743		if let Self::Executable(executable) = self { Some(executable) } else { None }
744	}
745}
746
747/// Parameter passed in when creating a new `Frame`.
748///
749/// It determines whether the new frame is for a call or an instantiate.
750enum FrameArgs<'a, T: Config, E> {
751	Call {
752		/// The account id of the contract that is to be called.
753		dest: T::AccountId,
754		/// If `None` the contract info needs to be reloaded from storage.
755		cached_info: Option<ContractInfo<T>>,
756		/// This frame was created by `seal_delegate_call` and hence uses different code than
757		/// what is stored at [`Self::Call::dest`]. Its caller ([`DelegatedCall::caller`]) is the
758		/// account which called the caller contract
759		delegated_call: Option<DelegateInfo<T>>,
760	},
761	Instantiate {
762		/// The contract or signed origin which instantiates the new contract.
763		sender: T::AccountId,
764		/// The executable whose `deploy` function is run.
765		executable: E,
766		/// A salt used in the contract address derivation of the new contract.
767		salt: Option<&'a [u8; 32]>,
768		/// The input data is used in the contract address derivation of the new contract.
769		input_data: &'a [u8],
770	},
771}
772
773/// Describes the different states of a contract as contained in a `Frame`.
774enum CachedContract<T: Config> {
775	/// The cached contract is up to date with the in-storage value.
776	Cached(ContractInfo<T>),
777	/// A recursive call into the same contract did write to the contract info.
778	///
779	/// In this case the cached contract is stale and needs to be reloaded from storage.
780	Invalidated,
781	/// The frame is associated with pre-compile that has no contract info.
782	None,
783}
784
785impl<T: Config> Frame<T> {
786	/// Return the `contract_info` of the current contract.
787	fn contract_info(&mut self) -> &mut ContractInfo<T> {
788		self.contract_info.get(&self.account_id)
789	}
790}
791
792/// Extract the contract info after loading it from storage.
793///
794/// This assumes that `load` was executed before calling this macro.
795macro_rules! get_cached_or_panic_after_load {
796	($c:expr) => {{
797		if let CachedContract::Cached(contract) = $c {
798			contract
799		} else {
800			panic!(
801				"It is impossible to remove a contract that is on the call stack;\
802				See implementations of terminate;\
803				Therefore fetching a contract will never fail while using an account id
804				that is currently active on the call stack;\
805				qed"
806			);
807		}
808	}};
809}
810
811/// Same as [`Stack::top_frame`].
812///
813/// We need this access as a macro because sometimes hiding the lifetimes behind
814/// a function won't work out.
815macro_rules! top_frame {
816	($stack:expr) => {
817		$stack.frames.last().unwrap_or(&$stack.first_frame)
818	};
819}
820
821/// Same as [`Stack::top_frame_mut`].
822///
823/// We need this access as a macro because sometimes hiding the lifetimes behind
824/// a function won't work out.
825macro_rules! top_frame_mut {
826	($stack:expr) => {
827		$stack.frames.last_mut().unwrap_or(&mut $stack.first_frame)
828	};
829}
830
831impl<T: Config> CachedContract<T> {
832	/// Return `Some(ContractInfo)` if the contract is in cached state. `None` otherwise.
833	fn into_contract(self) -> Option<ContractInfo<T>> {
834		if let CachedContract::Cached(contract) = self { Some(contract) } else { None }
835	}
836
837	/// Return `Some(&mut ContractInfo)` if the contract is in cached state. `None` otherwise.
838	fn as_contract(&mut self) -> Option<&mut ContractInfo<T>> {
839		if let CachedContract::Cached(contract) = self { Some(contract) } else { None }
840	}
841
842	/// Load the `contract_info` from storage if necessary.
843	fn load(&mut self, account_id: &T::AccountId) {
844		if let CachedContract::Invalidated = self &&
845			let Some(contract) =
846				AccountInfo::<T>::load_contract(&T::AddressMapper::to_address(account_id))
847		{
848			*self = CachedContract::Cached(contract);
849		}
850	}
851
852	/// Return the cached contract_info.
853	fn get(&mut self, account_id: &T::AccountId) -> &mut ContractInfo<T> {
854		self.load(account_id);
855		get_cached_or_panic_after_load!(self)
856	}
857
858	/// Set the status to invalidate if is cached.
859	fn invalidate(&mut self) {
860		if matches!(self, CachedContract::Cached(_)) {
861			*self = CachedContract::Invalidated;
862		}
863	}
864}
865
866impl<'a, T, E> Stack<'a, T, E>
867where
868	T: Config,
869	E: Executable<T>,
870{
871	/// Create and run a new call stack by calling into `dest`.
872	///
873	/// # Return Value
874	///
875	/// Result<(ExecReturnValue, CodeSize), (ExecError, CodeSize)>
876	pub fn run_call(
877		origin: Origin<T>,
878		dest: H160,
879		transaction_meter: &'a mut TransactionMeter<T>,
880		value: U256,
881		input_data: Vec<u8>,
882		exec_config: &ExecConfig<T>,
883	) -> ExecResult {
884		let dest = T::AddressMapper::to_account_id(&dest);
885		if let Some((mut stack, executable)) = Stack::<'_, T, E>::new(
886			FrameArgs::Call { dest: dest.clone(), cached_info: None, delegated_call: None },
887			origin.clone(),
888			transaction_meter,
889			value,
890			exec_config,
891			&input_data,
892		)? {
893			stack.run(executable, input_data).map(|_| stack.first_frame.last_frame_output)
894		} else {
895			if_tracing(|t| {
896				t.enter_child_span(
897					origin.account_id().map(T::AddressMapper::to_address).unwrap_or_default(),
898					T::AddressMapper::to_address(&dest),
899					None,
900					false,
901					false,
902					value,
903					&input_data,
904					Default::default(),
905				);
906			});
907
908			let result = if let Some(mock_answer) =
909				exec_config.mock_handler.as_ref().and_then(|handler| {
910					handler.mock_call(T::AddressMapper::to_address(&dest), &input_data, value)
911				}) {
912				Ok(mock_answer)
913			} else {
914				Self::transfer_from_origin(
915					&origin,
916					&origin,
917					&dest,
918					value,
919					transaction_meter,
920					exec_config,
921				)
922			};
923
924			if_tracing(|t| {
925				let gas_used =
926					transaction_meter.total_consumed_gas().try_into().unwrap_or(u64::MAX);
927				let weight_consumed = transaction_meter.weight_consumed();
928				match result {
929					Ok(ref output) => t.exit_child_span(&output, gas_used, weight_consumed),
930					Err(e) => {
931						t.exit_child_span_with_error(e.error.into(), gas_used, weight_consumed)
932					},
933				}
934			});
935
936			log::trace!(target: LOG_TARGET, "call finished with: {result:?}");
937
938			result
939		}
940	}
941
942	/// Create and run a new call stack by instantiating a new contract.
943	///
944	/// # Return Value
945	///
946	/// Result<(NewContractAccountId, ExecReturnValue), ExecError)>
947	pub fn run_instantiate(
948		origin: T::AccountId,
949		executable: E,
950		transaction_meter: &'a mut TransactionMeter<T>,
951		value: U256,
952		input_data: Vec<u8>,
953		salt: Option<&[u8; 32]>,
954		exec_config: &ExecConfig<T>,
955	) -> Result<(H160, ExecReturnValue), ExecError> {
956		let deployer = T::AddressMapper::to_address(&origin);
957		let (mut stack, executable) = Stack::<'_, T, E>::new(
958			FrameArgs::Instantiate {
959				sender: origin.clone(),
960				executable,
961				salt,
962				input_data: input_data.as_ref(),
963			},
964			Origin::from_account_id(origin),
965			transaction_meter,
966			value,
967			exec_config,
968			&input_data,
969		)?
970		.expect(FRAME_ALWAYS_EXISTS_ON_INSTANTIATE);
971		let address = T::AddressMapper::to_address(&stack.top_frame().account_id);
972		let result = stack
973			.run(executable, input_data)
974			.map(|_| (address, stack.first_frame.last_frame_output));
975		if let Ok((contract, output)) = &result &&
976			!output.did_revert()
977		{
978			Contracts::<T>::deposit_event(Event::Instantiated { deployer, contract: *contract });
979		}
980		log::trace!(target: LOG_TARGET, "instantiate finished with: {result:?}");
981		result
982	}
983
984	#[cfg(any(feature = "runtime-benchmarks", test))]
985	pub fn bench_new_call(
986		dest: H160,
987		origin: Origin<T>,
988		transaction_meter: &'a mut TransactionMeter<T>,
989		value: BalanceOf<T>,
990		exec_config: &'a ExecConfig<T>,
991		read_only: bool,
992		delegate_call: bool,
993	) -> (Self, E) {
994		let call = Self::new(
995			FrameArgs::Call {
996				dest: T::AddressMapper::to_account_id(&dest),
997				cached_info: None,
998				delegated_call: None,
999			},
1000			origin,
1001			transaction_meter,
1002			value.into(),
1003			exec_config,
1004			&Default::default(),
1005		)
1006		.unwrap()
1007		.unwrap();
1008		let mut stack = call.0;
1009		if read_only {
1010			stack.top_frame_mut().read_only = true;
1011		}
1012		if delegate_call {
1013			let frame = stack.top_frame_mut();
1014			frame.delegate = Some(DelegateInfo {
1015				caller: Origin::from_account_id(frame.account_id.clone()),
1016				callee: H160::zero(),
1017			});
1018		}
1019		(stack, call.1.into_executable().unwrap())
1020	}
1021
1022	/// Create a new call stack.
1023	///
1024	/// Returns `None` when calling a non existent contract. This is not an error case
1025	/// since this will result in a value transfer.
1026	fn new(
1027		args: FrameArgs<T, E>,
1028		origin: Origin<T>,
1029		transaction_meter: &'a mut TransactionMeter<T>,
1030		value: U256,
1031		exec_config: &'a ExecConfig<T>,
1032		input_data: &Vec<u8>,
1033	) -> Result<Option<(Self, ExecutableOrPrecompile<T, E, Self>)>, ExecError> {
1034		origin.ensure_mapped()?;
1035		let Some((first_frame, executable)) = Self::new_frame(
1036			args,
1037			value,
1038			transaction_meter,
1039			&CallResources::NoLimits,
1040			false,
1041			true,
1042			input_data,
1043			exec_config,
1044		)?
1045		else {
1046			return Ok(None);
1047		};
1048
1049		let mut timestamp = T::Time::now();
1050		let mut block_number = <frame_system::Pallet<T>>::block_number();
1051		// if dry run with timestamp override is provided we simulate the run in a `pending` block
1052		if let Some(timestamp_override) =
1053			exec_config.is_dry_run.as_ref().and_then(|cfg| cfg.timestamp_override)
1054		{
1055			block_number = block_number.saturating_add(1u32.into());
1056			// Delta is in milliseconds; increment timestamp by one second
1057			let delta = 1000u32.into();
1058			timestamp = cmp::max(timestamp.saturating_add(delta), timestamp_override);
1059		}
1060
1061		let stack = Self {
1062			origin,
1063			transaction_meter,
1064			timestamp,
1065			block_number,
1066			first_frame,
1067			frames: Default::default(),
1068			transient_storage: TransientStorage::new(limits::TRANSIENT_STORAGE_BYTES),
1069			access_list: AccessList::new(),
1070			exec_config,
1071			_phantom: Default::default(),
1072		};
1073		Ok(Some((stack, executable)))
1074	}
1075
1076	/// EIP-7702 chained delegation check for an account with no loadable code.
1077	///
1078	/// A chained delegation always surfaces with an empty snapshot: `set_delegation` only
1079	/// snapshots a `code_hash` when the target is a deployed contract, and a contract can
1080	/// never become delegated. So when `load_contract_with_delegation` returns no contract
1081	/// info but a delegation target, one read of the target decides: if the target is itself
1082	/// delegated, the spec resolves one hop, retrieves the target's indicator bytes
1083	/// `0xef0100 || ..`, and traps on the leading `0xef` invalid opcode. Otherwise the
1084	/// resolved code is genuinely empty and the call falls through to the transfer path.
1085	fn fail_if_chained_delegation(target: Option<H160>) -> Result<(), ExecError> {
1086		if let Some(target) = target &&
1087			AccountInfo::<T>::is_delegated(&target)
1088		{
1089			return Err(ExecError {
1090				error: <Error<T>>::ContractTrapped.into(),
1091				origin: ErrorOrigin::Callee,
1092			});
1093		}
1094		Ok(())
1095	}
1096
1097	/// Construct a new frame.
1098	///
1099	/// This does not take `self` because when constructing the first frame `self` is
1100	/// not initialized, yet.
1101	fn new_frame<S: State>(
1102		frame_args: FrameArgs<T, E>,
1103		value_transferred: U256,
1104		meter: &mut ResourceMeter<T, S>,
1105		call_resources: &CallResources<T>,
1106		read_only: bool,
1107		origin_is_caller: bool,
1108		input_data: &[u8],
1109		exec_config: &ExecConfig<T>,
1110	) -> Result<Option<(Frame<T>, ExecutableOrPrecompile<T, E, Self>)>, ExecError> {
1111		// `Some` once the account entry has been read: the delegation target it carried, so
1112		// `code_address` below does not decode the same entry a second time.
1113		let mut read_delegation: Option<Option<H160>> = None;
1114		// `Some` when this is a delegate call whose callee is an EIP-7702 delegated EOA: the
1115		// callee's delegation target, which is where the executed code (and therefore its
1116		// immutable data) lives.
1117		let mut delegate_code_target: Option<H160> = None;
1118
1119		let (account_id, contract_info, executable, delegate, entry_point) = match frame_args {
1120			FrameArgs::Call { dest, cached_info, delegated_call } => {
1121				let address = T::AddressMapper::to_address(&dest);
1122				let precompile = <AllPrecompiles<T>>::get(address.as_fixed_bytes());
1123
1124				// which contract info to load is unaffected by the fact if this
1125				// is a delegate call or not
1126				let mut contract = match (cached_info, &precompile) {
1127					(Some(info), _) => CachedContract::Cached(info),
1128					(None, None) => {
1129						let (info, target) =
1130							AccountInfo::<T>::load_contract_with_delegation(&address);
1131						read_delegation = Some(target);
1132						if let Some(info) = info {
1133							CachedContract::Cached(info)
1134						} else {
1135							Self::fail_if_chained_delegation(target)?;
1136							return Ok(None);
1137						}
1138					},
1139					(None, Some(precompile)) if precompile.has_contract_info() => {
1140						log::trace!(target: LOG_TARGET, "found precompile for address {address:?}");
1141						let (info, target) =
1142							AccountInfo::<T>::load_contract_with_delegation(&address);
1143						read_delegation = Some(target);
1144						if let Some(info) = info {
1145							CachedContract::Cached(info)
1146						} else {
1147							let info = ContractInfo::new(&address, 0u32.into(), H256::zero())?;
1148							CachedContract::Cached(info)
1149						}
1150					},
1151					// A precompile address can never be delegated: skip the `code_address`
1152					// delegation lookup below.
1153					(None, Some(_)) => {
1154						read_delegation = Some(None);
1155						CachedContract::None
1156					},
1157				};
1158
1159				let delegated_call = delegated_call.or_else(|| {
1160					exec_config.mock_handler.as_ref().and_then(|mock_handler| {
1161						mock_handler.mock_delegated_caller(address, input_data)
1162					})
1163				});
1164				// in case of delegate the executable is not the one at `address`
1165				let executable = if let Some(delegated_call) = &delegated_call {
1166					if let Some(precompile) =
1167						<AllPrecompiles<T>>::get(delegated_call.callee.as_fixed_bytes())
1168					{
1169						ExecutableOrPrecompile::Precompile {
1170							instance: precompile,
1171							_phantom: Default::default(),
1172						}
1173					} else {
1174						let (info, target) =
1175							AccountInfo::<T>::load_contract_with_delegation(&delegated_call.callee);
1176						let Some(info) = info else {
1177							Self::fail_if_chained_delegation(target)?;
1178							return Ok(None);
1179						};
1180						delegate_code_target = target;
1181						let executable = E::from_storage(info.code_hash, meter)?;
1182						ExecutableOrPrecompile::Executable(executable)
1183					}
1184				} else {
1185					if let Some(precompile) = precompile {
1186						ExecutableOrPrecompile::Precompile {
1187							instance: precompile,
1188							_phantom: Default::default(),
1189						}
1190					} else {
1191						let executable = E::from_storage(
1192							contract
1193								.as_contract()
1194								.expect("When not a precompile the contract was loaded above; qed")
1195								.code_hash,
1196							meter,
1197						)?;
1198						ExecutableOrPrecompile::Executable(executable)
1199					}
1200				};
1201
1202				(dest, contract, executable, delegated_call, ExportedFunction::Call)
1203			},
1204			FrameArgs::Instantiate { sender, executable, salt, input_data } => {
1205				let deployer = T::AddressMapper::to_address(&sender);
1206				let account_nonce = <System<T>>::account_nonce(&sender);
1207				let address = if let Some(salt) = salt {
1208					address::create2(&deployer, executable.code(), input_data, salt)
1209				} else {
1210					use sp_runtime::Saturating;
1211					address::create1(
1212						&deployer,
1213						// the Nonce from the origin has been incremented pre-dispatch, so we
1214						// need to subtract 1 to get the nonce at the time of the call.
1215						if origin_is_caller {
1216							account_nonce.saturating_sub(1u32.into()).saturated_into()
1217						} else {
1218							account_nonce.saturated_into()
1219						},
1220					)
1221				};
1222				let contract = ContractInfo::new(
1223					&address,
1224					<System<T>>::account_nonce(&sender),
1225					*executable.code_hash(),
1226				)?;
1227				(
1228					T::AddressMapper::to_fallback_account_id(&address),
1229					CachedContract::Cached(contract),
1230					ExecutableOrPrecompile::Executable(executable),
1231					None,
1232					ExportedFunction::Constructor,
1233				)
1234			},
1235		};
1236
1237		// Compute the code_address: the address where the code (and immutable data) comes from.
1238		// For delegate_call this is the callee — or the callee's delegation target when the
1239		// callee is itself a delegated EOA. For a call to an EIP-7702 delegated account it's
1240		// the delegation target, otherwise it's the account's own address.
1241		let address = T::AddressMapper::to_address(&account_id);
1242		let code_address = delegate
1243			.as_ref()
1244			.map(|d| delegate_code_target.unwrap_or(d.callee))
1245			.or_else(|| {
1246				// Constructors can't be delegated, skip the storage read.
1247				if entry_point == ExportedFunction::Constructor {
1248					return None;
1249				}
1250				read_delegation.unwrap_or_else(|| AccountInfo::<T>::get_delegation_target(&address))
1251			})
1252			.unwrap_or(address);
1253
1254		let frame = Frame {
1255			delegate,
1256			value_transferred,
1257			contract_info,
1258			account_id,
1259			entry_point,
1260			code_address,
1261			frame_meter: meter.new_nested(call_resources)?,
1262			allows_reentry: true,
1263			read_only,
1264			last_frame_output: Default::default(),
1265			contracts_created: Default::default(),
1266			contracts_to_be_destroyed: Default::default(),
1267		};
1268
1269		Ok(Some((frame, executable)))
1270	}
1271
1272	/// Create a subsequent nested frame.
1273	fn push_frame(
1274		&mut self,
1275		frame_args: FrameArgs<T, E>,
1276		value_transferred: U256,
1277		call_resources: &CallResources<T>,
1278		read_only: bool,
1279		input_data: &[u8],
1280	) -> Result<Option<ExecutableOrPrecompile<T, E, Self>>, ExecError> {
1281		if self.frames.len() as u32 == limits::CALL_STACK_DEPTH {
1282			return Err(Error::<T>::MaxCallDepthReached.into());
1283		}
1284
1285		// We need to make sure that changes made to the contract info are not discarded.
1286		// See the `in_memory_changes_not_discarded` test for more information.
1287		// We do not store on instantiate because we do not allow to call into a contract
1288		// from its own constructor.
1289		//
1290		// Additionally, we need to apply pending storage changes to the ContractInfo before
1291		// saving it, so that child frames can correctly calculate storage deposit refunds.
1292		// See: <https://github.com/paritytech/contract-issues/issues/213>
1293		let frame = self.top_frame();
1294		if let (CachedContract::Cached(contract), ExportedFunction::Call) =
1295			(&frame.contract_info, frame.entry_point)
1296		{
1297			let mut contract_with_pending_changes = contract.clone();
1298			frame
1299				.frame_meter
1300				.apply_pending_storage_changes(&mut contract_with_pending_changes);
1301			AccountInfo::<T>::insert_contract(
1302				&T::AddressMapper::to_address(&frame.account_id),
1303				contract_with_pending_changes,
1304			);
1305		}
1306
1307		let frame = top_frame_mut!(self);
1308		let meter = &mut frame.frame_meter;
1309		if let Some((frame, executable)) = Self::new_frame(
1310			frame_args,
1311			value_transferred,
1312			meter,
1313			call_resources,
1314			read_only,
1315			false,
1316			input_data,
1317			self.exec_config,
1318		)? {
1319			// EIP-684: an in-construction address is not in `AccountInfoOf` yet, so the
1320			// `is_contract` guard in `ContractInfo::new` misses this re-entrant collision.
1321			if frame.entry_point == ExportedFunction::Constructor &&
1322				self.frames().any(|f| {
1323					f.entry_point == ExportedFunction::Constructor &&
1324						f.account_id == frame.account_id
1325				}) {
1326				return Err(Error::<T>::DuplicateContract.into());
1327			}
1328			self.frames.try_push(frame).map_err(|_| Error::<T>::MaxCallDepthReached)?;
1329			Ok(Some(executable))
1330		} else {
1331			Ok(None)
1332		}
1333	}
1334
1335	/// Run the current (top) frame.
1336	///
1337	/// This can be either a call or an instantiate.
1338	fn run(
1339		&mut self,
1340		executable: ExecutableOrPrecompile<T, E, Self>,
1341		input_data: Vec<u8>,
1342	) -> Result<(), ExecError> {
1343		let frame = self.top_frame();
1344		let entry_point = frame.entry_point;
1345		let is_pvm = executable.is_pvm();
1346
1347		if_tracing(|tracer| {
1348			// For DELEGATECALL, `from` is the contract making the delegatecall and
1349			// `to` is the target contract whose code is being executed.
1350			let (from, to) = match frame.delegate.as_ref() {
1351				Some(delegate) => {
1352					(T::AddressMapper::to_address(&frame.account_id), delegate.callee)
1353				},
1354				None => (
1355					self.caller()
1356						.account_id()
1357						.map(T::AddressMapper::to_address)
1358						.unwrap_or_default(),
1359					T::AddressMapper::to_address(&frame.account_id),
1360				),
1361			};
1362			tracer.enter_child_span(
1363				from,
1364				to,
1365				(frame.code_address != to).then_some(frame.code_address),
1366				frame.delegate.is_some(),
1367				frame.read_only,
1368				frame.value_transferred,
1369				&input_data,
1370				frame
1371					.frame_meter
1372					.eth_gas_left()
1373					.unwrap_or_default()
1374					.try_into()
1375					.unwrap_or_default(),
1376			);
1377		});
1378		let mock_answer = self.exec_config.mock_handler.as_ref().and_then(|handler| {
1379			handler.mock_call(
1380				frame
1381					.delegate
1382					.as_ref()
1383					.map(|delegate| delegate.callee)
1384					.unwrap_or(T::AddressMapper::to_address(&frame.account_id)),
1385				&input_data,
1386				frame.value_transferred,
1387			)
1388		});
1389		// The output of the caller frame will be replaced by the output of this run.
1390		// It is also not accessible from nested frames.
1391		// Hence we drop it early to save the memory.
1392		let frames_len = self.frames.len();
1393		if let Some(caller_frame) = match frames_len {
1394			0 => None,
1395			1 => Some(&mut self.first_frame.last_frame_output),
1396			_ => self.frames.get_mut(frames_len - 2).map(|frame| &mut frame.last_frame_output),
1397		} {
1398			*caller_frame = Default::default();
1399		}
1400
1401		self.with_transient_storage_mut(|transient_storage| {
1402			transient_storage.start_transaction();
1403		});
1404		let is_first_frame = self.frames.is_empty();
1405		let access_list_checkpoints_len = self.access_list.frame_depth();
1406		// Open an access-list frame for nested CALL/CREATE. The first frame
1407		// is skipped; its touches land in the bare journal and persist
1408		// for the whole transaction.
1409		if !is_first_frame {
1410			self.access_list.enter_frame();
1411		}
1412
1413		let do_transaction = || -> ExecResult {
1414			let caller = self.caller();
1415			let bump_nonce = self.exec_config.bump_nonce;
1416			let frame = top_frame_mut!(self);
1417			let account_id = &frame.account_id.clone();
1418
1419			if u32::try_from(input_data.len())
1420				.map(|len| len > limits::CALLDATA_BYTES)
1421				.unwrap_or(true)
1422			{
1423				Err(<Error<T>>::CallDataTooLarge)?;
1424			}
1425
1426			// We need to make sure that the contract's account exists before calling its
1427			// constructor.
1428			if entry_point == ExportedFunction::Constructor {
1429				if !frame_system::Pallet::<T>::account_exists(&account_id) {
1430					T::Deposit::init_contract(account_id)?;
1431				}
1432
1433				// A consumer is added at account creation and removed it on termination, otherwise
1434				// the runtime could remove the account. As long as a contract exists its
1435				// account must exist. With the consumer, a correct runtime cannot remove the
1436				// account.
1437				<System<T>>::inc_consumers(account_id)?;
1438
1439				// Contracts nonce starts at 1
1440				<System<T>>::inc_account_nonce(account_id);
1441
1442				if bump_nonce || !is_first_frame {
1443					// Needs to be incremented before calling into the code so that it is visible
1444					// in case of recursion.
1445					<System<T>>::inc_account_nonce(caller.account_id()?);
1446				}
1447				// The incremented refcount should be visible to the constructor.
1448				if is_pvm {
1449					<CodeInfo<T>>::increment_refcount(
1450						*executable
1451							.as_executable()
1452							.expect("Precompiles cannot be instantiated; qed")
1453							.code_hash(),
1454					)?;
1455				}
1456			}
1457
1458			// Every non delegate call or instantiate also optionally transfers the balance.
1459			// If it is a delegate call, then we've already transferred tokens in the
1460			// last non-delegate frame.
1461			if frame.delegate.is_none() {
1462				Self::transfer_from_origin(
1463					&self.origin,
1464					&caller,
1465					account_id,
1466					frame.value_transferred,
1467					&mut frame.frame_meter,
1468					self.exec_config,
1469				)?;
1470			}
1471
1472			// We need to make sure that the pre-compiles contract exist before executing it.
1473			// A few more conditionals:
1474			// 	- Only contracts with extended API (has_contract_info) are guaranteed to have an
1475			//    account.
1476			//  - Only when not delegate calling we are executing in the context of the pre-compile.
1477			//    Pre-compiles itself cannot delegate call.
1478			if let Some(precompile) = executable.as_precompile() &&
1479				precompile.has_contract_info() &&
1480				frame.delegate.is_none() &&
1481				!<System<T>>::account_exists(account_id)
1482			{
1483				// prefix matching pre-compiles cannot have a contract info
1484				// hence we only mint once per pre-compile
1485				T::Currency::mint_into(account_id, T::Currency::minimum_balance())?;
1486				// make sure the pre-compile does not destroy its account by accident
1487				<System<T>>::inc_consumers(account_id)?;
1488			}
1489
1490			let mut code_deposit = executable
1491				.as_executable()
1492				.map(|exec| exec.code_info().deposit())
1493				.unwrap_or_default();
1494
1495			let mut output = match executable {
1496				ExecutableOrPrecompile::Executable(executable) => {
1497					executable.execute(self, entry_point, input_data)
1498				},
1499				ExecutableOrPrecompile::Precompile { instance, .. } => {
1500					instance.call(input_data, self)
1501				},
1502			}
1503			.and_then(|output| {
1504				if u32::try_from(output.data.len())
1505					.map(|len| len > limits::CALLDATA_BYTES)
1506					.unwrap_or(true)
1507				{
1508					Err(<Error<T>>::ReturnDataTooLarge)?;
1509				}
1510				Ok(output)
1511			})
1512			.map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?;
1513
1514			// Avoid useless work that would be reverted anyways.
1515			if output.did_revert() {
1516				return Ok(output);
1517			}
1518
1519			// The deposit we charge for a contract depends on the size of the immutable data.
1520			// Hence we need to delay charging the base deposit after execution.
1521			let frame = if entry_point == ExportedFunction::Constructor {
1522				let frame = top_frame_mut!(self);
1523				// if we are dealing with EVM bytecode
1524				// We upload the new runtime code, and update the code
1525				if !is_pvm {
1526					// Only keep return data for tracing and for dry runs.
1527					// When a dry-run simulates contract deployment, keep the execution result's
1528					// data.
1529					let data = if crate::tracing::if_tracing(|_| {}).is_none() &&
1530						self.exec_config.is_dry_run.is_none()
1531					{
1532						core::mem::replace(&mut output.data, Default::default())
1533					} else {
1534						output.data.clone()
1535					};
1536
1537					// Under Root there is no origin account to attribute the upload
1538					// deposit to: use the pallet's own account as a sentinel owner
1539					// with zero deposit so charge/refund are no-ops.
1540					let mut module = match &self.origin {
1541						Origin::Signed(o) => {
1542							crate::ContractBlob::<T>::from_evm_runtime_code(data, o.clone())?
1543						},
1544						Origin::Root => {
1545							crate::ContractBlob::<T>::from_evm_runtime_code_with_deposit(
1546								data,
1547								crate::Pallet::<T>::account_id(),
1548								Zero::zero(),
1549							)?
1550						},
1551					};
1552					module.store_code(&self.exec_config, &mut frame.frame_meter)?;
1553					code_deposit = module.code_info().deposit();
1554
1555					let contract_info = frame.contract_info();
1556					contract_info.code_hash = *module.code_hash();
1557					<CodeInfo<T>>::increment_refcount(contract_info.code_hash)?;
1558				}
1559
1560				let deposit = frame.contract_info().update_base_deposit(code_deposit);
1561				frame.frame_meter.charge_contract_deposit_and_transfer(
1562					frame.account_id.clone(),
1563					StorageDeposit::Charge(deposit),
1564				)?;
1565				frame
1566			} else {
1567				self.top_frame_mut()
1568			};
1569
1570			// The storage deposit is only charged at the end of every call stack.
1571			// To make sure that no sub call uses more than it is allowed to,
1572			// the limit is manually enforced here.
1573			let contract = frame.contract_info.as_contract();
1574			frame
1575				.frame_meter
1576				.finalize(contract)
1577				.map_err(|e| ExecError { error: e, origin: ErrorOrigin::Callee })?;
1578
1579			Ok(output)
1580		};
1581
1582		// All changes performed by the contract are executed under a storage transaction.
1583		// This allows for roll back on error. Changes to the cached contract_info are
1584		// committed or rolled back when popping the frame.
1585		//
1586		// `with_transactional` may return an error caused by a limit in the
1587		// transactional storage depth.
1588		let transaction_outcome =
1589			with_transaction(|| -> TransactionOutcome<Result<_, DispatchError>> {
1590				let output = if let Some(mock_answer) = mock_answer {
1591					Ok(mock_answer)
1592				} else {
1593					do_transaction()
1594				};
1595				match &output {
1596					Ok(result) if !result.did_revert() => {
1597						TransactionOutcome::Commit(Ok((true, output)))
1598					},
1599					_ => TransactionOutcome::Rollback(Ok((false, output))),
1600				}
1601			});
1602
1603		let (success, output) = match transaction_outcome {
1604			// `with_transactional` executed successfully, and we have the expected output.
1605			Ok((success, output)) => {
1606				if_tracing(|tracer| {
1607					let frame_meter = &top_frame!(self).frame_meter;
1608
1609					// we treat the initial frame meter differently to address
1610					// https://github.com/paritytech/polkadot-sdk/issues/8362
1611					let gas_consumed = if is_first_frame {
1612						frame_meter.total_consumed_gas()
1613					} else {
1614						frame_meter.eth_gas_consumed()
1615					};
1616
1617					let gas_consumed: u64 = gas_consumed.try_into().unwrap_or(u64::MAX);
1618					let weight_consumed = frame_meter.weight_consumed();
1619
1620					match &output {
1621						Ok(output) => {
1622							tracer.exit_child_span(&output, gas_consumed, weight_consumed)
1623						},
1624						Err(e) => tracer.exit_child_span_with_error(
1625							e.error.into(),
1626							gas_consumed,
1627							weight_consumed,
1628						),
1629					}
1630				});
1631
1632				(success, output)
1633			},
1634			// `with_transactional` returned an error, and we propagate that error and note no state
1635			// has changed.
1636			Err(error) => {
1637				if_tracing(|tracer| {
1638					let frame_meter = &top_frame!(self).frame_meter;
1639
1640					// we treat the initial frame meter differently to address
1641					// https://github.com/paritytech/polkadot-sdk/issues/8362
1642					let gas_consumed = if is_first_frame {
1643						frame_meter.total_consumed_gas()
1644					} else {
1645						frame_meter.eth_gas_consumed()
1646					};
1647
1648					let gas_consumed: u64 = gas_consumed.try_into().unwrap_or(u64::MAX);
1649					let weight_consumed = frame_meter.weight_consumed();
1650					tracer.exit_child_span_with_error(error.into(), gas_consumed, weight_consumed);
1651				});
1652
1653				(false, Err(error.into()))
1654			},
1655		};
1656		self.with_transient_storage_mut(|transient_storage| {
1657			if success {
1658				transient_storage.commit_transaction();
1659			} else {
1660				transient_storage.rollback_transaction();
1661			}
1662		});
1663		// For the first frame, only log the final metrics since it doesn't open a
1664		// checkpoint. Nested frames commit or roll back the checkpoint they opened.
1665		if is_first_frame {
1666			let m = self.access_list.metrics();
1667			log::trace!(
1668				target: LOG_TARGET,
1669				"access list metrics: size={size} cold={cold} hot={hot}",
1670				size = m.size, cold = m.cold, hot = m.hot,
1671			);
1672		} else if success {
1673			self.access_list.commit_frame();
1674		} else {
1675			self.access_list.rollback_frame();
1676		}
1677		debug_assert_eq!(
1678			self.access_list.frame_depth(),
1679			access_list_checkpoints_len,
1680			"this frame closed exactly the checkpoint it opened",
1681		);
1682		log::trace!(target: LOG_TARGET, "frame finished with: {output:?}");
1683
1684		self.pop_frame(success);
1685		output.map(|output| {
1686			self.top_frame_mut().last_frame_output = output;
1687		})
1688	}
1689
1690	/// Remove the current (top) frame from the stack.
1691	///
1692	/// This is called after running the current frame. It commits cached values to storage
1693	/// and invalidates all stale references to it that might exist further down the call stack.
1694	fn pop_frame(&mut self, persist: bool) {
1695		/// Bank the pending storage diff into the cached `ContractInfo`, then invalidate.
1696		///
1697		/// The `load` covers the case where an earlier same-contract reentry already
1698		/// invalidated this frame; without it a removal-bearing diff would be banked with
1699		/// no info and silently drop the refund pro-rata. A `None` after `load` means the
1700		/// frame is a precompile with no contract info, which has nothing to bank.
1701		fn bank_pending_changes_and_invalidate<T: Config>(f: &mut Frame<T>) {
1702			let contract = f.account_id.clone();
1703			f.contract_info.load(&f.account_id);
1704			if let Some(info) = f.contract_info.as_contract() {
1705				f.frame_meter.bank_pending_storage_changes(contract, info);
1706			}
1707			// `invalidate` drops the in-memory update `bank` made to `info`; that is safe
1708			// because storage already reflects it. Additions and `set_storage` removals leave
1709			// the frame `Cached` (write reloads the cache), so `push_frame` preview-persists
1710			// them before we get here. The only diff not yet in storage would be a removal on
1711			// an already-invalidated frame — reachable solely via `charge_storage`, which has
1712			// no contract-level caller. If that changes, persist here instead of invalidating.
1713			f.contract_info.invalidate();
1714		}
1715
1716		// Pop the current frame from the stack and return it in case it needs to interact
1717		// with duplicates that might exist on the stack.
1718		// A `None` means that we are returning from the `first_frame`.
1719		let frame = self.frames.pop();
1720
1721		// Both branches do essentially the same with the exception. The difference is that
1722		// the else branch does consume the hardcoded `first_frame`.
1723		if let Some(mut frame) = frame {
1724			let account_id = &frame.account_id;
1725			let prev = top_frame_mut!(self);
1726
1727			// Only weight counter changes are persisted in case of a failure.
1728			if !persist {
1729				prev.frame_meter.absorb_weight_meter_only(frame.frame_meter);
1730				return;
1731			}
1732
1733			// Record the storage meter changes of the nested call into the parent meter.
1734			// If the dropped frame's contract has a contract info we update the deposit
1735			// counter in its contract info. The load is necessary to pull it from storage in case
1736			// it was invalidated.
1737			frame.contract_info.load(account_id);
1738			let mut contract = frame.contract_info.into_contract();
1739			prev.frame_meter
1740				.absorb_all_meters(frame.frame_meter, account_id, contract.as_mut());
1741
1742			// only on success inherit the created and to be destroyed contracts
1743			prev.contracts_created.extend(frame.contracts_created);
1744			prev.contracts_to_be_destroyed.extend(frame.contracts_to_be_destroyed);
1745
1746			if let Some(contract) = contract {
1747				// Persist the info and invalidate the first stale cache we find.
1748				// This triggers a reload from storage on next use. Only the first
1749				// cache needs to be invalidated because that one will invalidate the next cache
1750				// when it is popped from the stack.
1751				AccountInfo::<T>::insert_contract(
1752					&T::AddressMapper::to_address(account_id),
1753					contract,
1754				);
1755				if let Some(f) = self.frames_mut().find(|f| f.account_id == *account_id) {
1756					// Bank before invalidating so finalize doesn't apply the diff a second time.
1757					bank_pending_changes_and_invalidate(f);
1758				}
1759			}
1760		} else {
1761			if !persist {
1762				self.transaction_meter
1763					.absorb_weight_meter_only(mem::take(&mut self.first_frame.frame_meter));
1764				return;
1765			}
1766
1767			let mut contract = self.first_frame.contract_info.as_contract();
1768			self.transaction_meter.absorb_all_meters(
1769				mem::take(&mut self.first_frame.frame_meter),
1770				&self.first_frame.account_id,
1771				contract.as_deref_mut(),
1772			);
1773
1774			if let Some(contract) = contract {
1775				AccountInfo::<T>::insert_contract(
1776					&T::AddressMapper::to_address(&self.first_frame.account_id),
1777					contract.clone(),
1778				);
1779			}
1780			// End of the callstack: destroy scheduled contracts in line with EVM semantics.
1781			let contracts_created = mem::take(&mut self.first_frame.contracts_created);
1782			let contracts_to_destroy = mem::take(&mut self.first_frame.contracts_to_be_destroyed);
1783			for (contract_account, args) in contracts_to_destroy {
1784				if args.only_if_same_tx && !contracts_created.contains(&contract_account) {
1785					continue;
1786				}
1787				Self::do_terminate(
1788					&mut self.transaction_meter,
1789					self.exec_config,
1790					&contract_account,
1791					&self.origin,
1792					&args,
1793				)
1794				.ok();
1795			}
1796		}
1797	}
1798
1799	/// Transfer some funds from `from` to `to`.
1800	///
1801	/// This is a no-op for zero `value`, avoiding events to be emitted for zero balance transfers.
1802	///
1803	/// If the destination account does not exist, it is pulled into existence by transferring the
1804	/// ED from `origin` to the new account. The total amount transferred to `to` will be ED +
1805	/// `value`. This makes the ED fully transparent for contracts.
1806	/// The ED transfer is executed atomically with the actual transfer, avoiding the possibility of
1807	/// the ED transfer succeeding but the actual transfer failing. In other words, if the `to` does
1808	/// not exist, the transfer does fail and nothing will be sent to `to` if either `origin` can
1809	/// not provide the ED or transferring `value` from `from` to `to` fails.
1810	/// Note: This will also fail if `origin` is root.
1811	fn transfer<S: State>(
1812		origin: &Origin<T>,
1813		from: &T::AccountId,
1814		to: &T::AccountId,
1815		value: U256,
1816		preservation: Preservation,
1817		meter: &mut ResourceMeter<T, S>,
1818		exec_config: &ExecConfig<T>,
1819	) -> DispatchResult {
1820		let value = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(value)
1821			.map_err(|_| Error::<T>::BalanceConversionFailed)?;
1822		if value.is_zero() {
1823			return Ok(());
1824		}
1825
1826		if <System<T>>::account_exists(to) {
1827			return transfer_with_dust::<T>(from, to, value, preservation);
1828		}
1829
1830		let origin = origin.account_id()?;
1831		let ed = <T as Config>::Currency::minimum_balance();
1832		let is_eth_tx = exec_config.collect_deposit_from_hold.is_some();
1833		with_transaction(|| -> TransactionOutcome<DispatchResult> {
1834			// Meter the ED deposit only after the transfer succeeds: the meter is not rolled
1835			// back, so metering earlier would count an ED for an account never created.
1836			match Ok::<(), DispatchError>(())
1837				.and_then(|_| {
1838					if is_eth_tx {
1839						let credit = T::FeeInfo::withdraw_txfee(ed)
1840							.ok_or(Error::<T>::StorageDepositNotEnoughFunds)?;
1841						T::Currency::resolve(to, credit)
1842							.map_err(|_| Error::<T>::StorageDepositNotEnoughFunds)?;
1843						Ok(())
1844					} else {
1845						T::Currency::transfer(origin, to, ed, Preservation::Preserve)
1846							.map(|_| ())
1847							.map_err(|_| Error::<T>::StorageDepositNotEnoughFunds.into())
1848					}
1849				})
1850				.and_then(|_| transfer_with_dust::<T>(from, to, value, preservation))
1851				.and_then(|_| meter.charge_deposit(&StorageDeposit::Charge(ed)))
1852			{
1853				Ok(_) => TransactionOutcome::Commit(Ok(())),
1854				Err(err) => TransactionOutcome::Rollback(Err(err)),
1855			}
1856		})
1857	}
1858
1859	/// Same as `transfer` but `from` is an `Origin`.
1860	fn transfer_from_origin<S: State>(
1861		origin: &Origin<T>,
1862		from: &Origin<T>,
1863		to: &T::AccountId,
1864		value: U256,
1865		meter: &mut ResourceMeter<T, S>,
1866		exec_config: &ExecConfig<T>,
1867	) -> ExecResult {
1868		// If the from address is root there is no account to transfer from, and therefore we can't
1869		// take any `value` other than 0.
1870		let from = match from {
1871			Origin::Signed(caller) => caller,
1872			Origin::Root if value.is_zero() => return Ok(Default::default()),
1873			Origin::Root => return Err(DispatchError::RootNotAllowed.into()),
1874		};
1875		Self::transfer(origin, from, to, value, Preservation::Preserve, meter, exec_config)
1876			.map(|_| Default::default())
1877			.map_err(Into::into)
1878	}
1879
1880	/// Performs the actual deletion of a contract at the end of a call stack.
1881	fn do_terminate(
1882		transaction_meter: &mut TransactionMeter<T>,
1883		exec_config: &ExecConfig<T>,
1884		contract_account: &T::AccountId,
1885		origin: &Origin<T>,
1886		args: &TerminateArgs<T>,
1887	) -> Result<(), DispatchError> {
1888		let contract_address = T::AddressMapper::to_address(contract_account);
1889
1890		// If root created this contract we need to use the pallet account_id because root has no
1891		// account.
1892		let origin: Origin<T> = match origin {
1893			Origin::Signed(o) => Origin::Signed(o.clone()),
1894			Origin::Root => Origin::from_account_id(crate::Pallet::<T>::account_id()),
1895		};
1896
1897		let mut delete_contract = |trie_id: &TrieId, code_hash: &H256| {
1898			// deposit needs to be removed as it adds a consumer
1899			let refund =
1900				T::Deposit::refund_all(&contract_account, exec_config.funds(origin.account_id()?))?;
1901
1902			// we added this consumer manually when instantiating
1903			System::<T>::dec_consumers(&contract_account);
1904
1905			// ED was minted when the account was brought into existence; burn it now.
1906			T::Deposit::destroy_contract(contract_account)?;
1907
1908			// this is needed to:
1909			// 1) Send any balance that was send to the contract after termination.
1910			// 2) To fail termination if any locks or holds prevent to completely empty the account.
1911			let balance = <Contracts<T>>::convert_native_to_evm(<AccountInfo<T>>::total_balance(
1912				contract_address.into(),
1913			));
1914			Self::transfer(
1915				&origin,
1916				contract_account,
1917				&args.beneficiary,
1918				balance,
1919				Preservation::Expendable,
1920				transaction_meter,
1921				exec_config,
1922			)?;
1923
1924			// this deletes the code if refcount drops to zero
1925			let _code_removed = <CodeInfo<T>>::decrement_refcount(*code_hash)?;
1926
1927			// delete the contracts data last as its infallible
1928			ContractInfo::<T>::queue_for_deletion(trie_id.clone(), contract_account.clone());
1929			AccountInfoOf::<T>::remove(contract_address);
1930			ImmutableDataOf::<T>::remove(contract_address);
1931
1932			// the meter needs to discard all deposits interacting with the terminated contract
1933			// we do this last as we cannot roll this back
1934			transaction_meter.terminate(contract_account.clone(), refund);
1935
1936			Ok(())
1937		};
1938
1939		// we cannot fail here as the contract that called `SELFDESTRUCT`
1940		// is no longer on the call stack. hence we simply roll back the
1941		// termination so that nothing happened.
1942		with_transaction(|| -> TransactionOutcome<Result<_, DispatchError>> {
1943			match delete_contract(&args.trie_id, &args.code_hash) {
1944				Ok(()) => {
1945					log::trace!(target: LOG_TARGET, "Terminated {contract_address:?}");
1946					TransactionOutcome::Commit(Ok(()))
1947				},
1948				Err(e) => {
1949					log::debug!(target: LOG_TARGET, "Contract at {contract_address:?} failed to terminate: {e:?}");
1950					TransactionOutcome::Rollback(Err(e))
1951				},
1952			}
1953		})
1954	}
1955
1956	/// Reference to the current (top) frame.
1957	fn top_frame(&self) -> &Frame<T> {
1958		top_frame!(self)
1959	}
1960
1961	/// Mutable reference to the current (top) frame.
1962	fn top_frame_mut(&mut self) -> &mut Frame<T> {
1963		top_frame_mut!(self)
1964	}
1965
1966	/// Iterator over all frames.
1967	///
1968	/// The iterator starts with the top frame and ends with the root frame.
1969	fn frames(&self) -> impl Iterator<Item = &Frame<T>> {
1970		core::iter::once(&self.first_frame).chain(&self.frames).rev()
1971	}
1972
1973	/// Same as `frames` but with a mutable reference as iterator item.
1974	fn frames_mut(&mut self) -> impl Iterator<Item = &mut Frame<T>> {
1975		core::iter::once(&mut self.first_frame).chain(&mut self.frames).rev()
1976	}
1977
1978	/// Returns whether the specified contract allows to be reentered right now.
1979	fn allows_reentry(&self, id: &T::AccountId) -> bool {
1980		!self.frames().any(|f| &f.account_id == id && !f.allows_reentry)
1981	}
1982
1983	/// Returns the *free* balance of the supplied AccountId.
1984	fn account_balance(&self, who: &T::AccountId) -> U256 {
1985		let balance = AccountInfo::<T>::balance_of(AccountIdOrAddress::AccountId(who.clone()));
1986		crate::Pallet::<T>::convert_native_to_evm(balance)
1987	}
1988
1989	/// Certain APIs, e.g. `{set,get}_immutable_data` behave differently depending
1990	/// on the configured entry point. Thus, we allow setting the export manually.
1991	#[cfg(feature = "runtime-benchmarks")]
1992	pub(crate) fn override_export(&mut self, export: ExportedFunction) {
1993		self.top_frame_mut().entry_point = export;
1994	}
1995
1996	#[cfg(feature = "runtime-benchmarks")]
1997	pub(crate) fn set_block_number(&mut self, block_number: BlockNumberFor<T>) {
1998		self.block_number = block_number;
1999	}
2000
2001	fn block_hash(&self, block_number: U256) -> Option<H256> {
2002		let Ok(block_number) = BlockNumberFor::<T>::try_from(block_number) else {
2003			return None;
2004		};
2005		if block_number >= self.block_number {
2006			return None;
2007		}
2008		if block_number < self.block_number.saturating_sub(256u32.into()) {
2009			return None;
2010		}
2011
2012		// Fallback to the system block hash for older blocks
2013		// 256 entries should suffice for all use cases, this mostly ensures
2014		// our benchmarks are passing.
2015		match crate::Pallet::<T>::eth_block_hash_from_number(block_number.into()) {
2016			Some(hash) => Some(hash),
2017			None => {
2018				use codec::Decode;
2019				let block_hash = System::<T>::block_hash(&block_number);
2020				Decode::decode(&mut TrailingZeroInput::new(block_hash.as_ref())).ok()
2021			},
2022		}
2023	}
2024
2025	/// Returns true if the current context has contract info.
2026	/// This is the case if `no_precompile || precompile_with_info`.
2027	fn has_contract_info(&self) -> bool {
2028		let address = self.address();
2029		let precompile = <AllPrecompiles<T>>::get::<Stack<'_, T, E>>(address.as_fixed_bytes());
2030		if let Some(precompile) = precompile {
2031			return precompile.has_contract_info();
2032		}
2033		true
2034	}
2035
2036	fn with_transient_storage_mut<R, F: FnOnce(&mut TransientStorage<T>) -> R>(
2037		&mut self,
2038		f: F,
2039	) -> R {
2040		if let Some(transient) = &self.exec_config.test_env_transient_storage {
2041			f(&mut transient.borrow_mut())
2042		} else {
2043			f(&mut self.transient_storage)
2044		}
2045	}
2046	fn with_transient_storage<R, F: FnOnce(&TransientStorage<T>) -> R>(&self, f: F) -> R {
2047		if let Some(transient) = &self.exec_config.test_env_transient_storage {
2048			f(&transient.borrow())
2049		} else {
2050			f(&self.transient_storage)
2051		}
2052	}
2053}
2054
2055impl<'a, T, E> Ext for Stack<'a, T, E>
2056where
2057	T: Config,
2058	E: Executable<T>,
2059{
2060	fn delegate_call(
2061		&mut self,
2062		call_resources: &CallResources<T>,
2063		address: H160,
2064		input_data: Vec<u8>,
2065	) -> Result<(), ExecError> {
2066		// We reset the return data now, so it is cleared out even if no new frame was executed.
2067		// This is for example the case for unknown code hashes or creating the frame fails.
2068		*self.last_frame_output_mut() = Default::default();
2069
2070		let top_frame = self.top_frame_mut();
2071		// Clone the contract info and apply pending storage changes so that
2072		// the child frame can correctly calculate storage deposit refunds.
2073		// See: <https://github.com/paritytech/contract-issues/issues/213>
2074		let mut contract_info = top_frame.contract_info().clone();
2075		top_frame.frame_meter.apply_pending_storage_changes(&mut contract_info);
2076		let account_id = top_frame.account_id.clone();
2077		let value = top_frame.value_transferred;
2078		if let Some(executable) = self.push_frame(
2079			FrameArgs::Call {
2080				dest: account_id,
2081				cached_info: Some(contract_info),
2082				delegated_call: Some(DelegateInfo {
2083					caller: self.caller().clone(),
2084					callee: address,
2085				}),
2086			},
2087			value,
2088			call_resources,
2089			self.is_read_only(),
2090			&input_data,
2091		)? {
2092			self.run(executable, input_data)
2093		} else {
2094			// Delegate-calls to non-contract accounts are considered success.
2095			Ok(())
2096		}
2097	}
2098
2099	fn terminate_if_same_tx(&mut self, beneficiary: &H160) -> Result<CodeRemoved, DispatchError> {
2100		if_tracing(|tracer| {
2101			let addr = T::AddressMapper::to_address(self.account_id());
2102			tracer.terminate(
2103				addr,
2104				*beneficiary,
2105				self.top_frame()
2106					.frame_meter
2107					.eth_gas_left()
2108					.unwrap_or_default()
2109					.try_into()
2110					.unwrap_or_default(),
2111				crate::Pallet::<T>::evm_balance(&addr),
2112			);
2113		});
2114		let frame = top_frame_mut!(self);
2115		let info = frame.contract_info();
2116		let trie_id = info.trie_id.clone();
2117		let code_hash = info.code_hash;
2118		let contract_address = T::AddressMapper::to_address(&frame.account_id);
2119		let beneficiary = T::AddressMapper::to_account_id(beneficiary);
2120
2121		// balance transfer is immediate
2122		Self::transfer(
2123			&self.origin,
2124			&frame.account_id,
2125			&beneficiary,
2126			<Contracts<T>>::evm_balance(&contract_address),
2127			Preservation::Preserve,
2128			&mut frame.frame_meter,
2129			self.exec_config,
2130		)?;
2131
2132		// schedule for delayed deletion
2133		let account_id = frame.account_id.clone();
2134		self.top_frame_mut().contracts_to_be_destroyed.insert(
2135			account_id,
2136			TerminateArgs { beneficiary, trie_id, code_hash, only_if_same_tx: true },
2137		);
2138		Ok(CodeRemoved::Yes)
2139	}
2140
2141	fn own_code_hash(&mut self) -> &H256 {
2142		&self.top_frame_mut().contract_info().code_hash
2143	}
2144
2145	fn immutable_data_len(&mut self) -> u32 {
2146		let frame = self.top_frame_mut();
2147		if frame.code_address == T::AddressMapper::to_address(&frame.account_id) {
2148			frame.contract_info().immutable_data_len()
2149		} else {
2150			limits::IMMUTABLE_BYTES
2151		}
2152	}
2153
2154	fn get_immutable_data(&mut self) -> Result<ImmutableData, DispatchError> {
2155		if self.top_frame().entry_point == ExportedFunction::Constructor {
2156			return Err(Error::<T>::InvalidImmutableAccess.into());
2157		}
2158
2159		// Immutable data is read from the address where the code originates.
2160		// This handles regular contracts, delegated accounts (EIP-7702), and delegate_call.
2161		let address = self.top_frame().code_address;
2162		Ok(<ImmutableDataOf<T>>::get(address).ok_or_else(|| Error::<T>::InvalidImmutableAccess)?)
2163	}
2164
2165	fn set_immutable_data(&mut self, data: ImmutableData) -> Result<(), DispatchError> {
2166		let frame = self.top_frame_mut();
2167		if frame.entry_point == ExportedFunction::Call || data.is_empty() {
2168			return Err(Error::<T>::InvalidImmutableAccess.into());
2169		}
2170		frame.contract_info().set_immutable_data_len(data.len() as u32);
2171		<ImmutableDataOf<T>>::insert(T::AddressMapper::to_address(&frame.account_id), &data);
2172		Ok(())
2173	}
2174}
2175
2176impl<'a, T, E> PrecompileWithInfoExt for Stack<'a, T, E>
2177where
2178	T: Config,
2179	E: Executable<T>,
2180{
2181	fn instantiate(
2182		&mut self,
2183		call_resources: &CallResources<T>,
2184		mut code: Code,
2185		value: U256,
2186		input_data: Vec<u8>,
2187		salt: Option<&[u8; 32]>,
2188	) -> Result<H160, ExecError> {
2189		// We reset the return data now, so it is cleared out even if no new frame was executed.
2190		// This is for example the case when creating the frame fails.
2191		*self.last_frame_output_mut() = Default::default();
2192
2193		let sender = self.top_frame().account_id.clone();
2194		let executable = {
2195			let executable = match &mut code {
2196				Code::Upload(initcode) => {
2197					if !T::AllowEVMBytecode::get() {
2198						return Err(<Error<T>>::CodeRejected.into());
2199					}
2200					ensure!(input_data.is_empty(), <Error<T>>::EvmConstructorNonEmptyData);
2201					let initcode = crate::tracing::if_tracing(|_| initcode.clone())
2202						.unwrap_or_else(|| mem::take(initcode));
2203					E::from_evm_init_code(initcode, sender.clone())?
2204				},
2205				Code::Existing(hash) => {
2206					let executable = E::from_storage(*hash, self.frame_meter_mut())?;
2207					ensure!(executable.code_info().is_pvm(), <Error<T>>::EvmConstructedFromHash);
2208					executable
2209				},
2210			};
2211			self.push_frame(
2212				FrameArgs::Instantiate {
2213					sender,
2214					executable,
2215					salt,
2216					input_data: input_data.as_ref(),
2217				},
2218				value,
2219				call_resources,
2220				self.is_read_only(),
2221				&input_data,
2222			)?
2223		};
2224		let executable = executable.expect(FRAME_ALWAYS_EXISTS_ON_INSTANTIATE);
2225
2226		// Mark the contract as created in this tx.
2227		let account_id = self.top_frame().account_id.clone();
2228		self.top_frame_mut().contracts_created.insert(account_id);
2229
2230		let address = T::AddressMapper::to_address(&self.top_frame().account_id);
2231		if_tracing(|t| t.instantiate_code(&code, salt));
2232		self.run(executable, input_data).map(|_| address)
2233	}
2234}
2235
2236impl<'a, T, E> PrecompileExt for Stack<'a, T, E>
2237where
2238	T: Config,
2239	E: Executable<T>,
2240{
2241	type T = T;
2242
2243	fn call(
2244		&mut self,
2245		call_resources: &CallResources<T>,
2246		dest_addr: &H160,
2247		value: U256,
2248		input_data: Vec<u8>,
2249		allows_reentry: ReentrancyProtection,
2250		read_only: bool,
2251	) -> Result<(), ExecError> {
2252		// We reset the return data now, so it is cleared out even if no new frame was executed.
2253		// This is for example the case for balance transfers or when creating the frame fails.
2254		*self.last_frame_output_mut() = Default::default();
2255
2256		// Before pushing the new frame: Protect the caller contract against reentrancy attacks.
2257		// It is important to do this before calling `allows_reentry` so that a direct recursion
2258		// is caught by it.
2259
2260		if allows_reentry == ReentrancyProtection::Strict {
2261			self.top_frame_mut().allows_reentry = false;
2262		}
2263
2264		let try_call = || {
2265			// Enable read-only access if requested; cannot disable it if already set.
2266			let is_read_only = read_only || self.is_read_only();
2267
2268			// We can skip the stateful lookup for pre-compiles.
2269			let dest = if <AllPrecompiles<T>>::get::<Self>(dest_addr.as_fixed_bytes()).is_some() {
2270				T::AddressMapper::to_fallback_account_id(dest_addr)
2271			} else {
2272				T::AddressMapper::to_account_id(dest_addr)
2273			};
2274
2275			if !self.allows_reentry(&dest) {
2276				return Err(<Error<T>>::ReentranceDenied.into());
2277			}
2278
2279			if allows_reentry == ReentrancyProtection::AllowNext {
2280				self.top_frame_mut().allows_reentry = false;
2281			}
2282
2283			// We ignore instantiate frames in our search for a cached contract.
2284			// Otherwise it would be possible to recursively call a contract from its own
2285			// constructor: We disallow calling not fully constructed contracts.
2286			//
2287			// When cloning the cached contract, we apply pending storage changes so that
2288			// the child frame can correctly calculate storage deposit refunds.
2289			// See: <https://github.com/paritytech/contract-issues/issues/213>
2290			let cached_info = self
2291				.frames()
2292				.find(|f| f.entry_point == ExportedFunction::Call && f.account_id == dest)
2293				.and_then(|f| match &f.contract_info {
2294					CachedContract::Cached(contract) => {
2295						let mut contract_with_pending = contract.clone();
2296						f.frame_meter.apply_pending_storage_changes(&mut contract_with_pending);
2297						Some(contract_with_pending)
2298					},
2299					_ => None,
2300				});
2301
2302			if let Some(executable) = self.push_frame(
2303				FrameArgs::Call { dest: dest.clone(), cached_info, delegated_call: None },
2304				value,
2305				call_resources,
2306				is_read_only,
2307				&input_data,
2308			)? {
2309				self.run(executable, input_data)
2310			} else {
2311				if_tracing(|t| {
2312					t.enter_child_span(
2313						T::AddressMapper::to_address(self.account_id()),
2314						T::AddressMapper::to_address(&dest),
2315						None,
2316						false,
2317						is_read_only,
2318						value,
2319						&input_data,
2320						Default::default(),
2321					);
2322				});
2323
2324				let snapshot = if_tracing(|_| top_frame!(self).frame_meter.snapshot());
2325
2326				let result = if let Some(mock_answer) =
2327					self.exec_config.mock_handler.as_ref().and_then(|handler| {
2328						handler.mock_call(T::AddressMapper::to_address(&dest), &input_data, value)
2329					}) {
2330					*self.last_frame_output_mut() = mock_answer.clone();
2331					Ok(mock_answer)
2332				} else if is_read_only && value.is_zero() {
2333					Ok(Default::default())
2334				} else if is_read_only {
2335					Err(Error::<T>::StateChangeDenied.into())
2336				} else {
2337					let account_id = self.account_id().clone();
2338					let frame = top_frame_mut!(self);
2339					Self::transfer_from_origin(
2340						&self.origin,
2341						&Origin::from_account_id(account_id),
2342						&dest,
2343						value,
2344						&mut frame.frame_meter,
2345						self.exec_config,
2346					)
2347				};
2348
2349				if_tracing(|t| {
2350					let snapshot = snapshot.as_ref().expect(
2351						"snapshot is taken inside if_tracing above; tracing state cannot \
2352						 change mid-call, so it is Some whenever this closure runs; qed",
2353					);
2354					let (gas_used, weight_delta) =
2355						top_frame!(self).frame_meter.delta_since(snapshot);
2356					match result {
2357						Ok(ref output) => t.exit_child_span(&output, gas_used, weight_delta),
2358						Err(e) => {
2359							t.exit_child_span_with_error(e.error.into(), gas_used, weight_delta)
2360						},
2361					}
2362				});
2363
2364				result.map(|_| ())
2365			}
2366		};
2367
2368		// We need to make sure to reset `allows_reentry` even on failure.
2369		let result = try_call();
2370
2371		// Protection is on a per call basis.
2372		self.top_frame_mut().allows_reentry = true;
2373
2374		result
2375	}
2376
2377	fn get_transient_storage(&self, key: &Key) -> Option<Vec<u8>> {
2378		self.with_transient_storage(|transient_storage| {
2379			transient_storage.read(self.account_id(), key)
2380		})
2381	}
2382
2383	fn get_transient_storage_size(&self, key: &Key) -> Option<u32> {
2384		self.with_transient_storage(|transient_storage| {
2385			transient_storage.read(self.account_id(), key).map(|value| value.len() as _)
2386		})
2387	}
2388
2389	fn set_transient_storage(
2390		&mut self,
2391		key: &Key,
2392		value: Option<Vec<u8>>,
2393		take_old: bool,
2394	) -> Result<WriteOutcome, DispatchError> {
2395		let account_id = self.account_id().clone();
2396		self.with_transient_storage_mut(|transient_storage| {
2397			transient_storage.write(&account_id, key, value, take_old)
2398		})
2399	}
2400
2401	fn account_id(&self) -> &T::AccountId {
2402		&self.top_frame().account_id
2403	}
2404
2405	fn caller(&self) -> Origin<T> {
2406		if let Some(Ok(mock_caller)) = self
2407			.exec_config
2408			.mock_handler
2409			.as_ref()
2410			.and_then(|mock_handler| mock_handler.mock_caller(self.frames.len()))
2411			.map(|mock_caller| Origin::<T>::from_runtime_origin(mock_caller))
2412		{
2413			return mock_caller;
2414		}
2415
2416		if let Some(DelegateInfo { caller, .. }) = &self.top_frame().delegate {
2417			caller.clone()
2418		} else {
2419			self.frames()
2420				.nth(1)
2421				.map(|f| Origin::from_account_id(f.account_id.clone()))
2422				.unwrap_or(self.origin.clone())
2423		}
2424	}
2425
2426	fn caller_of_caller(&self) -> Origin<T> {
2427		// fetch top frame of top frame
2428		let caller_of_caller_frame = match self.frames().nth(2) {
2429			None => return self.origin.clone(),
2430			Some(frame) => frame,
2431		};
2432		if let Some(DelegateInfo { caller, .. }) = &caller_of_caller_frame.delegate {
2433			caller.clone()
2434		} else {
2435			Origin::from_account_id(caller_of_caller_frame.account_id.clone())
2436		}
2437	}
2438
2439	fn origin(&self) -> &Origin<T> {
2440		if let Some(mock_origin) = self
2441			.exec_config
2442			.mock_handler
2443			.as_ref()
2444			.and_then(|mock_handler| mock_handler.mock_origin())
2445		{
2446			return mock_origin;
2447		}
2448
2449		&self.origin
2450	}
2451
2452	fn to_account_id(&self, address: &H160) -> T::AccountId {
2453		T::AddressMapper::to_account_id(address)
2454	}
2455
2456	fn code_hash(&self, address: &H160) -> H256 {
2457		if let Some(code) = <AllPrecompiles<T>>::code(address.as_fixed_bytes()).or_else(|| {
2458			self.exec_config
2459				.mock_handler
2460				.as_ref()
2461				.and_then(|handler| handler.mocked_code(*address))
2462		}) {
2463			return sp_io::hashing::keccak_256(code).into();
2464		}
2465
2466		// EIP-7702: delegated EOAs return keccak256(0xef0100 || target). This is the
2467		// EXTCODEHASH path; CODEHASH (self) uses the separate `own_code_hash` host
2468		// function and is therefore unaffected.
2469		if let Some(target) = <AccountInfo<T>>::get_delegation_target(address) {
2470			let indicator = <AccountInfo<T>>::delegation_indicator(&target);
2471			return sp_io::hashing::keccak_256(&indicator).into();
2472		}
2473
2474		<AccountInfo<T>>::load_contract(&address)
2475			.map(|contract| contract.code_hash)
2476			.unwrap_or_else(|| {
2477				if System::<T>::account_exists(&T::AddressMapper::to_account_id(address)) {
2478					return EMPTY_CODE_HASH;
2479				}
2480				H256::zero()
2481			})
2482	}
2483
2484	fn code_size(&self, address: &H160) -> u64 {
2485		if let Some(code) = <AllPrecompiles<T>>::code(address.as_fixed_bytes()).or_else(|| {
2486			self.exec_config
2487				.mock_handler
2488				.as_ref()
2489				.and_then(|handler| handler.mocked_code(*address))
2490		}) {
2491			return code.len() as u64;
2492		}
2493
2494		// EIP-7702: delegated EOAs return the delegation indicator size (23 bytes).
2495		//
2496		// PVM caveat: on PolkaVM, EXTCODESIZE and CODESIZE both lower to this
2497		// host function, so this branch is reached for both. It is spec-correct
2498		// for EXTCODESIZE but wrong for CODESIZE inside a delegated EOA's
2499		// execution — the executing code there is the target's PVM blob, whose
2500		// size is not 23. Spec-correct CODESIZE requires a separate host
2501		// function and a matching resolc change; tracked as a follow-up.
2502		if <AccountInfo<T>>::is_delegated(address) {
2503			return 23;
2504		}
2505
2506		<AccountInfo<T>>::load_contract(&address)
2507			.and_then(|contract| CodeInfoOf::<T>::get(contract.code_hash))
2508			.map(|info| info.code_len())
2509			.unwrap_or_default()
2510	}
2511
2512	fn caller_is_origin(&self, use_caller_of_caller: bool) -> bool {
2513		let caller = if use_caller_of_caller { self.caller_of_caller() } else { self.caller() };
2514		self.origin == caller
2515	}
2516
2517	fn caller_is_root(&self, use_caller_of_caller: bool) -> bool {
2518		// if the caller isn't origin, then it can't be root.
2519		self.caller_is_origin(use_caller_of_caller) && self.origin == Origin::Root
2520	}
2521
2522	fn origin_is_root(&self) -> bool {
2523		self.origin == Origin::Root
2524	}
2525
2526	fn balance(&self) -> U256 {
2527		self.account_balance(&self.top_frame().account_id)
2528	}
2529
2530	fn balance_of(&self, address: &H160) -> U256 {
2531		let balance =
2532			self.account_balance(&<Self::T as Config>::AddressMapper::to_account_id(address));
2533		if_tracing(|tracer| {
2534			tracer.balance_read(address, balance);
2535		});
2536		balance
2537	}
2538
2539	fn value_transferred(&self) -> U256 {
2540		self.top_frame().value_transferred.into()
2541	}
2542
2543	fn now(&self) -> U256 {
2544		(self.timestamp / 1000u32.into()).into()
2545	}
2546
2547	fn minimum_balance(&self) -> U256 {
2548		let min = T::Currency::minimum_balance();
2549		crate::Pallet::<T>::convert_native_to_evm(min)
2550	}
2551
2552	fn deposit_event(&mut self, topics: Vec<H256>, data: Vec<u8>) {
2553		let contract = T::AddressMapper::to_address(self.account_id());
2554		if_tracing(|tracer| {
2555			let log_index = frame_system::Pallet::<Self::T>::event_count();
2556			tracer.log_event(contract, &topics, &data, log_index);
2557		});
2558
2559		// Capture the log only if it is generated by an Ethereum transaction.
2560		block_storage::capture_ethereum_log(&contract, &data, &topics);
2561
2562		Contracts::<Self::T>::deposit_event(Event::ContractEmitted { contract, data, topics });
2563	}
2564
2565	fn block_number(&self) -> U256 {
2566		self.block_number.into()
2567	}
2568
2569	fn block_hash(&self, block_number: U256) -> Option<H256> {
2570		self.block_hash(block_number)
2571	}
2572
2573	fn block_author(&self) -> H160 {
2574		Contracts::<Self::T>::block_author()
2575	}
2576
2577	fn gas_limit(&self) -> u64 {
2578		<Contracts<T>>::evm_block_gas_limit().saturated_into()
2579	}
2580
2581	fn chain_id(&self) -> u64 {
2582		<T as Config>::ChainId::get()
2583	}
2584
2585	fn gas_meter(&self) -> &FrameMeter<Self::T> {
2586		&self.top_frame().frame_meter
2587	}
2588
2589	#[inline]
2590	fn gas_meter_mut(&mut self) -> &mut FrameMeter<Self::T> {
2591		&mut self.top_frame_mut().frame_meter
2592	}
2593
2594	fn frame_meter(&self) -> &FrameMeter<Self::T> {
2595		&self.top_frame().frame_meter
2596	}
2597
2598	#[inline]
2599	fn frame_meter_mut(&mut self) -> &mut FrameMeter<Self::T> {
2600		&mut self.top_frame_mut().frame_meter
2601	}
2602
2603	fn ecdsa_recover(&self, signature: &[u8; 65], message_hash: &[u8; 32]) -> Result<[u8; 33], ()> {
2604		secp256k1_ecdsa_recover_compressed(signature, message_hash).map_err(|_| ())
2605	}
2606
2607	fn sr25519_verify(&self, signature: &[u8; 64], message: &[u8], pub_key: &[u8; 32]) -> bool {
2608		sp_io::crypto::sr25519_verify(
2609			&SR25519Signature::from(*signature),
2610			message,
2611			&SR25519Public::from(*pub_key),
2612		)
2613	}
2614
2615	fn ecdsa_to_eth_address(&self, pk: &[u8; 33]) -> Result<[u8; 20], DispatchError> {
2616		Ok(ECDSAPublic::from(*pk)
2617			.to_eth_address()
2618			.or_else(|()| Err(Error::<T>::EcdsaRecoveryFailed))?)
2619	}
2620
2621	#[cfg(any(test, feature = "runtime-benchmarks"))]
2622	fn contract_info(&mut self) -> &mut ContractInfo<Self::T> {
2623		self.top_frame_mut().contract_info()
2624	}
2625
2626	#[cfg(any(feature = "runtime-benchmarks", test))]
2627	fn transient_storage(&mut self) -> &mut TransientStorage<Self::T> {
2628		&mut self.transient_storage
2629	}
2630
2631	fn is_read_only(&self) -> bool {
2632		self.top_frame().read_only
2633	}
2634
2635	fn is_delegate_call(&self) -> bool {
2636		self.top_frame().delegate.is_some()
2637	}
2638
2639	fn last_frame_output(&self) -> &ExecReturnValue {
2640		&self.top_frame().last_frame_output
2641	}
2642
2643	fn last_frame_output_mut(&mut self) -> &mut ExecReturnValue {
2644		&mut self.top_frame_mut().last_frame_output
2645	}
2646
2647	fn copy_code_slice(&mut self, buf: &mut [u8], address: &H160, code_offset: usize) {
2648		let len = buf.len();
2649		if len == 0 {
2650			return;
2651		}
2652
2653		let code = if let Some(code) =
2654			<AllPrecompiles<T>>::code(address.as_fixed_bytes()).or_else(|| {
2655				self.exec_config
2656					.mock_handler
2657					.as_ref()
2658					.and_then(|handler| handler.mocked_code(*address))
2659			}) {
2660			code.to_vec()
2661		} else if let Some(target) = <AccountInfo<T>>::get_delegation_target(address) {
2662			// EIP-7702: delegated EOAs return 0xef0100 || target as their code.
2663			//
2664			// PVM caveat: on PolkaVM, EXTCODECOPY and CODECOPY both lower to this
2665			// host function, so this branch is reached for both. It is spec-correct
2666			// for EXTCODECOPY but wrong for CODECOPY inside a delegated EOA's
2667			// execution — the executing code there is the target's PVM blob, not
2668			// the 23-byte indicator. Spec-correct CODECOPY requires a separate
2669			// host function and a matching resolc change; tracked as a follow-up.
2670			<AccountInfo<T>>::delegation_indicator(&target).to_vec()
2671		} else {
2672			let code_hash = self.code_hash(address);
2673			crate::PristineCode::<T>::get(&code_hash).unwrap_or_default()
2674		};
2675
2676		let copy_len = len.min(code.len().saturating_sub(code_offset));
2677		if copy_len > 0 {
2678			buf[..copy_len].copy_from_slice(&code[code_offset..code_offset + copy_len]);
2679		}
2680		buf[copy_len..].fill(0);
2681	}
2682
2683	fn terminate_caller(&mut self, beneficiary: &H160) -> Result<(), DispatchError> {
2684		ensure!(self.top_frame().delegate.is_none(), Error::<T>::PrecompileDelegateDenied);
2685		let parent = self.frames_mut().nth(1).ok_or_else(|| Error::<T>::ContractNotFound)?;
2686		ensure!(parent.entry_point == ExportedFunction::Call, Error::<T>::TerminatedInConstructor);
2687		ensure!(parent.delegate.is_none(), Error::<T>::PrecompileDelegateDenied);
2688
2689		let contract_address = T::AddressMapper::to_address(&parent.account_id);
2690
2691		// EIP-7702: delegated EOAs cannot be destroyed via the system precompile.
2692		ensure!(
2693			!AccountInfo::<T>::is_delegated(&contract_address),
2694			Error::<T>::CannotTerminateDelegatedAccount,
2695		);
2696
2697		let info = parent.contract_info();
2698		let trie_id = info.trie_id.clone();
2699		let code_hash = info.code_hash;
2700		let beneficiary = T::AddressMapper::to_account_id(beneficiary);
2701
2702		let parent_account_id = parent.account_id.clone();
2703
2704		// balance transfer is immediate
2705		Self::transfer(
2706			&self.origin,
2707			&parent_account_id,
2708			&beneficiary,
2709			<Contracts<T>>::evm_balance(&contract_address),
2710			Preservation::Preserve,
2711			&mut top_frame_mut!(self).frame_meter,
2712			&self.exec_config,
2713		)?;
2714
2715		// schedule for delayed deletion
2716		let args = TerminateArgs { beneficiary, trie_id, code_hash, only_if_same_tx: false };
2717		self.top_frame_mut().contracts_to_be_destroyed.insert(parent_account_id, args);
2718
2719		Ok(())
2720	}
2721
2722	fn effective_gas_price(&self) -> U256 {
2723		self.exec_config
2724			.effective_gas_price
2725			.unwrap_or_else(|| <Contracts<T>>::evm_base_fee())
2726	}
2727
2728	fn gas_left(&self) -> u64 {
2729		let frame = self.top_frame();
2730
2731		frame.frame_meter.eth_gas_left().unwrap_or_default().saturated_into::<u64>()
2732	}
2733
2734	fn get_storage(&mut self, key: &Key) -> Option<Vec<u8>> {
2735		assert!(self.has_contract_info());
2736		self.top_frame_mut().contract_info().read(key)
2737	}
2738
2739	fn get_storage_size(&mut self, key: &Key) -> Option<u32> {
2740		assert!(self.has_contract_info());
2741		self.top_frame_mut().contract_info().size(key.into())
2742	}
2743
2744	fn set_storage(
2745		&mut self,
2746		key: &Key,
2747		value: Option<Vec<u8>>,
2748		take_old: bool,
2749	) -> Result<WriteOutcome, DispatchError> {
2750		assert!(self.has_contract_info());
2751		let frame = self.top_frame_mut();
2752		frame.contract_info.get(&frame.account_id).write(
2753			key.into(),
2754			value,
2755			Some(&mut frame.frame_meter),
2756			take_old,
2757		)
2758	}
2759
2760	fn touch_storage_access(
2761		&mut self,
2762		transient: bool,
2763		key: &Key,
2764		op: StorageOp,
2765	) -> StorageAccessKind {
2766		if transient {
2767			return StorageAccessKind::Transient;
2768		}
2769		let address = self.address();
2770		StorageAccessKind::Persistent(
2771			self.access_list.touch(AccessEntry { address, slot: key.into() }, op),
2772		)
2773	}
2774
2775	fn peek_storage_access(&self, transient: bool, key: &Key) -> StorageAccessKind {
2776		if transient {
2777			return StorageAccessKind::Transient;
2778		}
2779		let address = self.address();
2780		StorageAccessKind::Persistent(
2781			self.access_list.peek(&AccessEntry { address, slot: key.into() }),
2782		)
2783	}
2784
2785	fn charge_storage(&mut self, diff: &Diff) -> DispatchResult {
2786		assert!(self.has_contract_info());
2787		self.top_frame_mut().frame_meter.record_contract_storage_changes(diff)
2788	}
2789}
2790
2791/// Returns true if the address has a precompile contract, else false.
2792pub fn is_precompile<T: Config, E: Executable<T>>(address: &H160) -> bool {
2793	<AllPrecompiles<T>>::get::<Stack<'_, T, E>>(address.as_fixed_bytes()).is_some()
2794}
2795
2796#[cfg(feature = "runtime-benchmarks")]
2797pub fn bench_do_terminate<T: Config>(
2798	transaction_meter: &mut TransactionMeter<T>,
2799	exec_config: &ExecConfig<T>,
2800	contract_account: &T::AccountId,
2801	origin: &Origin<T>,
2802	beneficiary: T::AccountId,
2803	trie_id: TrieId,
2804	code_hash: H256,
2805	only_if_same_tx: bool,
2806) -> Result<(), DispatchError> {
2807	Stack::<T, crate::ContractBlob<T>>::do_terminate(
2808		transaction_meter,
2809		exec_config,
2810		contract_account,
2811		origin,
2812		&TerminateArgs { beneficiary, trie_id, code_hash, only_if_same_tx },
2813	)
2814}
2815
2816mod sealing {
2817	use super::*;
2818
2819	pub trait Sealed {}
2820	impl<'a, T: Config, E> Sealed for Stack<'a, T, E> {}
2821
2822	#[cfg(test)]
2823	impl<T: Config> sealing::Sealed for mock_ext::MockExt<T> {}
2824}