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