Skip to content

Commit

Permalink
Merge pull request #1168 from interlay/fix/contracts-runtime-api
Browse files Browse the repository at this point in the history
fix: contracts runtime-api and code limit
  • Loading branch information
gregdhill authored Aug 8, 2023
2 parents d95530d + 78132f0 commit f77d5b1
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 2 deletions.
7 changes: 5 additions & 2 deletions parachain/runtime/kintsugi/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -265,7 +268,7 @@ impl pallet_contracts::Config for Runtime {
type WeightInfo = ();
type ChainExtension = BtcRelayExtension;
type Schedule = DefaultSchedule;
type CallStack = [pallet_contracts::Frame<Self>; 5];
type CallStack = [pallet_contracts::Frame<Self>; 1];
type DepositPerByte = DepositPerByte;
type DepositPerItem = DepositPerItem;
type DefaultDepositLimit = DefaultDepositLimit;
Expand Down
128 changes: 128 additions & 0 deletions parachain/runtime/kintsugi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -2156,6 +2157,133 @@ impl_runtime_apis! {
)
}
}

impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash> for Runtime {
fn call(
origin: AccountId,
dest: AccountId,
value: Balance,
gas_limit: Option<Weight>,
storage_deposit_limit: Option<Balance>,
input_data: Vec<u8>,
) -> pallet_contracts_primitives::ContractExecResult<Balance> {
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<Weight>,
storage_deposit_limit: Option<Balance>,
code: pallet_contracts_primitives::Code<Hash>,
data: Vec<u8>,
salt: Vec<u8>,
) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, Balance> {
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<u8>,
storage_deposit_limit: Option<Balance>,
determinism: pallet_contracts::Determinism,
) -> pallet_contracts_primitives::CodeUploadResult<Hash, Balance>
{
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<u8>,
) -> 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<Block> for Runtime {
// fn benchmark_metadata(extra: bool) -> (
// Vec<frame_benchmarking::BenchmarkList>,
// Vec<frame_support::traits::StorageInfo>,
// ) {
// 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::<BenchmarkList>::new();
// list_benchmarks!(list, extra);
//
// let storage_info = AllPalletsWithSystem::storage_info();
//
// (list, storage_info)
// }
//
// fn dispatch_benchmark(
// config: frame_benchmarking::BenchmarkConfig
// ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, 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<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
//
// let mut batches = Vec::<BenchmarkBatch>::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;
Expand Down
3 changes: 3 additions & 0 deletions parachain/runtime/runtime-tests/src/parachain/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions parachain/src/chain_spec/kintsugi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ 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 {
fn assimilate_storage(&self, storage: &mut Storage) -> Result<(), String> {
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)
}
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions parachain/src/chain_spec/testnet_kintsugi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit f77d5b1

Please sign in to comment.