From 5bd0ba996d0b0f9ba28b4bcfc3b91cdbfd467405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dino=20Pa=C4=8Dandi?= <3002868+Dinonard@users.noreply.github.com> Date: Wed, 29 Mar 2023 09:03:41 +0200 Subject: [PATCH] Pallet contracts on Astar (#891) * Pallet contracts on Astar * Update pallet-contracts dep * Bump pallet-contracts --- Cargo.lock | 18 +++--- bin/collator/Cargo.toml | 2 +- runtime/astar/Cargo.toml | 7 ++- runtime/astar/src/lib.rs | 111 +++++++++++++++++++++++++++++++++++-- runtime/local/Cargo.toml | 2 +- runtime/local/src/lib.rs | 1 - runtime/shibuya/Cargo.toml | 2 +- runtime/shibuya/src/lib.rs | 11 +--- runtime/shiden/Cargo.toml | 2 +- runtime/shiden/src/lib.rs | 12 +--- 10 files changed, 130 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cbab3be7a1..261e8f3f8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,7 +335,7 @@ dependencies = [ [[package]] name = "astar-collator" -version = "5.2.0" +version = "5.3.0" dependencies = [ "astar-runtime", "async-trait", @@ -435,7 +435,7 @@ dependencies = [ [[package]] name = "astar-runtime" -version = "5.2.0" +version = "5.3.0" dependencies = [ "array-bytes 6.0.0", "cumulus-pallet-aura-ext", @@ -467,6 +467,8 @@ dependencies = [ "pallet-block-reward", "pallet-collator-selection", "pallet-collective", + "pallet-contracts", + "pallet-contracts-primitives", "pallet-custom-signatures", "pallet-dapps-staking", "pallet-ethereum", @@ -5071,7 +5073,7 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "local-runtime" -version = "5.2.0" +version = "5.3.0" dependencies = [ "array-bytes 6.0.0", "fp-rpc", @@ -6478,7 +6480,7 @@ dependencies = [ [[package]] name = "pallet-contracts" version = "4.0.0-dev" -source = "git+https://github.com/AstarNetwork/substrate?branch=polkadot-v0.9.37/pallet-contracts-latest#81bf978d88425de89c0c59028f91948675fee223" +source = "git+https://github.com/AstarNetwork/substrate?branch=polkadot-v0.9.37/pallet-contracts-latest#bdc0032afd539fd4cb3fd1239dd85e2c16b533b6" dependencies = [ "bitflags", "frame-benchmarking", @@ -6506,7 +6508,7 @@ dependencies = [ [[package]] name = "pallet-contracts-primitives" version = "7.0.0" -source = "git+https://github.com/AstarNetwork/substrate?branch=polkadot-v0.9.37/pallet-contracts-latest#81bf978d88425de89c0c59028f91948675fee223" +source = "git+https://github.com/AstarNetwork/substrate?branch=polkadot-v0.9.37/pallet-contracts-latest#bdc0032afd539fd4cb3fd1239dd85e2c16b533b6" dependencies = [ "bitflags", "parity-scale-codec", @@ -6519,7 +6521,7 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/AstarNetwork/substrate?branch=polkadot-v0.9.37/pallet-contracts-latest#81bf978d88425de89c0c59028f91948675fee223" +source = "git+https://github.com/AstarNetwork/substrate?branch=polkadot-v0.9.37/pallet-contracts-latest#bdc0032afd539fd4cb3fd1239dd85e2c16b533b6" dependencies = [ "proc-macro2", "quote", @@ -11407,7 +11409,7 @@ dependencies = [ [[package]] name = "shibuya-runtime" -version = "5.2.0" +version = "5.3.0" dependencies = [ "array-bytes 6.0.0", "cumulus-pallet-aura-ext", @@ -11509,7 +11511,7 @@ dependencies = [ [[package]] name = "shiden-runtime" -version = "5.2.0" +version = "5.3.0" dependencies = [ "array-bytes 6.0.0", "cumulus-pallet-aura-ext", diff --git a/bin/collator/Cargo.toml b/bin/collator/Cargo.toml index 921ac49697..4641321f01 100644 --- a/bin/collator/Cargo.toml +++ b/bin/collator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "astar-collator" -version = "5.2.0" +version = "5.3.0" description = "Astar collator implementation in Rust." build = "build.rs" default-run = "astar-collator" diff --git a/runtime/astar/Cargo.toml b/runtime/astar/Cargo.toml index b6d03ed8cb..9dcd661796 100644 --- a/runtime/astar/Cargo.toml +++ b/runtime/astar/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "astar-runtime" -version = "5.2.0" +version = "5.3.0" build = "build.rs" authors.workspace = true edition.workspace = true @@ -41,6 +41,8 @@ pallet-aura = { workspace = true } pallet-authorship = { workspace = true } pallet-balances = { workspace = true } pallet-base-fee = { workspace = true } +pallet-contracts = { workspace = true } +pallet-contracts-primitives = { workspace = true } pallet-ethereum = { workspace = true } pallet-evm = { workspace = true } pallet-evm-precompile-blake2 = { workspace = true } @@ -176,6 +178,8 @@ std = [ "cumulus-pallet-aura-ext/std", "cumulus-pallet-dmp-queue/std", "cumulus-pallet-xcmp-queue/std", + "pallet-contracts/std", + "pallet-contracts-primitives/std", "cumulus-pallet-xcm/std", "pallet-collator-selection/std", "frame-benchmarking/std", @@ -240,6 +244,7 @@ try-runtime = [ "cumulus-pallet-xcmp-queue/try-runtime", "parachain-info/try-runtime", "pallet-base-fee/try-runtime", + "pallet-contracts/try-runtime", "pallet-evm/try-runtime", ] evm-tracing = [ diff --git a/runtime/astar/src/lib.rs b/runtime/astar/src/lib.rs index a15cdc5b8f..a71019652c 100644 --- a/runtime/astar/src/lib.rs +++ b/runtime/astar/src/lib.rs @@ -27,8 +27,8 @@ use frame_support::{ dispatch::DispatchClass, parameter_types, traits::{ - AsEnsureOriginWithArg, ConstU32, Contains, Currency, FindAuthor, Get, Imbalance, - OnUnbalanced, WithdrawReasons, + AsEnsureOriginWithArg, ConstBool, ConstU32, Contains, Currency, FindAuthor, Get, Imbalance, + Nothing, OnUnbalanced, Randomness, WithdrawReasons, }, weights::{ constants::{ @@ -57,6 +57,7 @@ use sp_runtime::{ traits::{ AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, ConvertInto, DispatchInfoOf, Dispatchable, OpaqueKeys, PostDispatchInfoOf, UniqueSaturatedInto, Verify, + Zero, }, transaction_validity::{ TransactionPriority, TransactionSource, TransactionValidity, TransactionValidityError, @@ -107,9 +108,7 @@ pub const fn deposit(items: u32, bytes: u32) -> Balance { /// /// The slight difference to general `deposit` function is because there is fixed bound on how large the DB /// key can grow so it doesn't make sense to have as high deposit per item as in the general approach. -/// -/// TODO: use this when `pallet-contracts` is added to **Astar** -pub const fn _contracts_deposit(items: u32, bytes: u32) -> Balance { +pub const fn contracts_deposit(items: u32, bytes: u32) -> Balance { items as Balance * 4 * MILLIASTR * INIT_SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE } @@ -140,7 +139,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("astar"), impl_name: create_runtime_str!("astar"), authoring_version: 1, - spec_version: 54, + spec_version: 55, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, @@ -614,6 +613,55 @@ impl pallet_vesting::Config for Runtime { const MAX_VESTING_SCHEDULES: u32 = 28; } +parameter_types! { + pub const DepositPerItem: Balance = contracts_deposit(1, 0); + pub const DepositPerByte: Balance = contracts_deposit(0, 1); + // The lazy deletion runs inside on_initialize. + pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * + RuntimeBlockWeights::get().max_block; + pub Schedule: pallet_contracts::Schedule = Default::default(); +} + +/// Codes using the randomness functionality cannot be uploaded. Neither can contracts +/// be instantiated from existing codes that use this deprecated functionality. +/// +/// But since some `Randomness` config type is still required for `pallet-contracts`, we provide this dummy type. +pub struct DummyDeprecatedRandomness; +impl Randomness for DummyDeprecatedRandomness { + fn random(_: &[u8]) -> (Hash, BlockNumber) { + (Default::default(), Zero::zero()) + } +} + +impl pallet_contracts::Config for Runtime { + type Time = Timestamp; + type Randomness = DummyDeprecatedRandomness; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + /// The safest default is to allow no calls at all. + /// + /// Runtimes should whitelist dispatchables that are allowed to be called from contracts + /// and make sure they are stable. Dispatchables exposed to contracts are not allowed to + /// change because that would break already deployed contracts. The `Call` structure itself + /// is not allowed to change the indices of existing pallets, too. + type CallFilter = Nothing; + type DepositPerItem = DepositPerItem; + type DepositPerByte = DepositPerByte; + type CallStack = [pallet_contracts::Frame; 5]; + type WeightPrice = pallet_transaction_payment::Pallet; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type ChainExtension = (); + type DeletionQueueDepth = ConstU32<128>; + type DeletionWeightLimit = DeletionWeightLimit; + type Schedule = Schedule; + type AddressGenerator = pallet_contracts::DefaultAddressGenerator; + type MaxCodeLen = ConstU32<{ 123 * 1024 }>; + type MaxStorageKeyLen = ConstU32<128>; + type UnsafeUnstableInterface = ConstBool; + type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; +} + parameter_types! { pub const TransactionByteFee: Balance = MILLIASTR / 100; pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); @@ -838,6 +886,8 @@ construct_runtime!( EthCall: pallet_custom_signatures = 62, BaseFee: pallet_base_fee = 63, + Contracts: pallet_contracts = 70, + Sudo: pallet_sudo = 99, } ); @@ -1246,6 +1296,55 @@ 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, + storage_deposit_limit: Option, + input_data: Vec, + ) -> pallet_contracts_primitives::ContractExecResult { + 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::Deterministic) + } + + 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 + { + 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 + { + 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) + } + } + #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( diff --git a/runtime/local/Cargo.toml b/runtime/local/Cargo.toml index 9b5d4ff9ce..cd4aef773c 100644 --- a/runtime/local/Cargo.toml +++ b/runtime/local/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "local-runtime" -version = "5.2.0" +version = "5.3.0" build = "build.rs" authors.workspace = true edition.workspace = true diff --git a/runtime/local/src/lib.rs b/runtime/local/src/lib.rs index 4f30f271ec..21e61fa6fd 100644 --- a/runtime/local/src/lib.rs +++ b/runtime/local/src/lib.rs @@ -760,7 +760,6 @@ impl pallet_vesting::Config for Runtime { parameter_types! { pub const DepositPerItem: Balance = deposit(1, 0); pub const DepositPerByte: Balance = deposit(0, 1); - pub const MaxValueSize: u32 = 16 * 1024; // The lazy deletion runs inside on_initialize. pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * RuntimeBlockWeights::get().max_block; diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index bedd110215..f09dafccc8 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shibuya-runtime" -version = "5.2.0" +version = "5.3.0" build = "build.rs" authors.workspace = true edition.workspace = true diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index fa5374d3f9..1999a9e8a2 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -29,8 +29,7 @@ use frame_support::{ parameter_types, traits::{ AsEnsureOriginWithArg, ConstU32, Contains, Currency, EitherOfDiverse, EqualPrivilegeOnly, - FindAuthor, Get, GetStorageVersion, Imbalance, InstanceFilter, Nothing, OnUnbalanced, - WithdrawReasons, + FindAuthor, Get, Imbalance, InstanceFilter, Nothing, OnUnbalanced, WithdrawReasons, }, weights::{ constants::{ @@ -170,7 +169,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("shibuya"), impl_name: create_runtime_str!("shibuya"), authoring_version: 1, - spec_version: 94, + spec_version: 95, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, @@ -246,11 +245,6 @@ impl Contains for BaseFilter { // registering the asset location should be good enough for users, any change can be handled via issue ticket or help request _ => false, }, - RuntimeCall::Contracts(_) => { - // We block the calls until storage migration has been finished. - // The DB read weight is already accounted for in the migration pallet's `on_initialize` function. - >::on_chain_storage_version() == 9 - } // These modules are not allowed to be called by transactions: // Other modules should works: _ => true, @@ -668,7 +662,6 @@ impl pallet_vesting::Config for Runtime { parameter_types! { pub const DepositPerItem: Balance = MILLISBY / 1_000_000; pub const DepositPerByte: Balance = MILLISBY / 1_000_000; - pub const MaxValueSize: u32 = 16 * 1024; // The lazy deletion runs inside on_initialize. pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * RuntimeBlockWeights::get().max_block; diff --git a/runtime/shiden/Cargo.toml b/runtime/shiden/Cargo.toml index fd6e5b5269..248f59e398 100644 --- a/runtime/shiden/Cargo.toml +++ b/runtime/shiden/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shiden-runtime" -version = "5.2.0" +version = "5.3.0" build = "build.rs" authors.workspace = true edition.workspace = true diff --git a/runtime/shiden/src/lib.rs b/runtime/shiden/src/lib.rs index 494bcfa5f1..dd347cab09 100644 --- a/runtime/shiden/src/lib.rs +++ b/runtime/shiden/src/lib.rs @@ -28,8 +28,8 @@ use frame_support::{ dispatch::DispatchClass, parameter_types, traits::{ - AsEnsureOriginWithArg, ConstU32, Contains, Currency, FindAuthor, Get, GetStorageVersion, - InstanceFilter, Nothing, OnUnbalanced, WithdrawReasons, + AsEnsureOriginWithArg, ConstU32, Contains, Currency, FindAuthor, Get, InstanceFilter, + Nothing, OnUnbalanced, WithdrawReasons, }, weights::{ constants::{ @@ -139,7 +139,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("shiden"), impl_name: create_runtime_str!("shiden"), authoring_version: 1, - spec_version: 92, + spec_version: 93, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, @@ -209,11 +209,6 @@ impl Contains for BaseFilter { _ => true, }, - RuntimeCall::Contracts(_) => { - // We block the calls until storage migration has been finished. - // The DB read weight is already accounted for in the migration pallet's `on_initialize` function. - >::on_chain_storage_version() == 9 - } // These modules are not allowed to be called by transactions: // To leave collator just shutdown it, next session funds will be released // Other modules should works: @@ -623,7 +618,6 @@ impl pallet_vesting::Config for Runtime { parameter_types! { pub const DepositPerItem: Balance = MILLISDN / 1_000_000; pub const DepositPerByte: Balance = MILLISDN / 1_000_000; - pub const MaxValueSize: u32 = 16 * 1024; // The lazy deletion runs inside on_initialize. pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * RuntimeBlockWeights::get().max_block;