1use 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
71type 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
76pub const EMPTY_CODE_HASH: H256 =
78 H256(sp_core::hex2array!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
79
80pub enum Key {
82 Fix([u8; 32]),
84 Var(VarSizedKey),
86}
87
88impl Key {
89 pub fn unhashed(&self) -> &[u8] {
91 match self {
92 Key::Fix(v) => v.as_ref(),
93 Key::Var(v) => v.as_ref(),
94 }
95 }
96
97 pub fn hash(&self) -> Vec<u8> {
99 match self {
100 Key::Fix(v) => blake2_256(v.as_slice()).to_vec(),
101 Key::Var(v) => Blake2_128Concat::hash(v.as_slice()),
102 }
103 }
104
105 pub fn from_fixed(v: [u8; 32]) -> Self {
106 Self::Fix(v)
107 }
108
109 pub fn try_from_var(v: Vec<u8>) -> Result<Self, ()> {
110 VarSizedKey::try_from(v).map(Self::Var).map_err(|_| ())
111 }
112}
113
114#[derive(Copy, Clone, PartialEq, Eq, Debug, codec::Decode, codec::Encode)]
120pub enum ErrorOrigin {
121 Caller,
126 Callee,
128}
129
130#[derive(Copy, Clone, PartialEq, Eq, Debug, codec::Decode, codec::Encode)]
132pub struct ExecError {
133 pub error: DispatchError,
135 pub origin: ErrorOrigin,
137}
138
139impl<T: Into<DispatchError>> From<T> for ExecError {
140 fn from(error: T) -> Self {
141 Self { error: error.into(), origin: ErrorOrigin::Caller }
142 }
143}
144
145#[derive(Clone, Encode, Decode, PartialEq, TypeInfo, RuntimeDebugNoBound)]
147pub enum Origin<T: Config> {
148 Root,
149 Signed(T::AccountId),
150}
151
152impl<T: Config> Origin<T> {
153 pub fn from_account_id(account_id: T::AccountId) -> Self {
155 Origin::Signed(account_id)
156 }
157 pub fn from_runtime_origin(o: OriginFor<T>) -> Result<Self, DispatchError> {
159 match o.into() {
160 Ok(RawOrigin::Root) => Ok(Self::Root),
161 Ok(RawOrigin::Signed(t)) => Ok(Self::Signed(t)),
162 _ => Err(BadOrigin.into()),
163 }
164 }
165 pub fn account_id(&self) -> Result<&T::AccountId, DispatchError> {
167 match self {
168 Origin::Signed(id) => Ok(id),
169 Origin::Root => Err(DispatchError::RootNotAllowed),
170 }
171 }
172
173 fn ensure_mapped(&self) -> DispatchResult {
178 match self {
179 Self::Root => Ok(()),
180 Self::Signed(account_id) if T::AddressMapper::is_mapped(account_id) => Ok(()),
181 Self::Signed(_) => Err(<Error<T>>::AccountUnmapped.into()),
182 }
183 }
184}
185pub trait Ext: PrecompileWithInfoExt {
187 fn delegate_call(
191 &mut self,
192 gas_limit: Weight,
193 deposit_limit: U256,
194 address: H160,
195 input_data: Vec<u8>,
196 ) -> Result<(), ExecError>;
197
198 fn terminate(&mut self, beneficiary: &H160) -> Result<CodeRemoved, DispatchError>;
206
207 fn own_code_hash(&mut self) -> &H256;
209
210 fn set_code_hash(&mut self, hash: H256) -> Result<CodeRemoved, DispatchError>;
213
214 fn immutable_data_len(&mut self) -> u32;
219
220 fn get_immutable_data(&mut self) -> Result<ImmutableData, DispatchError>;
224
225 fn set_immutable_data(&mut self, data: ImmutableData) -> Result<(), DispatchError>;
231}
232
233pub trait PrecompileWithInfoExt: PrecompileExt {
235 fn get_storage(&mut self, key: &Key) -> Option<Vec<u8>>;
240
241 fn get_storage_size(&mut self, key: &Key) -> Option<u32>;
246
247 fn set_storage(
250 &mut self,
251 key: &Key,
252 value: Option<Vec<u8>>,
253 take_old: bool,
254 ) -> Result<WriteOutcome, DispatchError>;
255
256 fn charge_storage(&mut self, diff: &Diff);
258
259 fn instantiate(
265 &mut self,
266 gas_limit: Weight,
267 deposit_limit: U256,
268 code: Code,
269 value: U256,
270 input_data: Vec<u8>,
271 salt: Option<&[u8; 32]>,
272 ) -> Result<H160, ExecError>;
273}
274
275pub trait PrecompileExt: sealing::Sealed {
277 type T: Config;
278
279 fn charge(&mut self, weight: Weight) -> Result<crate::gas::ChargedAmount, DispatchError> {
281 self.gas_meter_mut().charge(RuntimeCosts::Precompile(weight))
282 }
283
284 fn adjust_gas(&mut self, charged: crate::gas::ChargedAmount, actual_weight: Weight) {
285 self.gas_meter_mut()
286 .adjust_gas(charged, RuntimeCosts::Precompile(actual_weight));
287 }
288
289 fn call(
293 &mut self,
294 gas_limit: Weight,
295 deposit_limit: U256,
296 to: &H160,
297 value: U256,
298 input_data: Vec<u8>,
299 allows_reentry: bool,
300 read_only: bool,
301 ) -> Result<(), ExecError>;
302
303 fn get_transient_storage(&self, key: &Key) -> Option<Vec<u8>>;
308
309 fn get_transient_storage_size(&self, key: &Key) -> Option<u32>;
314
315 fn set_transient_storage(
318 &mut self,
319 key: &Key,
320 value: Option<Vec<u8>>,
321 take_old: bool,
322 ) -> Result<WriteOutcome, DispatchError>;
323
324 fn caller(&self) -> Origin<Self::T>;
326
327 fn origin(&self) -> &Origin<Self::T>;
329
330 fn code_hash(&self, address: &H160) -> H256;
333
334 fn code_size(&self, address: &H160) -> u64;
336
337 fn caller_is_origin(&self) -> bool;
339
340 fn caller_is_root(&self) -> bool;
342
343 fn account_id(&self) -> &AccountIdOf<Self::T>;
345
346 fn address(&self) -> H160 {
348 <Self::T as Config>::AddressMapper::to_address(self.account_id())
349 }
350
351 fn balance(&self) -> U256;
355
356 fn balance_of(&self, address: &H160) -> U256;
360
361 fn value_transferred(&self) -> U256;
363
364 fn now(&self) -> U256;
366
367 fn minimum_balance(&self) -> U256;
369
370 fn deposit_event(&mut self, topics: Vec<H256>, data: Vec<u8>);
374
375 fn block_number(&self) -> U256;
377
378 fn block_hash(&self, block_number: U256) -> Option<H256>;
381
382 fn block_author(&self) -> Option<H160>;
384
385 fn gas_limit(&self) -> u64;
387
388 fn chain_id(&self) -> u64;
390
391 fn max_value_size(&self) -> u32;
393
394 fn get_weight_price(&self, weight: Weight) -> U256;
396
397 fn gas_meter(&self) -> &GasMeter<Self::T>;
399
400 fn gas_meter_mut(&mut self) -> &mut GasMeter<Self::T>;
402
403 fn ecdsa_recover(&self, signature: &[u8; 65], message_hash: &[u8; 32]) -> Result<[u8; 33], ()>;
405
406 fn sr25519_verify(&self, signature: &[u8; 64], message: &[u8], pub_key: &[u8; 32]) -> bool;
408
409 fn ecdsa_to_eth_address(&self, pk: &[u8; 33]) -> Result<[u8; 20], ()>;
411
412 #[cfg(any(test, feature = "runtime-benchmarks"))]
414 fn contract_info(&mut self) -> &mut ContractInfo<Self::T>;
415
416 #[cfg(any(feature = "runtime-benchmarks", test))]
420 fn transient_storage(&mut self) -> &mut TransientStorage<Self::T>;
421
422 fn is_read_only(&self) -> bool;
424
425 fn last_frame_output(&self) -> &ExecReturnValue;
427
428 fn last_frame_output_mut(&mut self) -> &mut ExecReturnValue;
430}
431
432#[derive(
434 Copy,
435 Clone,
436 PartialEq,
437 Eq,
438 sp_core::RuntimeDebug,
439 codec::Decode,
440 codec::Encode,
441 codec::MaxEncodedLen,
442 scale_info::TypeInfo,
443)]
444pub enum ExportedFunction {
445 Constructor,
447 Call,
449}
450
451pub trait Executable<T: Config>: Sized {
456 fn from_storage(code_hash: H256, gas_meter: &mut GasMeter<T>) -> Result<Self, DispatchError>;
461
462 fn from_evm_init_code(code: Vec<u8>, owner: AccountIdOf<T>) -> Result<Self, DispatchError>;
464
465 fn execute<E: Ext<T = T>>(
475 self,
476 ext: &mut E,
477 function: ExportedFunction,
478 input_data: Vec<u8>,
479 ) -> ExecResult;
480
481 fn code_info(&self) -> &CodeInfo<T>;
483
484 fn code(&self) -> &[u8];
486
487 fn code_hash(&self) -> &H256;
489}
490
491pub struct Stack<'a, T: Config, E> {
497 origin: Origin<T>,
506 gas_meter: &'a mut GasMeter<T>,
508 storage_meter: &'a mut storage::meter::Meter<T>,
510 timestamp: MomentOf<T>,
512 block_number: BlockNumberFor<T>,
514 frames: BoundedVec<Frame<T>, ConstU32<{ limits::CALL_STACK_DEPTH }>>,
517 first_frame: Frame<T>,
519 transient_storage: TransientStorage<T>,
521 skip_transfer: bool,
524 _phantom: PhantomData<E>,
526}
527
528struct Frame<T: Config> {
533 account_id: T::AccountId,
535 contract_info: CachedContract<T>,
537 value_transferred: U256,
539 entry_point: ExportedFunction,
541 nested_gas: GasMeter<T>,
543 nested_storage: storage::meter::NestedMeter<T>,
545 allows_reentry: bool,
547 read_only: bool,
549 delegate: Option<DelegateInfo<T>>,
552 last_frame_output: ExecReturnValue,
554}
555
556struct DelegateInfo<T: Config> {
559 pub caller: Origin<T>,
561 pub callee: H160,
563}
564
565enum ExecutableOrPrecompile<T: Config, E: Executable<T>, Env> {
567 Executable(E),
569 Precompile { instance: PrecompileInstance<Env>, _phantom: PhantomData<T> },
571}
572
573impl<T: Config, E: Executable<T>, Env> ExecutableOrPrecompile<T, E, Env> {
574 fn as_executable(&self) -> Option<&E> {
575 if let Self::Executable(executable) = self {
576 Some(executable)
577 } else {
578 None
579 }
580 }
581
582 fn is_pvm(&self) -> bool {
583 match self {
584 Self::Executable(e) => e.code_info().is_pvm(),
585 _ => false,
586 }
587 }
588
589 fn as_precompile(&self) -> Option<&PrecompileInstance<Env>> {
590 if let Self::Precompile { instance, .. } = self {
591 Some(instance)
592 } else {
593 None
594 }
595 }
596
597 #[cfg(any(feature = "runtime-benchmarks", test))]
598 fn into_executable(self) -> Option<E> {
599 if let Self::Executable(executable) = self {
600 Some(executable)
601 } else {
602 None
603 }
604 }
605}
606
607enum FrameArgs<'a, T: Config, E> {
611 Call {
612 dest: T::AccountId,
614 cached_info: Option<ContractInfo<T>>,
616 delegated_call: Option<DelegateInfo<T>>,
620 },
621 Instantiate {
622 sender: T::AccountId,
624 executable: E,
626 salt: Option<&'a [u8; 32]>,
628 input_data: &'a [u8],
630 },
631}
632
633enum CachedContract<T: Config> {
635 Cached(ContractInfo<T>),
637 Invalidated,
641 Terminated,
646 None,
648}
649
650impl<T: Config> Frame<T> {
651 fn contract_info(&mut self) -> &mut ContractInfo<T> {
653 self.contract_info.get(&self.account_id)
654 }
655
656 fn terminate(&mut self) -> ContractInfo<T> {
663 self.contract_info.terminate(&self.account_id)
664 }
665}
666
667macro_rules! get_cached_or_panic_after_load {
671 ($c:expr) => {{
672 if let CachedContract::Cached(contract) = $c {
673 contract
674 } else {
675 panic!(
676 "It is impossible to remove a contract that is on the call stack;\
677 See implementations of terminate;\
678 Therefore fetching a contract will never fail while using an account id
679 that is currently active on the call stack;\
680 qed"
681 );
682 }
683 }};
684}
685
686macro_rules! top_frame {
691 ($stack:expr) => {
692 $stack.frames.last().unwrap_or(&$stack.first_frame)
693 };
694}
695
696macro_rules! top_frame_mut {
701 ($stack:expr) => {
702 $stack.frames.last_mut().unwrap_or(&mut $stack.first_frame)
703 };
704}
705
706impl<T: Config> CachedContract<T> {
707 fn into_contract(self) -> Option<ContractInfo<T>> {
709 if let CachedContract::Cached(contract) = self {
710 Some(contract)
711 } else {
712 None
713 }
714 }
715
716 fn as_contract(&mut self) -> Option<&mut ContractInfo<T>> {
718 if let CachedContract::Cached(contract) = self {
719 Some(contract)
720 } else {
721 None
722 }
723 }
724
725 fn load(&mut self, account_id: &T::AccountId) {
727 if let CachedContract::Invalidated = self {
728 if let Some(contract) =
729 AccountInfo::<T>::load_contract(&T::AddressMapper::to_address(account_id))
730 {
731 *self = CachedContract::Cached(contract);
732 }
733 }
734 }
735
736 fn get(&mut self, account_id: &T::AccountId) -> &mut ContractInfo<T> {
738 self.load(account_id);
739 get_cached_or_panic_after_load!(self)
740 }
741
742 fn terminate(&mut self, account_id: &T::AccountId) -> ContractInfo<T> {
744 self.load(account_id);
745 get_cached_or_panic_after_load!(mem::replace(self, Self::Terminated))
746 }
747
748 fn invalidate(&mut self) {
750 if matches!(self, CachedContract::Cached(_)) {
751 *self = CachedContract::Invalidated;
752 }
753 }
754}
755
756impl<'a, T, E> Stack<'a, T, E>
757where
758 T: Config,
759 BalanceOf<T>: Into<U256> + TryFrom<U256>,
760 MomentOf<T>: Into<U256>,
761 E: Executable<T>,
762 T::Hash: frame_support::traits::IsType<H256>,
763{
764 pub fn run_call(
770 origin: Origin<T>,
771 dest: H160,
772 gas_meter: &mut GasMeter<T>,
773 storage_meter: &mut storage::meter::Meter<T>,
774 value: U256,
775 input_data: Vec<u8>,
776 skip_transfer: bool,
777 ) -> ExecResult {
778 let dest = T::AddressMapper::to_account_id(&dest);
779 if let Some((mut stack, executable)) = Stack::<'_, T, E>::new(
780 FrameArgs::Call { dest: dest.clone(), cached_info: None, delegated_call: None },
781 origin.clone(),
782 gas_meter,
783 storage_meter,
784 value,
785 skip_transfer,
786 )? {
787 stack
788 .run(executable, input_data, BumpNonce::Yes)
789 .map(|_| stack.first_frame.last_frame_output)
790 } else {
791 if_tracing(|t| {
792 t.enter_child_span(
793 origin.account_id().map(T::AddressMapper::to_address).unwrap_or_default(),
794 T::AddressMapper::to_address(&dest),
795 false,
796 false,
797 value,
798 &input_data,
799 Weight::zero(),
800 );
801 });
802
803 let result = Self::transfer_from_origin(&origin, &origin, &dest, value, storage_meter);
804
805 if_tracing(|t| match result {
806 Ok(ref output) => t.exit_child_span(&output, Weight::zero()),
807 Err(e) => t.exit_child_span_with_error(e.error.into(), Weight::zero()),
808 });
809
810 result
811 }
812 }
813
814 pub fn run_instantiate(
820 origin: T::AccountId,
821 executable: E,
822 gas_meter: &mut GasMeter<T>,
823 storage_meter: &mut storage::meter::Meter<T>,
824 value: U256,
825 input_data: Vec<u8>,
826 salt: Option<&[u8; 32]>,
827 skip_transfer: bool,
828 bump_nonce: BumpNonce,
829 ) -> Result<(H160, ExecReturnValue), ExecError> {
830 let deployer = T::AddressMapper::to_address(&origin);
831 let (mut stack, executable) = Stack::<'_, T, E>::new(
832 FrameArgs::Instantiate {
833 sender: origin.clone(),
834 executable,
835 salt,
836 input_data: input_data.as_ref(),
837 },
838 Origin::from_account_id(origin),
839 gas_meter,
840 storage_meter,
841 value,
842 skip_transfer,
843 )?
844 .expect(FRAME_ALWAYS_EXISTS_ON_INSTANTIATE);
845 let address = T::AddressMapper::to_address(&stack.top_frame().account_id);
846 let result = stack
847 .run(executable, input_data, bump_nonce)
848 .map(|_| (address, stack.first_frame.last_frame_output));
849 if let Ok((contract, ref output)) = result {
850 if !output.did_revert() {
851 Contracts::<T>::deposit_event(Event::Instantiated { deployer, contract });
852 }
853 }
854 result
855 }
856
857 #[cfg(any(feature = "runtime-benchmarks", test))]
858 pub fn bench_new_call(
859 dest: H160,
860 origin: Origin<T>,
861 gas_meter: &'a mut GasMeter<T>,
862 storage_meter: &'a mut storage::meter::Meter<T>,
863 value: BalanceOf<T>,
864 ) -> (Self, E) {
865 let call = Self::new(
866 FrameArgs::Call {
867 dest: T::AddressMapper::to_account_id(&dest),
868 cached_info: None,
869 delegated_call: None,
870 },
871 origin,
872 gas_meter,
873 storage_meter,
874 value.into(),
875 false,
876 )
877 .unwrap()
878 .unwrap();
879 (call.0, call.1.into_executable().unwrap())
880 }
881
882 fn new(
887 args: FrameArgs<T, E>,
888 origin: Origin<T>,
889 gas_meter: &'a mut GasMeter<T>,
890 storage_meter: &'a mut storage::meter::Meter<T>,
891 value: U256,
892 skip_transfer: bool,
893 ) -> Result<Option<(Self, ExecutableOrPrecompile<T, E, Self>)>, ExecError> {
894 origin.ensure_mapped()?;
895 let Some((first_frame, executable)) = Self::new_frame(
896 args,
897 value,
898 gas_meter,
899 Weight::max_value(),
900 storage_meter,
901 BalanceOf::<T>::max_value(),
902 false,
903 true,
904 )?
905 else {
906 return Ok(None);
907 };
908
909 let stack = Self {
910 origin,
911 gas_meter,
912 storage_meter,
913 timestamp: T::Time::now(),
914 block_number: <frame_system::Pallet<T>>::block_number(),
915 first_frame,
916 frames: Default::default(),
917 transient_storage: TransientStorage::new(limits::TRANSIENT_STORAGE_BYTES),
918 skip_transfer,
919 _phantom: Default::default(),
920 };
921
922 Ok(Some((stack, executable)))
923 }
924
925 fn new_frame<S: storage::meter::State + Default + Debug>(
930 frame_args: FrameArgs<T, E>,
931 value_transferred: U256,
932 gas_meter: &mut GasMeter<T>,
933 gas_limit: Weight,
934 storage_meter: &mut storage::meter::GenericMeter<T, S>,
935 deposit_limit: BalanceOf<T>,
936 read_only: bool,
937 origin_is_caller: bool,
938 ) -> Result<Option<(Frame<T>, ExecutableOrPrecompile<T, E, Self>)>, ExecError> {
939 let (account_id, contract_info, executable, delegate, entry_point) = match frame_args {
940 FrameArgs::Call { dest, cached_info, delegated_call } => {
941 let address = T::AddressMapper::to_address(&dest);
942 let precompile = <AllPrecompiles<T>>::get(address.as_fixed_bytes());
943
944 let mut contract = match (cached_info, &precompile) {
947 (Some(info), _) => CachedContract::Cached(info),
948 (None, None) =>
949 if let Some(info) = AccountInfo::<T>::load_contract(&address) {
950 CachedContract::Cached(info)
951 } else {
952 return Ok(None);
953 },
954 (None, Some(precompile)) if precompile.has_contract_info() => {
955 if let Some(info) = AccountInfo::<T>::load_contract(&address) {
956 CachedContract::Cached(info)
957 } else {
958 let info = ContractInfo::new(&address, 0u32.into(), H256::zero())?;
959 CachedContract::Cached(info)
960 }
961 },
962 (None, Some(_)) => CachedContract::None,
963 };
964
965 let executable = if let Some(delegated_call) = &delegated_call {
967 if let Some(precompile) =
968 <AllPrecompiles<T>>::get(delegated_call.callee.as_fixed_bytes())
969 {
970 ExecutableOrPrecompile::Precompile {
971 instance: precompile,
972 _phantom: Default::default(),
973 }
974 } else {
975 let Some(info) = AccountInfo::<T>::load_contract(&delegated_call.callee)
976 else {
977 return Ok(None);
978 };
979 let executable = E::from_storage(info.code_hash, gas_meter)?;
980 ExecutableOrPrecompile::Executable(executable)
981 }
982 } else {
983 if let Some(precompile) = precompile {
984 ExecutableOrPrecompile::Precompile {
985 instance: precompile,
986 _phantom: Default::default(),
987 }
988 } else {
989 let executable = E::from_storage(
990 contract
991 .as_contract()
992 .expect("When not a precompile the contract was loaded above; qed")
993 .code_hash,
994 gas_meter,
995 )?;
996 ExecutableOrPrecompile::Executable(executable)
997 }
998 };
999
1000 (dest, contract, executable, delegated_call, ExportedFunction::Call)
1001 },
1002 FrameArgs::Instantiate { sender, executable, salt, input_data } => {
1003 let deployer = T::AddressMapper::to_address(&sender);
1004 let account_nonce = <System<T>>::account_nonce(&sender);
1005 let address = if let Some(salt) = salt {
1006 address::create2(&deployer, executable.code(), input_data, salt)
1007 } else {
1008 use sp_runtime::Saturating;
1009 address::create1(
1010 &deployer,
1011 if origin_is_caller {
1014 account_nonce.saturating_sub(1u32.into()).saturated_into()
1015 } else {
1016 account_nonce.saturated_into()
1017 },
1018 )
1019 };
1020 let contract = ContractInfo::new(
1021 &address,
1022 <System<T>>::account_nonce(&sender),
1023 *executable.code_hash(),
1024 )?;
1025 (
1026 T::AddressMapper::to_fallback_account_id(&address),
1027 CachedContract::Cached(contract),
1028 ExecutableOrPrecompile::Executable(executable),
1029 None,
1030 ExportedFunction::Constructor,
1031 )
1032 },
1033 };
1034
1035 let frame = Frame {
1036 delegate,
1037 value_transferred,
1038 contract_info,
1039 account_id,
1040 entry_point,
1041 nested_gas: gas_meter.nested(gas_limit),
1042 nested_storage: storage_meter.nested(deposit_limit),
1043 allows_reentry: true,
1044 read_only,
1045 last_frame_output: Default::default(),
1046 };
1047
1048 Ok(Some((frame, executable)))
1049 }
1050
1051 fn push_frame(
1053 &mut self,
1054 frame_args: FrameArgs<T, E>,
1055 value_transferred: U256,
1056 gas_limit: Weight,
1057 deposit_limit: BalanceOf<T>,
1058 read_only: bool,
1059 ) -> Result<Option<ExecutableOrPrecompile<T, E, Self>>, ExecError> {
1060 if self.frames.len() as u32 == limits::CALL_STACK_DEPTH {
1061 return Err(Error::<T>::MaxCallDepthReached.into());
1062 }
1063
1064 let frame = self.top_frame();
1069 if let (CachedContract::Cached(contract), ExportedFunction::Call) =
1070 (&frame.contract_info, frame.entry_point)
1071 {
1072 AccountInfo::<T>::insert_contract(
1073 &T::AddressMapper::to_address(&frame.account_id),
1074 contract.clone(),
1075 );
1076 }
1077
1078 let frame = top_frame_mut!(self);
1079 let nested_gas = &mut frame.nested_gas;
1080 let nested_storage = &mut frame.nested_storage;
1081 if let Some((frame, executable)) = Self::new_frame(
1082 frame_args,
1083 value_transferred,
1084 nested_gas,
1085 gas_limit,
1086 nested_storage,
1087 deposit_limit,
1088 read_only,
1089 false,
1090 )? {
1091 self.frames.try_push(frame).map_err(|_| Error::<T>::MaxCallDepthReached)?;
1092 Ok(Some(executable))
1093 } else {
1094 Ok(None)
1095 }
1096 }
1097
1098 fn run(
1102 &mut self,
1103 executable: ExecutableOrPrecompile<T, E, Self>,
1104 input_data: Vec<u8>,
1105 bump_nonce: BumpNonce,
1106 ) -> Result<(), ExecError> {
1107 let frame = self.top_frame();
1108 let entry_point = frame.entry_point;
1109 let is_pvm = executable.is_pvm();
1110
1111 if_tracing(|tracer| {
1112 tracer.enter_child_span(
1113 self.caller().account_id().map(T::AddressMapper::to_address).unwrap_or_default(),
1114 T::AddressMapper::to_address(&frame.account_id),
1115 frame.delegate.is_some(),
1116 frame.read_only,
1117 frame.value_transferred,
1118 &input_data,
1119 frame.nested_gas.gas_left(),
1120 );
1121 });
1122
1123 let frames_len = self.frames.len();
1127 if let Some(caller_frame) = match frames_len {
1128 0 => None,
1129 1 => Some(&mut self.first_frame.last_frame_output),
1130 _ => self.frames.get_mut(frames_len - 2).map(|frame| &mut frame.last_frame_output),
1131 } {
1132 *caller_frame = Default::default();
1133 }
1134
1135 self.transient_storage.start_transaction();
1136
1137 let do_transaction = || -> ExecResult {
1138 let caller = self.caller();
1139 let skip_transfer = self.skip_transfer;
1140 let frame = top_frame_mut!(self);
1141 let account_id = &frame.account_id.clone();
1142
1143 if u32::try_from(input_data.len())
1144 .map(|len| len > limits::CALLDATA_BYTES)
1145 .unwrap_or(true)
1146 {
1147 Err(<Error<T>>::CallDataTooLarge)?;
1148 }
1149
1150 if entry_point == ExportedFunction::Constructor {
1153 let origin = &self.origin.account_id()?;
1156
1157 let ed = <Contracts<T>>::min_balance();
1158 frame.nested_storage.record_charge(&StorageDeposit::Charge(ed))?;
1159 if self.skip_transfer {
1160 T::Currency::set_balance(account_id, ed);
1161 } else {
1162 T::Currency::transfer(origin, account_id, ed, Preservation::Preserve)
1163 .map_err(|_| <Error<T>>::StorageDepositNotEnoughFunds)?;
1164 }
1165
1166 <System<T>>::inc_consumers(account_id)?;
1171
1172 <System<T>>::inc_account_nonce(account_id);
1174
1175 if matches!(bump_nonce, BumpNonce::Yes) {
1176 <System<T>>::inc_account_nonce(caller.account_id()?);
1179 }
1180 if is_pvm {
1182 <CodeInfo<T>>::increment_refcount(
1183 *executable
1184 .as_executable()
1185 .expect("Precompiles cannot be instantiated; qed")
1186 .code_hash(),
1187 )?;
1188 }
1189 }
1190
1191 if frame.delegate.is_none() {
1195 Self::transfer_from_origin(
1196 &self.origin,
1197 &caller,
1198 account_id,
1199 frame.value_transferred,
1200 &mut frame.nested_storage,
1201 )?;
1202 }
1203
1204 if let Some(precompile) = executable.as_precompile() {
1211 if precompile.has_contract_info() &&
1212 frame.delegate.is_none() &&
1213 !<System<T>>::account_exists(account_id)
1214 {
1215 T::Currency::mint_into(account_id, T::Currency::minimum_balance())?;
1218 <System<T>>::inc_consumers(account_id)?;
1220 }
1221 }
1222
1223 let mut code_deposit = executable
1224 .as_executable()
1225 .map(|exec| exec.code_info().deposit())
1226 .unwrap_or_default();
1227
1228 let mut output = match executable {
1229 ExecutableOrPrecompile::Executable(executable) =>
1230 executable.execute(self, entry_point, input_data),
1231 ExecutableOrPrecompile::Precompile { instance, .. } =>
1232 instance.call(input_data, self),
1233 }
1234 .and_then(|output| {
1235 if u32::try_from(output.data.len())
1236 .map(|len| len > limits::CALLDATA_BYTES)
1237 .unwrap_or(true)
1238 {
1239 Err(<Error<T>>::ReturnDataTooLarge)?;
1240 }
1241 Ok(output)
1242 })
1243 .map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?;
1244
1245 if output.did_revert() {
1247 return Ok(output);
1248 }
1249
1250 let frame = self.top_frame_mut();
1251
1252 if entry_point == ExportedFunction::Constructor {
1255 let contract_info = frame.contract_info();
1256 if !is_pvm {
1259 let data = if crate::tracing::if_tracing(|_| {}).is_none() {
1261 core::mem::replace(&mut output.data, Default::default())
1262 } else {
1263 output.data.clone()
1264 };
1265
1266 let mut module = crate::ContractBlob::<T>::from_evm_runtime_code(
1267 data,
1268 caller.account_id()?.clone(),
1269 )?;
1270 module.store_code(skip_transfer)?;
1271 code_deposit = module.code_info().deposit();
1272 contract_info.code_hash = *module.code_hash();
1273
1274 <CodeInfo<T>>::increment_refcount(contract_info.code_hash)?;
1275 }
1276
1277 let deposit = contract_info.update_base_deposit(code_deposit);
1278 frame
1279 .nested_storage
1280 .charge_deposit(frame.account_id.clone(), StorageDeposit::Charge(deposit));
1281 }
1282
1283 let contract = frame.contract_info.as_contract();
1287 frame
1288 .nested_storage
1289 .enforce_limit(contract)
1290 .map_err(|e| ExecError { error: e, origin: ErrorOrigin::Callee })?;
1291
1292 Ok(output)
1293 };
1294
1295 let transaction_outcome =
1302 with_transaction(|| -> TransactionOutcome<Result<_, DispatchError>> {
1303 let output = do_transaction();
1304 match &output {
1305 Ok(result) if !result.did_revert() =>
1306 TransactionOutcome::Commit(Ok((true, output))),
1307 _ => TransactionOutcome::Rollback(Ok((false, output))),
1308 }
1309 });
1310
1311 let (success, output) = match transaction_outcome {
1312 Ok((success, output)) => {
1314 if_tracing(|tracer| {
1315 let gas_consumed = top_frame!(self).nested_gas.gas_consumed();
1316 match &output {
1317 Ok(output) => tracer.exit_child_span(&output, gas_consumed),
1318 Err(e) => tracer.exit_child_span_with_error(e.error.into(), gas_consumed),
1319 }
1320 });
1321
1322 (success, output)
1323 },
1324 Err(error) => {
1327 if_tracing(|tracer| {
1328 let gas_consumed = top_frame!(self).nested_gas.gas_consumed();
1329 tracer.exit_child_span_with_error(error.into(), gas_consumed);
1330 });
1331
1332 (false, Err(error.into()))
1333 },
1334 };
1335
1336 if success {
1337 self.transient_storage.commit_transaction();
1338 } else {
1339 self.transient_storage.rollback_transaction();
1340 }
1341
1342 log::trace!(target: LOG_TARGET, "frame finished with: {output:?}");
1343
1344 self.pop_frame(success);
1345 output.map(|output| {
1346 self.top_frame_mut().last_frame_output = output;
1347 })
1348 }
1349
1350 fn pop_frame(&mut self, persist: bool) {
1355 let frame = self.frames.pop();
1359
1360 if let Some(mut frame) = frame {
1363 let account_id = &frame.account_id;
1364 let prev = top_frame_mut!(self);
1365
1366 prev.nested_gas.absorb_nested(frame.nested_gas);
1367
1368 if !persist {
1370 return;
1371 }
1372
1373 frame.contract_info.load(account_id);
1378 let mut contract = frame.contract_info.into_contract();
1379 prev.nested_storage.absorb(frame.nested_storage, account_id, contract.as_mut());
1380
1381 if let Some(contract) = contract {
1383 if prev.account_id == *account_id {
1388 prev.contract_info = CachedContract::Cached(contract);
1389 return;
1390 }
1391
1392 AccountInfo::<T>::insert_contract(
1398 &T::AddressMapper::to_address(account_id),
1399 contract,
1400 );
1401 if let Some(f) = self.frames_mut().skip(1).find(|f| f.account_id == *account_id) {
1402 f.contract_info.invalidate();
1403 }
1404 }
1405 } else {
1406 self.gas_meter.absorb_nested(mem::take(&mut self.first_frame.nested_gas));
1407 if !persist {
1408 return;
1409 }
1410 let mut contract = self.first_frame.contract_info.as_contract();
1411 self.storage_meter.absorb(
1412 mem::take(&mut self.first_frame.nested_storage),
1413 &self.first_frame.account_id,
1414 contract.as_deref_mut(),
1415 );
1416 if let Some(contract) = contract {
1417 AccountInfo::<T>::insert_contract(
1418 &T::AddressMapper::to_address(&self.first_frame.account_id),
1419 contract.clone(),
1420 );
1421 }
1422 }
1423 }
1424
1425 fn transfer<S: storage::meter::State + Default + Debug>(
1438 origin: &Origin<T>,
1439 from: &T::AccountId,
1440 to: &T::AccountId,
1441 value: U256,
1442 storage_meter: &mut storage::meter::GenericMeter<T, S>,
1443 ) -> DispatchResult {
1444 fn transfer_with_dust<T: Config>(
1445 from: &AccountIdOf<T>,
1446 to: &AccountIdOf<T>,
1447 value: BalanceWithDust<BalanceOf<T>>,
1448 ) -> DispatchResult {
1449 let (value, dust) = value.deconstruct();
1450
1451 fn transfer_balance<T: Config>(
1452 from: &AccountIdOf<T>,
1453 to: &AccountIdOf<T>,
1454 value: BalanceOf<T>,
1455 ) -> DispatchResult {
1456 T::Currency::transfer(from, to, value, Preservation::Preserve)
1457 .map_err(|err| {
1458 log::debug!(target: crate::LOG_TARGET, "Transfer failed: from {from:?} to {to:?} (value: ${value:?}). Err: {err:?}");
1459 Error::<T>::TransferFailed
1460 })?;
1461 Ok(())
1462 }
1463
1464 fn transfer_dust<T: Config>(
1465 from: &mut AccountInfo<T>,
1466 to: &mut AccountInfo<T>,
1467 dust: u32,
1468 ) -> DispatchResult {
1469 from.dust =
1470 from.dust.checked_sub(dust).ok_or_else(|| Error::<T>::TransferFailed)?;
1471 to.dust = to.dust.checked_add(dust).ok_or_else(|| Error::<T>::TransferFailed)?;
1472 Ok(())
1473 }
1474
1475 if dust.is_zero() {
1476 return transfer_balance::<T>(from, to, value)
1477 }
1478
1479 let from_addr = <T::AddressMapper as AddressMapper<T>>::to_address(from);
1480 let mut from_info = AccountInfoOf::<T>::get(&from_addr).unwrap_or_default();
1481
1482 let to_addr = <T::AddressMapper as AddressMapper<T>>::to_address(to);
1483 let mut to_info = AccountInfoOf::<T>::get(&to_addr).unwrap_or_default();
1484
1485 let plank = T::NativeToEthRatio::get();
1486
1487 if from_info.dust < dust {
1488 T::Currency::burn_from(
1489 from,
1490 1u32.into(),
1491 Preservation::Preserve,
1492 Precision::Exact,
1493 Fortitude::Polite,
1494 )
1495 .map_err(|err| {
1496 log::debug!(target: crate::LOG_TARGET, "Burning 1 plank from {from:?} failed. Err: {err:?}");
1497 Error::<T>::TransferFailed
1498 })?;
1499
1500 from_info.dust =
1501 from_info.dust.checked_add(plank).ok_or_else(|| Error::<T>::TransferFailed)?;
1502 }
1503
1504 transfer_balance::<T>(from, to, value)?;
1505 transfer_dust::<T>(&mut from_info, &mut to_info, dust)?;
1506
1507 if to_info.dust >= plank {
1508 T::Currency::mint_into(to, 1u32.into())?;
1509 to_info.dust =
1510 to_info.dust.checked_sub(plank).ok_or_else(|| Error::<T>::TransferFailed)?;
1511 }
1512
1513 AccountInfoOf::<T>::set(&from_addr, Some(from_info));
1514 AccountInfoOf::<T>::set(&to_addr, Some(to_info));
1515
1516 Ok(())
1517 }
1518
1519 let value = BalanceWithDust::<BalanceOf<T>>::from_value::<T>(value)?;
1520 if value.is_zero() {
1521 return Ok(());
1522 }
1523
1524 if <System<T>>::account_exists(to) {
1525 return transfer_with_dust::<T>(from, to, value)
1526 }
1527
1528 let origin = origin.account_id()?;
1529 let ed = <T as Config>::Currency::minimum_balance();
1530 with_transaction(|| -> TransactionOutcome<DispatchResult> {
1531 match storage_meter
1532 .record_charge(&StorageDeposit::Charge(ed))
1533 .and_then(|_| {
1534 T::Currency::transfer(origin, to, ed, Preservation::Preserve)
1535 .map_err(|_| Error::<T>::StorageDepositNotEnoughFunds.into())
1536 })
1537 .and_then(|_| transfer_with_dust::<T>(from, to, value))
1538 {
1539 Ok(_) => TransactionOutcome::Commit(Ok(())),
1540 Err(err) => TransactionOutcome::Rollback(Err(err)),
1541 }
1542 })
1543 }
1544
1545 fn transfer_from_origin<S: storage::meter::State + Default + Debug>(
1547 origin: &Origin<T>,
1548 from: &Origin<T>,
1549 to: &T::AccountId,
1550 value: U256,
1551 storage_meter: &mut storage::meter::GenericMeter<T, S>,
1552 ) -> ExecResult {
1553 let from = match from {
1556 Origin::Signed(caller) => caller,
1557 Origin::Root if value.is_zero() => return Ok(Default::default()),
1558 Origin::Root => return Err(DispatchError::RootNotAllowed.into()),
1559 };
1560 Self::transfer(origin, from, to, value, storage_meter)
1561 .map(|_| Default::default())
1562 .map_err(Into::into)
1563 }
1564
1565 fn top_frame(&self) -> &Frame<T> {
1567 top_frame!(self)
1568 }
1569
1570 fn top_frame_mut(&mut self) -> &mut Frame<T> {
1572 top_frame_mut!(self)
1573 }
1574
1575 fn frames(&self) -> impl Iterator<Item = &Frame<T>> {
1579 core::iter::once(&self.first_frame).chain(&self.frames).rev()
1580 }
1581
1582 fn frames_mut(&mut self) -> impl Iterator<Item = &mut Frame<T>> {
1584 core::iter::once(&mut self.first_frame).chain(&mut self.frames).rev()
1585 }
1586
1587 fn is_recursive(&self) -> bool {
1589 let account_id = &self.top_frame().account_id;
1590 self.frames().skip(1).any(|f| &f.account_id == account_id)
1591 }
1592
1593 fn allows_reentry(&self, id: &T::AccountId) -> bool {
1595 !self.frames().any(|f| &f.account_id == id && !f.allows_reentry)
1596 }
1597
1598 fn account_balance(&self, who: &T::AccountId) -> U256 {
1600 let balance = AccountInfo::<T>::balance(AccountIdOrAddress::AccountId(who.clone()));
1601 crate::Pallet::<T>::convert_native_to_evm(balance)
1602 }
1603
1604 #[cfg(feature = "runtime-benchmarks")]
1607 pub(crate) fn override_export(&mut self, export: ExportedFunction) {
1608 self.top_frame_mut().entry_point = export;
1609 }
1610
1611 #[cfg(feature = "runtime-benchmarks")]
1612 pub(crate) fn set_block_number(&mut self, block_number: BlockNumberFor<T>) {
1613 self.block_number = block_number;
1614 }
1615
1616 fn block_hash(&self, block_number: U256) -> Option<H256> {
1617 let Ok(block_number) = BlockNumberFor::<T>::try_from(block_number) else {
1618 return None;
1619 };
1620 if block_number >= self.block_number {
1621 return None;
1622 }
1623 if block_number < self.block_number.saturating_sub(256u32.into()) {
1624 return None;
1625 }
1626 Some(System::<T>::block_hash(&block_number).into())
1627 }
1628}
1629
1630impl<'a, T, E> Ext for Stack<'a, T, E>
1631where
1632 T: Config,
1633 E: Executable<T>,
1634 BalanceOf<T>: Into<U256> + TryFrom<U256>,
1635 MomentOf<T>: Into<U256>,
1636 T::Hash: frame_support::traits::IsType<H256>,
1637{
1638 fn delegate_call(
1639 &mut self,
1640 gas_limit: Weight,
1641 deposit_limit: U256,
1642 address: H160,
1643 input_data: Vec<u8>,
1644 ) -> Result<(), ExecError> {
1645 *self.last_frame_output_mut() = Default::default();
1648
1649 let top_frame = self.top_frame_mut();
1650 let contract_info = top_frame.contract_info().clone();
1651 let account_id = top_frame.account_id.clone();
1652 let value = top_frame.value_transferred;
1653 if let Some(executable) = self.push_frame(
1654 FrameArgs::Call {
1655 dest: account_id,
1656 cached_info: Some(contract_info),
1657 delegated_call: Some(DelegateInfo {
1658 caller: self.caller().clone(),
1659 callee: address,
1660 }),
1661 },
1662 value,
1663 gas_limit,
1664 deposit_limit.saturated_into::<BalanceOf<T>>(),
1665 self.is_read_only(),
1666 )? {
1667 self.run(executable, input_data, BumpNonce::Yes)
1668 } else {
1669 Ok(())
1671 }
1672 }
1673
1674 fn terminate(&mut self, beneficiary: &H160) -> Result<CodeRemoved, DispatchError> {
1675 if self.is_recursive() {
1676 return Err(Error::<T>::TerminatedWhileReentrant.into());
1677 }
1678 let frame = self.top_frame_mut();
1679 if frame.entry_point == ExportedFunction::Constructor {
1680 return Err(Error::<T>::TerminatedInConstructor.into());
1681 }
1682 let info = frame.terminate();
1683 let beneficiary_account = T::AddressMapper::to_account_id(beneficiary);
1684 frame.nested_storage.terminate(&info, beneficiary_account);
1685
1686 info.queue_trie_for_deletion();
1687 let account_address = T::AddressMapper::to_address(&frame.account_id);
1688 AccountInfoOf::<T>::remove(&account_address);
1689 ImmutableDataOf::<T>::remove(&account_address);
1690 let removed = <CodeInfo<T>>::decrement_refcount(info.code_hash)?;
1691
1692 Ok(removed)
1693 }
1694
1695 fn own_code_hash(&mut self) -> &H256 {
1696 &self.top_frame_mut().contract_info().code_hash
1697 }
1698
1699 fn set_code_hash(&mut self, hash: H256) -> Result<CodeRemoved, DispatchError> {
1715 let frame = top_frame_mut!(self);
1716
1717 let info = frame.contract_info();
1718
1719 let prev_hash = info.code_hash;
1720 info.code_hash = hash;
1721
1722 let code_info = CodeInfoOf::<T>::get(hash).ok_or(Error::<T>::CodeNotFound)?;
1723
1724 let old_base_deposit = info.storage_base_deposit();
1725 let new_base_deposit = info.update_base_deposit(code_info.deposit());
1726 let deposit = StorageDeposit::Charge(new_base_deposit)
1727 .saturating_sub(&StorageDeposit::Charge(old_base_deposit));
1728
1729 frame.nested_storage.charge_deposit(frame.account_id.clone(), deposit);
1730
1731 <CodeInfo<T>>::increment_refcount(hash)?;
1732 let removed = <CodeInfo<T>>::decrement_refcount(prev_hash)?;
1733 Ok(removed)
1734 }
1735
1736 fn immutable_data_len(&mut self) -> u32 {
1737 self.top_frame_mut().contract_info().immutable_data_len()
1738 }
1739
1740 fn get_immutable_data(&mut self) -> Result<ImmutableData, DispatchError> {
1741 if self.top_frame().entry_point == ExportedFunction::Constructor {
1742 return Err(Error::<T>::InvalidImmutableAccess.into());
1743 }
1744
1745 let address = self
1747 .top_frame()
1748 .delegate
1749 .as_ref()
1750 .map(|d| d.callee)
1751 .unwrap_or(T::AddressMapper::to_address(self.account_id()));
1752 Ok(<ImmutableDataOf<T>>::get(address).ok_or_else(|| Error::<T>::InvalidImmutableAccess)?)
1753 }
1754
1755 fn set_immutable_data(&mut self, data: ImmutableData) -> Result<(), DispatchError> {
1756 let frame = self.top_frame_mut();
1757 if frame.entry_point == ExportedFunction::Call || data.is_empty() {
1758 return Err(Error::<T>::InvalidImmutableAccess.into());
1759 }
1760 frame.contract_info().set_immutable_data_len(data.len() as u32);
1761 <ImmutableDataOf<T>>::insert(T::AddressMapper::to_address(&frame.account_id), &data);
1762 Ok(())
1763 }
1764}
1765
1766impl<'a, T, E> PrecompileWithInfoExt for Stack<'a, T, E>
1767where
1768 T: Config,
1769 E: Executable<T>,
1770 BalanceOf<T>: Into<U256> + TryFrom<U256>,
1771 MomentOf<T>: Into<U256>,
1772 T::Hash: frame_support::traits::IsType<H256>,
1773{
1774 fn get_storage(&mut self, key: &Key) -> Option<Vec<u8>> {
1775 self.top_frame_mut().contract_info().read(key)
1776 }
1777
1778 fn get_storage_size(&mut self, key: &Key) -> Option<u32> {
1779 self.top_frame_mut().contract_info().size(key.into())
1780 }
1781
1782 fn set_storage(
1783 &mut self,
1784 key: &Key,
1785 value: Option<Vec<u8>>,
1786 take_old: bool,
1787 ) -> Result<WriteOutcome, DispatchError> {
1788 let frame = self.top_frame_mut();
1789 frame.contract_info.get(&frame.account_id).write(
1790 key.into(),
1791 value,
1792 Some(&mut frame.nested_storage),
1793 take_old,
1794 )
1795 }
1796
1797 fn charge_storage(&mut self, diff: &Diff) {
1798 self.top_frame_mut().nested_storage.charge(diff)
1799 }
1800
1801 fn instantiate(
1802 &mut self,
1803 gas_limit: Weight,
1804 deposit_limit: U256,
1805 code: Code,
1806 value: U256,
1807 input_data: Vec<u8>,
1808 salt: Option<&[u8; 32]>,
1809 ) -> Result<H160, ExecError> {
1810 *self.last_frame_output_mut() = Default::default();
1813 let sender = self.top_frame().account_id.clone();
1814 let executable = match &code {
1815 Code::Upload(bytecode) => {
1816 if !T::AllowEVMBytecode::get() {
1817 return Err(<Error<T>>::CodeRejected.into());
1818 }
1819 E::from_evm_init_code(bytecode.clone(), sender.clone())?
1820 },
1821 Code::Existing(hash) => E::from_storage(*hash, self.gas_meter_mut())?,
1822 };
1823 let executable = self.push_frame(
1824 FrameArgs::Instantiate {
1825 sender: sender.clone(),
1826 executable,
1827 salt,
1828 input_data: input_data.as_ref(),
1829 },
1830 value,
1831 gas_limit,
1832 deposit_limit.saturated_into::<BalanceOf<T>>(),
1833 self.is_read_only(),
1834 )?;
1835 let address = T::AddressMapper::to_address(&self.top_frame().account_id);
1836 if_tracing(|t| t.instantiate_code(&code, salt));
1837 self.run(executable.expect(FRAME_ALWAYS_EXISTS_ON_INSTANTIATE), input_data, BumpNonce::Yes)
1838 .map(|_| address)
1839 }
1840}
1841
1842impl<'a, T, E> PrecompileExt for Stack<'a, T, E>
1843where
1844 T: Config,
1845 E: Executable<T>,
1846 BalanceOf<T>: Into<U256> + TryFrom<U256>,
1847 MomentOf<T>: Into<U256>,
1848 T::Hash: frame_support::traits::IsType<H256>,
1849{
1850 type T = T;
1851
1852 fn call(
1853 &mut self,
1854 gas_limit: Weight,
1855 deposit_limit: U256,
1856 dest_addr: &H160,
1857 value: U256,
1858 input_data: Vec<u8>,
1859 allows_reentry: bool,
1860 read_only: bool,
1861 ) -> Result<(), ExecError> {
1862 self.top_frame_mut().allows_reentry = allows_reentry;
1866
1867 *self.last_frame_output_mut() = Default::default();
1870
1871 let try_call = || {
1872 let is_read_only = read_only || self.is_read_only();
1874
1875 let dest = if <AllPrecompiles<T>>::get::<Self>(dest_addr.as_fixed_bytes()).is_some() {
1877 T::AddressMapper::to_fallback_account_id(dest_addr)
1878 } else {
1879 T::AddressMapper::to_account_id(dest_addr)
1880 };
1881
1882 if !self.allows_reentry(&dest) {
1883 return Err(<Error<T>>::ReentranceDenied.into());
1884 }
1885
1886 let cached_info = self
1890 .frames()
1891 .find(|f| f.entry_point == ExportedFunction::Call && f.account_id == dest)
1892 .and_then(|f| match &f.contract_info {
1893 CachedContract::Cached(contract) => Some(contract.clone()),
1894 _ => None,
1895 });
1896
1897 if let Some(executable) = self.push_frame(
1898 FrameArgs::Call { dest: dest.clone(), cached_info, delegated_call: None },
1899 value,
1900 gas_limit,
1901 deposit_limit.saturated_into::<BalanceOf<T>>(),
1902 is_read_only,
1903 )? {
1904 self.run(executable, input_data, BumpNonce::Yes)
1905 } else {
1906 if_tracing(|t| {
1907 t.enter_child_span(
1908 T::AddressMapper::to_address(self.account_id()),
1909 T::AddressMapper::to_address(&dest),
1910 false,
1911 is_read_only,
1912 value,
1913 &input_data,
1914 Weight::zero(),
1915 );
1916 });
1917
1918 let result = if is_read_only && value.is_zero() {
1919 Ok(Default::default())
1920 } else if is_read_only {
1921 Err(Error::<T>::StateChangeDenied.into())
1922 } else {
1923 let account_id = self.account_id().clone();
1924 let frame = top_frame_mut!(self);
1925 Self::transfer_from_origin(
1926 &self.origin,
1927 &Origin::from_account_id(account_id),
1928 &dest,
1929 value,
1930 &mut frame.nested_storage,
1931 )
1932 };
1933
1934 if_tracing(|t| match result {
1935 Ok(ref output) => t.exit_child_span(&output, Weight::zero()),
1936 Err(e) => t.exit_child_span_with_error(e.error.into(), Weight::zero()),
1937 });
1938
1939 result.map(|_| ())
1940 }
1941 };
1942
1943 let result = try_call();
1945
1946 self.top_frame_mut().allows_reentry = true;
1948
1949 result
1950 }
1951
1952 fn get_transient_storage(&self, key: &Key) -> Option<Vec<u8>> {
1953 self.transient_storage.read(self.account_id(), key)
1954 }
1955
1956 fn get_transient_storage_size(&self, key: &Key) -> Option<u32> {
1957 self.transient_storage
1958 .read(self.account_id(), key)
1959 .map(|value| value.len() as _)
1960 }
1961
1962 fn set_transient_storage(
1963 &mut self,
1964 key: &Key,
1965 value: Option<Vec<u8>>,
1966 take_old: bool,
1967 ) -> Result<WriteOutcome, DispatchError> {
1968 let account_id = self.account_id().clone();
1969 self.transient_storage.write(&account_id, key, value, take_old)
1970 }
1971
1972 fn account_id(&self) -> &T::AccountId {
1973 &self.top_frame().account_id
1974 }
1975
1976 fn caller(&self) -> Origin<T> {
1977 if let Some(DelegateInfo { caller, .. }) = &self.top_frame().delegate {
1978 caller.clone()
1979 } else {
1980 self.frames()
1981 .nth(1)
1982 .map(|f| Origin::from_account_id(f.account_id.clone()))
1983 .unwrap_or(self.origin.clone())
1984 }
1985 }
1986
1987 fn origin(&self) -> &Origin<T> {
1988 &self.origin
1989 }
1990
1991 fn code_hash(&self, address: &H160) -> H256 {
1992 if let Some(code) = <AllPrecompiles<T>>::code(address.as_fixed_bytes()) {
1993 return sp_io::hashing::keccak_256(code).into()
1994 }
1995
1996 <AccountInfo<T>>::load_contract(&address)
1997 .map(|contract| contract.code_hash)
1998 .unwrap_or_else(|| {
1999 if System::<T>::account_exists(&T::AddressMapper::to_account_id(address)) {
2000 return EMPTY_CODE_HASH;
2001 }
2002 H256::zero()
2003 })
2004 }
2005
2006 fn code_size(&self, address: &H160) -> u64 {
2007 if let Some(code) = <AllPrecompiles<T>>::code(address.as_fixed_bytes()) {
2008 return code.len() as u64
2009 }
2010
2011 <AccountInfo<T>>::load_contract(&address)
2012 .and_then(|contract| CodeInfoOf::<T>::get(contract.code_hash))
2013 .map(|info| info.code_len())
2014 .unwrap_or_default()
2015 }
2016
2017 fn caller_is_origin(&self) -> bool {
2018 self.origin == self.caller()
2019 }
2020
2021 fn caller_is_root(&self) -> bool {
2022 self.caller_is_origin() && self.origin == Origin::Root
2024 }
2025
2026 fn balance(&self) -> U256 {
2027 self.account_balance(&self.top_frame().account_id)
2028 }
2029
2030 fn balance_of(&self, address: &H160) -> U256 {
2031 let balance =
2032 self.account_balance(&<Self::T as Config>::AddressMapper::to_account_id(address));
2033 if_tracing(|tracer| {
2034 tracer.balance_read(address, balance);
2035 });
2036 balance
2037 }
2038
2039 fn value_transferred(&self) -> U256 {
2040 self.top_frame().value_transferred.into()
2041 }
2042
2043 fn now(&self) -> U256 {
2044 (self.timestamp / 1000u32.into()).into()
2045 }
2046
2047 fn minimum_balance(&self) -> U256 {
2048 T::Currency::minimum_balance().into()
2049 }
2050
2051 fn deposit_event(&mut self, topics: Vec<H256>, data: Vec<u8>) {
2052 let contract = T::AddressMapper::to_address(self.account_id());
2053 if_tracing(|tracer| {
2054 tracer.log_event(contract, &topics, &data);
2055 });
2056 Contracts::<Self::T>::deposit_event(Event::ContractEmitted { contract, data, topics });
2057 }
2058
2059 fn block_number(&self) -> U256 {
2060 self.block_number.into()
2061 }
2062
2063 fn block_hash(&self, block_number: U256) -> Option<H256> {
2064 self.block_hash(block_number)
2065 }
2066
2067 fn block_author(&self) -> Option<H160> {
2068 Contracts::<Self::T>::block_author()
2069 }
2070
2071 fn gas_limit(&self) -> u64 {
2072 <T as frame_system::Config>::BlockWeights::get().max_block.ref_time()
2073 }
2074
2075 fn chain_id(&self) -> u64 {
2076 <T as Config>::ChainId::get()
2077 }
2078
2079 fn max_value_size(&self) -> u32 {
2080 limits::PAYLOAD_BYTES
2081 }
2082
2083 fn get_weight_price(&self, weight: Weight) -> U256 {
2084 T::WeightPrice::convert(weight).into()
2085 }
2086
2087 fn gas_meter(&self) -> &GasMeter<Self::T> {
2088 &self.top_frame().nested_gas
2089 }
2090
2091 fn gas_meter_mut(&mut self) -> &mut GasMeter<Self::T> {
2092 &mut self.top_frame_mut().nested_gas
2093 }
2094
2095 fn ecdsa_recover(&self, signature: &[u8; 65], message_hash: &[u8; 32]) -> Result<[u8; 33], ()> {
2096 secp256k1_ecdsa_recover_compressed(signature, message_hash).map_err(|_| ())
2097 }
2098
2099 fn sr25519_verify(&self, signature: &[u8; 64], message: &[u8], pub_key: &[u8; 32]) -> bool {
2100 sp_io::crypto::sr25519_verify(
2101 &SR25519Signature::from(*signature),
2102 message,
2103 &SR25519Public::from(*pub_key),
2104 )
2105 }
2106
2107 fn ecdsa_to_eth_address(&self, pk: &[u8; 33]) -> Result<[u8; 20], ()> {
2108 ECDSAPublic::from(*pk).to_eth_address()
2109 }
2110
2111 #[cfg(any(test, feature = "runtime-benchmarks"))]
2112 fn contract_info(&mut self) -> &mut ContractInfo<Self::T> {
2113 self.top_frame_mut().contract_info()
2114 }
2115
2116 #[cfg(any(feature = "runtime-benchmarks", test))]
2117 fn transient_storage(&mut self) -> &mut TransientStorage<Self::T> {
2118 &mut self.transient_storage
2119 }
2120
2121 fn is_read_only(&self) -> bool {
2122 self.top_frame().read_only
2123 }
2124
2125 fn last_frame_output(&self) -> &ExecReturnValue {
2126 &self.top_frame().last_frame_output
2127 }
2128
2129 fn last_frame_output_mut(&mut self) -> &mut ExecReturnValue {
2130 &mut self.top_frame_mut().last_frame_output
2131 }
2132}
2133
2134mod sealing {
2135 use super::*;
2136
2137 pub trait Sealed {}
2138 impl<'a, T: Config, E> Sealed for Stack<'a, T, E> {}
2139
2140 #[cfg(test)]
2141 impl<T: Config> sealing::Sealed for mock_ext::MockExt<T> {}
2142}