diff --git a/Cargo.lock b/Cargo.lock index f5464cf2a1..42e299384a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13156,13 +13156,13 @@ dependencies = [ "pallet-aura", "pallet-authorship", "pallet-balances", - "pallet-base-fee", "pallet-block-reward", "pallet-collator-selection", "pallet-collective", "pallet-contracts", "pallet-contracts-primitives", "pallet-dapps-staking", + "pallet-dynamic-evm-base-fee", "pallet-ethereum", "pallet-evm", "pallet-evm-precompile-assets-erc20", diff --git a/bin/collator/src/parachain/chain_spec/shiden.rs b/bin/collator/src/parachain/chain_spec/shiden.rs index 2982f8ac60..bc7ee05487 100644 --- a/bin/collator/src/parachain/chain_spec/shiden.rs +++ b/bin/collator/src/parachain/chain_spec/shiden.rs @@ -21,7 +21,7 @@ use cumulus_primitives_core::ParaId; use sc_service::ChainType; use shiden_runtime::{ - wasm_binary_unwrap, AccountId, AuraId, Balance, BaseFeeConfig, BlockRewardConfig, EVMConfig, + wasm_binary_unwrap, AccountId, AuraId, Balance, BlockRewardConfig, EVMConfig, ParachainInfoConfig, Precompiles, Signature, SystemConfig, SDN, }; use sp_core::{sr25519, Pair, Public}; @@ -156,10 +156,6 @@ fn make_genesis( }) .collect(), }, - base_fee: BaseFeeConfig::new( - sp_core::U256::from(1_000_000_000), - sp_runtime::Permill::zero(), - ), ethereum: Default::default(), polkadot_xcm: Default::default(), assets: Default::default(), diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index 3f57087b85..a0cf86f201 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -681,7 +681,7 @@ impl pallet_contracts::Config for Runtime { // These values are based on the Astar 2.0 Tokenomics Modeling report. parameter_types! { pub const TransactionLengthFeeFactor: Balance = 23_500_000_000_000; // 0.000_023_500_000_000_000 SBY per byte - pub const WeightFeeFactor: Balance = 30_855_000_000_000_000; // Around 0.03 SBY per unit of ref time. + pub const WeightFeeFactor: Balance = 30_855_000_000_000_000; // Around 0.03 SBY per unit of base weight. pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); pub const OperationalFeeMultiplier: u8 = 5; pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 666_667); // 0.000_015 @@ -718,17 +718,17 @@ pub struct DealWithFees; impl OnUnbalanced for DealWithFees { fn on_unbalanceds(mut fees_then_tips: impl Iterator) { if let Some(fees) = fees_then_tips.next() { - // Burn 80% of fees, rest goes to collators, including 100% of the tips. - let (to_burn, mut collators) = fees.ration(80, 20); + // Burn 80% of fees, rest goes to collator, including 100% of the tips. + let (to_burn, mut collator) = fees.ration(80, 20); if let Some(tips) = fees_then_tips.next() { - tips.merge_into(&mut collators); + tips.merge_into(&mut collator); } - // burn part of fees + // burn part of the fees drop(to_burn); - // pay fees to collators - >::on_unbalanced(collators); + // pay fees to collator + >::on_unbalanced(collator); } } } @@ -1311,57 +1311,10 @@ pub type Executive = frame_executive::Executive< Migrations, >; -// Used to cleanup BaseFee storage - remove once cleanup is done. -parameter_types! { - pub const BaseFeeStr: &'static str = "BaseFee"; -} - -/// Simple `OnRuntimeUpgrade` logic to prepare Shibuya runtime for `DynamicEvmBaseFee` pallet. -pub use frame_support::traits::{OnRuntimeUpgrade, StorageVersion}; -pub struct DynamicEvmBaseFeeMigration; -impl OnRuntimeUpgrade for DynamicEvmBaseFeeMigration { - fn on_runtime_upgrade() -> Weight { - // Safety check to ensure we don't execute this migration twice - if pallet_dynamic_evm_base_fee::BaseFeePerGas::::exists() { - return ::DbWeight::get().reads(1); - } - - // Set the init value to what was set before on the old `BaseFee` pallet. - pallet_dynamic_evm_base_fee::BaseFeePerGas::::put(U256::from(1_000_000_000_u128)); - - // Shibuya's multiplier is so low that we have to set it to minimum value directly. - pallet_transaction_payment::NextFeeMultiplier::::put(MinimumMultiplier::get()); - - // Set init storage version for the pallet - StorageVersion::new(1).put::>(); - - ::DbWeight::get().reads_writes(1, 3) - } -} - -/// Simple `OnRuntimeUpgrade` logic to remove all corrupted mappings -/// after the fixing the typo in mapping names in pallet. -pub struct ClearCorruptedUnifiedMappings; -impl OnRuntimeUpgrade for ClearCorruptedUnifiedMappings { - fn on_runtime_upgrade() -> Weight { - let maybe_limit = pallet_unified_accounts::EvmToNative::::iter().count(); - let total_rw = maybe_limit as u64 * 2; - // remove all items - let _ = pallet_unified_accounts::EvmToNative::::clear(maybe_limit as u32, None); - let _ = pallet_unified_accounts::NativeToEvm::::clear(maybe_limit as u32, None); - - ::DbWeight::get().reads_writes(total_rw, total_rw) - } -} - /// All migrations that will run on the next runtime upgrade. /// /// Once done, migrations should be removed from the tuple. -pub type Migrations = ( - frame_support::migrations::RemovePallet, - DynamicEvmBaseFeeMigration, - ClearCorruptedUnifiedMappings, -); +pub type Migrations = (); type EventRecord = frame_system::EventRecord< ::RuntimeEvent, diff --git a/runtime/shiden/Cargo.toml b/runtime/shiden/Cargo.toml index 9b8631a246..127dab3d94 100644 --- a/runtime/shiden/Cargo.toml +++ b/runtime/shiden/Cargo.toml @@ -42,9 +42,9 @@ pallet-assets = { workspace = true } 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-dynamic-evm-base-fee = { workspace = true } pallet-ethereum = { workspace = true } pallet-evm = { workspace = true } pallet-evm-precompile-blake2 = { workspace = true } @@ -147,7 +147,7 @@ std = [ "pallet-contracts/std", "pallet-contracts-primitives/std", "pallet-block-reward/std", - "pallet-base-fee/std", + "pallet-dynamic-evm-base-fee/std", "pallet-ethereum/std", "pallet-evm/std", "pallet-evm-precompile-blake2/std", @@ -222,6 +222,7 @@ runtime-benchmarks = [ "pallet-collator-selection/runtime-benchmarks", "astar-primitives/runtime-benchmarks", "pallet-assets/runtime-benchmarks", + "pallet-dynamic-evm-base-fee/runtime-benchmarks", ] try-runtime = [ "fp-self-contained/try-runtime", @@ -257,7 +258,7 @@ try-runtime = [ "cumulus-pallet-xcm/try-runtime", "cumulus-pallet-xcmp-queue/try-runtime", "parachain-info/try-runtime", - "pallet-base-fee/try-runtime", + "pallet-dynamic-evm-base-fee/try-runtime", "pallet-evm/try-runtime", "orml-xtokens/try-runtime", ] diff --git a/runtime/shiden/src/lib.rs b/runtime/shiden/src/lib.rs index 70ce1bf916..bd8dbbc46f 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, InstanceFilter, - Nothing, OnFinalize, OnUnbalanced, WithdrawReasons, + AsEnsureOriginWithArg, ConstU32, Contains, Currency, FindAuthor, Get, Imbalance, + InstanceFilter, Nothing, OnFinalize, OnUnbalanced, WithdrawReasons, }, weights::{ constants::{ @@ -57,7 +57,7 @@ use sp_inherents::{CheckInherentsResult, InherentData}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ - AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, ConvertInto, + AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, DispatchInfoOf, Dispatchable, OpaqueKeys, PostDispatchInfoOf, UniqueSaturatedInto, }, transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, @@ -93,27 +93,24 @@ pub use precompiles::{ShidenNetworkPrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX} pub type Precompiles = ShidenNetworkPrecompiles; /// Constant values used within the runtime. -pub const MICROSDN: Balance = 1_000_000_000_000; +pub const NANOSDN: Balance = 1_000_000_000; +pub const MICROSDN: Balance = 1_000 * NANOSDN; pub const MILLISDN: Balance = 1_000 * MICROSDN; pub const SDN: Balance = 1_000 * MILLISDN; -pub const INIT_SUPPLY_FACTOR: Balance = 1; - -pub const STORAGE_BYTE_FEE: Balance = 20 * MICROSDN * INIT_SUPPLY_FACTOR; +pub const STORAGE_BYTE_FEE: Balance = 200 * NANOSDN; /// Charge fee for stored bytes and items. pub const fn deposit(items: u32, bytes: u32) -> Balance { - items as Balance * 100 * MILLISDN * INIT_SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE + items as Balance * MILLISDN + (bytes as Balance) * STORAGE_BYTE_FEE } /// Charge fee for stored bytes and items as part of `pallet-contracts`. /// /// 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: using this requires some storage migration since we're using some old, legacy values ATM pub const fn contracts_deposit(items: u32, bytes: u32) -> Balance { - items as Balance * 4 * MILLISDN * INIT_SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE + items as Balance * 40 * MICROSDN + (bytes as Balance) * STORAGE_BYTE_FEE } /// Change this to adjust the block time. @@ -541,7 +538,7 @@ impl AddressToAssetId for Runtime { } parameter_types! { - pub const AssetDeposit: Balance = 10 * INIT_SUPPLY_FACTOR * SDN; + pub const AssetDeposit: Balance = 10 * SDN; pub const AssetsStringLimit: u32 = 50; /// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1) // https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271 @@ -593,8 +590,8 @@ impl pallet_vesting::Config for Runtime { // TODO: changing depost per item and per byte to `deposit` function will require storage migration it seems parameter_types! { - pub const DepositPerItem: Balance = MILLISDN / 1_000_000; - pub const DepositPerByte: Balance = MILLISDN / 1_000_000; + pub const DepositPerItem: Balance = contracts_deposit(1, 0); + pub const DepositPerByte: Balance = contracts_deposit(0, 1); // Fallback value if storage deposit limit not set by the user pub const DefaultDepositLimit: Balance = contracts_deposit(16, 16 * 1024); pub Schedule: pallet_contracts::Schedule = Default::default(); @@ -629,12 +626,13 @@ impl pallet_contracts::Config for Runtime { } parameter_types! { - pub const TransactionByteFee: Balance = MILLISDN / 100; + pub const TransactionLengthFeeFactor: Balance = 235_000_000_000; // 0.000_000_235_000_000_000 SDN per byte + pub const WeightFeeFactor: Balance = 308_550_000_000_000; // Around 0.000_300 SDN per unit of base weight. pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); pub const OperationalFeeMultiplier: u8 = 5; - pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000); - pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128); - pub MaximumMultiplier: Multiplier = Bounded::max_value(); + pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 666_667); // 0.000_015 + pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10); // 0.1 + pub MaximumMultiplier: Multiplier = Multiplier::saturating_from_integer(10); // 10 } /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the @@ -651,9 +649,8 @@ pub struct WeightToFee; impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; fn polynomial() -> WeightToFeeCoefficients { - // in Shiden, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 mSDN: - let p = MILLISDN; - let q = 10 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + let p = WeightFeeFactor::get(); + let q = Balance::from(ExtrinsicBaseWeight::get().ref_time()); smallvec::smallvec![WeightToFeeCoefficient { degree: 1, negative: false, @@ -667,13 +664,18 @@ pub struct BurnFees; impl OnUnbalanced for BurnFees { /// Payout tips but burn all the fees fn on_unbalanceds(mut fees_then_tips: impl Iterator) { - if let Some(fees_to_burn) = fees_then_tips.next() { + if let Some(fees) = fees_then_tips.next() { + // Burn 80% of fees, rest goes to the collator, including 100% of the tips. + let (to_burn, mut collator) = fees.ration(80, 20); if let Some(tips) = fees_then_tips.next() { - >::on_unbalanced(tips); + tips.merge_into(&mut collator); } - // burn fees - drop(fees_to_burn); + // burn part of the fees + drop(to_burn); + + // pay fees to collator + >::on_unbalanced(collator); } } } @@ -690,33 +692,33 @@ impl pallet_transaction_payment::Config for Runtime { MinimumMultiplier, MaximumMultiplier, >; - type LengthToFee = ConstantMultiplier; + type LengthToFee = ConstantMultiplier; } parameter_types! { - pub DefaultBaseFeePerGas: U256 = (MILLISDN / 1_000_000).into(); - // At the moment, we don't use dynamic fee calculation for Shiden by default - pub DefaultElasticity: Permill = Permill::zero(); + pub DefaultBaseFeePerGas: U256 = U256::from(14_700_000_000_u128); + pub MinBaseFeePerGas: U256 = U256::from(8_000_000_000_u128); + pub MaxBaseFeePerGas: U256 = U256::from(800_000_000_000_u128); + pub StepLimitRatio: Perquintill = Perquintill::from_rational(5_u128, 100_000); } -pub struct BaseFeeThreshold; -impl pallet_base_fee::BaseFeeThreshold for BaseFeeThreshold { - fn lower() -> Permill { - Permill::zero() - } - fn ideal() -> Permill { - Permill::from_parts(500_000) - } - fn upper() -> Permill { - Permill::from_parts(1_000_000) +/// Simple wrapper for fetching current native transaction fee weight fee multiplier. +pub struct AdjustmentFactorGetter; +impl Get for AdjustmentFactorGetter { + fn get() -> Multiplier { + pallet_transaction_payment::NextFeeMultiplier::::get() } } -impl pallet_base_fee::Config for Runtime { +impl pallet_dynamic_evm_base_fee::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type Threshold = BaseFeeThreshold; type DefaultBaseFeePerGas = DefaultBaseFeePerGas; - type DefaultElasticity = DefaultElasticity; + type MinBaseFeePerGas = MinBaseFeePerGas; + type MaxBaseFeePerGas = MaxBaseFeePerGas; + type AdjustmentFactor = AdjustmentFactorGetter; + type WeightFactor = WeightFeeFactor; + type StepLimitRatio = StepLimitRatio; + type WeightInfo = pallet_dynamic_evm_base_fee::weights::SubstrateWeight; } /// Current approximation of the gas/s consumption considering @@ -766,7 +768,7 @@ parameter_types! { } impl pallet_evm::Config for Runtime { - type FeeCalculator = BaseFee; + type FeeCalculator = DynamicEvmBaseFee; type GasWeightMapping = pallet_evm::FixedGasWeightMapping; type WeightPerGas = WeightPerGas; type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; @@ -885,7 +887,7 @@ impl InstanceFilter for ProxyType { | RuntimeCall::XcAssetConfig(..) // Skip entire EVM pallet // Skip entire Ethereum pallet - | RuntimeCall::BaseFee(..) // Skip entire Contracts pallet + | RuntimeCall::DynamicEvmBaseFee(..) // Skip entire Contracts pallet ) } ProxyType::Balances => { @@ -993,7 +995,7 @@ construct_runtime!( EVM: pallet_evm = 60, Ethereum: pallet_ethereum = 61, - BaseFee: pallet_base_fee = 63, + DynamicEvmBaseFee: pallet_dynamic_evm_base_fee = 63, Contracts: pallet_contracts = 70, RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 71, @@ -1036,17 +1038,40 @@ pub type Executive = frame_executive::Executive< Migrations, >; -// Used to cleanup StateTrieMigration storage - remove once cleanup is done. +// Used to cleanup BaseFee storage - remove once cleanup is done. parameter_types! { - pub const StateTrieMigrationStr: &'static str = "StateTrieMigration"; + pub const BaseFeeStr: &'static str = "BaseFee"; +} + +/// Simple `OnRuntimeUpgrade` logic to prepare Shiden runtime for `DynamicEvmBaseFee` pallet. +pub use frame_support::traits::{OnRuntimeUpgrade, StorageVersion}; +pub struct DynamicEvmBaseFeeMigration; +impl OnRuntimeUpgrade for DynamicEvmBaseFeeMigration { + fn on_runtime_upgrade() -> Weight { + // Safety check to ensure we don't execute this migration twice + if pallet_dynamic_evm_base_fee::BaseFeePerGas::::exists() { + return ::DbWeight::get().reads(1); + } + + // Set the init value to what was set before on the old `BaseFee` pallet. + pallet_dynamic_evm_base_fee::BaseFeePerGas::::put(U256::from(1_000_000_000_u128)); + + // Shiden's multiplier is so low that we have to set it to minimum value directly. + pallet_transaction_payment::NextFeeMultiplier::::put(MinimumMultiplier::get()); + + // Set init storage version for the pallet + StorageVersion::new(1).put::>(); + + ::DbWeight::get().reads_writes(1, 3) + } } /// All migrations that will run on the next runtime upgrade. /// /// Once done, migrations should be removed from the tuple. pub type Migrations = ( - frame_support::migrations::RemovePallet, - pallet_contracts::Migration, + frame_support::migrations::RemovePallet, + DynamicEvmBaseFeeMigration, ); type EventRecord = frame_system::EventRecord< @@ -1129,6 +1154,7 @@ mod benches { [pallet_xc_asset_config, XcAssetConfig] [pallet_collator_selection, CollatorSelection] [pallet_xcm, PolkadotXcm] + [pallet_dynamic_evm_base_fee, DynamicEvmBaseFee] ); } @@ -1491,7 +1517,7 @@ impl_runtime_apis! { } fn elasticity() -> Option { - Some(pallet_base_fee::Elasticity::::get()) + Some(Permill::zero()) } fn gas_limit_multiplier_support() {} diff --git a/tests/integration/src/setup.rs b/tests/integration/src/setup.rs index 1e1b6b5f2a..bc7dddeaca 100644 --- a/tests/integration/src/setup.rs +++ b/tests/integration/src/setup.rs @@ -220,9 +220,9 @@ pub fn run_to_block(n: u32) { AuraExt::on_finalize(block_number); PolkadotXcm::on_finalize(block_number); Ethereum::on_finalize(block_number); - #[cfg(any(feature = "shiden", features = "astar"))] + #[cfg(any(features = "astar"))] BaseFee::on_finalize(block_number); - #[cfg(any(feature = "shibuya"))] + #[cfg(any(feature = "shibuya", feature = "shiden"))] DynamicEvmBaseFee::on_finalize(block_number); System::set_block_number(block_number + 1); @@ -233,9 +233,9 @@ pub fn run_to_block(n: u32) { Aura::on_initialize(block_number); AuraExt::on_initialize(block_number); Ethereum::on_initialize(block_number); - #[cfg(any(feature = "shiden", features = "astar"))] + #[cfg(any(features = "astar"))] BaseFee::on_initialize(block_number); - #[cfg(any(feature = "shibuya"))] + #[cfg(any(feature = "shibuya", feature = "shiden"))] DynamicEvmBaseFee::on_initialize(block_number); #[cfg(any(feature = "shibuya", feature = "shiden", features = "astar"))] RandomnessCollectiveFlip::on_initialize(block_number);