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