diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f89329d59..141352a947 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - \[Assets\] Call implementation for `transfer_all` ([SDK `stable2409` #4527](https://github.com/paritytech/polkadot-sdk/pull/4527)) - Tx Payment: drop ED requirements for tx payments with exchangeable asset ([SDK `stable2409` #4488](https://github.com/paritytech/polkadot-sdk/pull/4488)) - Coretime auto-renew ([SDK `stable2409` #4424](https://github.com/paritytech/polkadot-sdk/pull/4424)) +- Initialises pallet-delegated-staking ([SDK `v1.12.0` #3904](https://github.com/paritytech/polkadot-sdk/pull/3904)) ### Changed @@ -26,6 +27,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Bridges V2 refactoring backport and `pallet_bridge_messages` simplifications ([SDK `stable2407` #4935](https://github.com/paritytech/polkadot-sdk/pull/4935)) - Renamed `assigner_on_demand` to `on_demand` ([SDK `stable2409` #4706](https://github.com/paritytech/polkadot-sdk/pull/4706)). - \[BEEFY\] Add runtime support for reporting fork voting ([SDK `stable2407` #4522](https://github.com/paritytech/polkadot-sdk/pull/4522)). +- Migrates Nomination Pool to use delegated staking: i.e. allowing delegated funds to be held in member's own account + instead of the pool account. This would enable pool member funds to be used for voting in opengov. + ([SDK `v1.13.0` #3905](https://github.com/paritytech/polkadot-sdk/pull/3905)) ## [1.3.4] 01.11.2024 diff --git a/Cargo.lock b/Cargo.lock index 220965c8e3..14d6b177ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9316,7 +9316,7 @@ checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" dependencies = [ "bitcoin_hashes 0.13.0", "rand", - "rand_core 0.5.1", + "rand_core 0.6.4", "serde", "unicode-normalization", ] @@ -10056,6 +10056,7 @@ dependencies = [ "pallet-broker", "pallet-child-bounties", "pallet-conviction-voting", + "pallet-delegated-staking", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-fast-unstake", @@ -14401,6 +14402,7 @@ dependencies = [ "pallet-bounties", "pallet-child-bounties", "pallet-conviction-voting", + "pallet-delegated-staking", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-fast-unstake", diff --git a/Cargo.toml b/Cargo.toml index 6de5f68a5f..8f44675da1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -152,6 +152,7 @@ pallet-session = { version = "38.0.0", default-features = false } pallet-session-benchmarking = { version = "38.0.0", default-features = false } pallet-society = { version = "38.0.0", default-features = false } pallet-staking = { version = "38.0.0", default-features = false } +pallet-delegated-staking = { version = "5.0.0", default-features = false } pallet-staking-reward-curve = { version = "12.0.0" } pallet-staking-reward-fn = { version = "22.0.0", default-features = false } pallet-staking-runtime-api = { version = "24.0.0", default-features = false } diff --git a/relay/kusama/Cargo.toml b/relay/kusama/Cargo.toml index 4e3c22f6f6..bbb220140d 100644 --- a/relay/kusama/Cargo.toml +++ b/relay/kusama/Cargo.toml @@ -51,6 +51,7 @@ pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-nomination-pools-runtime-api = { workspace = true } pallet-conviction-voting = { workspace = true } +pallet-delegated-staking = { workspace = true } pallet-election-provider-multi-phase = { workspace = true } pallet-fast-unstake = { workspace = true } frame-executive = { workspace = true } @@ -151,6 +152,7 @@ std = [ "pallet-bounties/std", "pallet-child-bounties/std", "pallet-conviction-voting/std", + "pallet-delegated-staking/std", "pallet-election-provider-multi-phase/std", "pallet-election-provider-support-benchmarking?/std", "pallet-fast-unstake/std", @@ -231,6 +233,7 @@ runtime-benchmarks = [ "pallet-bounties/runtime-benchmarks", "pallet-child-bounties/runtime-benchmarks", "pallet-conviction-voting/runtime-benchmarks", + "pallet-delegated-staking/runtime-benchmarks", "pallet-election-provider-multi-phase/runtime-benchmarks", "pallet-election-provider-support-benchmarking/runtime-benchmarks", "pallet-fast-unstake/runtime-benchmarks", @@ -288,6 +291,7 @@ try-runtime = [ "pallet-bounties/try-runtime", "pallet-child-bounties/try-runtime", "pallet-conviction-voting/try-runtime", + "pallet-delegated-staking/try-runtime", "pallet-election-provider-multi-phase/try-runtime", "pallet-fast-unstake/try-runtime", "pallet-grandpa/try-runtime", diff --git a/relay/kusama/src/lib.rs b/relay/kusama/src/lib.rs index 4d0e5aa557..fa097037e7 100644 --- a/relay/kusama/src/lib.rs +++ b/relay/kusama/src/lib.rs @@ -88,10 +88,11 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ - fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, ConstU8, EitherOf, - EitherOfDiverse, Everything, FromContains, InstanceFilter, KeyOwnerProofSystem, - LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, StorageMapShim, - WithdrawReasons, + fungible::HoldConsideration, + tokens::{imbalance::ResolveTo, UnityOrOuterConversion}, + ConstU32, ConstU8, EitherOf, EitherOfDiverse, Everything, FromContains, InstanceFilter, + KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, + StorageMapShim, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter, WeightToFee as _}, PalletId, @@ -127,6 +128,7 @@ pub use frame_system::Call as SystemCall; pub use pallet_balances::Call as BalancesCall; pub use pallet_election_provider_multi_phase::{Call as EPMCall, GeometricDepositBase}; use pallet_staking::UseValidatorsMap; +use pallet_treasury::TreasuryAccountId; use sp_runtime::traits::Get; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -805,7 +807,7 @@ impl pallet_staking::Config for Runtime { type HistoryDepth = frame_support::traits::ConstU32<84>; type MaxControllersInDeprecationBatch = ConstU32<5169>; type BenchmarkingConfig = polkadot_runtime_common::StakingBenchmarkingConfig; - type EventListeners = NominationPools; + type EventListeners = (NominationPools, DelegatedStaking); type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; type WeightInfo = weights::pallet_staking::WeightInfo; } @@ -1613,7 +1615,8 @@ impl pallet_nomination_pools::Config for Runtime { type RewardCounter = FixedU128; type BalanceToU256 = BalanceToU256; type U256ToBalance = U256ToBalance; - type StakeAdapter = pallet_nomination_pools::adapter::TransferStake; + type StakeAdapter = + pallet_nomination_pools::adapter::DelegateStake; type PostUnbondingPoolsWindow = ConstU32<4>; type MaxMetadataLen = ConstU32<256>; // we use the same number of allowed unlocking chunks as with staking. @@ -1623,6 +1626,22 @@ impl pallet_nomination_pools::Config for Runtime { type AdminOrigin = EitherOf, StakingAdmin>; } +parameter_types! { + pub const DelegatedStakingPalletId: PalletId = PalletId(*b"py/dlstk"); + pub const SlashRewardFraction: Perbill = Perbill::from_percent(1); +} + +impl pallet_delegated_staking::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type PalletId = DelegatedStakingPalletId; + type Currency = Balances; + // slashes are sent to the treasury. + type OnSlash = ResolveTo, Balances>; + type SlashRewardFraction = SlashRewardFraction; + type RuntimeHoldReason = RuntimeHoldReason; + type CoreStaking = Staking; +} + /// The [frame_support::traits::tokens::ConversionFromAssetBalance] implementation provided by the /// `AssetRate` pallet instance. /// @@ -1737,6 +1756,9 @@ construct_runtime! { // Fast unstake pallet: extension to staking. FastUnstake: pallet_fast_unstake = 42, + // Staking extension for delegation + DelegatedStaking: pallet_delegated_staking = 47, + // Parachains pallets. Start indices at 50 to leave room. ParachainsOrigin: parachains_origin = 50, Configuration: parachains_configuration = 51, @@ -1809,6 +1831,13 @@ impl Get for NominationPoolsMigrationV4OldPallet { } } +parameter_types! { + // This is used to limit max pools that migrates in the runtime upgrade. This is set to + // existing_pool_count plus ~15 to also account for any new pools getting created before the + // migration is actually executed. + pub const MaxPoolsToMigrate: u32 = 200; +} + /// All migrations that will run on the next runtime upgrade. /// /// This contains the combined migrations of the last 10 releases. It allows to skip runtime @@ -1827,6 +1856,11 @@ pub mod migrations { parachains_inclusion::migration::MigrateToV1, parachains_on_demand::migration::MigrateV0ToV1, restore_corrupted_ledgers::Migrate, + // Migrate NominationPools to `DelegateStake` adapter. This is an unversioned upgrade. + pallet_nomination_pools::migration::unversioned::DelegationStakeMigration< + Runtime, + MaxPoolsToMigrate, + >, ); /// Migrations/checks that do not need to be versioned and can run on every update. diff --git a/relay/polkadot/Cargo.toml b/relay/polkadot/Cargo.toml index 90c670eb2d..4ce77e7187 100644 --- a/relay/polkadot/Cargo.toml +++ b/relay/polkadot/Cargo.toml @@ -46,6 +46,7 @@ pallet-beefy-mmr = { workspace = true } pallet-bounties = { workspace = true } pallet-broker = { workspace = true } pallet-child-bounties = { workspace = true } +pallet-delegated-staking = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-conviction-voting = { workspace = true } @@ -155,6 +156,7 @@ std = [ "pallet-broker/std", "pallet-child-bounties/std", "pallet-conviction-voting/std", + "pallet-delegated-staking/std", "pallet-election-provider-multi-phase/std", "pallet-election-provider-support-benchmarking?/std", "pallet-fast-unstake/std", @@ -236,6 +238,7 @@ runtime-benchmarks = [ "pallet-broker/runtime-benchmarks", "pallet-child-bounties/runtime-benchmarks", "pallet-conviction-voting/runtime-benchmarks", + "pallet-delegated-staking/runtime-benchmarks", "pallet-election-provider-multi-phase/runtime-benchmarks", "pallet-election-provider-support-benchmarking/runtime-benchmarks", "pallet-fast-unstake/runtime-benchmarks", @@ -292,6 +295,7 @@ try-runtime = [ "pallet-broker/try-runtime", "pallet-child-bounties/try-runtime", "pallet-conviction-voting/try-runtime", + "pallet-delegated-staking/try-runtime", "pallet-election-provider-multi-phase/try-runtime", "pallet-fast-unstake/try-runtime", "pallet-grandpa/try-runtime", diff --git a/relay/polkadot/src/lib.rs b/relay/polkadot/src/lib.rs index 78de134d41..34da587d0c 100644 --- a/relay/polkadot/src/lib.rs +++ b/relay/polkadot/src/lib.rs @@ -65,10 +65,11 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ - fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, ConstU8, EitherOf, - EitherOfDiverse, Everything, FromContains, Get, InstanceFilter, KeyOwnerProofSystem, - LinearStoragePrice, OnRuntimeUpgrade, PrivilegeCmp, ProcessMessage, ProcessMessageError, - WithdrawReasons, + fungible::HoldConsideration, + tokens::{imbalance::ResolveTo, UnityOrOuterConversion}, + ConstU32, ConstU8, EitherOf, EitherOfDiverse, Everything, FromContains, Get, + InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, OnRuntimeUpgrade, PrivilegeCmp, + ProcessMessage, ProcessMessageError, WithdrawReasons, }, weights::{ constants::{WEIGHT_PROOF_SIZE_PER_KB, WEIGHT_REF_TIME_PER_MICROS}, @@ -121,6 +122,7 @@ pub use pallet_balances::Call as BalancesCall; pub use pallet_election_provider_multi_phase::{Call as EPMCall, GeometricDepositBase}; use pallet_staking::UseValidatorsMap; pub use pallet_timestamp::Call as TimestampCall; +use pallet_treasury::TreasuryAccountId; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -785,7 +787,7 @@ impl pallet_staking::Config for Runtime { type HistoryDepth = frame_support::traits::ConstU32<84>; type MaxControllersInDeprecationBatch = ConstU32<5314>; type BenchmarkingConfig = polkadot_runtime_common::StakingBenchmarkingConfig; - type EventListeners = NominationPools; + type EventListeners = (NominationPools, DelegatedStaking); type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; type WeightInfo = weights::pallet_staking::WeightInfo; } @@ -1523,7 +1525,8 @@ impl pallet_nomination_pools::Config for Runtime { type RewardCounter = FixedU128; type BalanceToU256 = polkadot_runtime_common::BalanceToU256; type U256ToBalance = polkadot_runtime_common::U256ToBalance; - type StakeAdapter = pallet_nomination_pools::adapter::TransferStake; + type StakeAdapter = + pallet_nomination_pools::adapter::DelegateStake; type PostUnbondingPoolsWindow = frame_support::traits::ConstU32<4>; type MaxMetadataLen = frame_support::traits::ConstU32<256>; // we use the same number of allowed unlocking chunks as with staking. @@ -1534,6 +1537,22 @@ impl pallet_nomination_pools::Config for Runtime { type AdminOrigin = EitherOf, StakingAdmin>; } +parameter_types! { + pub const DelegatedStakingPalletId: PalletId = PalletId(*b"py/dlstk"); + pub const SlashRewardFraction: Perbill = Perbill::from_percent(1); +} + +impl pallet_delegated_staking::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type PalletId = DelegatedStakingPalletId; + type Currency = Balances; + // slashes are sent to the treasury. + type OnSlash = ResolveTo, Balances>; + type SlashRewardFraction = SlashRewardFraction; + type RuntimeHoldReason = RuntimeHoldReason; + type CoreStaking = Staking; +} + pub struct InitiateNominationPools; impl frame_support::traits::OnRuntimeUpgrade for InitiateNominationPools { fn on_runtime_upgrade() -> frame_support::weights::Weight { @@ -1680,6 +1699,9 @@ construct_runtime! { // Fast unstake pallet: extension to staking. FastUnstake: pallet_fast_unstake = 40, + // Staking extension for delegation + DelegatedStaking: pallet_delegated_staking = 41, + // Parachains pallets. Start indices at 50 to leave room. ParachainsOrigin: parachains_origin = 50, Configuration: parachains_configuration = 51, @@ -2036,6 +2058,13 @@ pub mod migrations { } } + parameter_types! { + // This is used to limit max pools that migrates in the runtime upgrade. This is set to + // existing_pool_count plus ~15 to also account for any new pools getting created before the + // migration is actually executed. + pub const MaxPoolsToMigrate: u32 = 250; + } + /// Unreleased migrations. Add new ones here: pub type Unreleased = ( parachains_configuration::migration::v12::MigrateToV12, @@ -2058,6 +2087,11 @@ pub mod migrations { >, CancelAuctions, restore_corrupted_ledgers::Migrate, + // Migrate NominationPools to `DelegateStake` adapter. + pallet_nomination_pools::migration::unversioned::DelegationStakeMigration< + Runtime, + MaxPoolsToMigrate, + >, ); /// Migrations/checks that do not need to be versioned and can run on every update.