diff --git a/Cargo.lock b/Cargo.lock index 6163e649e7..3da296baa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -813,6 +813,7 @@ dependencies = [ "pallet-inflation", "pallet-membership", "pallet-message-queue", + "pallet-migrations", "pallet-multisig", "pallet-price-aggregator", "pallet-proxy", @@ -9088,6 +9089,24 @@ dependencies = [ "sp-weights", ] +[[package]] +name = "pallet-migrations" +version = "1.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.11.0#8c8edacf8942298c3807a2e192860da9e7e4996a" +dependencies = [ + "docify", + "frame-benchmarking", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.11.0)", +] + [[package]] name = "pallet-mmr" version = "27.0.0" @@ -14177,9 +14196,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -14195,9 +14214,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", @@ -14404,6 +14423,7 @@ dependencies = [ "pallet-insecure-randomness-collective-flip", "pallet-membership", "pallet-message-queue", + "pallet-migrations", "pallet-multisig", "pallet-preimage", "pallet-price-aggregator", @@ -14515,6 +14535,7 @@ dependencies = [ "pallet-insecure-randomness-collective-flip", "pallet-membership", "pallet-message-queue", + "pallet-migrations", "pallet-multisig", "pallet-price-aggregator", "pallet-proxy", diff --git a/Cargo.toml b/Cargo.toml index badba367f8..159349e33f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -163,6 +163,7 @@ pallet-contracts = { git = "https://github.com/paritytech/polkadot-sdk", branch pallet-contracts-uapi = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.11.0", default-features = false } pallet-identity = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.11.0", default-features = false } pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.11.0", default-features = false } +pallet-migrations = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.11.0", default-features = false } pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.11.0", default-features = false } pallet-session = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.11.0", default-features = false, features = ["historical"] } pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.11.0", default-features = false } diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 277c6a3915..c8ce3d4608 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -48,6 +48,7 @@ pub mod governance; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarks; +use frame_support::migrations::{FailedMigrationHandler, FailedMigrationHandling}; use sp_runtime::{ generic, traits::{BlakeTwo256, IdentifyAccount, Verify}, @@ -81,3 +82,14 @@ pub type AssetId = u128; pub type Block = sp_runtime::generic::Block; /// Index of a transaction in the chain. pub type Nonce = u32; + +/// Unfreeze chain on failed migration and continue with extrinsic execution. +/// Migration must be tested and make sure it doesn't fail. If it happens, we don't have other +/// choices but unfreeze chain and continue with extrinsic execution. +pub struct UnfreezeChainOnFailedMigration; +impl FailedMigrationHandler for UnfreezeChainOnFailedMigration { + fn failed(migration: Option) -> FailedMigrationHandling { + log::error!(target: "mbm", "Migration failed at cursor: {migration:?}"); + FailedMigrationHandling::ForceUnstuck + } +} diff --git a/runtime/astar/Cargo.toml b/runtime/astar/Cargo.toml index 65f546fe85..ae2a36cd8c 100644 --- a/runtime/astar/Cargo.toml +++ b/runtime/astar/Cargo.toml @@ -59,6 +59,7 @@ pallet-evm-precompile-simple = { workspace = true } pallet-identity = { workspace = true } pallet-membership = { workspace = true } pallet-message-queue = { workspace = true } +pallet-migrations = { workspace = true } pallet-multisig = { workspace = true } pallet-proxy = { workspace = true } pallet-session = { workspace = true, features = ["historical"] } @@ -188,6 +189,7 @@ std = [ "pallet-evm-precompile-sha3fips/std", "pallet-identity/std", "pallet-multisig/std", + "pallet-migrations/std", "pallet-session/std", "pallet-utility/std", "pallet-timestamp/std", @@ -271,6 +273,7 @@ runtime-benchmarks = [ "pallet-evm-precompile-xcm/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", + "pallet-migrations/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", @@ -311,6 +314,7 @@ try-runtime = [ "pallet-xcm/try-runtime", "pallet-identity/try-runtime", "pallet-multisig/try-runtime", + "pallet-migrations/try-runtime", "cumulus-pallet-aura-ext/try-runtime", "cumulus-pallet-parachain-system/try-runtime", "cumulus-pallet-xcm/try-runtime", diff --git a/runtime/astar/src/lib.rs b/runtime/astar/src/lib.rs index 9aaa20368d..248f93e636 100644 --- a/runtime/astar/src/lib.rs +++ b/runtime/astar/src/lib.rs @@ -82,7 +82,7 @@ use astar_primitives::{ evm::EvmRevertCodeHandler, oracle::{CurrencyId, DummyCombineData, Price}, xcm::AssetLocationIdConverter, - Address, AssetId, BlockNumber, Hash, Header, Nonce, + Address, AssetId, BlockNumber, Hash, Header, Nonce, UnfreezeChainOnFailedMigration, }; pub use astar_primitives::{governance::OracleMembershipInst, AccountId, Balance, Signature}; @@ -289,7 +289,7 @@ impl frame_system::Config for Runtime { type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; type SingleBlockMigrations = (); - type MultiBlockMigrator = (); + type MultiBlockMigrator = MultiBlockMigrations; type PreInherents = (); type PostInherents = (); type PostTransactions = (); @@ -1189,6 +1189,25 @@ impl frame_support::traits::SortedMembers for OracleMembershipWrapper } } +parameter_types! { + pub MbmServiceWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; +} + +impl pallet_migrations::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = (); + // Benchmarks need mocked migrations to guarantee that they succeed. + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + type CursorMaxLen = ConstU32<65_536>; + type IdentifierMaxLen = ConstU32<256>; + type MigrationStatusHandler = (); + type FailedMigrationHandler = UnfreezeChainOnFailedMigration; + type MaxServiceWeight = MbmServiceWeight; + type WeightInfo = pallet_migrations::weights::SubstrateWeight; +} + construct_runtime!( pub struct Runtime { @@ -1225,6 +1244,7 @@ construct_runtime!( XcmpQueue: cumulus_pallet_xcmp_queue = 50, PolkadotXcm: pallet_xcm = 51, CumulusXcm: cumulus_pallet_xcm = 52, + // skip 53 - cumulus_pallet_dmp_queue previously XcAssetConfig: pallet_xc_asset_config = 54, XTokens: orml_xtokens = 55, MessageQueue: pallet_message_queue = 56, @@ -1236,6 +1256,8 @@ construct_runtime!( Contracts: pallet_contracts = 70, Sudo: pallet_sudo = 99, + + MultiBlockMigrations: pallet_migrations = 120, } ); @@ -1277,7 +1299,7 @@ pub type Executive = frame_executive::Executive< parameter_types! { // Threshold amount variation allowed for this migration - 10% pub const ThresholdVariationPercentage: u32 = 10; - // percentages below are calulated based on total issuance at the time when dApp staking v3 was launched (8.4B) + // percentages below are calculated based on total issuance at the time when dApp staking v3 was launched (8.4B) pub const TierThresholds: [TierThreshold; 4] = [ TierThreshold::DynamicPercentage { percentage: Perbill::from_parts(35_700_000), // 3.57% @@ -1303,11 +1325,12 @@ parameter_types! { /// All migrations that will run on the next runtime upgrade. /// -/// Once done, migrations should be removed from the tuple. -pub type Migrations = ( - // permanent migration, do not remove - pallet_xcm::migration::MigrateToLatestXcmVersion, - // dapp-staking dyn tier threshold migrations +/// __NOTE:__ THE ORDER IS IMPORTANT. +pub type Migrations = (Unreleased, Permanent); + +/// Unreleased migrations. Add new ones here: +pub type Unreleased = ( + // dApp-staking dyn tier threshold migrations pallet_dapp_staking_v3::migration::versioned_migrations::V7ToV8< Runtime, TierThresholds, @@ -1320,6 +1343,9 @@ pub type Migrations = ( pallet_contracts::Migration, ); +/// Migrations/checks that do not need to be versioned and can run on every upgrade. +pub type Permanent = (pallet_xcm::migration::MigrateToLatestXcmVersion,); + type EventRecord = frame_system::EventRecord< ::RuntimeEvent, ::Hash, @@ -1397,6 +1423,7 @@ mod benches { [pallet_timestamp, Timestamp] [pallet_dapp_staking_v3, DappStaking] [pallet_inflation, Inflation] + [pallet_migrations, MultiBlockMigrations] [pallet_xc_asset_config, XcAssetConfig] [pallet_collator_selection, CollatorSelection] [pallet_xcm, PalletXcmExtrinsicsBenchmark::] diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index 3794996225..1890be8eb9 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -63,6 +63,7 @@ pallet-identity = { workspace = true } pallet-insecure-randomness-collective-flip = { workspace = true } pallet-membership = { workspace = true } pallet-message-queue = { workspace = true } +pallet-migrations = { workspace = true } pallet-multisig = { workspace = true } pallet-preimage = { workspace = true } pallet-proxy = { workspace = true } @@ -208,6 +209,7 @@ std = [ "pallet-price-aggregator/std", "pallet-identity/std", "pallet-multisig/std", + "pallet-migrations/std", "pallet-insecure-randomness-collective-flip/std", "pallet-session/std", "pallet-utility/std", @@ -302,6 +304,7 @@ runtime-benchmarks = [ "pallet-evm-precompile-xcm/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", + "pallet-migrations/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", @@ -347,6 +350,7 @@ try-runtime = [ "pallet-xcm/try-runtime", "pallet-identity/try-runtime", "pallet-multisig/try-runtime", + "pallet-migrations/try-runtime", "pallet-insecure-randomness-collective-flip/try-runtime", "pallet-scheduler/try-runtime", "pallet-proxy/try-runtime", diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index 2909ce96da..f875902e90 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -92,7 +92,7 @@ use astar_primitives::{ }, oracle::{CurrencyId, DummyCombineData, Price}, xcm::AssetLocationIdConverter, - Address, AssetId, BlockNumber, Hash, Header, Nonce, + Address, AssetId, BlockNumber, Hash, Header, Nonce, UnfreezeChainOnFailedMigration, }; pub use astar_primitives::{AccountId, Balance, Signature}; @@ -326,7 +326,7 @@ impl frame_system::Config for Runtime { type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; type SingleBlockMigrations = (); - type MultiBlockMigrator = (); + type MultiBlockMigrator = MultiBlockMigrations; type PreInherents = (); type PostInherents = (); type PostTransactions = (); @@ -1514,6 +1514,25 @@ impl pallet_collective_proxy::Config for Runtime { type WeightInfo = pallet_collective_proxy::weights::SubstrateWeight; } +parameter_types! { + pub MbmServiceWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; +} + +impl pallet_migrations::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = (); + // Benchmarks need mocked migrations to guarantee that they succeed. + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + type CursorMaxLen = ConstU32<65_536>; + type IdentifierMaxLen = ConstU32<256>; + type MigrationStatusHandler = (); + type FailedMigrationHandler = UnfreezeChainOnFailedMigration; + type MaxServiceWeight = MbmServiceWeight; + type WeightInfo = pallet_migrations::weights::SubstrateWeight; +} + construct_runtime!( pub struct Runtime { @@ -1548,6 +1567,7 @@ construct_runtime!( XcmpQueue: cumulus_pallet_xcmp_queue = 50, PolkadotXcm: pallet_xcm = 51, CumulusXcm: cumulus_pallet_xcm = 52, + // skip 53 - cumulus_pallet_dmp_queue previously XcAssetConfig: pallet_xc_asset_config = 54, XTokens: orml_xtokens = 55, MessageQueue: pallet_message_queue = 56, @@ -1577,6 +1597,8 @@ construct_runtime!( Treasury: pallet_treasury:: = 107, CommunityTreasury: pallet_treasury:: = 108, CollectiveProxy: pallet_collective_proxy = 109, + + MultiBlockMigrations: pallet_migrations = 120, } ); @@ -1618,7 +1640,7 @@ pub type Executive = frame_executive::Executive< parameter_types! { // Threshold amount variation allowed for this migration - 150% pub const ThresholdVariationPercentage: u32 = 150; - // percentages below are calulated based on a total issuance at the time when dApp staking v3 was launched (147M) + // percentages below are calculated based on a total issuance at the time when dApp staking v3 was launched (147M) pub const TierThresholds: [TierThreshold; 4] = [ TierThreshold::DynamicPercentage { percentage: Perbill::from_parts(20_000), // 0.0020% @@ -1644,11 +1666,12 @@ parameter_types! { /// All migrations that will run on the next runtime upgrade. /// -/// Once done, migrations should be removed from the tuple. -pub type Migrations = ( - // permanent migration, do not remove - pallet_xcm::migration::MigrateToLatestXcmVersion, - // dapp-staking dyn tier threshold migrations +/// __NOTE:__ THE ORDER IS IMPORTANT. +pub type Migrations = (Unreleased, Permanent); + +/// Unreleased migrations. Add new ones here: +pub type Unreleased = ( + // dApp-staking dyn tier threshold migrations pallet_dapp_staking_v3::migration::versioned_migrations::V7ToV8< Runtime, TierThresholds, @@ -1661,6 +1684,9 @@ pub type Migrations = ( pallet_contracts::Migration, ); +/// Migrations/checks that do not need to be versioned and can run on every upgrade. +pub type Permanent = (pallet_xcm::migration::MigrateToLatestXcmVersion,); + type EventRecord = frame_system::EventRecord< ::RuntimeEvent, ::Hash, @@ -1738,6 +1764,7 @@ mod benches { [pallet_timestamp, Timestamp] [pallet_dapp_staking_v3, DappStaking] [pallet_inflation, Inflation] + [pallet_migrations, MultiBlockMigrations] [pallet_xc_asset_config, XcAssetConfig] [pallet_collator_selection, CollatorSelection] [pallet_xcm, PalletXcmExtrinsicsBenchmark::] diff --git a/runtime/shiden/Cargo.toml b/runtime/shiden/Cargo.toml index cc18c64c45..c6a01c5704 100644 --- a/runtime/shiden/Cargo.toml +++ b/runtime/shiden/Cargo.toml @@ -61,6 +61,7 @@ pallet-identity = { workspace = true } pallet-insecure-randomness-collective-flip = { workspace = true } pallet-membership = { workspace = true } pallet-message-queue = { workspace = true } +pallet-migrations = { workspace = true } pallet-multisig = { workspace = true } pallet-proxy = { workspace = true } pallet-session = { workspace = true, features = ["historical"] } @@ -187,6 +188,7 @@ std = [ "pallet-evm-precompile-xcm/std", "pallet-identity/std", "pallet-multisig/std", + "pallet-migrations/std", "pallet-membership/std", "pallet-insecure-randomness-collective-flip/std", "pallet-session/std", @@ -273,6 +275,7 @@ runtime-benchmarks = [ "pallet-evm-precompile-xcm/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", + "pallet-migrations/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-utility/runtime-benchmarks", @@ -315,6 +318,7 @@ try-runtime = [ "pallet-xcm/try-runtime", "pallet-identity/try-runtime", "pallet-multisig/try-runtime", + "pallet-migrations/try-runtime", "pallet-proxy/try-runtime", "pallet-insecure-randomness-collective-flip/try-runtime", "pallet-contracts/try-runtime", diff --git a/runtime/shiden/src/lib.rs b/runtime/shiden/src/lib.rs index c05252053b..a37cbef95b 100644 --- a/runtime/shiden/src/lib.rs +++ b/runtime/shiden/src/lib.rs @@ -82,7 +82,7 @@ use astar_primitives::{ governance::OracleMembershipInst, oracle::{CurrencyId, DummyCombineData, Price}, xcm::AssetLocationIdConverter, - Address, AssetId, BlockNumber, Hash, Header, Nonce, + Address, AssetId, BlockNumber, Hash, Header, Nonce, UnfreezeChainOnFailedMigration, }; pub use astar_primitives::{AccountId, Balance, Signature}; @@ -291,7 +291,7 @@ impl frame_system::Config for Runtime { type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; type SingleBlockMigrations = (); - type MultiBlockMigrator = (); + type MultiBlockMigrator = MultiBlockMigrations; type PreInherents = (); type PostInherents = (); type PostTransactions = (); @@ -1188,6 +1188,25 @@ impl frame_support::traits::SortedMembers for OracleMembershipWrapper } } +parameter_types! { + pub MbmServiceWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; +} + +impl pallet_migrations::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = (); + // Benchmarks need mocked migrations to guarantee that they succeed. + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + type CursorMaxLen = ConstU32<65_536>; + type IdentifierMaxLen = ConstU32<256>; + type MigrationStatusHandler = (); + type FailedMigrationHandler = UnfreezeChainOnFailedMigration; + type MaxServiceWeight = MbmServiceWeight; + type WeightInfo = pallet_migrations::weights::SubstrateWeight; +} + construct_runtime!( pub struct Runtime { @@ -1224,6 +1243,7 @@ construct_runtime!( XcmpQueue: cumulus_pallet_xcmp_queue = 50, PolkadotXcm: pallet_xcm = 51, CumulusXcm: cumulus_pallet_xcm = 52, + // skip 53 - cumulus_pallet_dmp_queue previously XcAssetConfig: pallet_xc_asset_config = 54, XTokens: orml_xtokens = 55, MessageQueue: pallet_message_queue = 56, @@ -1236,6 +1256,8 @@ construct_runtime!( RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 71, Sudo: pallet_sudo = 99, + + MultiBlockMigrations: pallet_migrations = 120, } ); @@ -1277,7 +1299,7 @@ pub type Executive = frame_executive::Executive< parameter_types! { // Threshold amount variation allowed for this migration - 10% pub const ThresholdVariationPercentage: u32 = 10; - // percentages below are calulated based on a total issuance at the time when dApp staking v3 was launched (84.3M) + // percentages below are calculated based on a total issuance at the time when dApp staking v3 was launched (84.3M) pub const TierThresholds: [TierThreshold; 4] = [ TierThreshold::DynamicPercentage { percentage: Perbill::from_parts(35_700_000), // 3.57% @@ -1303,10 +1325,12 @@ parameter_types! { /// All migrations that will run on the next runtime upgrade. /// -/// Once done, migrations should be removed from the tuple. -pub type Migrations = ( - pallet_xcm::migration::MigrateToLatestXcmVersion, - // dapp-staking dyn tier threshold migrations +/// __NOTE:__ THE ORDER IS IMPORTANT. +pub type Migrations = (Unreleased, Permanent); + +/// Unreleased migrations. Add new ones here: +pub type Unreleased = ( + // dApp-staking dyn tier threshold migrations pallet_dapp_staking_v3::migration::versioned_migrations::V7ToV8< Runtime, TierThresholds, @@ -1319,6 +1343,9 @@ pub type Migrations = ( pallet_contracts::Migration, ); +/// Migrations/checks that do not need to be versioned and can run on every upgrade. +pub type Permanent = (pallet_xcm::migration::MigrateToLatestXcmVersion,); + type EventRecord = frame_system::EventRecord< ::RuntimeEvent, ::Hash, @@ -1396,6 +1423,7 @@ mod benches { [pallet_timestamp, Timestamp] [pallet_dapp_staking_v3, DappStaking] [pallet_inflation, Inflation] + [pallet_migrations, MultiBlockMigrations] [pallet_xc_asset_config, XcAssetConfig] [pallet_collator_selection, CollatorSelection] [pallet_xcm, PalletXcmExtrinsicsBenchmark::]