idn_runtime/configs/
contracts.rs

1/*
2 * Copyright 2025 by Ideal Labs, LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use crate::{
18	weights::ContractsWeightInfo, Balance, Balances, Perbill, RandBeacon, Runtime, RuntimeCall,
19	RuntimeEvent, RuntimeHoldReason, Timestamp, MILLIUNIT, UNIT,
20};
21use codec::Encode;
22use frame_support::{
23	parameter_types,
24	traits::{ConstBool, ConstU32, Nothing, Randomness},
25};
26use frame_system::EnsureSigned;
27use pallet_contracts::chain_extension::{
28	ChainExtension, Environment, Ext, InitState, RetVal, SysConfig,
29};
30use sp_core::{crypto::UncheckedFrom, H256};
31use sp_runtime::DispatchError;
32use sp_std::convert::AsRef;
33
34const fn deposit(items: u32, bytes: u32) -> Balance {
35	(items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10
36}
37
38#[derive(Default)]
39pub struct RandExtension;
40
41impl ChainExtension<Runtime> for RandExtension {
42	fn call<E: Ext>(&mut self, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>
43	where
44		<E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,
45	{
46		let func_id = env.func_id();
47		log::trace!(
48			target: "runtime",
49			"[ChainExtension]|call|func_id:{:}",
50			func_id
51		);
52		match func_id {
53			1101 => {
54				let mut env = env.buf_in_buf_out();
55				let arg: [u8; 32] = env.read_as()?;
56				let caller = env.ext().caller().clone();
57				let seed = [caller.encode(), env.ext().address().encode(), arg.encode()].concat();
58				let (rand_hash, _block_number): (H256, _) = RandBeacon::random(&seed);
59				env.write(&rand_hash.encode(), false, None)
60					.map_err(|_| DispatchError::Other("Failed to write output randomness"))?;
61
62				Ok(RetVal::Converging(0))
63			},
64			_ => {
65				log::error!("Called an unregistered `func_id`: {:}", func_id);
66				Err(DispatchError::Other("Unimplemented func_id"))
67			},
68		}
69	}
70
71	fn enabled() -> bool {
72		true
73	}
74}
75
76fn schedule<T: pallet_contracts::Config>() -> pallet_contracts::Schedule<T> {
77	pallet_contracts::Schedule {
78		limits: pallet_contracts::Limits {
79			runtime_memory: 1024 * 1024 * 1024,
80			validator_runtime_memory: 1024 * 1024 * 1024 * 2,
81			..Default::default()
82		},
83		..Default::default()
84	}
85}
86
87parameter_types! {
88	pub const DepositPerItem: Balance = deposit(1, 0);
89	pub const DepositPerByte: Balance = deposit(0, 1);
90	pub Schedule: pallet_contracts::Schedule<Runtime> = schedule::<Runtime>();
91	pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024);
92	pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0);
93	pub const MaxDelegateDependencies: u32 = 32;
94}
95
96impl pallet_contracts::Config for Runtime {
97	type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
98	type ApiVersion = ();
99	// IMPORTANT: only runtime calls through the api are allowed.
100	type CallFilter = Nothing;
101	type CallStack = [pallet_contracts::Frame<Self>; 23];
102	type ChainExtension = RandExtension;
103	type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
104	type Currency = Balances;
105	type Debug = ();
106	type DefaultDepositLimit = DefaultDepositLimit;
107	type DepositPerByte = DepositPerByte;
108	type DepositPerItem = DepositPerItem;
109	type Environment = ();
110	type InstantiateOrigin = EnsureSigned<Self::AccountId>;
111	type MaxCodeLen = ConstU32<{ 128 * 1024 }>;
112	type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>;
113	type MaxDelegateDependencies = ConstU32<32>;
114	type MaxStorageKeyLen = ConstU32<128>;
115	type MaxTransientStorageSize = ConstU32<{ 1024 * 1024 }>;
116	#[cfg(not(feature = "runtime-benchmarks"))]
117	type Migrations = ();
118	#[cfg(feature = "runtime-benchmarks")]
119	type Migrations = pallet_contracts::migration::codegen::BenchMigrations;
120	/// Contracts randomness provider is the randomness beacon pallet.
121	type Randomness = RandBeacon;
122	type RuntimeCall = RuntimeCall;
123	type RuntimeEvent = RuntimeEvent;
124	type RuntimeHoldReason = RuntimeHoldReason;
125	type Schedule = Schedule;
126	type Time = Timestamp;
127	type UnsafeUnstableInterface = ConstBool<true>;
128	type UploadOrigin = EnsureSigned<Self::AccountId>;
129	type WeightInfo = ContractsWeightInfo<Runtime>;
130	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
131	type Xcm = pallet_xcm::Pallet<Self>;
132}