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