diff --git a/parachain/runtime/kintsugi/src/contracts.rs b/parachain/runtime/kintsugi/src/contracts.rs index b9d1a05fd7..182e941ea9 100644 --- a/parachain/runtime/kintsugi/src/contracts.rs +++ b/parachain/runtime/kintsugi/src/contracts.rs @@ -38,11 +38,14 @@ parameter_types! { pub const DeletionWeightLimit: Weight = Weight::from_parts(100000000, 0); pub const DepositPerByte: Balance = 1; pub const DepositPerItem: Balance = 1; - pub const MaxCodeLen: u32 = 123 * 1024; + // can't increase much beyond 400k unless we decrease max call stack height + pub const MaxCodeLen: u32 = 400_000; pub const MaxStorageKeyLen: u32 = 128; pub const UnsafeUnstableInterface: bool = false; pub const MaxDebugBufferLen: u32 = 2 * 1024 * 1024; pub const DefaultDepositLimit: Balance = 1_000_000_000_000; + // address 943dd009e661df00c8a21661ce6b89d4 + pub storage EnableContracts: bool = false; } pub struct NativeCurrencyWithEd; @@ -265,7 +268,7 @@ impl pallet_contracts::Config for Runtime { type WeightInfo = (); type ChainExtension = BtcRelayExtension; type Schedule = DefaultSchedule; - type CallStack = [pallet_contracts::Frame; 5]; + type CallStack = [pallet_contracts::Frame; 1]; type DepositPerByte = DepositPerByte; type DepositPerItem = DepositPerItem; type DefaultDepositLimit = DefaultDepositLimit; diff --git a/parachain/runtime/kintsugi/src/lib.rs b/parachain/runtime/kintsugi/src/lib.rs index 597fdb3bc7..8bbc49cd9a 100644 --- a/parachain/runtime/kintsugi/src/lib.rs +++ b/parachain/runtime/kintsugi/src/lib.rs @@ -28,6 +28,7 @@ use frame_system::{ use loans::{OnSlashHook, PostDeposit, PostTransfer, PreDeposit, PreTransfer}; use orml_asset_registry::SequentialId; use orml_traits::{currency::MutationHooks, parameter_type_with_key}; +use pallet_contracts_primitives::ContractResult; use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; use sp_api::impl_runtime_apis; use sp_core::{OpaqueMetadata, H256}; @@ -2156,6 +2157,133 @@ impl_runtime_apis! { ) } } + + impl pallet_contracts::ContractsApi for Runtime { + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: Option, + storage_deposit_limit: Option, + input_data: Vec, + ) -> pallet_contracts_primitives::ContractExecResult { + if !contracts::EnableContracts::get() { + return ContractResult { + gas_consumed: Default::default(), + gas_required: Default::default(), + storage_deposit: Default::default(), + debug_message: Default::default(), + result: Err(sp_runtime::DispatchError::Other("pallet_contracts is disabled")), + }; + } + + let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block); + Contracts::bare_call( + origin, + dest, + value, + gas_limit, + storage_deposit_limit, + input_data, + true, + pallet_contracts::Determinism::Enforced, + ) + } + + fn instantiate( + origin: AccountId, + value: Balance, + gas_limit: Option, + storage_deposit_limit: Option, + code: pallet_contracts_primitives::Code, + data: Vec, + salt: Vec, + ) -> pallet_contracts_primitives::ContractInstantiateResult { + if !contracts::EnableContracts::get() { + return ContractResult { + gas_consumed: Default::default(), + gas_required: Default::default(), + storage_deposit: Default::default(), + debug_message: Default::default(), + result: Err(sp_runtime::DispatchError::Other("pallet_contracts is disabled")), + }; + } + + let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block); + Contracts::bare_instantiate( + origin, + value, + gas_limit, + storage_deposit_limit, + code, + data, + salt, + true, + ) + } + + fn upload_code( + origin: AccountId, + code: Vec, + storage_deposit_limit: Option, + determinism: pallet_contracts::Determinism, + ) -> pallet_contracts_primitives::CodeUploadResult + { + if !contracts::EnableContracts::get() { + return Err(sp_runtime::DispatchError::Other("pallet_contracts is disabled")); + } + Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism) + } + + fn get_storage( + address: AccountId, + key: Vec, + ) -> pallet_contracts_primitives::GetStorageResult { + Contracts::get_storage(address, key) + } + } + + // todo: enable this once we add contracts benchmarking +// #[cfg(feature = "runtime-benchmarks")] +// impl frame_benchmarking::Benchmark for Runtime { +// fn benchmark_metadata(extra: bool) -> ( +// Vec, +// Vec, +// ) { +// use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; +// use frame_support::traits::StorageInfoTrait; +// use frame_system_benchmarking::Pallet as SystemBench; +// use baseline::Pallet as BaselineBench; +// +// let mut list = Vec::::new(); +// list_benchmarks!(list, extra); +// +// let storage_info = AllPalletsWithSystem::storage_info(); +// +// (list, storage_info) +// } +// +// fn dispatch_benchmark( +// config: frame_benchmarking::BenchmarkConfig +// ) -> Result, sp_runtime::RuntimeString> { +// use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, TrackedStorageKey}; +// use frame_system_benchmarking::Pallet as SystemBench; +// use baseline::Pallet as BaselineBench; +// +// impl frame_system_benchmarking::Config for Runtime {} +// impl baseline::Config for Runtime {} +// +// use frame_support::traits::WhitelistedStorageKeys; +// let whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); +// +// let mut batches = Vec::::new(); +// let params = (&config, &whitelist); +// add_benchmarks!(params, batches); +// +// if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } +// Ok(batches) +// } +// } } struct CheckInherents; diff --git a/parachain/runtime/runtime-tests/src/parachain/contracts.rs b/parachain/runtime/runtime-tests/src/parachain/contracts.rs index 7c4dff3976..0e1672390e 100644 --- a/parachain/runtime/runtime-tests/src/parachain/contracts.rs +++ b/parachain/runtime/runtime-tests/src/parachain/contracts.rs @@ -30,6 +30,9 @@ mod relay { fn test_basic_contract() { // not sure this case would ever be used, best we have a test for it anyway.. ExtBuilder::build().execute_with(|| { + let key = kintsugi_runtime_parachain::contracts::EnableContracts::key(); + let hex = hex::encode(key); + println!("key = {hex}"); // note: current working directory is diffent when you run this test, vs when you debug it. // However, the `PWD` env variable is (surprisingly) set to the workspace root in both cases. // So, we use a path relative to PWD diff --git a/parachain/src/chain_spec/kintsugi.rs b/parachain/src/chain_spec/kintsugi.rs index a77c2ee6ab..822389f282 100644 --- a/parachain/src/chain_spec/kintsugi.rs +++ b/parachain/src/chain_spec/kintsugi.rs @@ -17,6 +17,8 @@ pub struct KintsugiDevGenesisExt { pub(crate) enable_instant_seal: bool, /// The flag to enable EVM contract creation. pub(crate) enable_create: bool, + /// The flag to enable wasm contracts. + pub(crate) enable_contracts: bool, } impl sp_runtime::BuildStorage for KintsugiDevGenesisExt { @@ -24,6 +26,7 @@ impl sp_runtime::BuildStorage for KintsugiDevGenesisExt { sp_state_machine::BasicExternalities::execute_with_storage(storage, || { kintsugi_runtime::EnableManualSeal::set(&self.enable_instant_seal); kintsugi_runtime::evm::EnableCreate::set(&self.enable_create); + kintsugi_runtime::contracts::EnableContracts::set(&self.enable_contracts); }); self.genesis_config.assimilate_storage(storage) } @@ -73,6 +76,7 @@ pub fn kintsugi_dev_config(enable_instant_seal: bool) -> KintsugiDevChainSpec { ), enable_instant_seal, enable_create: true, + enable_contracts: true, }, Vec::new(), None, diff --git a/parachain/src/chain_spec/testnet_kintsugi.rs b/parachain/src/chain_spec/testnet_kintsugi.rs index 7ec7628e1a..a3ef51ea94 100644 --- a/parachain/src/chain_spec/testnet_kintsugi.rs +++ b/parachain/src/chain_spec/testnet_kintsugi.rs @@ -105,6 +105,7 @@ pub fn development_config(id: ParaId, enable_instant_seal: bool) -> KintsugiDevC ), enable_instant_seal, enable_create: true, + enable_contracts: true, }, Vec::new(), None,