>(parent_hash)
- else {
- return (parent_hash == included_block)
- .then(|| SlotClaim::unchecked::(author_pub, para_slot, timestamp));
- };
+ // This function is typically called when we want to build block N. At that point, the
+ // unincluded segment in the runtime is unaware of the hash of block N-1. If the unincluded
+ // segment in the runtime is full, but block N-1 is the included block, the unincluded segment
+ // should have length 0 and we can build. Since the hash is not available to the runtime
+ // however, we need this extra check here.
+ if parent_hash == included_block {
+ return Some(SlotClaim::unchecked::
(author_pub, para_slot, timestamp));
+ }
+
+ let api_version = runtime_api
+ .api_version::>(parent_hash)
+ .ok()
+ .flatten()?;
let slot = if api_version > 1 { relay_slot } else { para_slot };
@@ -243,3 +250,116 @@ where
.max_by_key(|a| a.depth)
.map(|parent| (included_block, parent))
}
+
+#[cfg(test)]
+mod tests {
+ use crate::collators::can_build_upon;
+ use codec::Encode;
+ use cumulus_primitives_aura::Slot;
+ use cumulus_primitives_core::BlockT;
+ use cumulus_relay_chain_interface::PHash;
+ use cumulus_test_client::{
+ runtime::{Block, Hash},
+ Client, DefaultTestClientBuilderExt, InitBlockBuilder, TestClientBuilder,
+ TestClientBuilderExt,
+ };
+ use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
+ use polkadot_primitives::HeadData;
+ use sc_consensus::{BlockImport, BlockImportParams, ForkChoiceStrategy};
+ use sp_consensus::BlockOrigin;
+ use sp_keystore::{Keystore, KeystorePtr};
+ use sp_timestamp::Timestamp;
+ use std::sync::Arc;
+
+ async fn import_block>(
+ importer: &I,
+ block: Block,
+ origin: BlockOrigin,
+ import_as_best: bool,
+ ) {
+ let (header, body) = block.deconstruct();
+
+ let mut block_import_params = BlockImportParams::new(origin, header);
+ block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(import_as_best));
+ block_import_params.body = Some(body);
+ importer.import_block(block_import_params).await.unwrap();
+ }
+
+ fn sproof_with_parent_by_hash(client: &Client, hash: PHash) -> RelayStateSproofBuilder {
+ let header = client.header(hash).ok().flatten().expect("No header for parent block");
+ let included = HeadData(header.encode());
+ let mut builder = RelayStateSproofBuilder::default();
+ builder.para_id = cumulus_test_client::runtime::PARACHAIN_ID.into();
+ builder.included_para_head = Some(included);
+
+ builder
+ }
+ async fn build_and_import_block(client: &Client, included: Hash) -> Block {
+ let sproof = sproof_with_parent_by_hash(client, included);
+
+ let block_builder = client.init_block_builder(None, sproof).block_builder;
+
+ let block = block_builder.build().unwrap().block;
+
+ let origin = BlockOrigin::NetworkInitialSync;
+ import_block(client, block.clone(), origin, true).await;
+ block
+ }
+
+ fn set_up_components() -> (Arc, KeystorePtr) {
+ let keystore = Arc::new(sp_keystore::testing::MemoryKeystore::new()) as Arc<_>;
+ for key in sp_keyring::Sr25519Keyring::iter() {
+ Keystore::sr25519_generate_new(
+ &*keystore,
+ sp_application_crypto::key_types::AURA,
+ Some(&key.to_seed()),
+ )
+ .expect("Can insert key into MemoryKeyStore");
+ }
+ (Arc::new(TestClientBuilder::new().build()), keystore)
+ }
+
+ /// This tests a special scenario where the unincluded segment in the runtime
+ /// is full. We are calling `can_build_upon`, passing the last built block as the
+ /// included one. In the runtime we will not find the hash of the included block in the
+ /// unincluded segment. The `can_build_upon` runtime API would therefore return `false`, but
+ /// we are ensuring on the node side that we are are always able to build on the included block.
+ #[tokio::test]
+ async fn test_can_build_upon() {
+ let (client, keystore) = set_up_components();
+
+ let genesis_hash = client.chain_info().genesis_hash;
+ let mut last_hash = genesis_hash;
+
+ // Fill up the unincluded segment tracker in the runtime.
+ while can_build_upon::<_, _, sp_consensus_aura::sr25519::AuthorityPair>(
+ Slot::from(u64::MAX),
+ Slot::from(u64::MAX),
+ Timestamp::default(),
+ last_hash,
+ genesis_hash,
+ &*client,
+ &keystore,
+ )
+ .await
+ .is_some()
+ {
+ let block = build_and_import_block(&client, genesis_hash).await;
+ last_hash = block.header().hash();
+ }
+
+ // Blocks were built with the genesis hash set as included block.
+ // We call `can_build_upon` with the last built block as the included block.
+ let result = can_build_upon::<_, _, sp_consensus_aura::sr25519::AuthorityPair>(
+ Slot::from(u64::MAX),
+ Slot::from(u64::MAX),
+ Timestamp::default(),
+ last_hash,
+ last_hash,
+ &*client,
+ &keystore,
+ )
+ .await;
+ assert!(result.is_some());
+ }
+}
diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml
index a164a8197f72e..c6a8baeff3b37 100644
--- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml
@@ -14,6 +14,7 @@ workspace = true
# Substrate
frame-support = { workspace = true }
+pallet-asset-rewards = { workspace = true }
sp-core = { workspace = true }
sp-keyring = { workspace = true }
diff --git a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs
index e2757f8b9a35b..f5466a63f1f5b 100644
--- a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs
+++ b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs
@@ -58,6 +58,8 @@ pub const USDT_ID: u32 = 1984;
pub const PENPAL_A_ID: u32 = 2000;
pub const PENPAL_B_ID: u32 = 2001;
+pub const ASSET_HUB_ROCOCO_ID: u32 = 1000;
+pub const ASSET_HUB_WESTEND_ID: u32 = 1000;
pub const ASSETS_PALLET_ID: u8 = 50;
parameter_types! {
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml
index 9e8b8f2a52d78..b53edb39c73b5 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml
@@ -17,6 +17,7 @@ codec = { workspace = true }
# Substrate
frame-support = { workspace = true }
pallet-asset-conversion = { workspace = true }
+pallet-asset-rewards = { workspace = true }
pallet-assets = { workspace = true }
pallet-balances = { workspace = true }
pallet-message-queue = { workspace = true }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs
index f3a1b3f5bfa28..513ca278a319e 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs
@@ -76,10 +76,11 @@ mod imports {
genesis::ED as ROCOCO_ED,
rococo_runtime::{
governance as rococo_governance,
+ governance::pallet_custom_origins::Origin::Treasurer,
xcm_config::{
UniversalLocation as RococoUniversalLocation, XcmConfig as RococoXcmConfig,
},
- OriginCaller as RococoOriginCaller,
+ Dmp, OriginCaller as RococoOriginCaller,
},
RococoRelayPallet as RococoPallet,
},
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs
index 88fa379c4072b..75714acb07cd9 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs
@@ -16,6 +16,7 @@
mod claim_assets;
mod hybrid_transfers;
mod reserve_transfer;
+mod reward_pool;
mod send;
mod set_xcm_versions;
mod swap;
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reward_pool.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reward_pool.rs
new file mode 100644
index 0000000000000..2f3ee536a7b99
--- /dev/null
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reward_pool.rs
@@ -0,0 +1,114 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::imports::*;
+use codec::Encode;
+use frame_support::{assert_ok, sp_runtime::traits::Dispatchable, traits::schedule::DispatchTime};
+use xcm_executor::traits::ConvertLocation;
+
+#[test]
+fn treasury_creates_asset_reward_pool() {
+ AssetHubRococo::execute_with(|| {
+ type RuntimeEvent = ::RuntimeEvent;
+ type Balances = ::Balances;
+
+ let treasurer =
+ Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]);
+ let treasurer_account =
+ ahr_xcm_config::LocationToAccountId::convert_location(&treasurer).unwrap();
+
+ assert_ok!(Balances::force_set_balance(
+ ::RuntimeOrigin::root(),
+ treasurer_account.clone().into(),
+ ASSET_HUB_ROCOCO_ED * 100_000,
+ ));
+
+ let events = AssetHubRococo::events();
+ match events.iter().last() {
+ Some(RuntimeEvent::Balances(pallet_balances::Event::BalanceSet { who, .. })) =>
+ assert_eq!(*who, treasurer_account),
+ _ => panic!("Expected Balances::BalanceSet event"),
+ }
+ });
+
+ Rococo::execute_with(|| {
+ type AssetHubRococoRuntimeCall = ::RuntimeCall;
+ type AssetHubRococoRuntime = ::Runtime;
+ type RococoRuntimeCall = ::RuntimeCall;
+ type RococoRuntime = ::Runtime;
+ type RococoRuntimeEvent = ::RuntimeEvent;
+ type RococoRuntimeOrigin = ::RuntimeOrigin;
+
+ Dmp::make_parachain_reachable(AssetHubRococo::para_id());
+
+ let staked_asset_id = bx!(RelayLocation::get());
+ let reward_asset_id = bx!(RelayLocation::get());
+
+ let reward_rate_per_block = 1_000_000_000;
+ let lifetime = 1_000_000_000;
+ let admin = None;
+
+ let create_pool_call =
+ RococoRuntimeCall::XcmPallet(pallet_xcm::Call::::send {
+ dest: bx!(VersionedLocation::V4(
+ xcm::v4::Junction::Parachain(AssetHubRococo::para_id().into()).into()
+ )),
+ message: bx!(VersionedXcm::V5(Xcm(vec![
+ UnpaidExecution { weight_limit: Unlimited, check_origin: None },
+ Transact {
+ origin_kind: OriginKind::SovereignAccount,
+ fallback_max_weight: None,
+ call: AssetHubRococoRuntimeCall::AssetRewards(
+ pallet_asset_rewards::Call::::create_pool {
+ staked_asset_id,
+ reward_asset_id,
+ reward_rate_per_block,
+ expiry: DispatchTime::After(lifetime),
+ admin
+ }
+ )
+ .encode()
+ .into(),
+ }
+ ]))),
+ });
+
+ let treasury_origin: RococoRuntimeOrigin = Treasurer.into();
+ assert_ok!(create_pool_call.dispatch(treasury_origin));
+
+ assert_expected_events!(
+ Rococo,
+ vec![
+ RococoRuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {},
+ ]
+ );
+ });
+
+ AssetHubRococo::execute_with(|| {
+ type Runtime = ::Runtime;
+ type RuntimeEvent = ::RuntimeEvent;
+
+ assert_eq!(1, pallet_asset_rewards::Pools::::iter().count());
+
+ let events = AssetHubRococo::events();
+ match events.iter().last() {
+ Some(RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed {
+ success: true,
+ ..
+ })) => (),
+ _ => panic!("Expected MessageQueue::Processed event"),
+ }
+ });
+}
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml
index 5cd00c239e60d..ef68a53c3b18b 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml
@@ -19,6 +19,7 @@ frame-metadata-hash-extension = { workspace = true, default-features = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-asset-conversion = { workspace = true }
+pallet-asset-rewards = { workspace = true }
pallet-asset-tx-payment = { workspace = true }
pallet-assets = { workspace = true }
pallet-balances = { workspace = true }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs
index 36630e2d22217..68dc87250f76b 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs
@@ -79,8 +79,12 @@ mod imports {
},
westend_emulated_chain::{
genesis::ED as WESTEND_ED,
- westend_runtime::xcm_config::{
- UniversalLocation as WestendUniversalLocation, XcmConfig as WestendXcmConfig,
+ westend_runtime::{
+ governance::pallet_custom_origins::Origin::Treasurer,
+ xcm_config::{
+ UniversalLocation as WestendUniversalLocation, XcmConfig as WestendXcmConfig,
+ },
+ Dmp,
},
WestendRelayPallet as WestendPallet,
},
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs
index 0dfe7a85f4c2a..576c44fc542fd 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs
@@ -17,6 +17,7 @@ mod claim_assets;
mod fellowship_treasury;
mod hybrid_transfers;
mod reserve_transfer;
+mod reward_pool;
mod send;
mod set_asset_claimer;
mod set_xcm_versions;
diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reward_pool.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reward_pool.rs
new file mode 100644
index 0000000000000..4df51abcacebf
--- /dev/null
+++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reward_pool.rs
@@ -0,0 +1,113 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::imports::*;
+use codec::Encode;
+use frame_support::{assert_ok, sp_runtime::traits::Dispatchable, traits::schedule::DispatchTime};
+use xcm_executor::traits::ConvertLocation;
+
+#[test]
+fn treasury_creates_asset_reward_pool() {
+ AssetHubWestend::execute_with(|| {
+ type RuntimeEvent = ::RuntimeEvent;
+ type Balances = ::Balances;
+
+ let treasurer =
+ Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]);
+ let treasurer_account =
+ ahw_xcm_config::LocationToAccountId::convert_location(&treasurer).unwrap();
+
+ assert_ok!(Balances::force_set_balance(
+ ::RuntimeOrigin::root(),
+ treasurer_account.clone().into(),
+ ASSET_HUB_WESTEND_ED * 100_000,
+ ));
+
+ let events = AssetHubWestend::events();
+ match events.iter().last() {
+ Some(RuntimeEvent::Balances(pallet_balances::Event::BalanceSet { who, .. })) =>
+ assert_eq!(*who, treasurer_account),
+ _ => panic!("Expected Balances::BalanceSet event"),
+ }
+ });
+ Westend::execute_with(|| {
+ type AssetHubWestendRuntimeCall = ::RuntimeCall;
+ type AssetHubWestendRuntime = ::Runtime;
+ type WestendRuntimeCall = ::RuntimeCall;
+ type WestendRuntime = ::Runtime;
+ type WestendRuntimeEvent = ::RuntimeEvent;
+ type WestendRuntimeOrigin = ::RuntimeOrigin;
+
+ Dmp::make_parachain_reachable(AssetHubWestend::para_id());
+
+ let staked_asset_id = bx!(RelayLocation::get());
+ let reward_asset_id = bx!(RelayLocation::get());
+
+ let reward_rate_per_block = 1_000_000_000;
+ let lifetime = 1_000_000_000;
+ let admin = None;
+
+ let create_pool_call =
+ WestendRuntimeCall::XcmPallet(pallet_xcm::Call::::send {
+ dest: bx!(VersionedLocation::V4(
+ xcm::v4::Junction::Parachain(AssetHubWestend::para_id().into()).into()
+ )),
+ message: bx!(VersionedXcm::V5(Xcm(vec![
+ UnpaidExecution { weight_limit: Unlimited, check_origin: None },
+ Transact {
+ origin_kind: OriginKind::SovereignAccount,
+ fallback_max_weight: None,
+ call: AssetHubWestendRuntimeCall::AssetRewards(
+ pallet_asset_rewards::Call::::create_pool {
+ staked_asset_id,
+ reward_asset_id,
+ reward_rate_per_block,
+ expiry: DispatchTime::After(lifetime),
+ admin
+ }
+ )
+ .encode()
+ .into(),
+ }
+ ]))),
+ });
+
+ let treasury_origin: WestendRuntimeOrigin = Treasurer.into();
+ assert_ok!(create_pool_call.dispatch(treasury_origin));
+
+ assert_expected_events!(
+ Westend,
+ vec![
+ WestendRuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {},
+ ]
+ );
+ });
+
+ AssetHubWestend::execute_with(|| {
+ type Runtime = ::Runtime;
+ type RuntimeEvent = ::RuntimeEvent;
+
+ assert_eq!(1, pallet_asset_rewards::Pools::::iter().count());
+
+ let events = AssetHubWestend::events();
+ match events.iter().last() {
+ Some(RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed {
+ success: true,
+ ..
+ })) => (),
+ _ => panic!("Expected MessageQueue::Processed event"),
+ }
+ });
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
index abe59a8439a8a..d612dd03c247a 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
@@ -30,6 +30,7 @@ frame-try-runtime = { optional = true, workspace = true }
pallet-asset-conversion = { workspace = true }
pallet-asset-conversion-ops = { workspace = true }
pallet-asset-conversion-tx-payment = { workspace = true }
+pallet-asset-rewards = { workspace = true }
pallet-assets = { workspace = true }
pallet-assets-freezer = { workspace = true }
pallet-aura = { workspace = true }
@@ -61,6 +62,7 @@ sp-storage = { workspace = true }
sp-transaction-pool = { workspace = true }
sp-version = { workspace = true }
sp-weights = { workspace = true }
+
# num-traits feature needed for dex integer sq root:
primitive-types = { features = ["codec", "num-traits", "scale-info"], workspace = true }
@@ -123,6 +125,7 @@ runtime-benchmarks = [
"pallet-asset-conversion-ops/runtime-benchmarks",
"pallet-asset-conversion-tx-payment/runtime-benchmarks",
"pallet-asset-conversion/runtime-benchmarks",
+ "pallet-asset-rewards/runtime-benchmarks",
"pallet-assets-freezer/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
@@ -162,6 +165,7 @@ try-runtime = [
"pallet-asset-conversion-ops/try-runtime",
"pallet-asset-conversion-tx-payment/try-runtime",
"pallet-asset-conversion/try-runtime",
+ "pallet-asset-rewards/try-runtime",
"pallet-assets-freezer/try-runtime",
"pallet-assets/try-runtime",
"pallet-aura/try-runtime",
@@ -212,6 +216,7 @@ std = [
"pallet-asset-conversion-ops/std",
"pallet-asset-conversion-tx-payment/std",
"pallet-asset-conversion/std",
+ "pallet-asset-rewards/std",
"pallet-assets-freezer/std",
"pallet-assets/std",
"pallet-aura/std",
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
index db9a8201ebbe0..43b7bf0ba1184 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
@@ -35,7 +35,7 @@ use assets_common::{
foreign_creators::ForeignCreators,
local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
matching::{FromNetwork, FromSiblingParachain},
- AssetIdForTrustBackedAssetsConvert,
+ AssetIdForPoolAssets, AssetIdForPoolAssetsConvert, AssetIdForTrustBackedAssetsConvert,
};
use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
use cumulus_primitives_core::{AggregateMessageOrigin, ClaimQueueOffset, CoreSelector};
@@ -61,9 +61,9 @@ use frame_support::{
genesis_builder_helper::{build_state, get_preset},
ord_parameter_types, parameter_types,
traits::{
- fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool,
- ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter,
- TransformOrigin,
+ fungible, fungible::HoldConsideration, fungibles, tokens::imbalance::ResolveAssetTo,
+ AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8,
+ ConstantStoragePrice, EitherOfDiverse, Equals, InstanceFilter, TransformOrigin,
},
weights::{ConstantMultiplier, Weight, WeightToFee as _},
BoundedVec, PalletId,
@@ -84,8 +84,8 @@ use sp_runtime::{Perbill, RuntimeDebug};
use testnet_parachains_constants::rococo::{consensus::*, currency::*, fee::WeightToFee, time::*};
use xcm_config::{
ForeignAssetsConvertedConcreteId, GovernanceLocation, LocationToAccountId,
- PoolAssetsConvertedConcreteId, TokenLocation, TrustBackedAssetsConvertedConcreteId,
- TrustBackedAssetsPalletLocation,
+ PoolAssetsConvertedConcreteId, PoolAssetsPalletLocation, TokenLocation,
+ TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocation,
};
#[cfg(test)]
@@ -111,6 +111,9 @@ use xcm_runtime_apis::{
fees::Error as XcmPaymentApiError,
};
+#[cfg(feature = "runtime-benchmarks")]
+use frame_support::traits::PalletInfoAccess;
+
use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
impl_opaque_keys! {
@@ -217,8 +220,8 @@ impl pallet_balances::Config for Runtime {
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
- type FreezeIdentifier = ();
- type MaxFreezes = ConstU32<0>;
+ type FreezeIdentifier = RuntimeFreezeReason;
+ type MaxFreezes = ConstU32<50>;
type DoneSlashHandler = ();
}
@@ -302,7 +305,7 @@ impl pallet_assets::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type RemoveItemsLimit = ConstU32<1000>;
- type AssetId = u32;
+ type AssetId = AssetIdForPoolAssets;
type AssetIdParameter = u32;
type Currency = Balances;
type CreateOrigin =
@@ -343,8 +346,21 @@ pub type LocalAndForeignAssets = fungibles::UnionOf<
AccountId,
>;
-/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`.
-pub type NativeAndAssets = fungible::UnionOf<
+/// Union fungibles implementation for `AssetsFreezer` and `ForeignAssetsFreezer`.
+pub type LocalAndForeignAssetsFreezer = fungibles::UnionOf<
+ AssetsFreezer,
+ ForeignAssetsFreezer,
+ LocalFromLeft<
+ AssetIdForTrustBackedAssetsConvert,
+ AssetIdForTrustBackedAssets,
+ xcm::v5::Location,
+ >,
+ xcm::v5::Location,
+ AccountId,
+>;
+
+/// Union fungibles implementation for [`LocalAndForeignAssets`] and [`Balances`].
+pub type NativeAndNonPoolAssets = fungible::UnionOf<
Balances,
LocalAndForeignAssets,
TargetFromLeft,
@@ -352,6 +368,45 @@ pub type NativeAndAssets = fungible::UnionOf<
AccountId,
>;
+/// Union fungibles implementation for [`LocalAndForeignAssetsFreezer`] and [`Balances`].
+pub type NativeAndNonPoolAssetsFreezer = fungible::UnionOf<
+ Balances,
+ LocalAndForeignAssetsFreezer,
+ TargetFromLeft,
+ xcm::v5::Location,
+ AccountId,
+>;
+
+/// Union fungibles implementation for [`PoolAssets`] and [`NativeAndNonPoolAssets`].
+///
+/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
+pub type NativeAndAllAssets = fungibles::UnionOf<
+ PoolAssets,
+ NativeAndNonPoolAssets,
+ LocalFromLeft<
+ AssetIdForPoolAssetsConvert,
+ AssetIdForPoolAssets,
+ xcm::v5::Location,
+ >,
+ xcm::v5::Location,
+ AccountId,
+>;
+
+/// Union fungibles implementation for [`PoolAssetsFreezer`] and [`NativeAndNonPoolAssetsFreezer`].
+///
+/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
+pub type NativeAndAllAssetsFreezer = fungibles::UnionOf<
+ PoolAssetsFreezer,
+ NativeAndNonPoolAssetsFreezer,
+ LocalFromLeft<
+ AssetIdForPoolAssetsConvert,
+ AssetIdForPoolAssets,
+ xcm::v5::Location,
+ >,
+ xcm::v5::Location,
+ AccountId,
+>;
+
pub type PoolIdToAccountId = pallet_asset_conversion::AccountIdConverter<
AssetConversionPalletId,
(xcm::v5::Location, xcm::v5::Location),
@@ -362,7 +417,7 @@ impl pallet_asset_conversion::Config for Runtime {
type Balance = Balance;
type HigherPrecisionBalance = sp_core::U256;
type AssetKind = xcm::v5::Location;
- type Assets = NativeAndAssets;
+ type Assets = NativeAndNonPoolAssets;
type PoolId = (Self::AssetKind, Self::AssetKind);
type PoolLocator = pallet_asset_conversion::WithFirstAsset<
TokenLocation,
@@ -823,9 +878,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime {
type AssetId = xcm::v5::Location;
type OnChargeAssetTransaction = SwapAssetAdapter<
TokenLocation,
- NativeAndAssets,
+ NativeAndNonPoolAssets,
AssetConversion,
- ResolveAssetTo,
+ ResolveAssetTo,
>;
type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo;
#[cfg(feature = "runtime-benchmarks")]
@@ -953,6 +1008,55 @@ impl pallet_xcm_bridge_hub_router::Config for Runtim
type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId;
}
+#[cfg(feature = "runtime-benchmarks")]
+pub struct PalletAssetRewardsBenchmarkHelper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl pallet_asset_rewards::benchmarking::BenchmarkHelper
+ for PalletAssetRewardsBenchmarkHelper
+{
+ fn staked_asset() -> Location {
+ Location::new(
+ 0,
+ [PalletInstance(::index() as u8), GeneralIndex(100)],
+ )
+ }
+ fn reward_asset() -> Location {
+ Location::new(
+ 0,
+ [PalletInstance(::index() as u8), GeneralIndex(101)],
+ )
+ }
+}
+
+parameter_types! {
+ pub const AssetRewardsPalletId: PalletId = PalletId(*b"py/astrd");
+ pub const RewardsPoolCreationHoldReason: RuntimeHoldReason =
+ RuntimeHoldReason::AssetRewards(pallet_asset_rewards::HoldReason::PoolCreation);
+ // 1 item, 135 bytes into the storage on pool creation.
+ pub const StakePoolCreationDeposit: Balance = deposit(1, 135);
+}
+
+impl pallet_asset_rewards::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+ type PalletId = AssetRewardsPalletId;
+ type Balance = Balance;
+ type Assets = NativeAndAllAssets;
+ type AssetsFreezer = NativeAndAllAssetsFreezer;
+ type AssetId = xcm::v5::Location;
+ type CreatePoolOrigin = EnsureSigned;
+ type RuntimeFreezeReason = RuntimeFreezeReason;
+ type Consideration = HoldConsideration<
+ AccountId,
+ Balances,
+ RewardsPoolCreationHoldReason,
+ ConstantStoragePrice,
+ >;
+ type WeightInfo = weights::pallet_asset_rewards::WeightInfo;
+ #[cfg(feature = "runtime-benchmarks")]
+ type BenchmarkHelper = PalletAssetRewardsBenchmarkHelper;
+}
+
// Create the runtime by composing the FRAME pallets that were previously configured.
construct_runtime!(
pub enum Runtime
@@ -998,10 +1102,13 @@ construct_runtime!(
NftFractionalization: pallet_nft_fractionalization = 54,
PoolAssets: pallet_assets:: = 55,
AssetConversion: pallet_asset_conversion = 56,
+
AssetsFreezer: pallet_assets_freezer:: = 57,
ForeignAssetsFreezer: pallet_assets_freezer:: = 58,
PoolAssetsFreezer: pallet_assets_freezer:: = 59,
+ AssetRewards: pallet_asset_rewards = 60,
+
// TODO: the pallet instance should be removed once all pools have migrated
// to the new account IDs.
AssetConversionMigration: pallet_asset_conversion_ops = 200,
@@ -1193,6 +1300,7 @@ mod benches {
[pallet_assets, Foreign]
[pallet_assets, Pool]
[pallet_asset_conversion, AssetConversion]
+ [pallet_asset_rewards, AssetRewards]
[pallet_asset_conversion_tx_payment, AssetTxPayment]
[pallet_balances, Balances]
[pallet_message_queue, MessageQueue]
@@ -1503,6 +1611,12 @@ impl_runtime_apis! {
}
}
+ impl pallet_asset_rewards::AssetRewards for Runtime {
+ fn pool_creation_cost() -> Balance {
+ StakePoolCreationDeposit::get()
+ }
+ }
+
impl cumulus_primitives_core::GetCoreSelectorApi for Runtime {
fn core_selector() -> (CoreSelector, ClaimQueueOffset) {
ParachainSystem::core_selector()
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs
index ae78a56d8b3c1..6893766ac72d2 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs
@@ -24,6 +24,7 @@ pub mod frame_system_extensions;
pub mod pallet_asset_conversion;
pub mod pallet_asset_conversion_ops;
pub mod pallet_asset_conversion_tx_payment;
+pub mod pallet_asset_rewards;
pub mod pallet_assets_foreign;
pub mod pallet_assets_local;
pub mod pallet_assets_pool;
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_rewards.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_rewards.rs
new file mode 100644
index 0000000000000..218c93c510350
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_rewards.rs
@@ -0,0 +1,217 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus. If not, see .
+
+//! Autogenerated weights for `pallet_asset_rewards`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2025-01-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-ys-ssygq-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// target/production/polkadot-parachain
+// benchmark
+// pallet
+// --steps=50
+// --repeat=20
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
+// --pallet=pallet_asset_rewards
+// --chain=asset-hub-rococo-dev
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_asset_rewards`.
+pub struct WeightInfo(PhantomData);
+impl pallet_asset_rewards::WeightInfo for WeightInfo {
+ /// Storage: `Assets::Asset` (r:2 w:0)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::NextPoolId` (r:1 w:1)
+ /// Proof: `AssetRewards::NextPoolId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolCost` (r:0 w:1)
+ /// Proof: `AssetRewards::PoolCost` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::Pools` (r:0 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn create_pool() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `358`
+ // Estimated: `6360`
+ // Minimum execution time: 65_882_000 picoseconds.
+ Weight::from_parts(67_073_000, 0)
+ .saturating_add(Weight::from_parts(0, 6360))
+ .saturating_add(T::DbWeight::get().reads(5))
+ .saturating_add(T::DbWeight::get().writes(5))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::Freezes` (r:1 w:1)
+ /// Proof: `AssetsFreezer::Freezes` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:1 w:0)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:1)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ fn stake() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `872`
+ // Estimated: `4809`
+ // Minimum execution time: 56_950_000 picoseconds.
+ Weight::from_parts(58_088_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(5))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::Freezes` (r:1 w:1)
+ /// Proof: `AssetsFreezer::Freezes` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:1 w:0)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:1)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ fn unstake() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `872`
+ // Estimated: `4809`
+ // Minimum execution time: 59_509_000 picoseconds.
+ Weight::from_parts(61_064_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(5))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:0)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Asset` (r:1 w:1)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:2 w:2)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:0)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ fn harvest_rewards() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `1072`
+ // Estimated: `6208`
+ // Minimum execution time: 80_685_000 picoseconds.
+ Weight::from_parts(83_505_000, 0)
+ .saturating_add(Weight::from_parts(0, 6208))
+ .saturating_add(T::DbWeight::get().reads(6))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn set_pool_reward_rate_per_block() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `318`
+ // Estimated: `4809`
+ // Minimum execution time: 17_032_000 picoseconds.
+ Weight::from_parts(17_628_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(1))
+ .saturating_add(T::DbWeight::get().writes(1))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn set_pool_admin() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `318`
+ // Estimated: `4809`
+ // Minimum execution time: 15_290_000 picoseconds.
+ Weight::from_parts(16_212_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(1))
+ .saturating_add(T::DbWeight::get().writes(1))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn set_pool_expiry_block() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `318`
+ // Estimated: `4809`
+ // Minimum execution time: 17_721_000 picoseconds.
+ Weight::from_parts(18_603_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(1))
+ .saturating_add(T::DbWeight::get().writes(1))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:0)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Asset` (r:1 w:1)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:2 w:2)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:0)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ fn deposit_reward_tokens() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `747`
+ // Estimated: `6208`
+ // Minimum execution time: 67_754_000 picoseconds.
+ Weight::from_parts(69_428_000, 0)
+ .saturating_add(Weight::from_parts(0, 6208))
+ .saturating_add(T::DbWeight::get().reads(6))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:0)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Asset` (r:1 w:1)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:2 w:2)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:1)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:2 w:2)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolCost` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolCost` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::Freezes` (r:0 w:1)
+ /// Proof: `AssetsFreezer::Freezes` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`)
+ fn cleanup_pool() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `1105`
+ // Estimated: `6208`
+ // Minimum execution time: 127_524_000 picoseconds.
+ Weight::from_parts(130_238_000, 0)
+ .saturating_add(Weight::from_parts(0, 6208))
+ .saturating_add(T::DbWeight::get().reads(10))
+ .saturating_add(T::DbWeight::get().writes(10))
+ }
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs
index 08b2f520c4b9a..0c6ff5e4bfddc 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs
@@ -76,6 +76,10 @@ parameter_types! {
pub TrustBackedAssetsPalletLocation: Location =
PalletInstance(TrustBackedAssetsPalletIndex::get()).into();
pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8;
+ pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location =
+ xcm::v3::Junction::PalletInstance(::index() as u8).into();
+ pub PoolAssetsPalletLocationV3: xcm::v3::Location =
+ xcm::v3::Junction::PalletInstance(::index() as u8).into();
pub ForeignAssetsPalletLocation: Location =
PalletInstance(::index() as u8).into();
pub PoolAssetsPalletLocation: Location =
@@ -336,7 +340,7 @@ pub type TrustedTeleporters = (
/// asset and the asset required for fee payment.
pub type PoolAssetsExchanger = SingleAssetExchangeAdapter<
crate::AssetConversion,
- crate::NativeAndAssets,
+ crate::NativeAndNonPoolAssets,
(
TrustBackedAssetsAsLocation,
ForeignAssetsConvertedConcreteId,
@@ -387,7 +391,7 @@ impl xcm_executor::Config for XcmConfig {
TokenLocation,
crate::AssetConversion,
WeightToFee,
- crate::NativeAndAssets,
+ crate::NativeAndNonPoolAssets,
(
TrustBackedAssetsAsLocation<
TrustBackedAssetsPalletLocation,
@@ -396,7 +400,7 @@ impl xcm_executor::Config for XcmConfig {
>,
ForeignAssetsConvertedConcreteId,
),
- ResolveAssetTo,
+ ResolveAssetTo,
AccountId,
>,
// This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
index cb10ae9a48003..65ef63a7fb356 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
@@ -30,6 +30,7 @@ frame-try-runtime = { optional = true, workspace = true }
pallet-asset-conversion = { workspace = true }
pallet-asset-conversion-ops = { workspace = true }
pallet-asset-conversion-tx-payment = { workspace = true }
+pallet-asset-rewards = { workspace = true }
pallet-assets = { workspace = true }
pallet-assets-freezer = { workspace = true }
pallet-aura = { workspace = true }
@@ -62,6 +63,7 @@ sp-std = { workspace = true }
sp-storage = { workspace = true }
sp-transaction-pool = { workspace = true }
sp-version = { workspace = true }
+
# num-traits feature needed for dex integer sq root:
primitive-types = { features = ["codec", "num-traits", "scale-info"], workspace = true }
@@ -125,6 +127,7 @@ runtime-benchmarks = [
"pallet-asset-conversion-ops/runtime-benchmarks",
"pallet-asset-conversion-tx-payment/runtime-benchmarks",
"pallet-asset-conversion/runtime-benchmarks",
+ "pallet-asset-rewards/runtime-benchmarks",
"pallet-assets-freezer/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
@@ -166,6 +169,7 @@ try-runtime = [
"pallet-asset-conversion-ops/try-runtime",
"pallet-asset-conversion-tx-payment/try-runtime",
"pallet-asset-conversion/try-runtime",
+ "pallet-asset-rewards/try-runtime",
"pallet-assets-freezer/try-runtime",
"pallet-assets/try-runtime",
"pallet-aura/try-runtime",
@@ -218,6 +222,7 @@ std = [
"pallet-asset-conversion-ops/std",
"pallet-asset-conversion-tx-payment/std",
"pallet-asset-conversion/std",
+ "pallet-asset-rewards/std",
"pallet-assets-freezer/std",
"pallet-assets/std",
"pallet-aura/std",
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
index 5966dd01f18fe..f56c4568f2d1f 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
@@ -33,7 +33,7 @@ extern crate alloc;
use alloc::{vec, vec::Vec};
use assets_common::{
local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
- AssetIdForTrustBackedAssetsConvert,
+ AssetIdForPoolAssets, AssetIdForPoolAssetsConvert, AssetIdForTrustBackedAssetsConvert,
};
use codec::{Decode, Encode, MaxEncodedLen};
use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
@@ -44,10 +44,12 @@ use frame_support::{
genesis_builder_helper::{build_state, get_preset},
ord_parameter_types, parameter_types,
traits::{
- fungible, fungibles,
+ fungible,
+ fungible::HoldConsideration,
+ fungibles,
tokens::{imbalance::ResolveAssetTo, nonfungibles_v2::Inspect},
- AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, Equals,
- InstanceFilter, Nothing, TransformOrigin,
+ AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8,
+ ConstantStoragePrice, Equals, InstanceFilter, Nothing, TransformOrigin,
},
weights::{ConstantMultiplier, Weight, WeightToFee as _},
BoundedVec, PalletId,
@@ -81,8 +83,8 @@ use testnet_parachains_constants::westend::{
};
use xcm_config::{
ForeignAssetsConvertedConcreteId, LocationToAccountId, PoolAssetsConvertedConcreteId,
- TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocation, WestendLocation,
- XcmOriginToTransactDispatchOrigin,
+ PoolAssetsPalletLocation, TrustBackedAssetsConvertedConcreteId,
+ TrustBackedAssetsPalletLocation, WestendLocation, XcmOriginToTransactDispatchOrigin,
};
#[cfg(any(feature = "std", test))]
@@ -93,11 +95,15 @@ use assets_common::{
matching::{FromNetwork, FromSiblingParachain},
};
use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
+use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
use xcm::{
latest::prelude::AssetId,
prelude::{VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm},
};
+#[cfg(feature = "runtime-benchmarks")]
+use frame_support::traits::PalletInfoAccess;
+
#[cfg(feature = "runtime-benchmarks")]
use xcm::latest::prelude::{
Asset, Assets as XcmAssets, Fungible, Here, InteriorLocation, Junction, Junction::*, Location,
@@ -109,8 +115,6 @@ use xcm_runtime_apis::{
fees::Error as XcmPaymentApiError,
};
-use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
-
impl_opaque_keys! {
pub struct SessionKeys {
pub aura: Aura,
@@ -125,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: alloc::borrow::Cow::Borrowed("westmint"),
impl_name: alloc::borrow::Cow::Borrowed("westmint"),
authoring_version: 1,
- spec_version: 1_017_004,
+ spec_version: 1_017_005,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 16,
@@ -218,8 +222,8 @@ impl pallet_balances::Config for Runtime {
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
- type FreezeIdentifier = ();
- type MaxFreezes = ConstU32<0>;
+ type FreezeIdentifier = RuntimeFreezeReason;
+ type MaxFreezes = ConstU32<50>;
type DoneSlashHandler = ();
}
@@ -341,8 +345,22 @@ pub type LocalAndForeignAssets = fungibles::UnionOf<
xcm::v5::Location,
AccountId,
>;
+
+/// Union fungibles implementation for `AssetsFreezer` and `ForeignAssetsFreezer`.
+pub type LocalAndForeignAssetsFreezer = fungibles::UnionOf<
+ AssetsFreezer,
+ ForeignAssetsFreezer,
+ LocalFromLeft<
+ AssetIdForTrustBackedAssetsConvert,
+ AssetIdForTrustBackedAssets,
+ xcm::v5::Location,
+ >,
+ xcm::v5::Location,
+ AccountId,
+>;
+
/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`.
-pub type NativeAndAssets = fungible::UnionOf<
+pub type NativeAndNonPoolAssets = fungible::UnionOf<
Balances,
LocalAndForeignAssets,
TargetFromLeft,
@@ -350,6 +368,45 @@ pub type NativeAndAssets = fungible::UnionOf<
AccountId,
>;
+/// Union fungibles implementation for [`LocalAndForeignAssetsFreezer`] and [`Balances`].
+pub type NativeAndNonPoolAssetsFreezer = fungible::UnionOf<
+ Balances,
+ LocalAndForeignAssetsFreezer,
+ TargetFromLeft,
+ xcm::v5::Location,
+ AccountId,
+>;
+
+/// Union fungibles implementation for [`PoolAssets`] and [`NativeAndNonPoolAssets`].
+///
+/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
+pub type NativeAndAllAssets = fungibles::UnionOf<
+ PoolAssets,
+ NativeAndNonPoolAssets,
+ LocalFromLeft<
+ AssetIdForPoolAssetsConvert,
+ AssetIdForPoolAssets,
+ xcm::v5::Location,
+ >,
+ xcm::v5::Location,
+ AccountId,
+>;
+
+/// Union fungibles implementation for [`PoolAssetsFreezer`] and [`NativeAndNonPoolAssetsFreezer`].
+///
+/// NOTE: Should be kept updated to include ALL balances and assets in the runtime.
+pub type NativeAndAllAssetsFreezer = fungibles::UnionOf<
+ PoolAssetsFreezer,
+ NativeAndNonPoolAssetsFreezer,
+ LocalFromLeft<
+ AssetIdForPoolAssetsConvert,
+ AssetIdForPoolAssets,
+ xcm::v5::Location,
+ >,
+ xcm::v5::Location,
+ AccountId,
+>;
+
pub type PoolIdToAccountId = pallet_asset_conversion::AccountIdConverter<
AssetConversionPalletId,
(xcm::v5::Location, xcm::v5::Location),
@@ -360,7 +417,7 @@ impl pallet_asset_conversion::Config for Runtime {
type Balance = Balance;
type HigherPrecisionBalance = sp_core::U256;
type AssetKind = xcm::v5::Location;
- type Assets = NativeAndAssets;
+ type Assets = NativeAndNonPoolAssets;
type PoolId = (Self::AssetKind, Self::AssetKind);
type PoolLocator = pallet_asset_conversion::WithFirstAsset<
WestendLocation,
@@ -388,6 +445,55 @@ impl pallet_asset_conversion::Config for Runtime {
>;
}
+#[cfg(feature = "runtime-benchmarks")]
+pub struct PalletAssetRewardsBenchmarkHelper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl pallet_asset_rewards::benchmarking::BenchmarkHelper
+ for PalletAssetRewardsBenchmarkHelper
+{
+ fn staked_asset() -> Location {
+ Location::new(
+ 0,
+ [PalletInstance(::index() as u8), GeneralIndex(100)],
+ )
+ }
+ fn reward_asset() -> Location {
+ Location::new(
+ 0,
+ [PalletInstance(::index() as u8), GeneralIndex(101)],
+ )
+ }
+}
+
+parameter_types! {
+ pub const AssetRewardsPalletId: PalletId = PalletId(*b"py/astrd");
+ pub const RewardsPoolCreationHoldReason: RuntimeHoldReason =
+ RuntimeHoldReason::AssetRewards(pallet_asset_rewards::HoldReason::PoolCreation);
+ // 1 item, 135 bytes into the storage on pool creation.
+ pub const StakePoolCreationDeposit: Balance = deposit(1, 135);
+}
+
+impl pallet_asset_rewards::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+ type PalletId = AssetRewardsPalletId;
+ type Balance = Balance;
+ type Assets = NativeAndAllAssets;
+ type AssetsFreezer = NativeAndAllAssetsFreezer;
+ type AssetId = xcm::v5::Location;
+ type CreatePoolOrigin = EnsureSigned;
+ type RuntimeFreezeReason = RuntimeFreezeReason;
+ type Consideration = HoldConsideration<
+ AccountId,
+ Balances,
+ RewardsPoolCreationHoldReason,
+ ConstantStoragePrice,
+ >;
+ type WeightInfo = weights::pallet_asset_rewards::WeightInfo;
+ #[cfg(feature = "runtime-benchmarks")]
+ type BenchmarkHelper = PalletAssetRewardsBenchmarkHelper;
+}
+
impl pallet_asset_conversion_ops::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type PriorAccountIdConverter = pallet_asset_conversion::AccountIdConverterNoSeed<
@@ -816,9 +922,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime {
type AssetId = xcm::v5::Location;
type OnChargeAssetTransaction = SwapAssetAdapter<
WestendLocation,
- NativeAndAssets,
+ NativeAndNonPoolAssets,
AssetConversion,
- ResolveAssetTo,
+ ResolveAssetTo,
>;
type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo;
#[cfg(feature = "runtime-benchmarks")]
@@ -971,7 +1077,6 @@ impl pallet_revive::Config for Runtime {
type InstantiateOrigin = EnsureSigned;
type RuntimeHoldReason = RuntimeHoldReason;
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
- type Debug = ();
type Xcm = pallet_xcm::Pallet;
type ChainId = ConstU64<420_420_421>;
type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
@@ -1035,11 +1140,14 @@ construct_runtime!(
NftFractionalization: pallet_nft_fractionalization = 54,
PoolAssets: pallet_assets:: = 55,
AssetConversion: pallet_asset_conversion = 56,
+
AssetsFreezer: pallet_assets_freezer:: = 57,
ForeignAssetsFreezer: pallet_assets_freezer:: = 58,
PoolAssetsFreezer: pallet_assets_freezer:: = 59,
Revive: pallet_revive = 60,
+ AssetRewards: pallet_asset_rewards = 61,
+
StateTrieMigration: pallet_state_trie_migration = 70,
// TODO: the pallet instance should be removed once all pools have migrated
@@ -1317,6 +1425,7 @@ mod benches {
[pallet_assets, Foreign]
[pallet_assets, Pool]
[pallet_asset_conversion, AssetConversion]
+ [pallet_asset_rewards, AssetRewards]
[pallet_asset_conversion_tx_payment, AssetTxPayment]
[pallet_balances, Balances]
[pallet_message_queue, MessageQueue]
@@ -1674,6 +1783,12 @@ impl_runtime_apis! {
}
}
+ impl pallet_asset_rewards::AssetRewards for Runtime {
+ fn pool_creation_cost() -> Balance {
+ StakePoolCreationDeposit::get()
+ }
+ }
+
impl cumulus_primitives_core::GetCoreSelectorApi for Runtime {
fn core_selector() -> (CoreSelector, ClaimQueueOffset) {
ParachainSystem::core_selector()
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs
index 442b58635f48a..d653838ad80e6 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs
@@ -23,6 +23,7 @@ pub mod frame_system_extensions;
pub mod pallet_asset_conversion;
pub mod pallet_asset_conversion_ops;
pub mod pallet_asset_conversion_tx_payment;
+pub mod pallet_asset_rewards;
pub mod pallet_assets_foreign;
pub mod pallet_assets_local;
pub mod pallet_assets_pool;
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_rewards.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_rewards.rs
new file mode 100644
index 0000000000000..3bbc289fec7b6
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_rewards.rs
@@ -0,0 +1,217 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus. If not, see .
+
+//! Autogenerated weights for `pallet_asset_rewards`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2025-01-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-ys-ssygq-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// target/production/polkadot-parachain
+// benchmark
+// pallet
+// --steps=50
+// --repeat=20
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
+// --pallet=pallet_asset_rewards
+// --chain=asset-hub-westend-dev
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_asset_rewards`.
+pub struct WeightInfo(PhantomData);
+impl pallet_asset_rewards::WeightInfo for WeightInfo {
+ /// Storage: `Assets::Asset` (r:2 w:0)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::NextPoolId` (r:1 w:1)
+ /// Proof: `AssetRewards::NextPoolId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolCost` (r:0 w:1)
+ /// Proof: `AssetRewards::PoolCost` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::Pools` (r:0 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn create_pool() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `392`
+ // Estimated: `6360`
+ // Minimum execution time: 60_734_000 picoseconds.
+ Weight::from_parts(61_828_000, 0)
+ .saturating_add(Weight::from_parts(0, 6360))
+ .saturating_add(T::DbWeight::get().reads(5))
+ .saturating_add(T::DbWeight::get().writes(5))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::Freezes` (r:1 w:1)
+ /// Proof: `AssetsFreezer::Freezes` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:1 w:0)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:1)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ fn stake() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `906`
+ // Estimated: `4809`
+ // Minimum execution time: 56_014_000 picoseconds.
+ Weight::from_parts(58_487_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(5))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::Freezes` (r:1 w:1)
+ /// Proof: `AssetsFreezer::Freezes` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:1 w:0)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:1)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ fn unstake() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `906`
+ // Estimated: `4809`
+ // Minimum execution time: 59_071_000 picoseconds.
+ Weight::from_parts(60_631_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(5))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:0)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Asset` (r:1 w:1)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:2 w:2)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:0)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ fn harvest_rewards() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `1106`
+ // Estimated: `6208`
+ // Minimum execution time: 80_585_000 picoseconds.
+ Weight::from_parts(82_186_000, 0)
+ .saturating_add(Weight::from_parts(0, 6208))
+ .saturating_add(T::DbWeight::get().reads(6))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn set_pool_reward_rate_per_block() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `318`
+ // Estimated: `4809`
+ // Minimum execution time: 17_083_000 picoseconds.
+ Weight::from_parts(17_816_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(1))
+ .saturating_add(T::DbWeight::get().writes(1))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn set_pool_admin() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `318`
+ // Estimated: `4809`
+ // Minimum execution time: 15_269_000 picoseconds.
+ Weight::from_parts(15_881_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(1))
+ .saturating_add(T::DbWeight::get().writes(1))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ fn set_pool_expiry_block() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `318`
+ // Estimated: `4809`
+ // Minimum execution time: 17_482_000 picoseconds.
+ Weight::from_parts(18_124_000, 0)
+ .saturating_add(Weight::from_parts(0, 4809))
+ .saturating_add(T::DbWeight::get().reads(1))
+ .saturating_add(T::DbWeight::get().writes(1))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:0)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Asset` (r:1 w:1)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:2 w:2)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:0)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ fn deposit_reward_tokens() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `781`
+ // Estimated: `6208`
+ // Minimum execution time: 66_644_000 picoseconds.
+ Weight::from_parts(67_950_000, 0)
+ .saturating_add(Weight::from_parts(0, 6208))
+ .saturating_add(T::DbWeight::get().reads(6))
+ .saturating_add(T::DbWeight::get().writes(4))
+ }
+ /// Storage: `AssetRewards::Pools` (r:1 w:1)
+ /// Proof: `AssetRewards::Pools` (`max_values`: None, `max_size`: Some(1344), added: 3819, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolStakers` (r:1 w:0)
+ /// Proof: `AssetRewards::PoolStakers` (`max_values`: None, `max_size`: Some(116), added: 2591, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Asset` (r:1 w:1)
+ /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+ /// Storage: `Assets::Account` (r:2 w:2)
+ /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::FrozenBalances` (r:1 w:1)
+ /// Proof: `AssetsFreezer::FrozenBalances` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:2 w:2)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `AssetRewards::PoolCost` (r:1 w:1)
+ /// Proof: `AssetRewards::PoolCost` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `MaxEncodedLen`)
+ /// Storage: `AssetsFreezer::Freezes` (r:0 w:1)
+ /// Proof: `AssetsFreezer::Freezes` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`)
+ fn cleanup_pool() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `1139`
+ // Estimated: `6208`
+ // Minimum execution time: 124_136_000 picoseconds.
+ Weight::from_parts(128_642_000, 0)
+ .saturating_add(Weight::from_parts(0, 6208))
+ .saturating_add(T::DbWeight::get().reads(10))
+ .saturating_add(T::DbWeight::get().writes(10))
+ }
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs
index b4e938f1f8b57..1ea2ce5136abd 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs
@@ -65,6 +65,7 @@ use xcm_executor::XcmExecutor;
parameter_types! {
pub const RootLocation: Location = Location::here();
pub const WestendLocation: Location = Location::parent();
+ pub const GovernanceLocation: Location = Location::parent();
pub const RelayNetwork: Option = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH));
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorLocation =
@@ -359,7 +360,7 @@ pub type TrustedTeleporters = (
/// asset and the asset required for fee payment.
pub type PoolAssetsExchanger = SingleAssetExchangeAdapter<
crate::AssetConversion,
- crate::NativeAndAssets,
+ crate::NativeAndNonPoolAssets,
(
TrustBackedAssetsAsLocation,
ForeignAssetsConvertedConcreteId,
@@ -409,7 +410,7 @@ impl xcm_executor::Config for XcmConfig {
WestendLocation,
crate::AssetConversion,
WeightToFee,
- crate::NativeAndAssets,
+ crate::NativeAndNonPoolAssets,
(
TrustBackedAssetsAsLocation<
TrustBackedAssetsPalletLocation,
@@ -418,7 +419,7 @@ impl xcm_executor::Config for XcmConfig {
>,
ForeignAssetsConvertedConcreteId,
),
- ResolveAssetTo,
+ ResolveAssetTo,
AccountId,
>,
// This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated
diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs
index 25c2df6b68d16..50b1b63146bc8 100644
--- a/cumulus/parachains/runtimes/assets/common/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs
@@ -123,10 +123,11 @@ pub type ForeignAssetsConvertedConcreteId<
BalanceConverter,
>;
-type AssetIdForPoolAssets = u32;
+pub type AssetIdForPoolAssets = u32;
+
/// `Location` vs `AssetIdForPoolAssets` converter for `PoolAssets`.
-pub type AssetIdForPoolAssetsConvert =
- AsPrefixedGeneralIndex;
+pub type AssetIdForPoolAssetsConvert =
+ AsPrefixedGeneralIndex;
/// [`MatchedConvertedConcreteId`] converter dedicated for `PoolAssets`
pub type PoolAssetsConvertedConcreteId =
MatchedConvertedConcreteId<
diff --git a/docs/sdk/packages/guides/first-pallet/Cargo.toml b/docs/sdk/packages/guides/first-pallet/Cargo.toml
index a1411580119da..e6325c31781a6 100644
--- a/docs/sdk/packages/guides/first-pallet/Cargo.toml
+++ b/docs/sdk/packages/guides/first-pallet/Cargo.toml
@@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { workspace = true }
docify = { workspace = true }
-frame = { workspace = true, features = ["experimental", "runtime"] }
+frame = { workspace = true, features = ["runtime"] }
scale-info = { workspace = true }
[features]
diff --git a/docs/sdk/packages/guides/first-runtime/Cargo.toml b/docs/sdk/packages/guides/first-runtime/Cargo.toml
index 303d5c5e7f5fc..8ed17dea1b71e 100644
--- a/docs/sdk/packages/guides/first-runtime/Cargo.toml
+++ b/docs/sdk/packages/guides/first-runtime/Cargo.toml
@@ -18,7 +18,7 @@ scale-info = { workspace = true }
serde_json = { workspace = true }
# this is a frame-based runtime, thus importing `frame` with runtime feature enabled.
-frame = { workspace = true, features = ["experimental", "runtime"] }
+frame = { workspace = true, features = ["runtime"] }
# pallets that we want to use
pallet-balances = { workspace = true }
diff --git a/polkadot/node/core/pvf/tests/it/process.rs b/polkadot/node/core/pvf/tests/it/process.rs
index 353367b394f34..29326365b5baa 100644
--- a/polkadot/node/core/pvf/tests/it/process.rs
+++ b/polkadot/node/core/pvf/tests/it/process.rs
@@ -77,7 +77,9 @@ fn find_process_by_sid_and_name(
let mut found = None;
for process in all_processes {
- let stat = process.stat().expect("/proc existed above. Potential race occurred");
+ let Ok(stat) = process.stat() else {
+ continue;
+ };
if stat.session != sid || !process.exe().unwrap().to_str().unwrap().contains(exe_name) {
continue
diff --git a/polkadot/node/metrics/Cargo.toml b/polkadot/node/metrics/Cargo.toml
index 454337cb63f87..318deca4f2438 100644
--- a/polkadot/node/metrics/Cargo.toml
+++ b/polkadot/node/metrics/Cargo.toml
@@ -18,7 +18,7 @@ gum = { workspace = true, default-features = true }
metered = { features = ["futures_channel"], workspace = true }
# Both `sc-service` and `sc-cli` are required by runtime metrics `logger_hook()`.
-sc-cli = { workspace = true, default-features = true }
+sc-cli = { workspace = true }
sc-service = { workspace = true, default-features = true }
bs58 = { features = ["alloc"], workspace = true, default-features = true }
diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs
index b3f2a0033278a..c2c3d35ee5b42 100644
--- a/polkadot/runtime/rococo/src/lib.rs
+++ b/polkadot/runtime/rococo/src/lib.rs
@@ -1822,7 +1822,7 @@ mod benches {
[polkadot_runtime_parachains::initializer, Initializer]
[polkadot_runtime_parachains::paras_inherent, ParaInherent]
[polkadot_runtime_parachains::paras, Paras]
- [polkadot_runtime_parachains::assigner_on_demand, OnDemandAssignmentProvider]
+ [polkadot_runtime_parachains::on_demand, OnDemandAssignmentProvider]
// Substrate
[pallet_balances, Balances]
[pallet_balances, NisCounterpartBalances]
diff --git a/polkadot/runtime/rococo/src/xcm_config.rs b/polkadot/runtime/rococo/src/xcm_config.rs
index bb77ec0000e56..10c3f6c0cbfcf 100644
--- a/polkadot/runtime/rococo/src/xcm_config.rs
+++ b/polkadot/runtime/rococo/src/xcm_config.rs
@@ -18,7 +18,8 @@
use super::{
parachains_origin, AccountId, AllPalletsWithSystem, Balances, Dmp, Fellows, ParaId, Runtime,
- RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, Treasury, WeightToFee, XcmPallet,
+ RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, Treasurer, Treasury, WeightToFee,
+ XcmPallet,
};
use crate::governance::StakingAdmin;
@@ -228,11 +229,14 @@ impl xcm_executor::Config for XcmConfig {
}
parameter_types! {
+ /// Collective pluralistic body.
pub const CollectiveBodyId: BodyId = BodyId::Unit;
- // StakingAdmin pluralistic body.
+ /// StakingAdmin pluralistic body.
pub const StakingAdminBodyId: BodyId = BodyId::Defense;
- // Fellows pluralistic body.
+ /// Fellows pluralistic body.
pub const FellowsBodyId: BodyId = BodyId::Technical;
+ /// Treasury pluralistic body.
+ pub const TreasuryBodyId: BodyId = BodyId::Treasury;
}
/// Type to convert an `Origin` type value into a `Location` value which represents an interior
@@ -249,6 +253,9 @@ pub type StakingAdminToPlurality =
/// Type to convert the Fellows origin to a Plurality `Location` value.
pub type FellowsToPlurality = OriginToPluralityVoice;
+/// Type to convert the Treasury origin to a Plurality `Location` value.
+pub type TreasurerToPlurality = OriginToPluralityVoice;
+
/// Type to convert a pallet `Origin` type value into a `Location` value which represents an
/// interior location of this chain for a destination chain.
pub type LocalPalletOriginToLocation = (
@@ -256,13 +263,18 @@ pub type LocalPalletOriginToLocation = (
StakingAdminToPlurality,
// Fellows origin to be used in XCM as a corresponding Plurality `Location` value.
FellowsToPlurality,
+ // Treasurer origin to be used in XCM as a corresponding Plurality `Location` value.
+ TreasurerToPlurality,
);
impl pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
// Note that this configuration of `SendXcmOrigin` is different from the one present in
// production.
- type SendXcmOrigin = xcm_builder::EnsureXcmOrigin;
+ type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<
+ RuntimeOrigin,
+ (LocalPalletOriginToLocation, LocalOriginToLocation),
+ >;
type XcmRouter = XcmRouter;
// Anyone can execute XCM messages locally.
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin;
diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs
index 4f9ba8d8508cd..cdf6fa92da2f5 100644
--- a/polkadot/runtime/test-runtime/src/lib.rs
+++ b/polkadot/runtime/test-runtime/src/lib.rs
@@ -366,11 +366,13 @@ impl onchain::Config for OnChainSeqPhragmen {
const MAX_QUOTA_NOMINATIONS: u32 = 16;
impl pallet_staking::Config for Runtime {
+ type OldCurrency = Balances;
type Currency = Balances;
type CurrencyBalance = Balance;
type UnixTime = Timestamp;
type CurrencyToVote = polkadot_runtime_common::CurrencyToVote;
type RewardRemainder = ();
+ type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeEvent = RuntimeEvent;
type Slash = ();
type Reward = ();
diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs
index 58d2bdcb7c7db..a9ba0778fe0ef 100644
--- a/polkadot/runtime/westend/src/lib.rs
+++ b/polkadot/runtime/westend/src/lib.rs
@@ -728,8 +728,10 @@ parameter_types! {
}
impl pallet_staking::Config for Runtime {
+ type OldCurrency = Balances;
type Currency = Balances;
type CurrencyBalance = Balance;
+ type RuntimeHoldReason = RuntimeHoldReason;
type UnixTime = Timestamp;
type CurrencyToVote = CurrencyToVote;
type RewardRemainder = ();
@@ -1085,6 +1087,7 @@ pub enum ProxyType {
CancelProxy,
Auction,
NominationPools,
+ ParaRegistration,
}
impl Default for ProxyType {
fn default() -> Self {
@@ -1181,6 +1184,15 @@ impl InstanceFilter for ProxyType {
RuntimeCall::Registrar(..) |
RuntimeCall::Slots(..)
),
+ ProxyType::ParaRegistration => matches!(
+ c,
+ RuntimeCall::Registrar(paras_registrar::Call::reserve { .. }) |
+ RuntimeCall::Registrar(paras_registrar::Call::register { .. }) |
+ RuntimeCall::Utility(pallet_utility::Call::batch { .. }) |
+ RuntimeCall::Utility(pallet_utility::Call::batch_all { .. }) |
+ RuntimeCall::Utility(pallet_utility::Call::force_batch { .. }) |
+ RuntimeCall::Proxy(pallet_proxy::Call::remove_proxy { .. })
+ ),
}
}
fn is_superset(&self, o: &Self) -> bool {
diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs
index fcdaf7ff2de6d..65b81cc00f069 100644
--- a/polkadot/runtime/westend/src/tests.rs
+++ b/polkadot/runtime/westend/src/tests.rs
@@ -155,25 +155,27 @@ mod remote_tests {
let transport: Transport = var("WS").unwrap_or("ws://127.0.0.1:9900".to_string()).into();
let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok();
+ let online_config = OnlineConfig {
+ transport,
+ state_snapshot: maybe_state_snapshot.clone(),
+ child_trie: false,
+ pallets: vec![
+ "Staking".into(),
+ "System".into(),
+ "Balances".into(),
+ "NominationPools".into(),
+ "DelegatedStaking".into(),
+ ],
+ ..Default::default()
+ };
let mut ext = Builder::::default()
.mode(if let Some(state_snapshot) = maybe_state_snapshot {
Mode::OfflineOrElseOnline(
OfflineConfig { state_snapshot: state_snapshot.clone() },
- OnlineConfig {
- transport,
- state_snapshot: Some(state_snapshot),
- pallets: vec![
- "staking".into(),
- "system".into(),
- "balances".into(),
- "nomination-pools".into(),
- "delegated-staking".into(),
- ],
- ..Default::default()
- },
+ online_config,
)
} else {
- Mode::Online(OnlineConfig { transport, ..Default::default() })
+ Mode::Online(online_config)
})
.build()
.await
@@ -241,6 +243,77 @@ mod remote_tests {
);
});
}
+
+ #[tokio::test]
+ async fn staking_curr_fun_migrate() {
+ // Intended to be run only manually.
+ if var("RUN_MIGRATION_TESTS").is_err() {
+ return;
+ }
+ sp_tracing::try_init_simple();
+
+ let transport: Transport = var("WS").unwrap_or("ws://127.0.0.1:9944".to_string()).into();
+ let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok();
+ let online_config = OnlineConfig {
+ transport,
+ state_snapshot: maybe_state_snapshot.clone(),
+ child_trie: false,
+ pallets: vec!["Staking".into(), "System".into(), "Balances".into()],
+ ..Default::default()
+ };
+ let mut ext = Builder::::default()
+ .mode(if let Some(state_snapshot) = maybe_state_snapshot {
+ Mode::OfflineOrElseOnline(
+ OfflineConfig { state_snapshot: state_snapshot.clone() },
+ online_config,
+ )
+ } else {
+ Mode::Online(online_config)
+ })
+ .build()
+ .await
+ .unwrap();
+ ext.execute_with(|| {
+ // create an account with some balance
+ let alice = AccountId::from([1u8; 32]);
+ use frame_support::traits::Currency;
+ let _ = Balances::deposit_creating(&alice, 100_000 * UNITS);
+
+ let mut success = 0;
+ let mut err = 0;
+ let mut force_withdraw_acc = 0;
+ // iterate over all pools
+ pallet_staking::Ledger::::iter().for_each(|(ctrl, ledger)| {
+ match pallet_staking::Pallet::::migrate_currency(
+ RuntimeOrigin::signed(alice.clone()).into(),
+ ledger.stash.clone(),
+ ) {
+ Ok(_) => {
+ let updated_ledger =
+ pallet_staking::Ledger::::get(&ctrl).expect("ledger exists");
+ let force_withdraw = ledger.total - updated_ledger.total;
+ if force_withdraw > 0 {
+ force_withdraw_acc += force_withdraw;
+ log::info!(target: "remote_test", "Force withdraw from stash {:?}: value {:?}", ledger.stash, force_withdraw);
+ }
+ success += 1;
+ },
+ Err(e) => {
+ log::error!(target: "remote_test", "Error migrating {:?}: {:?}", ledger.stash, e);
+ err += 1;
+ },
+ }
+ });
+
+ log::info!(
+ target: "remote_test",
+ "Migration stats: success: {}, err: {}, total force withdrawn stake: {}",
+ success,
+ err,
+ force_withdraw_acc
+ );
+ });
+ }
}
#[test]
diff --git a/polkadot/runtime/westend/src/weights/pallet_staking.rs b/polkadot/runtime/westend/src/weights/pallet_staking.rs
index 393fa0b37176a..f1e7f5ba1576e 100644
--- a/polkadot/runtime/westend/src/weights/pallet_staking.rs
+++ b/polkadot/runtime/westend/src/weights/pallet_staking.rs
@@ -17,9 +17,9 @@
//! Autogenerated weights for `pallet_staking`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2024-03-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-09-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-h2rr8wx7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-obbyq9g6-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024
// Executed Command:
@@ -52,19 +52,19 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
/// Storage: `Staking::Payee` (r:0 w:1)
/// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
fn bond() -> Weight {
// Proof Size summary in bytes:
- // Measured: `1009`
- // Estimated: `4764`
- // Minimum execution time: 40_585_000 picoseconds.
- Weight::from_parts(41_800_000, 0)
- .saturating_add(Weight::from_parts(0, 4764))
+ // Measured: `1035`
+ // Estimated: `4556`
+ // Minimum execution time: 70_147_000 picoseconds.
+ Weight::from_parts(71_795_000, 0)
+ .saturating_add(Weight::from_parts(0, 4556))
.saturating_add(T::DbWeight::get().reads(4))
.saturating_add(T::DbWeight::get().writes(4))
}
@@ -72,20 +72,20 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListNodes` (r:3 w:3)
/// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListBags` (r:2 w:2)
/// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`)
fn bond_extra() -> Weight {
// Proof Size summary in bytes:
- // Measured: `1921`
+ // Measured: `1947`
// Estimated: `8877`
- // Minimum execution time: 81_809_000 picoseconds.
- Weight::from_parts(84_387_000, 0)
+ // Minimum execution time: 125_203_000 picoseconds.
+ Weight::from_parts(128_088_000, 0)
.saturating_add(Weight::from_parts(0, 8877))
.saturating_add(T::DbWeight::get().reads(9))
.saturating_add(T::DbWeight::get().writes(7))
@@ -100,23 +100,23 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:0)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListNodes` (r:3 w:3)
/// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListBags` (r:2 w:2)
/// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`)
fn unbond() -> Weight {
// Proof Size summary in bytes:
- // Measured: `2128`
+ // Measured: `2051`
// Estimated: `8877`
- // Minimum execution time: 89_419_000 picoseconds.
- Weight::from_parts(91_237_000, 0)
+ // Minimum execution time: 101_991_000 picoseconds.
+ Weight::from_parts(104_567_000, 0)
.saturating_add(Weight::from_parts(0, 8877))
.saturating_add(T::DbWeight::get().reads(12))
- .saturating_add(T::DbWeight::get().writes(7))
+ .saturating_add(T::DbWeight::get().writes(6))
}
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
@@ -124,23 +124,25 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0)
/// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+ /// Storage: `DelegatedStaking::Agents` (r:1 w:0)
+ /// Proof: `DelegatedStaking::Agents` (`max_values`: None, `max_size`: Some(120), added: 2595, mode: `MaxEncodedLen`)
/// The range of component `s` is `[0, 100]`.
fn withdraw_unbonded_update(s: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `1223`
- // Estimated: `4764`
- // Minimum execution time: 45_152_000 picoseconds.
- Weight::from_parts(46_460_819, 0)
- .saturating_add(Weight::from_parts(0, 4764))
- // Standard Error: 972
- .saturating_add(Weight::from_parts(55_473, 0).saturating_mul(s.into()))
- .saturating_add(T::DbWeight::get().reads(6))
+ // Measured: `1253`
+ // Estimated: `4556`
+ // Minimum execution time: 76_450_000 picoseconds.
+ Weight::from_parts(78_836_594, 0)
+ .saturating_add(Weight::from_parts(0, 4556))
+ // Standard Error: 1_529
+ .saturating_add(Weight::from_parts(66_662, 0).saturating_mul(s.into()))
+ .saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Staking::Ledger` (r:1 w:1)
@@ -151,10 +153,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::SlashingSpans` (r:1 w:1)
/// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:1)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `Staking::Validators` (r:1 w:0)
/// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`)
/// Storage: `Staking::Nominators` (r:1 w:1)
@@ -174,15 +176,15 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `s` is `[0, 100]`.
fn withdraw_unbonded_kill(s: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `2127 + s * (4 ±0)`
+ // Measured: `2153 + s * (4 ±0)`
// Estimated: `6248 + s * (4 ±0)`
- // Minimum execution time: 82_762_000 picoseconds.
- Weight::from_parts(91_035_077, 0)
+ // Minimum execution time: 121_962_000 picoseconds.
+ Weight::from_parts(131_000_151, 0)
.saturating_add(Weight::from_parts(0, 6248))
- // Standard Error: 3_771
- .saturating_add(Weight::from_parts(1_217_871, 0).saturating_mul(s.into()))
+ // Standard Error: 3_846
+ .saturating_add(Weight::from_parts(1_277_843, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(13))
- .saturating_add(T::DbWeight::get().writes(11))
+ .saturating_add(T::DbWeight::get().writes(12))
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into())))
.saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into()))
}
@@ -210,10 +212,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn validate() -> Weight {
// Proof Size summary in bytes:
- // Measured: `1301`
+ // Measured: `1334`
// Estimated: `4556`
- // Minimum execution time: 50_555_000 picoseconds.
- Weight::from_parts(52_052_000, 0)
+ // Minimum execution time: 66_450_000 picoseconds.
+ Weight::from_parts(68_302_000, 0)
.saturating_add(Weight::from_parts(0, 4556))
.saturating_add(T::DbWeight::get().reads(11))
.saturating_add(T::DbWeight::get().writes(5))
@@ -227,13 +229,13 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `k` is `[1, 128]`.
fn kick(k: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `1778 + k * (572 ±0)`
+ // Measured: `1811 + k * (572 ±0)`
// Estimated: `4556 + k * (3033 ±0)`
- // Minimum execution time: 35_037_000 picoseconds.
- Weight::from_parts(35_081_878, 0)
+ // Minimum execution time: 43_875_000 picoseconds.
+ Weight::from_parts(47_332_240, 0)
.saturating_add(Weight::from_parts(0, 4556))
- // Standard Error: 5_473
- .saturating_add(Weight::from_parts(6_667_924, 0).saturating_mul(k.into()))
+ // Standard Error: 6_530
+ .saturating_add(Weight::from_parts(7_398_001, 0).saturating_mul(k.into()))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into())))
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into())))
@@ -264,13 +266,13 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `n` is `[1, 16]`.
fn nominate(n: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `1797 + n * (102 ±0)`
+ // Measured: `1830 + n * (102 ±0)`
// Estimated: `6248 + n * (2520 ±0)`
- // Minimum execution time: 62_098_000 picoseconds.
- Weight::from_parts(60_154_061, 0)
+ // Minimum execution time: 80_640_000 picoseconds.
+ Weight::from_parts(78_801_092, 0)
.saturating_add(Weight::from_parts(0, 6248))
- // Standard Error: 19_257
- .saturating_add(Weight::from_parts(3_839_855, 0).saturating_mul(n.into()))
+ // Standard Error: 22_249
+ .saturating_add(Weight::from_parts(4_996_344, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(12))
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into())))
.saturating_add(T::DbWeight::get().writes(6))
@@ -294,10 +296,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn chill() -> Weight {
// Proof Size summary in bytes:
- // Measured: `1747`
+ // Measured: `1780`
// Estimated: `6248`
- // Minimum execution time: 54_993_000 picoseconds.
- Weight::from_parts(56_698_000, 0)
+ // Minimum execution time: 71_494_000 picoseconds.
+ Weight::from_parts(73_487_000, 0)
.saturating_add(Weight::from_parts(0, 6248))
.saturating_add(T::DbWeight::get().reads(9))
.saturating_add(T::DbWeight::get().writes(6))
@@ -310,10 +312,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
fn set_payee() -> Weight {
// Proof Size summary in bytes:
- // Measured: `865`
+ // Measured: `898`
// Estimated: `4556`
- // Minimum execution time: 18_100_000 picoseconds.
- Weight::from_parts(18_547_000, 0)
+ // Minimum execution time: 24_310_000 picoseconds.
+ Weight::from_parts(24_676_000, 0)
.saturating_add(Weight::from_parts(0, 4556))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
@@ -326,10 +328,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
fn update_payee() -> Weight {
// Proof Size summary in bytes:
- // Measured: `932`
+ // Measured: `965`
// Estimated: `4556`
- // Minimum execution time: 23_428_000 picoseconds.
- Weight::from_parts(24_080_000, 0)
+ // Minimum execution time: 31_348_000 picoseconds.
+ Weight::from_parts(32_384_000, 0)
.saturating_add(Weight::from_parts(0, 4556))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1))
@@ -340,10 +342,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
fn set_controller() -> Weight {
// Proof Size summary in bytes:
- // Measured: `865`
+ // Measured: `898`
// Estimated: `8122`
- // Minimum execution time: 21_159_000 picoseconds.
- Weight::from_parts(21_706_000, 0)
+ // Minimum execution time: 27_537_000 picoseconds.
+ Weight::from_parts(28_714_000, 0)
.saturating_add(Weight::from_parts(0, 8122))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(3))
@@ -354,8 +356,8 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 1_910_000 picoseconds.
- Weight::from_parts(2_003_000, 0)
+ // Minimum execution time: 2_362_000 picoseconds.
+ Weight::from_parts(2_518_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(1))
}
@@ -365,8 +367,8 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 7_076_000 picoseconds.
- Weight::from_parts(7_349_000, 0)
+ // Minimum execution time: 7_752_000 picoseconds.
+ Weight::from_parts(8_105_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(1))
}
@@ -376,8 +378,8 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 7_067_000 picoseconds.
- Weight::from_parts(7_389_000, 0)
+ // Minimum execution time: 7_868_000 picoseconds.
+ Weight::from_parts(8_175_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(1))
}
@@ -387,8 +389,8 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 7_148_000 picoseconds.
- Weight::from_parts(7_446_000, 0)
+ // Minimum execution time: 7_945_000 picoseconds.
+ Weight::from_parts(8_203_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(1))
}
@@ -399,11 +401,11 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 2_025_000 picoseconds.
- Weight::from_parts(2_229_953, 0)
+ // Minimum execution time: 2_458_000 picoseconds.
+ Weight::from_parts(2_815_664, 0)
.saturating_add(Weight::from_parts(0, 0))
// Standard Error: 67
- .saturating_add(Weight::from_parts(11_785, 0).saturating_mul(v.into()))
+ .saturating_add(Weight::from_parts(12_287, 0).saturating_mul(v.into()))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Staking::Ledger` (r:1502 w:1502)
@@ -415,13 +417,13 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `i` is `[0, 751]`.
fn deprecate_controller_batch(i: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `680 + i * (227 ±0)`
+ // Measured: `713 + i * (227 ±0)`
// Estimated: `990 + i * (7132 ±0)`
- // Minimum execution time: 4_321_000 picoseconds.
- Weight::from_parts(4_407_000, 0)
+ // Minimum execution time: 4_976_000 picoseconds.
+ Weight::from_parts(5_102_000, 0)
.saturating_add(Weight::from_parts(0, 990))
- // Standard Error: 37_239
- .saturating_add(Weight::from_parts(21_300_598, 0).saturating_mul(i.into()))
+ // Standard Error: 36_458
+ .saturating_add(Weight::from_parts(25_359_275, 0).saturating_mul(i.into()))
.saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(i.into())))
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into())))
.saturating_add(Weight::from_parts(0, 7132).saturating_mul(i.into()))
@@ -432,10 +434,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:1)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Staking::Validators` (r:1 w:0)
@@ -457,15 +459,15 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `s` is `[0, 100]`.
fn force_unstake(s: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `2127 + s * (4 ±0)`
+ // Measured: `2153 + s * (4 ±0)`
// Estimated: `6248 + s * (4 ±0)`
- // Minimum execution time: 78_908_000 picoseconds.
- Weight::from_parts(84_886_373, 0)
+ // Minimum execution time: 116_776_000 picoseconds.
+ Weight::from_parts(125_460_389, 0)
.saturating_add(Weight::from_parts(0, 6248))
- // Standard Error: 3_376
- .saturating_add(Weight::from_parts(1_217_850, 0).saturating_mul(s.into()))
+ // Standard Error: 3_095
+ .saturating_add(Weight::from_parts(1_300_502, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(13))
- .saturating_add(T::DbWeight::get().writes(12))
+ .saturating_add(T::DbWeight::get().writes(13))
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into())))
.saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into()))
}
@@ -474,13 +476,13 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `s` is `[1, 1000]`.
fn cancel_deferred_slash(s: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `66639`
- // Estimated: `70104`
- // Minimum execution time: 136_389_000 picoseconds.
- Weight::from_parts(1_207_241_524, 0)
- .saturating_add(Weight::from_parts(0, 70104))
- // Standard Error: 77_138
- .saturating_add(Weight::from_parts(6_443_948, 0).saturating_mul(s.into()))
+ // Measured: `66672`
+ // Estimated: `70137`
+ // Minimum execution time: 135_135_000 picoseconds.
+ Weight::from_parts(937_565_332, 0)
+ .saturating_add(Weight::from_parts(0, 70137))
+ // Standard Error: 57_675
+ .saturating_add(Weight::from_parts(4_828_080, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@@ -498,12 +500,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasValidatorReward` (r:1 w:0)
/// Proof: `Staking::ErasValidatorReward` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Locks` (r:65 w:65)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:65 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
- /// Storage: `System::Account` (r:65 w:65)
- /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:65 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:65 w:65)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakersPaged` (r:1 w:0)
/// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Staking::ErasRewardPoints` (r:1 w:0)
@@ -512,30 +512,32 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `MaxEncodedLen`)
/// Storage: `Staking::Payee` (r:65 w:0)
/// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:65 w:65)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// The range of component `n` is `[0, 64]`.
fn payout_stakers_alive_staked(n: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `8249 + n * (396 ±0)`
- // Estimated: `10779 + n * (3774 ±0)`
- // Minimum execution time: 130_222_000 picoseconds.
- Weight::from_parts(167_236_150, 0)
- .saturating_add(Weight::from_parts(0, 10779))
- // Standard Error: 34_051
- .saturating_add(Weight::from_parts(39_899_917, 0).saturating_mul(n.into()))
+ // Measured: `8275 + n * (389 ±0)`
+ // Estimated: `10805 + n * (3566 ±0)`
+ // Minimum execution time: 180_144_000 picoseconds.
+ Weight::from_parts(237_134_733, 0)
+ .saturating_add(Weight::from_parts(0, 10805))
+ // Standard Error: 52_498
+ .saturating_add(Weight::from_parts(73_633_326, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(14))
.saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into())))
.saturating_add(T::DbWeight::get().writes(4))
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into())))
- .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into()))
+ .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into()))
}
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::Bonded` (r:1 w:0)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:0)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListNodes` (r:3 w:3)
/// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListBags` (r:2 w:2)
@@ -543,26 +545,26 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `l` is `[1, 32]`.
fn rebond(l: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `1922 + l * (5 ±0)`
+ // Measured: `1845 + l * (5 ±0)`
// Estimated: `8877`
- // Minimum execution time: 79_136_000 picoseconds.
- Weight::from_parts(82_129_497, 0)
+ // Minimum execution time: 89_307_000 picoseconds.
+ Weight::from_parts(92_902_634, 0)
.saturating_add(Weight::from_parts(0, 8877))
- // Standard Error: 3_867
- .saturating_add(Weight::from_parts(75_156, 0).saturating_mul(l.into()))
+ // Standard Error: 4_446
+ .saturating_add(Weight::from_parts(73_546, 0).saturating_mul(l.into()))
.saturating_add(T::DbWeight::get().reads(9))
- .saturating_add(T::DbWeight::get().writes(7))
+ .saturating_add(T::DbWeight::get().writes(6))
}
+ /// Storage: `Staking::VirtualStakers` (r:1 w:1)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
/// Storage: `Staking::Bonded` (r:1 w:1)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::SlashingSpans` (r:1 w:1)
/// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`)
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `Balances::Freezes` (r:1 w:0)
- /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `Staking::Validators` (r:1 w:0)
/// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`)
/// Storage: `Staking::Nominators` (r:1 w:1)
@@ -582,15 +584,15 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `s` is `[1, 100]`.
fn reap_stash(s: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `2127 + s * (4 ±0)`
+ // Measured: `2153 + s * (4 ±0)`
// Estimated: `6248 + s * (4 ±0)`
- // Minimum execution time: 89_375_000 picoseconds.
- Weight::from_parts(91_224_907, 0)
+ // Minimum execution time: 130_544_000 picoseconds.
+ Weight::from_parts(133_260_598, 0)
.saturating_add(Weight::from_parts(0, 6248))
- // Standard Error: 3_424
- .saturating_add(Weight::from_parts(1_219_542, 0).saturating_mul(s.into()))
+ // Standard Error: 3_545
+ .saturating_add(Weight::from_parts(1_313_348, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(12))
- .saturating_add(T::DbWeight::get().writes(11))
+ .saturating_add(T::DbWeight::get().writes(12))
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into())))
.saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into()))
}
@@ -633,14 +635,14 @@ impl pallet_staking::WeightInfo for WeightInfo {
fn new_era(v: u32, n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `0 + n * (716 ±0) + v * (3594 ±0)`
- // Estimated: `456136 + n * (3566 ±4) + v * (3566 ±0)`
- // Minimum execution time: 520_905_000 picoseconds.
- Weight::from_parts(523_771_000, 0)
+ // Estimated: `456136 + n * (3566 ±4) + v * (3566 ±40)`
+ // Minimum execution time: 654_756_000 picoseconds.
+ Weight::from_parts(658_861_000, 0)
.saturating_add(Weight::from_parts(0, 456136))
- // Standard Error: 2_142_714
- .saturating_add(Weight::from_parts(68_631_588, 0).saturating_mul(v.into()))
- // Standard Error: 213_509
- .saturating_add(Weight::from_parts(19_343_025, 0).saturating_mul(n.into()))
+ // Standard Error: 2_078_102
+ .saturating_add(Weight::from_parts(67_775_668, 0).saturating_mul(v.into()))
+ // Standard Error: 207_071
+ .saturating_add(Weight::from_parts(22_624_711, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(184))
.saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into())))
.saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into())))
@@ -669,15 +671,15 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `n` is `[500, 1000]`.
fn get_npos_voters(v: u32, n: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `3108 + n * (907 ±0) + v * (391 ±0)`
+ // Measured: `3141 + n * (907 ±0) + v * (391 ±0)`
// Estimated: `456136 + n * (3566 ±0) + v * (3566 ±0)`
- // Minimum execution time: 36_848_619_000 picoseconds.
- Weight::from_parts(37_362_442_000, 0)
+ // Minimum execution time: 42_790_195_000 picoseconds.
+ Weight::from_parts(42_954_437_000, 0)
.saturating_add(Weight::from_parts(0, 456136))
- // Standard Error: 415_031
- .saturating_add(Weight::from_parts(5_204_987, 0).saturating_mul(v.into()))
- // Standard Error: 415_031
- .saturating_add(Weight::from_parts(4_132_636, 0).saturating_mul(n.into()))
+ // Standard Error: 478_107
+ .saturating_add(Weight::from_parts(6_744_044, 0).saturating_mul(v.into()))
+ // Standard Error: 478_107
+ .saturating_add(Weight::from_parts(4_837_739, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(179))
.saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into())))
.saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into())))
@@ -692,13 +694,13 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// The range of component `v` is `[500, 1000]`.
fn get_npos_targets(v: u32, ) -> Weight {
// Proof Size summary in bytes:
- // Measured: `946 + v * (50 ±0)`
+ // Measured: `979 + v * (50 ±0)`
// Estimated: `3510 + v * (2520 ±0)`
- // Minimum execution time: 2_512_817_000 picoseconds.
- Weight::from_parts(119_401_374, 0)
+ // Minimum execution time: 2_851_801_000 picoseconds.
+ Weight::from_parts(4_477_533, 0)
.saturating_add(Weight::from_parts(0, 3510))
- // Standard Error: 8_463
- .saturating_add(Weight::from_parts(4_860_364, 0).saturating_mul(v.into()))
+ // Standard Error: 8_644
+ .saturating_add(Weight::from_parts(5_811_682, 0).saturating_mul(v.into()))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into())))
.saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into()))
@@ -721,8 +723,8 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 3_686_000 picoseconds.
- Weight::from_parts(3_881_000, 0)
+ // Minimum execution time: 4_250_000 picoseconds.
+ Weight::from_parts(4_472_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(7))
}
@@ -744,8 +746,8 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 3_143_000 picoseconds.
- Weight::from_parts(3_424_000, 0)
+ // Minimum execution time: 3_986_000 picoseconds.
+ Weight::from_parts(4_144_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(7))
}
@@ -773,10 +775,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn chill_other() -> Weight {
// Proof Size summary in bytes:
- // Measured: `1870`
+ // Measured: `1903`
// Estimated: `6248`
- // Minimum execution time: 66_946_000 picoseconds.
- Weight::from_parts(69_382_000, 0)
+ // Minimum execution time: 87_291_000 picoseconds.
+ Weight::from_parts(89_344_000, 0)
.saturating_add(Weight::from_parts(0, 6248))
.saturating_add(T::DbWeight::get().reads(12))
.saturating_add(T::DbWeight::get().writes(6))
@@ -787,10 +789,10 @@ impl pallet_staking::WeightInfo for WeightInfo {
/// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`)
fn force_apply_min_commission() -> Weight {
// Proof Size summary in bytes:
- // Measured: `658`
+ // Measured: `691`
// Estimated: `3510`
- // Minimum execution time: 11_278_000 picoseconds.
- Weight::from_parts(11_603_000, 0)
+ // Minimum execution time: 16_113_000 picoseconds.
+ Weight::from_parts(16_593_000, 0)
.saturating_add(Weight::from_parts(0, 3510))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
@@ -801,29 +803,53 @@ impl pallet_staking::WeightInfo for WeightInfo {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
- // Minimum execution time: 1_963_000 picoseconds.
- Weight::from_parts(2_077_000, 0)
+ // Minimum execution time: 2_433_000 picoseconds.
+ Weight::from_parts(2_561_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(1))
}
- /// Storage: `Balances::Locks` (r:1 w:1)
- /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
- /// Storage: `System::Account` (r:1 w:1)
+ /// Storage: `Staking::VirtualStakers` (r:1 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:0)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+ /// Storage: `System::Account` (r:1 w:0)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Locks` (r:1 w:0)
+ /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
/// Storage: `Staking::Bonded` (r:1 w:1)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
+ fn restore_ledger() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `1040`
+ // Estimated: `4764`
+ // Minimum execution time: 50_167_000 picoseconds.
+ Weight::from_parts(51_108_000, 0)
+ .saturating_add(Weight::from_parts(0, 4764))
+ .saturating_add(T::DbWeight::get().reads(6))
+ .saturating_add(T::DbWeight::get().writes(2))
+ }
+ /// Storage: `Staking::VirtualStakers` (r:1 w:0)
+ /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::Bonded` (r:1 w:0)
+ /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
+ /// Storage: `Staking::Ledger` (r:1 w:0)
+ /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Locks` (r:1 w:1)
+ /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
/// Storage: `Balances::Freezes` (r:1 w:0)
/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
- fn restore_ledger() -> Weight {
+ fn migrate_currency() -> Weight {
// Proof Size summary in bytes:
- // Measured: `1014`
+ // Measured: `1209`
// Estimated: `4764`
- // Minimum execution time: 40_258_000 picoseconds.
- Weight::from_parts(41_210_000, 0)
+ // Minimum execution time: 91_790_000 picoseconds.
+ Weight::from_parts(92_991_000, 0)
.saturating_add(Weight::from_parts(0, 4764))
- .saturating_add(T::DbWeight::get().reads(5))
- .saturating_add(T::DbWeight::get().writes(4))
+ .saturating_add(T::DbWeight::get().reads(6))
+ .saturating_add(T::DbWeight::get().writes(2))
}
}
diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs
index 3f6a7304c8a94..4235edf82b24d 100644
--- a/polkadot/runtime/westend/src/xcm_config.rs
+++ b/polkadot/runtime/westend/src/xcm_config.rs
@@ -280,7 +280,10 @@ impl pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
// Note that this configuration of `SendXcmOrigin` is different from the one present in
// production.
- type SendXcmOrigin = xcm_builder::EnsureXcmOrigin;
+ type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<
+ RuntimeOrigin,
+ (LocalPalletOriginToLocation, LocalOriginToLocation),
+ >;
type XcmRouter = XcmRouter;
// Anyone can execute XCM messages locally.
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin;
diff --git a/polkadot/xcm/docs/Cargo.toml b/polkadot/xcm/docs/Cargo.toml
index 6fa7ea9a23a92..c3bda50619c15 100644
--- a/polkadot/xcm/docs/Cargo.toml
+++ b/polkadot/xcm/docs/Cargo.toml
@@ -18,7 +18,7 @@ xcm-simulator = { workspace = true, default-features = true }
# For building FRAME runtimes
codec = { workspace = true, default-features = true }
-frame = { features = ["experimental", "runtime"], workspace = true, default-features = true }
+frame = { features = ["runtime"], workspace = true, default-features = true }
polkadot-parachain-primitives = { workspace = true, default-features = true }
polkadot-primitives = { workspace = true, default-features = true }
polkadot-runtime-parachains = { workspace = true, default-features = true }
diff --git a/prdoc/pr_3926.prdoc b/prdoc/pr_3926.prdoc
new file mode 100644
index 0000000000000..7f352f7a45fb3
--- /dev/null
+++ b/prdoc/pr_3926.prdoc
@@ -0,0 +1,30 @@
+title: Introduce pallet-asset-rewards
+
+doc:
+ - audience: Runtime Dev
+ description: |
+ Introduce pallet-asset-rewards, which allows accounts to be rewarded for freezing fungible
+ tokens. The motivation for creating this pallet is to allow incentivising LPs.
+ See the pallet docs for more info about the pallet.
+
+crates:
+ - name: pallet-asset-rewards
+ bump: major
+ - name: polkadot-sdk
+ bump: minor
+ - name: kitchensink-runtime
+ bump: major
+ - name: asset-hub-rococo-runtime
+ bump: major
+ - name: asset-hub-westend-runtime
+ bump: major
+ - name: assets-common
+ bump: minor
+ - name: rococo-runtime
+ bump: minor
+ - name: westend-runtime
+ bump: patch
+ - name: frame-support
+ bump: minor
+ - name: emulated-integration-tests-common
+ bump: minor
diff --git a/prdoc/pr_5501.prdoc b/prdoc/pr_5501.prdoc
new file mode 100644
index 0000000000000..f2a5aa9a46679
--- /dev/null
+++ b/prdoc/pr_5501.prdoc
@@ -0,0 +1,47 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Currency to Fungible migration for pallet-staking
+
+doc:
+ - audience: Runtime User
+ description: |
+ Lazy migration of staking balance from `Currency::locks` to `Fungible::holds`. New extrinsic
+ `staking::migrate_currency` removes the old lock along with other housekeeping. Additionally, any ledger mutation
+ creates hold if it does not exist.
+
+ The pallet-staking configuration item `Currency` is updated to use `fungible::hold::Mutate` type while still
+ requiring `LockableCurrency` type to be passed as `OldCurrency` for migration purposes.
+
+
+crates:
+ - name: westend-runtime
+ bump: major
+ - name: kitchensink-runtime
+ bump: minor
+ - name: pallet-delegated-staking
+ bump: patch
+ - name: pallet-nomination-pools
+ bump: minor
+ - name: pallet-nomination-pools-runtime-api
+ bump: patch
+ - name: sp-staking
+ bump: patch
+ - name: pallet-beefy
+ bump: patch
+ - name: pallet-fast-unstake
+ bump: patch
+ - name: pallet-staking
+ bump: major
+ - name: pallet-grandpa
+ bump: patch
+ - name: pallet-babe
+ bump: patch
+ - name: pallet-nomination-pools-benchmarking
+ bump: patch
+ - name: pallet-session-benchmarking
+ bump: patch
+ - name: pallet-root-offences
+ bump: patch
+ - name: pallet-offences-benchmarking
+ bump: patch
diff --git a/prdoc/pr_6995.prdoc b/prdoc/pr_6995.prdoc
new file mode 100644
index 0000000000000..ffdb4738a6fd5
--- /dev/null
+++ b/prdoc/pr_6995.prdoc
@@ -0,0 +1,14 @@
+title: added new proxy ParaRegistration to Westend
+doc:
+- audience: Runtime User
+ description: |-
+ This adds a new Proxy type to Westend Runtime called ParaRegistration. This is related to: https://github.com/polkadot-fellows/runtimes/pull/520.
+
+ This new proxy allows:
+ 1. Reserve paraID
+ 2. Register Parachain
+ 3. Leverage Utilites pallet
+ 4. Remove proxy.
+crates:
+- name: westend-runtime
+ bump: major
diff --git a/prdoc/pr_7081.prdoc b/prdoc/pr_7081.prdoc
new file mode 100644
index 0000000000000..be1d8aa6ee013
--- /dev/null
+++ b/prdoc/pr_7081.prdoc
@@ -0,0 +1,14 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: '[pallet-mmr] Migrate to using frame umbrella crate'
+
+doc:
+ - audience: Runtime Dev
+ description: This PR migrates the pallet-mmr to use the frame umbrella crate. This
+ is part of the ongoing effort to migrate all pallets to use the frame umbrella crate.
+ The effort is tracked [here](https://github.com/paritytech/polkadot-sdk/issues/6504).
+
+crates:
+ - name: pallet-mmr
+ bump: minor
diff --git a/prdoc/pr_7093.prdoc b/prdoc/pr_7093.prdoc
new file mode 100644
index 0000000000000..cad4477e8832f
--- /dev/null
+++ b/prdoc/pr_7093.prdoc
@@ -0,0 +1,8 @@
+title: 'initial docify readme with some content #6333'
+doc:
+- audience: Runtime Dev
+ description: |
+ Docifying the README.MD under templates/parachain by adding a Docify.
+ Also Adding the Cargo.toml under the same folder, essentially making it a crate as Docify acts
+ for Readmes only under the same crate.
+crates: [ ]
diff --git a/prdoc/pr_7177.prdoc b/prdoc/pr_7177.prdoc
new file mode 100644
index 0000000000000..9ab0be1f20a93
--- /dev/null
+++ b/prdoc/pr_7177.prdoc
@@ -0,0 +1,20 @@
+title: Make frame crate not experimental
+doc:
+- audience: Runtime Dev
+ description: |-
+ Frame crate may still be unstable, but it is no longer feature gated by the feature `experimental`.
+crates:
+- name: polkadot-sdk-frame
+ bump: minor
+- name: pallet-salary
+ bump: patch
+- name: pallet-multisig
+ bump: patch
+- name: pallet-proxy
+ bump: patch
+- name: pallet-atomic-swap
+ bump: patch
+- name: pallet-mixnet
+ bump: patch
+- name: pallet-node-authorization
+ bump: patch
diff --git a/prdoc/pr_7194.prdoc b/prdoc/pr_7194.prdoc
new file mode 100644
index 0000000000000..3a9db46ceae96
--- /dev/null
+++ b/prdoc/pr_7194.prdoc
@@ -0,0 +1,15 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: '[FRAME] `pallet_asset_tx_payment`: replace `AssetId` bound from `Copy` to `Clone`'
+
+doc:
+ - audience: Runtime Dev
+ description: |
+ `OnChargeAssetTransaction`'s associated type `AssetId` is bounded by `Copy` which makes it impossible
+ to use `staging_xcm::v4::Location` as `AssetId`. This PR bounds `AssetId` to `Clone` instead, which is
+ more lenient.
+
+crates:
+ - name: pallet-asset-tx-payment
+ bump: minor
diff --git a/prdoc/pr_7203.prdoc b/prdoc/pr_7203.prdoc
new file mode 100644
index 0000000000000..96a3d19472e9f
--- /dev/null
+++ b/prdoc/pr_7203.prdoc
@@ -0,0 +1,13 @@
+title: 'pallet_revive: Bump PolkaVM'
+doc:
+- audience: Runtime Dev
+ description: Update to PolkaVM `0.19`. This version renumbers the opcodes in order
+ to be in-line with the grey paper. Hopefully, for the last time. This means that
+ it breaks existing contracts.
+crates:
+- name: pallet-revive
+ bump: patch
+- name: pallet-revive-fixtures
+ bump: patch
+- name: pallet-revive-uapi
+ bump: patch
diff --git a/prdoc/pr_7205.prdoc b/prdoc/pr_7205.prdoc
new file mode 100644
index 0000000000000..758beb0b6313c
--- /dev/null
+++ b/prdoc/pr_7205.prdoc
@@ -0,0 +1,10 @@
+title: 'Collator: Fix `can_build_upon` by always allowing to build on included block'
+doc:
+- audience: Node Dev
+ description: |-
+ Fixes a bug introduced in #6825.
+ We should always allow building on the included block of parachains. In situations where the unincluded segment
+ is full, but the included block moved to the most recent block, building was wrongly disallowed.
+crates:
+- name: cumulus-client-consensus-aura
+ bump: minor
diff --git a/prdoc/pr_7251.prdoc b/prdoc/pr_7251.prdoc
new file mode 100644
index 0000000000000..98e371dc940ff
--- /dev/null
+++ b/prdoc/pr_7251.prdoc
@@ -0,0 +1,7 @@
+title: '[pallet-revive] eth-rpc error logging'
+doc:
+- audience: Runtime Dev
+ description: Log error instead of failing with an error when block processing fails
+crates:
+- name: pallet-revive-eth-rpc
+ bump: minor
diff --git a/prdoc/pr_7263.prdoc b/prdoc/pr_7263.prdoc
new file mode 100644
index 0000000000000..892e804939559
--- /dev/null
+++ b/prdoc/pr_7263.prdoc
@@ -0,0 +1,28 @@
+title: Fix `frame-benchmarking-cli` not buildable without rocksdb
+doc:
+- audience: Runtime Dev
+ description: |-
+ ## Description
+
+ The `frame-benchmarking-cli` crate has not been buildable without the `rocksdb` feature since version 1.17.0.
+
+ **Error:**
+ ```rust
+ self.database()?.unwrap_or(Database::RocksDb),
+ ^^^^^^^ variant or associated item not found in `Database`
+ ```
+
+ This issue is also related to the `rocksdb` feature bleeding (#3793), where the `rocksdb` feature was always activated even when compiling this crate with `--no-default-features`.
+
+ **Fix:**
+ - Resolved the error by choosing `paritydb` as the default database when compiled without the `rocksdb` feature.
+ - Fixed the issue where the `sc-cli` crate's `rocksdb` feature was always active, even compiling `frame-benchmarking-cli` with `--no-default-features`.
+
+ ## Review Notes
+
+ Fix the crate to be built without rocksdb, not intended to solve #3793.
+crates:
+- name: polkadot-node-metrics
+ bump: patch
+- name: frame-benchmarking-cli
+ bump: patch
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 97728f12f5f93..26f4dacf9a1e3 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -53,13 +53,15 @@ use frame_support::{
Balanced, Credit, HoldConsideration, ItemOf, NativeFromLeft, NativeOrWithId, UnionOf,
},
tokens::{
- imbalance::ResolveAssetTo, nonfungibles_v2::Inspect, pay::PayAssetFromAccount,
+ imbalance::{ResolveAssetTo, ResolveTo},
+ nonfungibles_v2::Inspect,
+ pay::PayAssetFromAccount,
GetSalary, PayFromAccount,
},
- AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, Contains,
- Currency, EitherOfDiverse, EnsureOriginWithArg, EqualPrivilegeOnly, Imbalance, InsideBoth,
- InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, LockIdentifier, Nothing,
- OnUnbalanced, VariantCountOf, WithdrawReasons,
+ AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, ConstU64,
+ ConstantStoragePrice, Contains, Currency, EitherOfDiverse, EnsureOriginWithArg,
+ EqualPrivilegeOnly, Imbalance, InsideBoth, InstanceFilter, KeyOwnerProofSystem,
+ LinearStoragePrice, LockIdentifier, Nothing, OnUnbalanced, VariantCountOf, WithdrawReasons,
},
weights::{
constants::{
@@ -511,7 +513,8 @@ impl pallet_glutton::Config for Runtime {
}
parameter_types! {
- pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
+ pub const PreimageHoldReason: RuntimeHoldReason =
+ RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
}
impl pallet_preimage::Config for Runtime {
@@ -618,6 +621,12 @@ impl pallet_transaction_payment::Config for Runtime {
type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight;
}
+pub type AssetsFreezerInstance = pallet_assets_freezer::Instance1;
+impl pallet_assets_freezer::Config for Runtime {
+ type RuntimeFreezeReason = RuntimeFreezeReason;
+ type RuntimeEvent = RuntimeEvent;
+}
+
impl pallet_asset_conversion_tx_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type AssetId = NativeOrWithId;
@@ -712,13 +721,15 @@ impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
}
impl pallet_staking::Config for Runtime {
+ type OldCurrency = Balances;
type Currency = Balances;
type CurrencyBalance = Balance;
type UnixTime = Timestamp;
type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote;
- type RewardRemainder = Treasury;
+ type RewardRemainder = ResolveTo;
type RuntimeEvent = RuntimeEvent;
- type Slash = Treasury; // send the slashed funds to the treasury.
+ type RuntimeHoldReason = RuntimeHoldReason;
+ type Slash = ResolveTo; // send the slashed funds to the treasury.
type Reward = (); // rewards are minted from the void
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
@@ -741,7 +752,7 @@ impl pallet_staking::Config for Runtime {
type MaxUnlockingChunks = ConstU32<32>;
type MaxControllersInDeprecationBatch = MaxControllersInDeprecationBatch;
type HistoryDepth = HistoryDepth;
- type EventListeners = NominationPools;
+ type EventListeners = (NominationPools, DelegatedStaking);
type WeightInfo = pallet_staking::weights::SubstrateWeight;
type BenchmarkingConfig = StakingBenchmarkingConfig;
type DisablingStrategy = pallet_staking::UpToLimitWithReEnablingDisablingStrategy;
@@ -925,6 +936,21 @@ impl pallet_bags_list::Config for Runtime {
type WeightInfo = pallet_bags_list::weights::SubstrateWeight;
}
+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;
+ type OnSlash = ();
+ type SlashRewardFraction = SlashRewardFraction;
+ type RuntimeHoldReason = RuntimeHoldReason;
+ type CoreStaking = Staking;
+}
+
parameter_types! {
pub const PostUnbondPoolsWindow: u32 = 4;
pub const NominationPoolsPalletId: PalletId = PalletId(*b"py/nopls");
@@ -953,7 +979,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 = PostUnbondPoolsWindow;
type MaxMetadataLen = ConstU32<256>;
type MaxUnbonding = ConstU32<8>;
@@ -1464,7 +1491,6 @@ impl pallet_revive::Config for Runtime {
type InstantiateOrigin = EnsureSigned;
type RuntimeHoldReason = RuntimeHoldReason;
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
- type Debug = ();
type Xcm = ();
type ChainId = ConstU64<420_420_420>;
type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
@@ -1858,6 +1884,53 @@ impl pallet_asset_conversion::Config for Runtime {
type BenchmarkHelper = ();
}
+pub type NativeAndAssetsFreezer =
+ UnionOf, AccountId>;
+
+/// Benchmark Helper
+#[cfg(feature = "runtime-benchmarks")]
+pub struct AssetRewardsBenchmarkHelper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl pallet_asset_rewards::benchmarking::BenchmarkHelper>
+ for AssetRewardsBenchmarkHelper
+{
+ fn staked_asset() -> NativeOrWithId {
+ NativeOrWithId::::WithId(100)
+ }
+ fn reward_asset() -> NativeOrWithId {
+ NativeOrWithId::::WithId(101)
+ }
+}
+
+parameter_types! {
+ pub const StakingRewardsPalletId: PalletId = PalletId(*b"py/stkrd");
+ pub const CreationHoldReason: RuntimeHoldReason =
+ RuntimeHoldReason::AssetRewards(pallet_asset_rewards::HoldReason::PoolCreation);
+ // 1 item, 135 bytes into the storage on pool creation.
+ pub const StakePoolCreationDeposit: Balance = deposit(1, 135);
+}
+
+impl pallet_asset_rewards::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+ type RuntimeFreezeReason = RuntimeFreezeReason;
+ type AssetId = NativeOrWithId;
+ type Balance = Balance;
+ type Assets = NativeAndAssets;
+ type PalletId = StakingRewardsPalletId;
+ type CreatePoolOrigin = EnsureSigned;
+ type WeightInfo = ();
+ type AssetsFreezer = NativeAndAssetsFreezer;
+ type Consideration = HoldConsideration<
+ AccountId,
+ Balances,
+ CreationHoldReason,
+ ConstantStoragePrice,
+ >;
+ #[cfg(feature = "runtime-benchmarks")]
+ type BenchmarkHelper = AssetRewardsBenchmarkHelper;
+}
+
impl pallet_asset_conversion_ops::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type PriorAccountIdConverter = pallet_asset_conversion::AccountIdConverterNoSeed<(
@@ -2636,6 +2709,15 @@ mod runtime {
#[runtime::pallet_index(81)]
pub type VerifySignature = pallet_verify_signature::Pallet;
+
+ #[runtime::pallet_index(82)]
+ pub type DelegatedStaking = pallet_delegated_staking::Pallet;
+
+ #[runtime::pallet_index(83)]
+ pub type AssetRewards = pallet_asset_rewards::Pallet;
+
+ #[runtime::pallet_index(84)]
+ pub type AssetsFreezer = pallet_assets_freezer::Pallet;
}
impl TryFrom for pallet_revive::Call {
@@ -2846,6 +2928,7 @@ mod benches {
[pallet_example_tasks, TasksExample]
[pallet_democracy, Democracy]
[pallet_asset_conversion, AssetConversion]
+ [pallet_asset_rewards, AssetRewards]
[pallet_asset_conversion_tx_payment, AssetConversionTxPayment]
[pallet_transaction_payment, TransactionPayment]
[pallet_election_provider_multi_phase, ElectionProviderMultiPhase]
@@ -3553,6 +3636,12 @@ impl_runtime_apis! {
}
}
+ impl pallet_asset_rewards::AssetRewards for Runtime {
+ fn pool_creation_cost() -> Balance {
+ StakePoolCreationDeposit::get()
+ }
+ }
+
#[cfg(feature = "try-runtime")]
impl frame_try_runtime::TryRuntime for Runtime {
fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
diff --git a/substrate/bin/node/testing/src/genesis.rs b/substrate/bin/node/testing/src/genesis.rs
index 606349e0bd6ba..624b00b4d6c23 100644
--- a/substrate/bin/node/testing/src/genesis.rs
+++ b/substrate/bin/node/testing/src/genesis.rs
@@ -38,9 +38,9 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig {
(alice(), 111 * DOLLARS),
(bob(), 100 * DOLLARS),
(charlie(), 100_000_000 * DOLLARS),
- (dave(), 111 * DOLLARS),
+ (dave(), 112 * DOLLARS),
(eve(), 101 * DOLLARS),
- (ferdie(), 100 * DOLLARS),
+ (ferdie(), 101 * DOLLARS),
];
endowed.extend(extra_endowed.into_iter().map(|endowed| (endowed, 100 * DOLLARS)));
diff --git a/substrate/frame/asset-rewards/Cargo.toml b/substrate/frame/asset-rewards/Cargo.toml
new file mode 100644
index 0000000000000..a03fa17cf0dc0
--- /dev/null
+++ b/substrate/frame/asset-rewards/Cargo.toml
@@ -0,0 +1,71 @@
+[package]
+name = "pallet-asset-rewards"
+version = "0.1.0"
+authors.workspace = true
+edition.workspace = true
+license = "Apache-2.0"
+homepage.workspace = true
+repository.workspace = true
+description = "FRAME asset rewards pallet"
+
+[lints]
+workspace = true
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+codec = { workspace = true }
+frame-benchmarking = { workspace = true, optional = true }
+frame-support = { workspace = true, features = ["experimental"] }
+frame-system = { workspace = true }
+scale-info = { workspace = true, features = ["derive"] }
+sp-api = { workspace = true }
+sp-arithmetic = { workspace = true }
+sp-core = { workspace = true }
+sp-io = { workspace = true }
+sp-runtime = { workspace = true }
+sp-std = { workspace = true }
+
+[dev-dependencies]
+pallet-assets = { workspace = true }
+pallet-assets-freezer = { workspace = true }
+pallet-balances = { workspace = true }
+primitive-types = { workspace = true, features = ["codec", "num-traits", "scale-info"] }
+
+[features]
+default = ["std"]
+std = [
+ "codec/std",
+ "frame-benchmarking?/std",
+ "frame-support/std",
+ "frame-system/std",
+ "pallet-assets-freezer/std",
+ "pallet-assets/std",
+ "pallet-balances/std",
+ "primitive-types/std",
+ "scale-info/std",
+ "sp-api/std",
+ "sp-arithmetic/std",
+ "sp-core/std",
+ "sp-io/std",
+ "sp-runtime/std",
+ "sp-std/std",
+]
+runtime-benchmarks = [
+ "frame-benchmarking/runtime-benchmarks",
+ "frame-support/runtime-benchmarks",
+ "frame-system/runtime-benchmarks",
+ "pallet-assets-freezer/runtime-benchmarks",
+ "pallet-assets/runtime-benchmarks",
+ "pallet-balances/runtime-benchmarks",
+ "sp-runtime/runtime-benchmarks",
+]
+try-runtime = [
+ "frame-support/try-runtime",
+ "frame-system/try-runtime",
+ "pallet-assets-freezer/try-runtime",
+ "pallet-assets/try-runtime",
+ "pallet-balances/try-runtime",
+ "sp-runtime/try-runtime",
+]
diff --git a/substrate/frame/asset-rewards/src/benchmarking.rs b/substrate/frame/asset-rewards/src/benchmarking.rs
new file mode 100644
index 0000000000000..5605804dd20ec
--- /dev/null
+++ b/substrate/frame/asset-rewards/src/benchmarking.rs
@@ -0,0 +1,355 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Asset Rewards pallet benchmarking.
+
+use super::*;
+use crate::Pallet as AssetRewards;
+use frame_benchmarking::{v2::*, whitelisted_caller, BenchmarkError};
+use frame_support::{
+ assert_ok,
+ traits::{
+ fungibles::{Create, Inspect, Mutate},
+ Consideration, EnsureOrigin, Footprint,
+ },
+};
+use frame_system::{pallet_prelude::BlockNumberFor, Pallet as System, RawOrigin};
+use sp_runtime::{traits::One, Saturating};
+use sp_std::prelude::*;
+
+/// Benchmark Helper
+pub trait BenchmarkHelper {
+ /// Returns the staked asset id.
+ ///
+ /// If the asset does not exist, it will be created by the benchmark.
+ fn staked_asset() -> AssetId;
+ /// Returns the reward asset id.
+ ///
+ /// If the asset does not exist, it will be created by the benchmark.
+ fn reward_asset() -> AssetId;
+}
+
+fn pool_expire() -> DispatchTime> {
+ DispatchTime::At(BlockNumberFor::::from(100u32))
+}
+
+fn create_reward_pool() -> Result
+where
+ T::Assets: Create + Mutate,
+{
+ let caller_origin =
+ T::CreatePoolOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
+ let caller = T::CreatePoolOrigin::ensure_origin(caller_origin.clone()).unwrap();
+
+ let footprint = Footprint::from_mel::<(PoolId, PoolInfoFor)>();
+ T::Consideration::ensure_successful(&caller, footprint);
+
+ let staked_asset = T::BenchmarkHelper::staked_asset();
+ let reward_asset = T::BenchmarkHelper::reward_asset();
+
+ let min_staked_balance =
+ T::Assets::minimum_balance(staked_asset.clone()).max(T::Balance::one());
+ if !T::Assets::asset_exists(staked_asset.clone()) {
+ assert_ok!(T::Assets::create(
+ staked_asset.clone(),
+ caller.clone(),
+ true,
+ min_staked_balance
+ ));
+ }
+ let min_reward_balance =
+ T::Assets::minimum_balance(reward_asset.clone()).max(T::Balance::one());
+ if !T::Assets::asset_exists(reward_asset.clone()) {
+ assert_ok!(T::Assets::create(
+ reward_asset.clone(),
+ caller.clone(),
+ true,
+ min_reward_balance
+ ));
+ }
+
+ assert_ok!(AssetRewards::::create_pool(
+ caller_origin.clone(),
+ Box::new(staked_asset),
+ Box::new(reward_asset),
+ // reward rate per block
+ min_reward_balance,
+ pool_expire::(),
+ Some(caller),
+ ));
+
+ Ok(caller_origin)
+}
+
+fn mint_into(caller: &T::AccountId, asset: &T::AssetId) -> T::Balance
+where
+ T::Assets: Mutate,
+{
+ let min_balance = T::Assets::minimum_balance(asset.clone());
+ assert_ok!(T::Assets::mint_into(
+ asset.clone(),
+ &caller,
+ min_balance.saturating_mul(10u32.into())
+ ));
+ min_balance
+}
+
+fn assert_last_event(generic_event: ::RuntimeEvent) {
+ System::::assert_last_event(generic_event.into());
+}
+
+#[benchmarks(where T::Assets: Create + Mutate)]
+mod benchmarks {
+ use super::*;
+
+ #[benchmark]
+ fn create_pool() -> Result<(), BenchmarkError> {
+ let caller_origin =
+ T::CreatePoolOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
+ let caller = T::CreatePoolOrigin::ensure_origin(caller_origin.clone()).unwrap();
+
+ let footprint = Footprint::from_mel::<(PoolId, PoolInfoFor)>();
+ T::Consideration::ensure_successful(&caller, footprint);
+
+ let staked_asset = T::BenchmarkHelper::staked_asset();
+ let reward_asset = T::BenchmarkHelper::reward_asset();
+
+ let min_balance = T::Assets::minimum_balance(staked_asset.clone()).max(T::Balance::one());
+ if !T::Assets::asset_exists(staked_asset.clone()) {
+ assert_ok!(T::Assets::create(staked_asset.clone(), caller.clone(), true, min_balance));
+ }
+ let min_balance = T::Assets::minimum_balance(reward_asset.clone()).max(T::Balance::one());
+ if !T::Assets::asset_exists(reward_asset.clone()) {
+ assert_ok!(T::Assets::create(reward_asset.clone(), caller.clone(), true, min_balance));
+ }
+
+ #[extrinsic_call]
+ _(
+ caller_origin as T::RuntimeOrigin,
+ Box::new(staked_asset.clone()),
+ Box::new(reward_asset.clone()),
+ min_balance,
+ pool_expire::(),
+ Some(caller.clone()),
+ );
+
+ assert_last_event::(
+ Event::PoolCreated {
+ creator: caller.clone(),
+ admin: caller,
+ staked_asset_id: staked_asset,
+ reward_asset_id: reward_asset,
+ reward_rate_per_block: min_balance,
+ expiry_block: pool_expire::().evaluate(System::::block_number()),
+ pool_id: 0,
+ }
+ .into(),
+ );
+
+ Ok(())
+ }
+
+ #[benchmark]
+ fn stake() -> Result<(), BenchmarkError> {
+ create_reward_pool::()?;
+
+ let staker: T::AccountId = whitelisted_caller();
+ let min_balance = mint_into::(&staker, &T::BenchmarkHelper::staked_asset());
+
+ // stake first to get worth case benchmark.
+ assert_ok!(AssetRewards::::stake(
+ RawOrigin::Signed(staker.clone()).into(),
+ 0,
+ min_balance
+ ));
+
+ #[extrinsic_call]
+ _(RawOrigin::Signed(staker.clone()), 0, min_balance);
+
+ assert_last_event::(Event::Staked { staker, pool_id: 0, amount: min_balance }.into());
+
+ Ok(())
+ }
+
+ #[benchmark]
+ fn unstake() -> Result<(), BenchmarkError> {
+ create_reward_pool::()?;
+
+ let staker: T::AccountId = whitelisted_caller();
+ let min_balance = mint_into::(&staker, &T::BenchmarkHelper::staked_asset());
+
+ assert_ok!(AssetRewards::::stake(
+ RawOrigin::Signed(staker.clone()).into(),
+ 0,
+ min_balance,
+ ));
+
+ #[extrinsic_call]
+ _(RawOrigin::Signed(staker.clone()), 0, min_balance, None);
+
+ assert_last_event::(
+ Event::Unstaked { caller: staker.clone(), staker, pool_id: 0, amount: min_balance }
+ .into(),
+ );
+
+ Ok(())
+ }
+
+ #[benchmark]
+ fn harvest_rewards() -> Result<(), BenchmarkError> {
+ create_reward_pool::()?;
+
+ let pool_acc = AssetRewards::::pool_account_id(&0u32);
+ let min_reward_balance = mint_into::(&pool_acc, &T::BenchmarkHelper::reward_asset());
+
+ let staker = whitelisted_caller();
+ let _ = mint_into::(&staker, &T::BenchmarkHelper::staked_asset());
+ assert_ok!(AssetRewards::::stake(
+ RawOrigin::Signed(staker.clone()).into(),
+ 0,
+ T::Balance::one(),
+ ));
+
+ System::::set_block_number(System::::block_number() + BlockNumberFor::