From f3bc3048acdf7c326574cb0ed7af35e9d511849b Mon Sep 17 00:00:00 2001 From: runcomet Date: Mon, 28 Oct 2024 15:21:43 -0700 Subject: [PATCH 01/21] add dev_accounts field --- substrate/frame/balances/Cargo.toml | 2 +- substrate/frame/balances/src/lib.rs | 35 ++++++++++++++++++- .../balances/src/tests/currency_tests.rs | 14 ++++++-- substrate/frame/balances/src/tests/mod.rs | 2 ++ 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/substrate/frame/balances/Cargo.toml b/substrate/frame/balances/Cargo.toml index 44899e5b7d8d..9341ea924451 100644 --- a/substrate/frame/balances/Cargo.toml +++ b/substrate/frame/balances/Cargo.toml @@ -24,11 +24,11 @@ frame-support = { workspace = true } frame-system = { workspace = true } sp-runtime = { workspace = true } docify = { workspace = true } +sp-core = { workspace = true, default-features = true } [dev-dependencies] pallet-transaction-payment = { workspace = true, default-features = true } frame-support = { features = ["experimental"], workspace = true, default-features = true } -sp-core = { workspace = true, default-features = true } sp-io = { workspace = true, default-features = true } paste = { workspace = true, default-features = true } diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 65e594a904f9..0bf48a0aa5f5 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -180,6 +180,10 @@ use sp_runtime::{ }, ArithmeticError, DispatchError, FixedPointOperand, Perbill, RuntimeDebug, TokenError, }; + +#[cfg(feature = "runtime-benchmarks")] +use sp_core::{sr25519::Pair as SrPair, Pair}; + pub use types::{ AccountData, AdjustmentDirection, BalanceLock, DustCleaner, ExtraFlags, Reasons, ReserveData, }; @@ -505,11 +509,19 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig, I: 'static = ()> { pub balances: Vec<(T::AccountId, T::Balance)>, + + #[cfg(feature = "runtime-benchmarks")] + pub dev_accounts: (u32, T::Balance, String), } impl, I: 'static> Default for GenesisConfig { fn default() -> Self { - Self { balances: Default::default() } + Self { + balances: Default::default(), + + #[cfg(feature = "runtime-benchmarks")] + dev_accounts: (Default::default(), Default::default(), String::new()), + } } } @@ -540,6 +552,27 @@ pub mod pallet { "duplicate balances in genesis." ); + // Generate additional dev accounts. + #[cfg(feature = "runtime-benchmarks")] + { + let (num_accounts, balance, ref derivation) = self.dev_accounts; + for index in 0..num_accounts { + assert!( + balance >= >::ExistentialDeposit::get(), + "the balance of any account should always be at least the existential deposit.", + ); + // Create key pair from the derivation string + let derivation_string = &derivation.replace("{}", &index.to_string()); + let pair: SrPair = Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); + + // Convert the public key to AccountId + let who = T::AccountId::decode(&mut &pair.public().encode()[..]).unwrap(); + frame_system::Pallet::::inc_providers(&who); + assert!(T::AccountStore::insert(&who, AccountData { free: balance, ..Default::default() }) + .is_ok()); + } + } + for &(ref who, free) in self.balances.iter() { frame_system::Pallet::::inc_providers(who); assert!(T::AccountStore::insert(who, AccountData { free, ..Default::default() }) diff --git a/substrate/frame/balances/src/tests/currency_tests.rs b/substrate/frame/balances/src/tests/currency_tests.rs index a4984b34f6db..e935b50c0c4c 100644 --- a/substrate/frame/balances/src/tests/currency_tests.rs +++ b/substrate/frame/balances/src/tests/currency_tests.rs @@ -716,7 +716,12 @@ fn burn_must_work() { fn cannot_set_genesis_value_below_ed() { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = 11); let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let _ = crate::GenesisConfig:: { balances: vec![(1, 10)] } + let _ = crate::GenesisConfig:: { + balances: vec![(1, 10)], + + #[cfg(feature = "runtime-benchmarks")] + dev_accounts: (1000000, 500, "//Sender/{}".to_string()) + } .assimilate_storage(&mut t) .unwrap(); } @@ -725,7 +730,12 @@ fn cannot_set_genesis_value_below_ed() { #[should_panic = "duplicate balances in genesis."] fn cannot_set_genesis_value_twice() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let _ = crate::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (1, 15)] } + let _ = crate::GenesisConfig:: { + balances: vec![(1, 10), (2, 20), (1, 15)], + + #[cfg(feature = "runtime-benchmarks")] + dev_accounts: (1000000, 500, "//Sender/{}".to_string()) + } .assimilate_storage(&mut t) .unwrap(); } diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index ba0cdabdabbb..747af9f8cfca 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -170,6 +170,8 @@ impl ExtBuilder { } else { vec![] }, + #[cfg(feature = "runtime-benchmarks")] + dev_accounts: (1000000, self.existential_deposit, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); From cb0d3bad20d3d71075d4f3483cbc3badf95f759e Mon Sep 17 00:00:00 2001 From: runcomet Date: Mon, 4 Nov 2024 06:46:56 -0800 Subject: [PATCH 02/21] populate dev_accounts field --- bridges/modules/messages/src/tests/mock.rs | 2 +- cumulus/pallets/collator-selection/src/mock.rs | 2 +- .../asset-hub-rococo/src/genesis_config_presets.rs | 3 ++- .../asset-hub-westend/src/genesis_config_presets.rs | 3 ++- .../bridge-hub-rococo/src/genesis_config_presets.rs | 3 ++- .../src/genesis_config_presets.rs | 3 ++- .../src/genesis_config_presets.rs | 3 ++- cumulus/parachains/runtimes/test-utils/src/lib.rs | 2 +- polkadot/runtime/common/src/assigned_slots/mod.rs | 1 + polkadot/runtime/common/src/auctions.rs | 1 + polkadot/runtime/common/src/crowdloan/mod.rs | 1 + polkadot/runtime/common/src/paras_registrar/mod.rs | 1 + polkadot/runtime/common/src/slots/mod.rs | 1 + .../runtime/rococo/src/genesis_config_presets.rs | 4 +++- .../runtime/westend/src/genesis_config_presets.rs | 4 +++- polkadot/xcm/pallet-xcm/src/mock.rs | 2 +- .../src/asset_exchange/single_asset_adapter/mock.rs | 1 + polkadot/xcm/xcm-builder/tests/mock/mod.rs | 2 +- polkadot/xcm/xcm-runtime-apis/tests/mock.rs | 4 ++-- polkadot/xcm/xcm-simulator/example/src/lib.rs | 2 ++ polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs | 3 ++- substrate/bin/node/testing/src/genesis.rs | 2 +- substrate/frame/alliance/src/mock.rs | 1 + substrate/frame/asset-conversion/ops/src/mock.rs | 1 + substrate/frame/asset-conversion/src/mock.rs | 1 + substrate/frame/babe/src/mock.rs | 2 +- substrate/frame/balances/Cargo.toml | 2 +- substrate/frame/balances/src/lib.rs | 10 +++++++++- substrate/frame/balances/src/tests/general_tests.rs | 13 +++++++++++++ substrate/frame/balances/src/tests/mod.rs | 2 +- substrate/frame/bounties/src/tests.rs | 5 +++-- substrate/frame/child-bounties/src/tests.rs | 1 + substrate/frame/collective/src/tests.rs | 2 +- substrate/frame/contracts/mock-network/src/lib.rs | 2 ++ substrate/frame/contracts/src/tests.rs | 2 +- substrate/frame/conviction-voting/src/tests.rs | 1 + substrate/frame/delegated-staking/src/mock.rs | 1 + substrate/frame/democracy/src/tests.rs | 1 + .../frame/election-provider-multi-phase/src/mock.rs | 1 + substrate/frame/elections-phragmen/src/lib.rs | 1 + substrate/frame/fast-unstake/src/mock.rs | 1 + substrate/frame/grandpa/src/mock.rs | 2 +- substrate/frame/identity/src/tests.rs | 1 + substrate/frame/indices/src/mock.rs | 1 + substrate/frame/lottery/src/mock.rs | 1 + substrate/frame/multisig/src/tests.rs | 1 + substrate/frame/nis/src/mock.rs | 1 + substrate/frame/preimage/src/mock.rs | 1 + substrate/frame/proxy/src/tests.rs | 1 + substrate/frame/recovery/src/mock.rs | 1 + substrate/frame/referenda/src/mock.rs | 2 +- substrate/frame/revive/mock-network/src/lib.rs | 2 ++ substrate/frame/revive/src/tests.rs | 2 +- substrate/frame/root-offences/src/mock.rs | 1 + substrate/frame/safe-mode/src/mock.rs | 2 +- substrate/frame/society/src/mock.rs | 2 +- substrate/frame/staking/src/mock.rs | 1 + substrate/frame/state-trie-migration/src/lib.rs | 2 +- substrate/frame/tips/src/tests.rs | 3 ++- .../asset-tx-payment/src/tests.rs | 1 + substrate/frame/transaction-storage/src/mock.rs | 1 + substrate/frame/treasury/src/tests.rs | 4 +++- substrate/frame/tx-pause/src/mock.rs | 1 + substrate/frame/utility/src/tests.rs | 1 + substrate/frame/vesting/src/mock.rs | 1 + substrate/test-utils/runtime/src/genesismap.rs | 2 +- 66 files changed, 105 insertions(+), 33 deletions(-) diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index 2935ebd69610..60d0f60957b4 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -461,7 +461,7 @@ pub fn inbound_unrewarded_relayers_state(lane: TestLaneIdType) -> UnrewardedRela /// Return test externalities to use in tests. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(ENDOWED_ACCOUNT, 1_000_000)] } + pallet_balances::GenesisConfig:: { balances: vec![(ENDOWED_ACCOUNT, 1_000_000)], dev_accounts: (10, 1_000_000, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); sp_io::TestExternalities::new(t) diff --git a/cumulus/pallets/collator-selection/src/mock.rs b/cumulus/pallets/collator-selection/src/mock.rs index d13f9e9d8c44..6a97525c4f57 100644 --- a/cumulus/pallets/collator-selection/src/mock.rs +++ b/cumulus/pallets/collator-selection/src/mock.rs @@ -188,7 +188,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { invulnerables, }; let session = pallet_session::GenesisConfig:: { keys, ..Default::default() }; - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); // collator selection must be initialized before session. diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs index 1dbd92d6bff0..e45a5203512f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Asset Hub Rococo Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, string::ToString}; use cumulus_primitives_core::ParaId; use hex_literal::hex; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; @@ -35,6 +35,7 @@ fn asset_hub_rococo_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), + dev_accounts: (10, ASSET_HUB_ROCOCO_ED, "//Sender/{}".to_string()), }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs index b287dcd56219..fe0054625240 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Asset Hub Westend Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, string::ToString}; use cumulus_primitives_core::ParaId; use hex_literal::hex; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; @@ -37,6 +37,7 @@ fn asset_hub_westend_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), + dev_accounts: (10, ASSET_HUB_WESTEND_ED, "//Sender/{}".to_string()) }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index 07048d54ab1b..4b0f929612a6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Bridge Hub Rococo Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, string::ToString}; use cumulus_primitives_core::ParaId; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; use sp_core::sr25519; @@ -40,6 +40,7 @@ fn bridge_hub_rococo_genesis( .cloned() .map(|k| (k, 1u128 << 60)) .collect::>(), + dev_accounts: (10, BRIDGE_HUB_ROCOCO_ED, "//Sender/{}".to_string()), }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index 0b270e584339..2714e17a2109 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Bridge Hub Westend Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, string::ToString}; use cumulus_primitives_core::ParaId; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; use sp_core::sr25519; @@ -40,6 +40,7 @@ fn bridge_hub_westend_genesis( .cloned() .map(|k| (k, 1u128 << 60)) .collect::>(), + dev_accounts: (10, BRIDGE_HUB_WESTEND_ED, "//Sender/{}".to_string()) }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs index 30a23d7aaea4..ebff423b8b67 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Bridge Hub Westend Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, string::ToString}; use cumulus_primitives_core::ParaId; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; use sp_core::sr25519; @@ -37,6 +37,7 @@ fn collectives_westend_genesis( .cloned() .map(|k| (k, COLLECTIVES_WESTEND_ED * 4096)) .collect::>(), + dev_accounts: (10, COLLECTIVES_WESTEND_ED, "//Sender/{}".to_string()) }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 3b38eee244f1..9a8632df7cfe 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -230,7 +230,7 @@ impl ExtBuilder { .unwrap(); } - pallet_balances::GenesisConfig:: { balances: self.balances } + pallet_balances::GenesisConfig:: { balances: self.balances, dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index 96c98c45954d..f4c7f2403708 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -764,6 +764,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index 78f20d918bab..9404ee73ab6c 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -866,6 +866,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs index 8cf288197e3d..f258efc8a771 100644 --- a/polkadot/runtime/common/src/crowdloan/mod.rs +++ b/polkadot/runtime/common/src/crowdloan/mod.rs @@ -1085,6 +1085,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 1000), (2, 2000), (3, 3000), (4, 4000)], + dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 07f02e926561..be964ee7406f 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -860,6 +860,7 @@ mod tests { pallet_balances::GenesisConfig:: { balances: vec![(1, 10_000_000), (2, 10_000_000), (3, 10_000_000)], + dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs index 333f14c6608a..d970918b2611 100644 --- a/polkadot/runtime/common/src/slots/mod.rs +++ b/polkadot/runtime/common/src/slots/mod.rs @@ -578,6 +578,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs index c237dfd967f6..58d890b68cd1 100644 --- a/polkadot/runtime/rococo/src/genesis_config_presets.rs +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -22,7 +22,7 @@ use crate::{ }; #[cfg(not(feature = "std"))] use alloc::format; -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, string::ToString}; use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, SchedulerParams, ValidatorId}; use rococo_runtime_constants::currency::UNITS as ROC; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; @@ -185,6 +185,7 @@ fn rococo_testnet_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), + dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()) }, session: SessionConfig { keys: initial_authorities @@ -453,6 +454,7 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect::>(), + dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()) }, session: SessionConfig { keys: initial_authorities diff --git a/polkadot/runtime/westend/src/genesis_config_presets.rs b/polkadot/runtime/westend/src/genesis_config_presets.rs index f59bacce31bd..ae21c06c0603 100644 --- a/polkadot/runtime/westend/src/genesis_config_presets.rs +++ b/polkadot/runtime/westend/src/genesis_config_presets.rs @@ -22,7 +22,7 @@ use crate::{ }; #[cfg(not(feature = "std"))] use alloc::format; -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, string::ToString}; use pallet_staking::{Forcing, StakerStatus}; use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, SchedulerParams, ValidatorId}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; @@ -191,6 +191,7 @@ fn westend_testnet_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), + dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()) }, session: SessionConfig { keys: initial_authorities @@ -370,6 +371,7 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect::>(), + dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()), }, session: SessionConfig { keys: initial_authorities diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 8d0476b0e70d..8e3c255ca79b 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -700,7 +700,7 @@ pub(crate) fn new_test_ext_with_balances_and_xcm_version( ) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, ExistentialDeposit::get(), "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs b/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs index 4d9809e84f88..04c63b78fa73 100644 --- a/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs +++ b/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs @@ -339,6 +339,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(0, INITIAL_BALANCE), (1, INITIAL_BALANCE), (2, INITIAL_BALANCE)], + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index 0468b0a5410c..ecd9512b76d6 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -243,7 +243,7 @@ construct_runtime!( pub fn kusama_like_with_balances(balances: Vec<(AccountId, Balance)>) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 1_000_000_000u32.into(), "//Sender/{}".into()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs index 6575feccf8a3..500086bc3436 100644 --- a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs +++ b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs @@ -357,7 +357,7 @@ impl pallet_xcm::Config for TestRuntime { pub fn new_test_ext_with_balances(balances: Vec<(AccountId, Balance)>) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); @@ -373,7 +373,7 @@ pub fn new_test_ext_with_balances_and_assets( ) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-simulator/example/src/lib.rs b/polkadot/xcm/xcm-simulator/example/src/lib.rs index 6fb9a69770ea..908d0054a7d1 100644 --- a/polkadot/xcm/xcm-simulator/example/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/example/src/lib.rs @@ -101,6 +101,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE), (parent_account_id(), INITIAL_BALANCE)], + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); @@ -125,6 +126,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { (child_account_id(1), INITIAL_BALANCE), (child_account_id(2), INITIAL_BALANCE), ], + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs index adf6cacd278b..37c7bcbcc0a5 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs @@ -117,6 +117,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: (0..6).map(|i| ([i; 32].into(), INITIAL_BALANCE)).collect(), + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); @@ -138,7 +139,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { balances.append(&mut (1..=3).map(|i| (para_account_id(i), INITIAL_BALANCE)).collect()); balances.append(&mut (0..6).map(|i| ([i; 32].into(), INITIAL_BALANCE)).collect()); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/bin/node/testing/src/genesis.rs b/substrate/bin/node/testing/src/genesis.rs index 7f5364744c66..7ec5c5bb506e 100644 --- a/substrate/bin/node/testing/src/genesis.rs +++ b/substrate/bin/node/testing/src/genesis.rs @@ -47,7 +47,7 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig { RuntimeGenesisConfig { indices: IndicesConfig { indices: vec![] }, - balances: BalancesConfig { balances: endowed }, + balances: BalancesConfig { balances: endowed, dev_accounts: (10, 100 * DOLLARS, "//Sender/{}".to_string()) }, session: SessionConfig { keys: vec![ (alice(), dave(), session_keys_from_seed(Ed25519Keyring::Alice.into())), diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs index 5442e8779020..1fa1d90d63b4 100644 --- a/substrate/frame/alliance/src/mock.rs +++ b/substrate/frame/alliance/src/mock.rs @@ -279,6 +279,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { (8, 1000), (9, 1000), ], + dev-accounts: (10, 1000, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/asset-conversion/ops/src/mock.rs b/substrate/frame/asset-conversion/ops/src/mock.rs index 5c05faa6aa88..a85bc291799c 100644 --- a/substrate/frame/asset-conversion/ops/src/mock.rs +++ b/substrate/frame/asset-conversion/ops/src/mock.rs @@ -135,6 +135,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(1, 10000), (2, 20000), (3, 30000), (4, 40000)], + dev_accounts: (10, 10000, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/asset-conversion/src/mock.rs b/substrate/frame/asset-conversion/src/mock.rs index d8832d70488a..268bd5634353 100644 --- a/substrate/frame/asset-conversion/src/mock.rs +++ b/substrate/frame/asset-conversion/src/mock.rs @@ -162,6 +162,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(1, 10000), (2, 20000), (3, 30000), (4, 40000)], + dev_accounts: (10, 10000, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index 4e4052b2b566..c77b8691b753 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -304,7 +304,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec) -> sp_io::Tes let balances: Vec<_> = (0..authorities.len()).map(|i| (i as u64, 10_000_000)).collect(); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 10_000_000, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/balances/Cargo.toml b/substrate/frame/balances/Cargo.toml index 9341ea924451..8091edcb94f7 100644 --- a/substrate/frame/balances/Cargo.toml +++ b/substrate/frame/balances/Cargo.toml @@ -24,7 +24,7 @@ frame-support = { workspace = true } frame-system = { workspace = true } sp-runtime = { workspace = true } docify = { workspace = true } -sp-core = { workspace = true, default-features = true } +sp-core = { workspace = true } [dev-dependencies] pallet-transaction-payment = { workspace = true, default-features = true } diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 0bf48a0aa5f5..4a431f76d783 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -152,7 +152,7 @@ pub mod weights; extern crate alloc; -use alloc::vec::Vec; +use alloc::{vec::Vec, string::{String, ToString}}; use codec::{Codec, MaxEncodedLen}; use core::{cmp, fmt::Debug, mem, result}; use frame_support::{ @@ -556,11 +556,19 @@ pub mod pallet { #[cfg(feature = "runtime-benchmarks")] { let (num_accounts, balance, ref derivation) = self.dev_accounts; + let num_balance = >::Balance::from(num_accounts); for index in 0..num_accounts { assert!( balance >= >::ExistentialDeposit::get(), "the balance of any account should always be at least the existential deposit.", ); + // Check if the derivation string follows the pattern "//character/{}" + assert!( + derivation.starts_with("//") && + derivation[2..].contains('/') && // There should be a character after "//" and before "{}" + derivation.ends_with("{}"), + "Invalid derivation string" + ); // Create key pair from the derivation string let derivation_string = &derivation.replace("{}", &index.to_string()); let pair: SrPair = Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); diff --git a/substrate/frame/balances/src/tests/general_tests.rs b/substrate/frame/balances/src/tests/general_tests.rs index a855fae5616a..d062d8862914 100644 --- a/substrate/frame/balances/src/tests/general_tests.rs +++ b/substrate/frame/balances/src/tests/general_tests.rs @@ -141,3 +141,16 @@ fn try_state_works() { .contains("Found `Freeze` with too many elements")); }); } + +#[cfg(feature = "runtime-benchmarks")] +#[test] +fn dev_accounts_populated() { + ExtBuilder::default().build_and_execute_with(|| { + UseSystem::set(true); // copmment this out and uncomment this from time to time to check stuff. + // Print total issuance for debugging + let ti = TotalIssuance::::get(); + println!("Total Issuance after genesis: {}", ti); + println!("Why are you printing twice?"); + ensure_ti_valid(); + }); +} diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 747af9f8cfca..63c8416eef21 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -171,7 +171,7 @@ impl ExtBuilder { vec![] }, #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (1000000, self.existential_deposit, "//Sender/{}".to_string()) + dev_accounts: (10, self.existential_deposit, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/bounties/src/tests.rs b/substrate/frame/bounties/src/tests.rs index c152391d807a..b0c7f4f43f2c 100644 --- a/substrate/frame/bounties/src/tests.rs +++ b/substrate/frame/bounties/src/tests.rs @@ -179,7 +179,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)] }, + balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], dev_accounts: (10, 100, "//Sender/{}".to_string()) }, treasury: Default::default(), treasury_1: Default::default(), } @@ -310,7 +310,7 @@ fn treasury_account_doesnt_get_deleted() { #[test] fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)] } + pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], dev_accounts: (10, 100, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); // Treasury genesis config is not build thus treasury account does not exist @@ -976,6 +976,7 @@ fn genesis_funding_works() { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], + dev_accounts: (10, 100, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/child-bounties/src/tests.rs b/substrate/frame/child-bounties/src/tests.rs index 125844fa70e2..cc596e3bc916 100644 --- a/substrate/frame/child-bounties/src/tests.rs +++ b/substrate/frame/child-bounties/src/tests.rs @@ -135,6 +135,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], + dev_accounts: (10, 100, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index 70ce221f10d0..6e9cf310fa95 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -203,7 +203,7 @@ impl ExtBuilder { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), // balances: pallet_balances::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(1, 100), (2, 200)] }, + balances: pallet_balances::GenesisConfig { balances: vec![(1, 100), (2, 200)], dev_accounts: (10, 100, "//Sender/{}".to_string()) }, collective: pallet_collective::GenesisConfig { members: self.collective_members, phantom: Default::default(), diff --git a/substrate/frame/contracts/mock-network/src/lib.rs b/substrate/frame/contracts/mock-network/src/lib.rs index cb9e22439b76..bce533e8c4c3 100644 --- a/substrate/frame/contracts/mock-network/src/lib.rs +++ b/substrate/frame/contracts/mock-network/src/lib.rs @@ -99,6 +99,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { (relay_sovereign_account_id(), INITIAL_BALANCE), (BOB, INITIAL_BALANCE), ], + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); @@ -137,6 +138,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { (parachain_sovereign_account_id(1), INITIAL_BALANCE), (parachain_account_sovereign_account_id(1, ALICE), INITIAL_BALANCE), ], + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index c3b6e3273f34..72e615190c54 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -552,7 +552,7 @@ impl ExtBuilder { sp_tracing::try_init_simple(); self.set_associated_consts(); let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![] } + pallet_balances::GenesisConfig:: { balances: vec![], dev_accounts: (10, self.existential_deposit, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); let mut ext = sp_io::TestExternalities::new(t); diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs index 37cdd7a5b338..b3aa7ea400ab 100644 --- a/substrate/frame/conviction-voting/src/tests.rs +++ b/substrate/frame/conviction-voting/src/tests.rs @@ -160,6 +160,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + dev_accounts: (10, 20, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/delegated-staking/src/mock.rs b/substrate/frame/delegated-staking/src/mock.rs index 811d5739f4e9..fc75b03787ea 100644 --- a/substrate/frame/delegated-staking/src/mock.rs +++ b/substrate/frame/delegated-staking/src/mock.rs @@ -188,6 +188,7 @@ impl ExtBuilder { (GENESIS_NOMINATOR_ONE, 1000), (GENESIS_NOMINATOR_TWO, 2000), ], + dev_accounts: (10, 1000, "//Sender/{}".to_string()) } .assimilate_storage(&mut storage); diff --git a/substrate/frame/democracy/src/tests.rs b/substrate/frame/democracy/src/tests.rs index 10e5ee75611d..901b16c3e0cd 100644 --- a/substrate/frame/democracy/src/tests.rs +++ b/substrate/frame/democracy/src/tests.rs @@ -169,6 +169,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + dev_accounts: (10, 10, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index 32a099e1a26f..648fe2b7ffe4 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -591,6 +591,7 @@ impl ExtBuilder { (999, 100), (9999, 100), ], + dev_accounts: (10, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut storage); diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index a1c5f69e1b65..1538a53cf8df 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -1476,6 +1476,7 @@ mod tests { (5, 50 * self.balance_factor), (6, 60 * self.balance_factor), ], + dev_accounts: (10, 10 * self.balance_factor, "//Sender/{}".to_string()), }, elections: elections_phragmen::GenesisConfig:: { members: self.genesis_members, diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index 757052e230a1..650e2aefcab6 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -226,6 +226,7 @@ impl ExtBuilder { .chain(validators_range.clone().map(|x| (x, 7 + 100))) .chain(nominators_range.clone().map(|x| (x, 7 + 100))) .collect::>(), + dev_accounts: (10, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut storage); diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index caac4107cfb7..92dd386beb00 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -216,7 +216,7 @@ pub fn new_test_ext_raw_authorities(authorities: AuthorityList) -> sp_io::TestEx let balances: Vec<_> = (0..authorities.len()).map(|i| (i as u64, 10_000_000)).collect(); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 10_000_000, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 3adb823ad5da..17f3842bf735 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -103,6 +103,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { (account(20), 1000), (account(30), 1000), ], + dev_accounts: (10, 100, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/indices/src/mock.rs b/substrate/frame/indices/src/mock.rs index 72bbc6dab4a4..d53d071e8710 100644 --- a/substrate/frame/indices/src/mock.rs +++ b/substrate/frame/indices/src/mock.rs @@ -59,6 +59,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + dev_accounts: (10, 10, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/lottery/src/mock.rs b/substrate/frame/lottery/src/mock.rs index d2c442e2ac6e..f880729b8700 100644 --- a/substrate/frame/lottery/src/mock.rs +++ b/substrate/frame/lottery/src/mock.rs @@ -78,6 +78,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)], + dev_accounts: (10, 100, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/multisig/src/tests.rs b/substrate/frame/multisig/src/tests.rs index cfdd33f7dfcc..f5ead2e85ae6 100644 --- a/substrate/frame/multisig/src/tests.rs +++ b/substrate/frame/multisig/src/tests.rs @@ -79,6 +79,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], + dev_accounts: (10, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/nis/src/mock.rs b/substrate/frame/nis/src/mock.rs index 2b008f8ec2a4..298649f08e62 100644 --- a/substrate/frame/nis/src/mock.rs +++ b/substrate/frame/nis/src/mock.rs @@ -133,6 +133,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100)], + dev_accounts: (10, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/preimage/src/mock.rs b/substrate/frame/preimage/src/mock.rs index 9c72d09cae14..1573ecb8d4ab 100644 --- a/substrate/frame/preimage/src/mock.rs +++ b/substrate/frame/preimage/src/mock.rs @@ -81,6 +81,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); let balances = pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)], + dev_accounts: (10, 100, "//Sender/{}".to_string()) }; balances.assimilate_storage(&mut t).unwrap(); t.into() diff --git a/substrate/frame/proxy/src/tests.rs b/substrate/frame/proxy/src/tests.rs index 3edb96026a82..140dea692c47 100644 --- a/substrate/frame/proxy/src/tests.rs +++ b/substrate/frame/proxy/src/tests.rs @@ -140,6 +140,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 3)], + dev_accounts: (10, 10, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs index 8e30cbe997e1..45f1323522dc 100644 --- a/substrate/frame/recovery/src/mock.rs +++ b/substrate/frame/recovery/src/mock.rs @@ -80,6 +80,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)], + dev_accounts: (10, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/referenda/src/mock.rs b/substrate/frame/referenda/src/mock.rs index c96a50af8658..26205abc83f6 100644 --- a/substrate/frame/referenda/src/mock.rs +++ b/substrate/frame/referenda/src/mock.rs @@ -219,7 +219,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); let balances = vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100), (6, 100)]; - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 100, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); let mut ext = sp_io::TestExternalities::new(t); diff --git a/substrate/frame/revive/mock-network/src/lib.rs b/substrate/frame/revive/mock-network/src/lib.rs index 848994653972..d1f1241878bd 100644 --- a/substrate/frame/revive/mock-network/src/lib.rs +++ b/substrate/frame/revive/mock-network/src/lib.rs @@ -99,6 +99,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { (relay_sovereign_account_id(), INITIAL_BALANCE), (BOB, INITIAL_BALANCE), ], + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); @@ -137,6 +138,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { (parachain_sovereign_account_id(1), INITIAL_BALANCE), (parachain_account_sovereign_account_id(1, ALICE), INITIAL_BALANCE), ], + dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index c7d1a8b2cf0d..171bba47e923 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -541,7 +541,7 @@ impl ExtBuilder { sp_tracing::try_init_simple(); self.set_associated_consts(); let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![] } + pallet_balances::GenesisConfig:: { balances: vec![], dev_accounts: (10, 1000, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); let mut ext = sp_io::TestExternalities::new(t); diff --git a/substrate/frame/root-offences/src/mock.rs b/substrate/frame/root-offences/src/mock.rs index af073d7672cf..c37df85d6e61 100644 --- a/substrate/frame/root-offences/src/mock.rs +++ b/substrate/frame/root-offences/src/mock.rs @@ -211,6 +211,7 @@ impl ExtBuilder { (31, self.balance_factor * 500), (41, self.balance_factor * 1000), ], + dev_accounts: (10, 1000, "//Sender/{}".to_string()) } .assimilate_storage(&mut storage) .unwrap(); diff --git a/substrate/frame/safe-mode/src/mock.rs b/substrate/frame/safe-mode/src/mock.rs index ec1ad8249514..71c5201b14f3 100644 --- a/substrate/frame/safe-mode/src/mock.rs +++ b/substrate/frame/safe-mode/src/mock.rs @@ -231,7 +231,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // The 0 account is NOT a special origin, the rest may be. - balances: vec![(0, BAL_ACC0), (1, BAL_ACC1), (2, 5678), (3, 5678), (4, 5678)], + balances: vec![(0, BAL_ACC0), (1, BAL_ACC1), (2, 5678), (3, 5678), (4, 5678)], dev_accounts: (10, 100, "//String/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/society/src/mock.rs b/substrate/frame/society/src/mock.rs index 3c27c08a1061..e6d12739eb5c 100644 --- a/substrate/frame/society/src/mock.rs +++ b/substrate/frame/society/src/mock.rs @@ -115,7 +115,7 @@ impl EnvBuilder { pub fn execute R>(mut self, f: F) -> R { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); self.balances.push((Society::account_id(), self.balance.max(self.pot))); - pallet_balances::GenesisConfig:: { balances: self.balances } + pallet_balances::GenesisConfig:: { balances: self.balances, dev_accounts: (10, 100000, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); pallet_society::GenesisConfig:: { pot: self.pot } diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 4a0209fc5b08..f5ff01fbb0dd 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -464,6 +464,7 @@ impl ExtBuilder { // This allows us to have a total_payout different from 0. (999, 1_000_000_000_000), ], + dev_accounts: (10, self.balance_factor, "//Sender/{}".to_string()), } .assimilate_storage(&mut storage); diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index 3fe5abb81031..83af1264e713 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -1257,7 +1257,7 @@ mod mock { frame_system::GenesisConfig::::default() .assimilate_storage(&mut custom_storage) .unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 1000)] } + pallet_balances::GenesisConfig:: { balances: vec![(1, 1000)], dev_accounts: (10, 1000, "//Sender/{}".to_string()) } .assimilate_storage(&mut custom_storage) .unwrap(); } diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs index 7e4a9368ad0c..5394c05f88e7 100644 --- a/substrate/frame/tips/src/tests.rs +++ b/substrate/frame/tips/src/tests.rs @@ -178,7 +178,7 @@ impl Config for Test { pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)] }, + balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], dev_accounts: (10, 1000, "//Sender/{}".to_string()) }, treasury: Default::default(), treasury_1: Default::default(), } @@ -580,6 +580,7 @@ fn genesis_funding_works() { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], + dev_accounts: (10, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs index 098ecf11dd92..5b844030cab9 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -78,6 +78,7 @@ impl ExtBuilder { } else { vec![] }, + dev_accounts: (10, self.balance_factor, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/transaction-storage/src/mock.rs b/substrate/frame/transaction-storage/src/mock.rs index 73174b73dbac..591622f90dfc 100644 --- a/substrate/frame/transaction-storage/src/mock.rs +++ b/substrate/frame/transaction-storage/src/mock.rs @@ -68,6 +68,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { system: Default::default(), balances: pallet_balances::GenesisConfig:: { balances: vec![(1, 1000000000), (2, 100), (3, 100), (4, 100)], + dev_accounts: (1, 100000000, "//Sender/{}".to_string()), }, transaction_storage: pallet_transaction_storage::GenesisConfig:: { storage_period: 10, diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs index 106bfb530a88..ca18803e4431 100644 --- a/substrate/frame/treasury/src/tests.rs +++ b/substrate/frame/treasury/src/tests.rs @@ -214,6 +214,7 @@ impl ExtBuilder { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], + dev_accounts: (1, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); @@ -382,7 +383,7 @@ fn treasury_account_doesnt_get_deleted() { #[test] fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)] } + pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], dev_accounts: (1, 999, "//Sender/{}".to_string()) } .assimilate_storage(&mut t) .unwrap(); // Treasury genesis config is not build thus treasury account does not exist @@ -417,6 +418,7 @@ fn genesis_funding_works() { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], + dev_accounts: (1, 100, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/tx-pause/src/mock.rs b/substrate/frame/tx-pause/src/mock.rs index 84ce45e83528..b997ae013583 100644 --- a/substrate/frame/tx-pause/src/mock.rs +++ b/substrate/frame/tx-pause/src/mock.rs @@ -156,6 +156,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // The 0 account is NOT a special origin. The rest may be: balances: vec![(0, 1234), (1, 5678), (2, 5678), (3, 5678), (4, 5678)], + dev_accounts: (1, 1000, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs index 9755efaea41a..bba0ff1aeb2a 100644 --- a/substrate/frame/utility/src/tests.rs +++ b/substrate/frame/utility/src/tests.rs @@ -237,6 +237,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], + dev_accounts: (1, 10, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/vesting/src/mock.rs b/substrate/frame/vesting/src/mock.rs index f0954a5b989c..4b0902906948 100644 --- a/substrate/frame/vesting/src/mock.rs +++ b/substrate/frame/vesting/src/mock.rs @@ -94,6 +94,7 @@ impl ExtBuilder { (12, 10 * self.existential_deposit), (13, 9999 * self.existential_deposit), ], + dev_accounts: (10, self.existential_deposit, "//Sender/{}".to_string()), } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/test-utils/runtime/src/genesismap.rs b/substrate/test-utils/runtime/src/genesismap.rs index 9e972886b377..5d1e972e1231 100644 --- a/substrate/test-utils/runtime/src/genesismap.rs +++ b/substrate/test-utils/runtime/src/genesismap.rs @@ -130,7 +130,7 @@ impl GenesisStorageBuilder { authorities: authorities_sr25519.clone(), ..Default::default() }, - balances: pallet_balances::GenesisConfig { balances: self.balances.clone() }, + balances: pallet_balances::GenesisConfig { balances: self.balances.clone(), dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) }, } } From 78fa5fc94f94ca1e40c6887f1cbaec43a6bea033 Mon Sep 17 00:00:00 2001 From: runcomet Date: Mon, 4 Nov 2024 08:17:27 -0800 Subject: [PATCH 03/21] use default dev_accounts --- bridges/modules/messages/src/tests/mock.rs | 2 +- cumulus/parachains/runtimes/test-utils/src/lib.rs | 2 +- polkadot/runtime/common/src/assigned_slots/mod.rs | 2 +- polkadot/runtime/common/src/auctions.rs | 2 +- polkadot/runtime/common/src/crowdloan/mod.rs | 2 +- polkadot/runtime/common/src/paras_registrar/mod.rs | 2 +- polkadot/runtime/common/src/slots/mod.rs | 2 +- polkadot/xcm/pallet-xcm/src/mock.rs | 2 +- .../src/asset_exchange/single_asset_adapter/mock.rs | 2 +- polkadot/xcm/xcm-builder/tests/mock/mod.rs | 2 +- polkadot/xcm/xcm-runtime-apis/tests/mock.rs | 4 ++-- polkadot/xcm/xcm-simulator/example/src/lib.rs | 4 ++-- polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs | 4 ++-- substrate/frame/alliance/src/mock.rs | 2 +- substrate/frame/asset-conversion/ops/src/mock.rs | 2 +- substrate/frame/asset-conversion/src/mock.rs | 2 +- substrate/frame/babe/src/mock.rs | 2 +- substrate/frame/bounties/src/tests.rs | 6 +++--- substrate/frame/child-bounties/src/tests.rs | 2 +- substrate/frame/collective/src/tests.rs | 2 +- substrate/frame/contracts/mock-network/src/lib.rs | 4 ++-- substrate/frame/contracts/src/tests.rs | 2 +- substrate/frame/conviction-voting/src/tests.rs | 2 +- substrate/frame/delegated-staking/src/mock.rs | 2 +- substrate/frame/democracy/src/tests.rs | 2 +- substrate/frame/election-provider-multi-phase/src/mock.rs | 2 +- substrate/frame/elections-phragmen/src/lib.rs | 2 +- substrate/frame/fast-unstake/src/mock.rs | 2 +- substrate/frame/grandpa/src/mock.rs | 2 +- substrate/frame/identity/src/tests.rs | 2 +- substrate/frame/indices/src/mock.rs | 2 +- substrate/frame/lottery/src/mock.rs | 2 +- substrate/frame/multisig/src/tests.rs | 2 +- substrate/frame/nis/src/mock.rs | 2 +- substrate/frame/preimage/src/mock.rs | 2 +- substrate/frame/proxy/src/tests.rs | 2 +- substrate/frame/recovery/src/mock.rs | 2 +- substrate/frame/referenda/src/mock.rs | 2 +- substrate/frame/revive/mock-network/src/lib.rs | 4 ++-- substrate/frame/revive/src/tests.rs | 2 +- substrate/frame/root-offences/src/mock.rs | 2 +- substrate/frame/safe-mode/src/mock.rs | 2 +- substrate/frame/society/src/mock.rs | 2 +- substrate/frame/staking/src/mock.rs | 2 +- substrate/frame/state-trie-migration/src/lib.rs | 2 +- substrate/frame/tips/src/tests.rs | 4 ++-- .../frame/transaction-payment/asset-tx-payment/src/tests.rs | 2 +- substrate/frame/transaction-storage/src/mock.rs | 2 +- substrate/frame/treasury/src/tests.rs | 6 +++--- substrate/frame/tx-pause/src/mock.rs | 2 +- substrate/frame/utility/src/tests.rs | 2 +- substrate/frame/vesting/src/mock.rs | 2 +- substrate/test-utils/runtime/src/genesismap.rs | 2 +- 53 files changed, 63 insertions(+), 63 deletions(-) diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index 60d0f60957b4..d962fc1dc928 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -461,7 +461,7 @@ pub fn inbound_unrewarded_relayers_state(lane: TestLaneIdType) -> UnrewardedRela /// Return test externalities to use in tests. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(ENDOWED_ACCOUNT, 1_000_000)], dev_accounts: (10, 1_000_000, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: vec![(ENDOWED_ACCOUNT, 1_000_000)], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); sp_io::TestExternalities::new(t) diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 9a8632df7cfe..92e1a147df5f 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -230,7 +230,7 @@ impl ExtBuilder { .unwrap(); } - pallet_balances::GenesisConfig:: { balances: self.balances, dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: self.balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index f4c7f2403708..0c7c6faa6f69 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -764,7 +764,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index 9404ee73ab6c..b0674ddc501a 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -866,7 +866,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs index f258efc8a771..20476042f0be 100644 --- a/polkadot/runtime/common/src/crowdloan/mod.rs +++ b/polkadot/runtime/common/src/crowdloan/mod.rs @@ -1085,7 +1085,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 1000), (2, 2000), (3, 3000), (4, 4000)], - dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index be964ee7406f..008cc82dba32 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -860,7 +860,7 @@ mod tests { pallet_balances::GenesisConfig:: { balances: vec![(1, 10_000_000), (2, 10_000_000), (3, 10_000_000)], - dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs index d970918b2611..4ed7f0f2ab83 100644 --- a/polkadot/runtime/common/src/slots/mod.rs +++ b/polkadot/runtime/common/src/slots/mod.rs @@ -578,7 +578,7 @@ mod tests { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - dev_accounts: (10, crate::integration_tests::ExistentialDeposit::get().into(), "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 8e3c255ca79b..58b4226ccf19 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -700,7 +700,7 @@ pub(crate) fn new_test_ext_with_balances_and_xcm_version( ) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, ExistentialDeposit::get(), "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs b/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs index 04c63b78fa73..2e41e86e9f41 100644 --- a/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs +++ b/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs @@ -339,7 +339,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(0, INITIAL_BALANCE), (1, INITIAL_BALANCE), (2, INITIAL_BALANCE)], - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index ecd9512b76d6..c3e532845082 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -243,7 +243,7 @@ construct_runtime!( pub fn kusama_like_with_balances(balances: Vec<(AccountId, Balance)>) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 1_000_000_000u32.into(), "//Sender/{}".into()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs index 500086bc3436..90cb5156e3c8 100644 --- a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs +++ b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs @@ -357,7 +357,7 @@ impl pallet_xcm::Config for TestRuntime { pub fn new_test_ext_with_balances(balances: Vec<(AccountId, Balance)>) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); @@ -373,7 +373,7 @@ pub fn new_test_ext_with_balances_and_assets( ) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-simulator/example/src/lib.rs b/polkadot/xcm/xcm-simulator/example/src/lib.rs index 908d0054a7d1..8a05569831b5 100644 --- a/polkadot/xcm/xcm-simulator/example/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/example/src/lib.rs @@ -101,7 +101,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE), (parent_account_id(), INITIAL_BALANCE)], - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); @@ -126,7 +126,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { (child_account_id(1), INITIAL_BALANCE), (child_account_id(2), INITIAL_BALANCE), ], - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs index 37c7bcbcc0a5..8ea5e033f3ad 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs @@ -117,7 +117,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: (0..6).map(|i| ([i; 32].into(), INITIAL_BALANCE)).collect(), - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); @@ -139,7 +139,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { balances.append(&mut (1..=3).map(|i| (para_account_id(i), INITIAL_BALANCE)).collect()); balances.append(&mut (0..6).map(|i| ([i; 32].into(), INITIAL_BALANCE)).collect()); - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs index 1fa1d90d63b4..0d9185648450 100644 --- a/substrate/frame/alliance/src/mock.rs +++ b/substrate/frame/alliance/src/mock.rs @@ -279,7 +279,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { (8, 1000), (9, 1000), ], - dev-accounts: (10, 1000, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/asset-conversion/ops/src/mock.rs b/substrate/frame/asset-conversion/ops/src/mock.rs index a85bc291799c..576b266b39c1 100644 --- a/substrate/frame/asset-conversion/ops/src/mock.rs +++ b/substrate/frame/asset-conversion/ops/src/mock.rs @@ -135,7 +135,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(1, 10000), (2, 20000), (3, 30000), (4, 40000)], - dev_accounts: (10, 10000, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/asset-conversion/src/mock.rs b/substrate/frame/asset-conversion/src/mock.rs index 268bd5634353..313d9f9857e4 100644 --- a/substrate/frame/asset-conversion/src/mock.rs +++ b/substrate/frame/asset-conversion/src/mock.rs @@ -162,7 +162,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { balances: vec![(1, 10000), (2, 20000), (3, 30000), (4, 40000)], - dev_accounts: (10, 10000, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index c77b8691b753..d34d5441d1bb 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -304,7 +304,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec) -> sp_io::Tes let balances: Vec<_> = (0..authorities.len()).map(|i| (i as u64, 10_000_000)).collect(); - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 10_000_000, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/bounties/src/tests.rs b/substrate/frame/bounties/src/tests.rs index b0c7f4f43f2c..1053ec660655 100644 --- a/substrate/frame/bounties/src/tests.rs +++ b/substrate/frame/bounties/src/tests.rs @@ -179,7 +179,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], dev_accounts: (10, 100, "//Sender/{}".to_string()) }, + balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], ..Default::default() }, treasury: Default::default(), treasury_1: Default::default(), } @@ -310,7 +310,7 @@ fn treasury_account_doesnt_get_deleted() { #[test] fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], dev_accounts: (10, 100, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); // Treasury genesis config is not build thus treasury account does not exist @@ -976,7 +976,7 @@ fn genesis_funding_works() { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], - dev_accounts: (10, 100, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/child-bounties/src/tests.rs b/substrate/frame/child-bounties/src/tests.rs index cc596e3bc916..197bc414d3ac 100644 --- a/substrate/frame/child-bounties/src/tests.rs +++ b/substrate/frame/child-bounties/src/tests.rs @@ -135,7 +135,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], - dev_accounts: (10, 100, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index 6e9cf310fa95..2bad3c1a08d9 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -203,7 +203,7 @@ impl ExtBuilder { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), // balances: pallet_balances::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(1, 100), (2, 200)], dev_accounts: (10, 100, "//Sender/{}".to_string()) }, + balances: pallet_balances::GenesisConfig { balances: vec![(1, 100), (2, 200)], ..Default::default() }, collective: pallet_collective::GenesisConfig { members: self.collective_members, phantom: Default::default(), diff --git a/substrate/frame/contracts/mock-network/src/lib.rs b/substrate/frame/contracts/mock-network/src/lib.rs index bce533e8c4c3..c918cd39ed91 100644 --- a/substrate/frame/contracts/mock-network/src/lib.rs +++ b/substrate/frame/contracts/mock-network/src/lib.rs @@ -99,7 +99,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { (relay_sovereign_account_id(), INITIAL_BALANCE), (BOB, INITIAL_BALANCE), ], - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); @@ -138,7 +138,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { (parachain_sovereign_account_id(1), INITIAL_BALANCE), (parachain_account_sovereign_account_id(1, ALICE), INITIAL_BALANCE), ], - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index 72e615190c54..eed8076e8861 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -552,7 +552,7 @@ impl ExtBuilder { sp_tracing::try_init_simple(); self.set_associated_consts(); let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![], dev_accounts: (10, self.existential_deposit, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: vec![], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); let mut ext = sp_io::TestExternalities::new(t); diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs index b3aa7ea400ab..17f967dd143d 100644 --- a/substrate/frame/conviction-voting/src/tests.rs +++ b/substrate/frame/conviction-voting/src/tests.rs @@ -160,7 +160,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - dev_accounts: (10, 20, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/delegated-staking/src/mock.rs b/substrate/frame/delegated-staking/src/mock.rs index fc75b03787ea..7550d0c463f3 100644 --- a/substrate/frame/delegated-staking/src/mock.rs +++ b/substrate/frame/delegated-staking/src/mock.rs @@ -188,7 +188,7 @@ impl ExtBuilder { (GENESIS_NOMINATOR_ONE, 1000), (GENESIS_NOMINATOR_TWO, 2000), ], - dev_accounts: (10, 1000, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut storage); diff --git a/substrate/frame/democracy/src/tests.rs b/substrate/frame/democracy/src/tests.rs index 901b16c3e0cd..777744800684 100644 --- a/substrate/frame/democracy/src/tests.rs +++ b/substrate/frame/democracy/src/tests.rs @@ -169,7 +169,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - dev_accounts: (10, 10, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index 648fe2b7ffe4..9323e3533f10 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -591,7 +591,7 @@ impl ExtBuilder { (999, 100), (9999, 100), ], - dev_accounts: (10, 100, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut storage); diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index 1538a53cf8df..c74ee920a4fc 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -1476,7 +1476,7 @@ mod tests { (5, 50 * self.balance_factor), (6, 60 * self.balance_factor), ], - dev_accounts: (10, 10 * self.balance_factor, "//Sender/{}".to_string()), + ..Default::default() }, elections: elections_phragmen::GenesisConfig:: { members: self.genesis_members, diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index 650e2aefcab6..5546221b2337 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -226,7 +226,7 @@ impl ExtBuilder { .chain(validators_range.clone().map(|x| (x, 7 + 100))) .chain(nominators_range.clone().map(|x| (x, 7 + 100))) .collect::>(), - dev_accounts: (10, 100, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut storage); diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index 92dd386beb00..be4d1b68e152 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -216,7 +216,7 @@ pub fn new_test_ext_raw_authorities(authorities: AuthorityList) -> sp_io::TestEx let balances: Vec<_> = (0..authorities.len()).map(|i| (i as u64, 10_000_000)).collect(); - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 10_000_000, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 17f3842bf735..6c3cf331f578 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -103,7 +103,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { (account(20), 1000), (account(30), 1000), ], - dev_accounts: (10, 100, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/indices/src/mock.rs b/substrate/frame/indices/src/mock.rs index d53d071e8710..80d0a88881f9 100644 --- a/substrate/frame/indices/src/mock.rs +++ b/substrate/frame/indices/src/mock.rs @@ -59,7 +59,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - dev_accounts: (10, 10, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/lottery/src/mock.rs b/substrate/frame/lottery/src/mock.rs index f880729b8700..98bbdd045cbf 100644 --- a/substrate/frame/lottery/src/mock.rs +++ b/substrate/frame/lottery/src/mock.rs @@ -78,7 +78,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)], - dev_accounts: (10, 100, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/multisig/src/tests.rs b/substrate/frame/multisig/src/tests.rs index f5ead2e85ae6..3956a735177d 100644 --- a/substrate/frame/multisig/src/tests.rs +++ b/substrate/frame/multisig/src/tests.rs @@ -79,7 +79,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], - dev_accounts: (10, 100, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/nis/src/mock.rs b/substrate/frame/nis/src/mock.rs index 298649f08e62..e00378f8387c 100644 --- a/substrate/frame/nis/src/mock.rs +++ b/substrate/frame/nis/src/mock.rs @@ -133,7 +133,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100)], - dev_accounts: (10, 100, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/preimage/src/mock.rs b/substrate/frame/preimage/src/mock.rs index 1573ecb8d4ab..dec590c6a197 100644 --- a/substrate/frame/preimage/src/mock.rs +++ b/substrate/frame/preimage/src/mock.rs @@ -81,7 +81,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); let balances = pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)], - dev_accounts: (10, 100, "//Sender/{}".to_string()) + ..Default::default() }; balances.assimilate_storage(&mut t).unwrap(); t.into() diff --git a/substrate/frame/proxy/src/tests.rs b/substrate/frame/proxy/src/tests.rs index 140dea692c47..386a7c2bae63 100644 --- a/substrate/frame/proxy/src/tests.rs +++ b/substrate/frame/proxy/src/tests.rs @@ -140,7 +140,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 3)], - dev_accounts: (10, 10, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs index 45f1323522dc..8a0ac37b00d5 100644 --- a/substrate/frame/recovery/src/mock.rs +++ b/substrate/frame/recovery/src/mock.rs @@ -80,7 +80,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)], - dev_accounts: (10, 100, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/referenda/src/mock.rs b/substrate/frame/referenda/src/mock.rs index 26205abc83f6..5d36ce137d46 100644 --- a/substrate/frame/referenda/src/mock.rs +++ b/substrate/frame/referenda/src/mock.rs @@ -219,7 +219,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); let balances = vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100), (6, 100)]; - pallet_balances::GenesisConfig:: { balances, dev_accounts: (10, 100, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); let mut ext = sp_io::TestExternalities::new(t); diff --git a/substrate/frame/revive/mock-network/src/lib.rs b/substrate/frame/revive/mock-network/src/lib.rs index d1f1241878bd..b57c4f76212b 100644 --- a/substrate/frame/revive/mock-network/src/lib.rs +++ b/substrate/frame/revive/mock-network/src/lib.rs @@ -99,7 +99,7 @@ pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { (relay_sovereign_account_id(), INITIAL_BALANCE), (BOB, INITIAL_BALANCE), ], - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); @@ -138,7 +138,7 @@ pub fn relay_ext() -> sp_io::TestExternalities { (parachain_sovereign_account_id(1), INITIAL_BALANCE), (parachain_account_sovereign_account_id(1, ALICE), INITIAL_BALANCE), ], - dev_accounts: (10, INITIAL_BALANCE, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index 171bba47e923..6c3f81652267 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -541,7 +541,7 @@ impl ExtBuilder { sp_tracing::try_init_simple(); self.set_associated_consts(); let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![], dev_accounts: (10, 1000, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: vec![], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); let mut ext = sp_io::TestExternalities::new(t); diff --git a/substrate/frame/root-offences/src/mock.rs b/substrate/frame/root-offences/src/mock.rs index c37df85d6e61..efa22c25e284 100644 --- a/substrate/frame/root-offences/src/mock.rs +++ b/substrate/frame/root-offences/src/mock.rs @@ -211,7 +211,7 @@ impl ExtBuilder { (31, self.balance_factor * 500), (41, self.balance_factor * 1000), ], - dev_accounts: (10, 1000, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut storage) .unwrap(); diff --git a/substrate/frame/safe-mode/src/mock.rs b/substrate/frame/safe-mode/src/mock.rs index 71c5201b14f3..784eee450390 100644 --- a/substrate/frame/safe-mode/src/mock.rs +++ b/substrate/frame/safe-mode/src/mock.rs @@ -231,7 +231,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // The 0 account is NOT a special origin, the rest may be. - balances: vec![(0, BAL_ACC0), (1, BAL_ACC1), (2, 5678), (3, 5678), (4, 5678)], dev_accounts: (10, 100, "//String/{}".to_string()), + balances: vec![(0, BAL_ACC0), (1, BAL_ACC1), (2, 5678), (3, 5678), (4, 5678)], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/society/src/mock.rs b/substrate/frame/society/src/mock.rs index e6d12739eb5c..a717aace767d 100644 --- a/substrate/frame/society/src/mock.rs +++ b/substrate/frame/society/src/mock.rs @@ -115,7 +115,7 @@ impl EnvBuilder { pub fn execute R>(mut self, f: F) -> R { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); self.balances.push((Society::account_id(), self.balance.max(self.pot))); - pallet_balances::GenesisConfig:: { balances: self.balances, dev_accounts: (10, 100000, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: self.balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); pallet_society::GenesisConfig:: { pot: self.pot } diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index f5ff01fbb0dd..91793276645f 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -464,7 +464,7 @@ impl ExtBuilder { // This allows us to have a total_payout different from 0. (999, 1_000_000_000_000), ], - dev_accounts: (10, self.balance_factor, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut storage); diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index 83af1264e713..eaaaf2c19fc1 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -1257,7 +1257,7 @@ mod mock { frame_system::GenesisConfig::::default() .assimilate_storage(&mut custom_storage) .unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 1000)], dev_accounts: (10, 1000, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: vec![(1, 1000)], ..Default::default() } .assimilate_storage(&mut custom_storage) .unwrap(); } diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs index 5394c05f88e7..697b269d6022 100644 --- a/substrate/frame/tips/src/tests.rs +++ b/substrate/frame/tips/src/tests.rs @@ -178,7 +178,7 @@ impl Config for Test { pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], dev_accounts: (10, 1000, "//Sender/{}".to_string()) }, + balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], ..Default::default() }, treasury: Default::default(), treasury_1: Default::default(), } @@ -580,7 +580,7 @@ fn genesis_funding_works() { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], - dev_accounts: (10, 100, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs index 5b844030cab9..5fb88bf20e8e 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -78,7 +78,7 @@ impl ExtBuilder { } else { vec![] }, - dev_accounts: (10, self.balance_factor, "//Sender/{}".to_string()), + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/transaction-storage/src/mock.rs b/substrate/frame/transaction-storage/src/mock.rs index 591622f90dfc..6df6692e71ad 100644 --- a/substrate/frame/transaction-storage/src/mock.rs +++ b/substrate/frame/transaction-storage/src/mock.rs @@ -68,7 +68,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { system: Default::default(), balances: pallet_balances::GenesisConfig:: { balances: vec![(1, 1000000000), (2, 100), (3, 100), (4, 100)], - dev_accounts: (1, 100000000, "//Sender/{}".to_string()), + ..Defualt::default() }, transaction_storage: pallet_transaction_storage::GenesisConfig:: { storage_period: 10, diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs index ca18803e4431..57ea000485f8 100644 --- a/substrate/frame/treasury/src/tests.rs +++ b/substrate/frame/treasury/src/tests.rs @@ -214,7 +214,7 @@ impl ExtBuilder { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], - dev_accounts: (1, 100, "//Sender/{}".to_string()), + ..Defualt::default() } .assimilate_storage(&mut t) .unwrap(); @@ -383,7 +383,7 @@ fn treasury_account_doesnt_get_deleted() { #[test] fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], dev_accounts: (1, 999, "//Sender/{}".to_string()) } + pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], ..Defualt::default() } .assimilate_storage(&mut t) .unwrap(); // Treasury genesis config is not build thus treasury account does not exist @@ -418,7 +418,7 @@ fn genesis_funding_works() { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], - dev_accounts: (1, 100, "//Sender/{}".to_string()), + ..Defualt::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/tx-pause/src/mock.rs b/substrate/frame/tx-pause/src/mock.rs index b997ae013583..11ed9afd6f33 100644 --- a/substrate/frame/tx-pause/src/mock.rs +++ b/substrate/frame/tx-pause/src/mock.rs @@ -156,7 +156,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // The 0 account is NOT a special origin. The rest may be: balances: vec![(0, 1234), (1, 5678), (2, 5678), (3, 5678), (4, 5678)], - dev_accounts: (1, 1000, "//Sender/{}".to_string()), + ..Defualt::defualt() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs index bba0ff1aeb2a..729902ed3976 100644 --- a/substrate/frame/utility/src/tests.rs +++ b/substrate/frame/utility/src/tests.rs @@ -237,7 +237,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], - dev_accounts: (1, 10, "//Sender/{}".to_string()), + ..Defualt::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/vesting/src/mock.rs b/substrate/frame/vesting/src/mock.rs index 4b0902906948..9adab76e30c8 100644 --- a/substrate/frame/vesting/src/mock.rs +++ b/substrate/frame/vesting/src/mock.rs @@ -94,7 +94,7 @@ impl ExtBuilder { (12, 10 * self.existential_deposit), (13, 9999 * self.existential_deposit), ], - dev_accounts: (10, self.existential_deposit, "//Sender/{}".to_string()), + ..Defualt::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/test-utils/runtime/src/genesismap.rs b/substrate/test-utils/runtime/src/genesismap.rs index 5d1e972e1231..1e20699e2faa 100644 --- a/substrate/test-utils/runtime/src/genesismap.rs +++ b/substrate/test-utils/runtime/src/genesismap.rs @@ -130,7 +130,7 @@ impl GenesisStorageBuilder { authorities: authorities_sr25519.clone(), ..Default::default() }, - balances: pallet_balances::GenesisConfig { balances: self.balances.clone(), dev_accounts: (10, 100u32.into(), "//Sender/{}".to_string()) }, + balances: pallet_balances::GenesisConfig { balances: self.balances.clone(), ..Default::default() }, } } From a4a1effae44f2cac7e6eab4c236ef2d6bedd9a85 Mon Sep 17 00:00:00 2001 From: runcomet Date: Mon, 4 Nov 2024 09:50:06 -0800 Subject: [PATCH 04/21] BalancesConfig --- .../assets/asset-hub-rococo/src/genesis_config_presets.rs | 4 ++-- .../assets/asset-hub-westend/src/genesis_config_presets.rs | 4 ++-- .../bridge-hub-rococo/src/genesis_config_presets.rs | 4 ++-- .../bridge-hub-westend/src/genesis_config_presets.rs | 4 ++-- .../collectives-westend/src/genesis_config_presets.rs | 4 ++-- polkadot/runtime/rococo/src/genesis_config_presets.rs | 6 +++--- polkadot/runtime/westend/src/genesis_config_presets.rs | 6 +++--- substrate/bin/node/testing/src/genesis.rs | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs index e45a5203512f..72ed53ed5720 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Asset Hub Rococo Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec, string::ToString}; +use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; use hex_literal::hex; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; @@ -35,7 +35,7 @@ fn asset_hub_rococo_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), - dev_accounts: (10, ASSET_HUB_ROCOCO_ED, "//Sender/{}".to_string()), + ..Default::default() }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs index fe0054625240..3cd95567732b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Asset Hub Westend Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec, string::ToString}; +use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; use hex_literal::hex; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; @@ -37,7 +37,7 @@ fn asset_hub_westend_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), - dev_accounts: (10, ASSET_HUB_WESTEND_ED, "//Sender/{}".to_string()) + ..Default::default() }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index 4b0f929612a6..c0f22c442120 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Bridge Hub Rococo Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec, string::ToString}; +use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; use sp_core::sr25519; @@ -40,7 +40,7 @@ fn bridge_hub_rococo_genesis( .cloned() .map(|k| (k, 1u128 << 60)) .collect::>(), - dev_accounts: (10, BRIDGE_HUB_ROCOCO_ED, "//Sender/{}".to_string()), + ..Default::default() }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index 2714e17a2109..51d97e78c510 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Bridge Hub Westend Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec, string::ToString}; +use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; use sp_core::sr25519; @@ -40,7 +40,7 @@ fn bridge_hub_westend_genesis( .cloned() .map(|k| (k, 1u128 << 60)) .collect::>(), - dev_accounts: (10, BRIDGE_HUB_WESTEND_ED, "//Sender/{}".to_string()) + ..Default::default() }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs index ebff423b8b67..8eded3bb975d 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs @@ -16,7 +16,7 @@ //! # Bridge Hub Westend Runtime genesis config presets use crate::*; -use alloc::{vec, vec::Vec, string::ToString}; +use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; use parachains_common::{genesis_config_helpers::*, AccountId, AuraId}; use sp_core::sr25519; @@ -37,7 +37,7 @@ fn collectives_westend_genesis( .cloned() .map(|k| (k, COLLECTIVES_WESTEND_ED * 4096)) .collect::>(), - dev_accounts: (10, COLLECTIVES_WESTEND_ED, "//Sender/{}".to_string()) + ..Default::default() }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs index 58d890b68cd1..c2e3971e9a97 100644 --- a/polkadot/runtime/rococo/src/genesis_config_presets.rs +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -22,7 +22,7 @@ use crate::{ }; #[cfg(not(feature = "std"))] use alloc::format; -use alloc::{vec, vec::Vec, string::ToString}; +use alloc::{vec, vec::Vec}; use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, SchedulerParams, ValidatorId}; use rococo_runtime_constants::currency::UNITS as ROC; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; @@ -185,7 +185,7 @@ fn rococo_testnet_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), - dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()) + ..Default::default() }, session: SessionConfig { keys: initial_authorities @@ -454,7 +454,7 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect::>(), - dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()) + ..Default::default() }, session: SessionConfig { keys: initial_authorities diff --git a/polkadot/runtime/westend/src/genesis_config_presets.rs b/polkadot/runtime/westend/src/genesis_config_presets.rs index ae21c06c0603..02d4fc14e56f 100644 --- a/polkadot/runtime/westend/src/genesis_config_presets.rs +++ b/polkadot/runtime/westend/src/genesis_config_presets.rs @@ -22,7 +22,7 @@ use crate::{ }; #[cfg(not(feature = "std"))] use alloc::format; -use alloc::{vec, vec::Vec, string::ToString}; +use alloc::{vec, vec::Vec}; use pallet_staking::{Forcing, StakerStatus}; use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, SchedulerParams, ValidatorId}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; @@ -191,7 +191,7 @@ fn westend_testnet_genesis( let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), - dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()) + ..Default::default() }, session: SessionConfig { keys: initial_authorities @@ -371,7 +371,7 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect::>(), - dev_accounts: (10, ENDOWMENT, "//Sender/{}".to_string()), + ..Default::default() }, session: SessionConfig { keys: initial_authorities diff --git a/substrate/bin/node/testing/src/genesis.rs b/substrate/bin/node/testing/src/genesis.rs index 7ec5c5bb506e..606349e0bd6b 100644 --- a/substrate/bin/node/testing/src/genesis.rs +++ b/substrate/bin/node/testing/src/genesis.rs @@ -47,7 +47,7 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig { RuntimeGenesisConfig { indices: IndicesConfig { indices: vec![] }, - balances: BalancesConfig { balances: endowed, dev_accounts: (10, 100 * DOLLARS, "//Sender/{}".to_string()) }, + balances: BalancesConfig { balances: endowed, ..Default::default() }, session: SessionConfig { keys: vec![ (alice(), dave(), session_keys_from_seed(Ed25519Keyring::Alice.into())), From 3163d5f4e62728a4ff5aa312b4302ec38bec6d4c Mon Sep 17 00:00:00 2001 From: runcomet Date: Tue, 12 Nov 2024 18:48:08 -0800 Subject: [PATCH 05/21] configure ensure_ti_valid awareness of dev_accounts --- .../frame/balances/src/tests/general_tests.rs | 13 ----- substrate/frame/balances/src/tests/mod.rs | 53 +++++++++++++++---- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/substrate/frame/balances/src/tests/general_tests.rs b/substrate/frame/balances/src/tests/general_tests.rs index d062d8862914..a855fae5616a 100644 --- a/substrate/frame/balances/src/tests/general_tests.rs +++ b/substrate/frame/balances/src/tests/general_tests.rs @@ -141,16 +141,3 @@ fn try_state_works() { .contains("Found `Freeze` with too many elements")); }); } - -#[cfg(feature = "runtime-benchmarks")] -#[test] -fn dev_accounts_populated() { - ExtBuilder::default().build_and_execute_with(|| { - UseSystem::set(true); // copmment this out and uncomment this from time to time to check stuff. - // Print total issuance for debugging - let ti = TotalIssuance::::get(); - println!("Total Issuance after genesis: {}", ti); - println!("Why are you printing twice?"); - ensure_ti_valid(); - }); -} diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index a621b8c21f9f..8b953b957291 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -43,6 +43,11 @@ use sp_runtime::{ }; use std::collections::BTreeSet; +#[cfg(feature = "runtime-benchmarks")] +use sp_core::{sr25519::Pair as SrPair, Pair}; + +use frame_support::traits::BuildGenesisConfig; + mod currency_tests; mod dispatchable_tests; mod fungible_conformance_tests; @@ -281,19 +286,45 @@ pub fn info_from_weight(w: Weight) -> DispatchInfo { /// Check that the total-issuance matches the sum of all accounts' total balances. pub fn ensure_ti_valid() { - let mut sum = 0; + let mut sum = 0; - for acc in frame_system::Account::::iter_keys() { - if UseSystem::get() { - let data = frame_system::Pallet::::account(acc); - sum += data.data.total(); - } else { - let data = crate::Account::::get(acc); - sum += data.total(); - } - } + // Fetch the dev accounts from the GenesisConfig. + #[cfg(feature = "runtime-benchmarks")] + let dev_accounts = (10, 100, "//Sender/{}".to_string()); // You can customize this as needed + #[cfg(feature = "runtime-benchmarks")] + let (num_accounts, balance, ref derivation) = dev_accounts; + + // Generate the dev account public keys. + #[cfg(feature = "runtime-benchmarks")] + let dev_account_ids: Vec<_> = (0..num_accounts) + .map(|index| { + let derivation_string = derivation.replace("{}", &index.to_string()); + let pair: SrPair = Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); + ::AccountId::decode(&mut &pair.public().encode()[..]).unwrap() + }) + .collect(); + + // Iterate over all account keys (i.e., the account IDs). + for acc in frame_system::Account::::iter_keys() { + // Skip dev accounts by checking if the account is in the dev_account_ids list. + // This also proves dev_accounts exists in storage. + #[cfg(feature = "runtime-benchmarks")] + if dev_account_ids.contains(&acc) { + continue; + } + + // Check if we are using the system pallet or some other custom storage for accounts. + if UseSystem::get() { + let data = frame_system::Pallet::::account(acc); + sum += data.data.total(); + } else { + let data = crate::Account::::get(acc); + sum += data.total(); + } + } - assert_eq!(TotalIssuance::::get(), sum, "Total Issuance wrong"); + // Ensure the total issuance matches the sum of the account balances + assert_eq!(TotalIssuance::::get(), sum, "Total Issuance is incorrect"); } #[test] From 25ca49c0ee7a2e895a9d41539f8b54b1c13794fb Mon Sep 17 00:00:00 2001 From: runcomet Date: Thu, 14 Nov 2024 00:35:29 -0800 Subject: [PATCH 06/21] nit --- substrate/frame/balances/src/lib.rs | 3 +-- substrate/frame/balances/src/tests/currency_tests.rs | 8 ++------ substrate/frame/balances/src/tests/mod.rs | 4 +--- substrate/frame/transaction-storage/src/mock.rs | 2 +- substrate/frame/treasury/src/tests.rs | 6 +++--- substrate/frame/tx-pause/src/mock.rs | 2 +- substrate/frame/utility/src/tests.rs | 2 +- substrate/frame/vesting/src/mock.rs | 2 +- 8 files changed, 11 insertions(+), 18 deletions(-) diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 030b4ffa0b67..fe3612af1a2f 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -152,7 +152,7 @@ pub mod weights; extern crate alloc; -use alloc::{vec::Vec, string::{String, ToString}}; +use alloc::vec::Vec; use codec::{Codec, MaxEncodedLen}; use core::{cmp, fmt::Debug, mem, result}; use frame_support::{ @@ -556,7 +556,6 @@ pub mod pallet { #[cfg(feature = "runtime-benchmarks")] { let (num_accounts, balance, ref derivation) = self.dev_accounts; - let num_balance = >::Balance::from(num_accounts); for index in 0..num_accounts { assert!( balance >= >::ExistentialDeposit::get(), diff --git a/substrate/frame/balances/src/tests/currency_tests.rs b/substrate/frame/balances/src/tests/currency_tests.rs index 2566d07f6a18..d6d9b5538e13 100644 --- a/substrate/frame/balances/src/tests/currency_tests.rs +++ b/substrate/frame/balances/src/tests/currency_tests.rs @@ -719,9 +719,7 @@ fn cannot_set_genesis_value_below_ed() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); let _ = crate::GenesisConfig:: { balances: vec![(1, 10)], - - #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (1000000, 500, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); @@ -733,9 +731,7 @@ fn cannot_set_genesis_value_twice() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); let _ = crate::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (1, 15)], - - #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (1000000, 500, "//Sender/{}".to_string()) + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 8b953b957291..cb28ec253949 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -46,8 +46,6 @@ use std::collections::BTreeSet; #[cfg(feature = "runtime-benchmarks")] use sp_core::{sr25519::Pair as SrPair, Pair}; -use frame_support::traits::BuildGenesisConfig; - mod currency_tests; mod dispatchable_tests; mod fungible_conformance_tests; @@ -292,7 +290,7 @@ pub fn ensure_ti_valid() { #[cfg(feature = "runtime-benchmarks")] let dev_accounts = (10, 100, "//Sender/{}".to_string()); // You can customize this as needed #[cfg(feature = "runtime-benchmarks")] - let (num_accounts, balance, ref derivation) = dev_accounts; + let (num_accounts, _balance, ref derivation) = dev_accounts; // Generate the dev account public keys. #[cfg(feature = "runtime-benchmarks")] diff --git a/substrate/frame/transaction-storage/src/mock.rs b/substrate/frame/transaction-storage/src/mock.rs index 6df6692e71ad..1eee1de6ecac 100644 --- a/substrate/frame/transaction-storage/src/mock.rs +++ b/substrate/frame/transaction-storage/src/mock.rs @@ -68,7 +68,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { system: Default::default(), balances: pallet_balances::GenesisConfig:: { balances: vec![(1, 1000000000), (2, 100), (3, 100), (4, 100)], - ..Defualt::default() + ..Default::default() }, transaction_storage: pallet_transaction_storage::GenesisConfig:: { storage_period: 10, diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs index 4a0e99528b04..6f9f3dc68af2 100644 --- a/substrate/frame/treasury/src/tests.rs +++ b/substrate/frame/treasury/src/tests.rs @@ -221,7 +221,7 @@ impl ExtBuilder { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], - ..Defualt::default() + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); @@ -407,7 +407,7 @@ fn treasury_account_doesnt_get_deleted() { #[test] fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], ..Defualt::default() } + pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); // Treasury genesis config is not build thus treasury account does not exist @@ -446,7 +446,7 @@ fn genesis_funding_works() { pallet_balances::GenesisConfig:: { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], - ..Defualt::default() + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/tx-pause/src/mock.rs b/substrate/frame/tx-pause/src/mock.rs index 11ed9afd6f33..09294645db0b 100644 --- a/substrate/frame/tx-pause/src/mock.rs +++ b/substrate/frame/tx-pause/src/mock.rs @@ -156,7 +156,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // The 0 account is NOT a special origin. The rest may be: balances: vec![(0, 1234), (1, 5678), (2, 5678), (3, 5678), (4, 5678)], - ..Defualt::defualt() + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs index 8add1733b396..d075ec1ff82e 100644 --- a/substrate/frame/utility/src/tests.rs +++ b/substrate/frame/utility/src/tests.rs @@ -237,7 +237,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], - ..Defualt::default() + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/vesting/src/mock.rs b/substrate/frame/vesting/src/mock.rs index 9adab76e30c8..8fae9bbf7497 100644 --- a/substrate/frame/vesting/src/mock.rs +++ b/substrate/frame/vesting/src/mock.rs @@ -94,7 +94,7 @@ impl ExtBuilder { (12, 10 * self.existential_deposit), (13, 9999 * self.existential_deposit), ], - ..Defualt::default() + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); From 4cac3a82bf91ee8b86877ca821220cea382a5cc3 Mon Sep 17 00:00:00 2001 From: runcomet Date: Thu, 21 Nov 2024 03:32:55 -0800 Subject: [PATCH 07/21] Option String --- substrate/frame/balances/src/lib.rs | 47 ++++++++++++----------- substrate/frame/balances/src/tests/mod.rs | 6 +-- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index fe3612af1a2f..cd3de6a5ed74 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -511,7 +511,7 @@ pub mod pallet { pub balances: Vec<(T::AccountId, T::Balance)>, #[cfg(feature = "runtime-benchmarks")] - pub dev_accounts: (u32, T::Balance, String), + pub dev_accounts: (u32, T::Balance, Option), } impl, I: 'static> Default for GenesisConfig { @@ -520,7 +520,7 @@ pub mod pallet { balances: Default::default(), #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (Default::default(), Default::default(), String::new()), + dev_accounts: (Default::default(), Default::default(), None), } } } @@ -556,27 +556,28 @@ pub mod pallet { #[cfg(feature = "runtime-benchmarks")] { let (num_accounts, balance, ref derivation) = self.dev_accounts; - for index in 0..num_accounts { - assert!( - balance >= >::ExistentialDeposit::get(), - "the balance of any account should always be at least the existential deposit.", - ); - // Check if the derivation string follows the pattern "//character/{}" - assert!( - derivation.starts_with("//") && - derivation[2..].contains('/') && // There should be a character after "//" and before "{}" - derivation.ends_with("{}"), - "Invalid derivation string" - ); - // Create key pair from the derivation string - let derivation_string = &derivation.replace("{}", &index.to_string()); - let pair: SrPair = Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); - - // Convert the public key to AccountId - let who = T::AccountId::decode(&mut &pair.public().encode()[..]).unwrap(); - frame_system::Pallet::::inc_providers(&who); - assert!(T::AccountStore::insert(&who, AccountData { free: balance, ..Default::default() }) - .is_ok()); + // Check if `derivation` is `Some` and generate key pair + if let Some(derivation_string) = &derivation { + for index in 0..num_accounts { + // Replace "{}" in the derivation string with the index + let derivation_string = derivation_string.replace("{}", &index.to_string()); + + // Attempt to create the key pair from the derivation string with error handling + let pair: SrPair = Pair::from_string(&derivation_string, None) + .expect(&format!("Failed to parse derivation string: {}", derivation_string)); + + // Convert the public key to AccountId + let who = T::AccountId::decode(&mut &pair.public().encode()[..]) + .expect(&format!("Failed to decode public key from pair: {}", pair.public())); + + frame_system::Pallet::::inc_providers(&who); + // Insert the account into the store and ensure it succeeds + assert!(T::AccountStore::insert(&who, AccountData { free: balance, ..Default::default() }) + .is_ok()) + } + } else { + // If `derivation` is None, log or handle the error as needed. + log::error!(target: LOG_TARGET, "Derivation string is missing for runtime benchmarks."); } } diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index cb28ec253949..7a33d570d999 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -173,7 +173,7 @@ impl ExtBuilder { vec![] }, #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (10, self.existential_deposit, "//Sender/{}".to_string()) + dev_accounts: (1000, self.existential_deposit, Some("//Sender/{}".to_string())) } .assimilate_storage(&mut t) .unwrap(); @@ -286,9 +286,9 @@ pub fn info_from_weight(w: Weight) -> DispatchInfo { pub fn ensure_ti_valid() { let mut sum = 0; - // Fetch the dev accounts from the GenesisConfig. + // Fetch the dev accounts from Account Storage. #[cfg(feature = "runtime-benchmarks")] - let dev_accounts = (10, 100, "//Sender/{}".to_string()); // You can customize this as needed + let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, "//Sender/{}".to_string()); // You can customize this as needed #[cfg(feature = "runtime-benchmarks")] let (num_accounts, _balance, ref derivation) = dev_accounts; From beb80569031245fad35752659576e78e174ae143 Mon Sep 17 00:00:00 2001 From: runcomet Date: Thu, 21 Nov 2024 15:36:17 -0800 Subject: [PATCH 08/21] doc fix --- substrate/frame/balances/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index cd3de6a5ed74..725f0120dcfe 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -576,7 +576,7 @@ pub mod pallet { .is_ok()) } } else { - // If `derivation` is None, log or handle the error as needed. + // `derivation` is None, handle as needed. log::error!(target: LOG_TARGET, "Derivation string is missing for runtime benchmarks."); } } From e647bca501e6f12b3b2a28483753a1b7a2825c66 Mon Sep 17 00:00:00 2001 From: runcomet Date: Fri, 22 Nov 2024 14:03:03 -0800 Subject: [PATCH 09/21] derive_dev_account helper function --- substrate/frame/balances/src/lib.rs | 64 ++++++++++----- .../balances/src/tests/currency_tests.rs | 11 +-- substrate/frame/balances/src/tests/mod.rs | 82 ++++++++++--------- 3 files changed, 89 insertions(+), 68 deletions(-) diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 725f0120dcfe..26154ae66793 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -516,11 +516,11 @@ pub mod pallet { impl, I: 'static> Default for GenesisConfig { fn default() -> Self { - Self { + Self { balances: Default::default(), - + #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (Default::default(), Default::default(), None), + dev_accounts: (One::one(), >::ExistentialDeposit::get(), None), } } } @@ -556,28 +556,15 @@ pub mod pallet { #[cfg(feature = "runtime-benchmarks")] { let (num_accounts, balance, ref derivation) = self.dev_accounts; + // Check if `derivation` is `Some` and generate key pair if let Some(derivation_string) = &derivation { - for index in 0..num_accounts { - // Replace "{}" in the derivation string with the index - let derivation_string = derivation_string.replace("{}", &index.to_string()); - - // Attempt to create the key pair from the derivation string with error handling - let pair: SrPair = Pair::from_string(&derivation_string, None) - .expect(&format!("Failed to parse derivation string: {}", derivation_string)); - - // Convert the public key to AccountId - let who = T::AccountId::decode(&mut &pair.public().encode()[..]) - .expect(&format!("Failed to decode public key from pair: {}", pair.public())); - - frame_system::Pallet::::inc_providers(&who); - // Insert the account into the store and ensure it succeeds - assert!(T::AccountStore::insert(&who, AccountData { free: balance, ..Default::default() }) - .is_ok()) - } + Pallet::::derive_dev_account(num_accounts, balance, derivation_string); } else { - // `derivation` is None, handle as needed. - log::error!(target: LOG_TARGET, "Derivation string is missing for runtime benchmarks."); + // Derivation string is missing, using default.. + let default_derivation = "//Sender/{}".to_string(); + + Pallet::::derive_dev_account(num_accounts, balance, &default_derivation); } } @@ -1289,5 +1276,38 @@ pub mod pallet { }); Ok(actual) } + + /// Generate dev account from derivation string. + #[cfg(feature = "runtime-benchmarks")] + pub fn derive_dev_account(num_accounts: u32, balance: T::Balance, derivation: &String) { + // Ensure that the number of accounts is not zero + assert!(num_accounts > 0, "num_accounts must be greater than zero"); + + assert!( + balance >= >::ExistentialDeposit::get(), + "the balance of any account should always be at least the existential deposit.", + ); + + for index in 0..num_accounts { + // Replace "{}" in the derivation string with the index. + let derivation_string = derivation.replace("{}", &index.to_string()); + + // Attempt to create the key pair from the derivation string with error handling. + let pair: SrPair = Pair::from_string(&derivation_string, None) + .expect(&format!("Failed to parse derivation string: {}", derivation_string)); + + // Convert the public key to AccountId. + let who = T::AccountId::decode(&mut &pair.public().encode()[..]) + .expect(&format!("Failed to decode public key from pair: {}", pair.public())); + + frame_system::Pallet::::inc_providers(&who); + // Insert the account into the store and ensure it succeeds. + assert!(T::AccountStore::insert( + &who, + AccountData { free: balance, ..Default::default() } + ) + .is_ok()); + } + } } } diff --git a/substrate/frame/balances/src/tests/currency_tests.rs b/substrate/frame/balances/src/tests/currency_tests.rs index a5024efde467..a6377c3ad72e 100644 --- a/substrate/frame/balances/src/tests/currency_tests.rs +++ b/substrate/frame/balances/src/tests/currency_tests.rs @@ -721,10 +721,7 @@ fn burn_must_work() { fn cannot_set_genesis_value_below_ed() { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = 11); let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let _ = crate::GenesisConfig:: { - balances: vec![(1, 10)], - ..Default::default() - } + let _ = crate::GenesisConfig:: { balances: vec![(1, 10)], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); } @@ -733,12 +730,12 @@ fn cannot_set_genesis_value_below_ed() { #[should_panic = "duplicate balances in genesis."] fn cannot_set_genesis_value_twice() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let _ = crate::GenesisConfig:: { + let _ = crate::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (1, 15)], ..Default::default() } - .assimilate_storage(&mut t) - .unwrap(); + .assimilate_storage(&mut t) + .unwrap(); } #[test] diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 7a33d570d999..f0f4717b44ff 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -173,7 +173,7 @@ impl ExtBuilder { vec![] }, #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (1000, self.existential_deposit, Some("//Sender/{}".to_string())) + dev_accounts: (1000, self.existential_deposit, Some("//Sender/{}".to_string())), } .assimilate_storage(&mut t) .unwrap(); @@ -284,45 +284,49 @@ pub fn info_from_weight(w: Weight) -> DispatchInfo { /// Check that the total-issuance matches the sum of all accounts' total balances. pub fn ensure_ti_valid() { - let mut sum = 0; - - // Fetch the dev accounts from Account Storage. - #[cfg(feature = "runtime-benchmarks")] - let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, "//Sender/{}".to_string()); // You can customize this as needed - #[cfg(feature = "runtime-benchmarks")] - let (num_accounts, _balance, ref derivation) = dev_accounts; - - // Generate the dev account public keys. - #[cfg(feature = "runtime-benchmarks")] - let dev_account_ids: Vec<_> = (0..num_accounts) - .map(|index| { - let derivation_string = derivation.replace("{}", &index.to_string()); - let pair: SrPair = Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); - ::AccountId::decode(&mut &pair.public().encode()[..]).unwrap() - }) - .collect(); - - // Iterate over all account keys (i.e., the account IDs). - for acc in frame_system::Account::::iter_keys() { - // Skip dev accounts by checking if the account is in the dev_account_ids list. + let mut sum = 0; + + // Fetch the dev accounts from Account Storage. + #[cfg(feature = "runtime-benchmarks")] + let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, "//Sender/{}".to_string()); // You can customize this as needed + #[cfg(feature = "runtime-benchmarks")] + let (num_accounts, _balance, ref derivation) = dev_accounts; + + // Generate the dev account public keys. + #[cfg(feature = "runtime-benchmarks")] + let dev_account_ids: Vec<_> = (0..num_accounts) + .map(|index| { + let derivation_string = derivation.replace("{}", &index.to_string()); + let pair: SrPair = + Pair::from_string(&derivation_string, None).expect("Invalid derivation string"); + ::AccountId::decode( + &mut &pair.public().encode()[..], + ) + .unwrap() + }) + .collect(); + + // Iterate over all account keys (i.e., the account IDs). + for acc in frame_system::Account::::iter_keys() { + // Skip dev accounts by checking if the account is in the dev_account_ids list. // This also proves dev_accounts exists in storage. - #[cfg(feature = "runtime-benchmarks")] - if dev_account_ids.contains(&acc) { - continue; - } - - // Check if we are using the system pallet or some other custom storage for accounts. - if UseSystem::get() { - let data = frame_system::Pallet::::account(acc); - sum += data.data.total(); - } else { - let data = crate::Account::::get(acc); - sum += data.total(); - } - } - - // Ensure the total issuance matches the sum of the account balances - assert_eq!(TotalIssuance::::get(), sum, "Total Issuance is incorrect"); + #[cfg(feature = "runtime-benchmarks")] + if dev_account_ids.contains(&acc) { + continue; + } + + // Check if we are using the system pallet or some other custom storage for accounts. + if UseSystem::get() { + let data = frame_system::Pallet::::account(acc); + sum += data.data.total(); + } else { + let data = crate::Account::::get(acc); + sum += data.total(); + } + } + + // Ensure the total issuance matches the sum of the account balances + assert_eq!(TotalIssuance::::get(), sum, "Total Issuance is incorrect"); } #[test] From e8efd68d6476e906ad1a60f3fe3427ce7724f835 Mon Sep 17 00:00:00 2001 From: runcomet Date: Sat, 30 Nov 2024 10:40:48 -0800 Subject: [PATCH 10/21] add prdoc --- prdoc/pr_6267.prdoc | 135 ++++++++++++++++++ substrate/frame/balances/src/lib.rs | 10 +- .../asset-conversion-tx-payment/src/tests.rs | 1 + .../frame/transaction-payment/src/tests.rs | 1 + 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 prdoc/pr_6267.prdoc diff --git a/prdoc/pr_6267.prdoc b/prdoc/pr_6267.prdoc new file mode 100644 index 000000000000..c218e2a5093b --- /dev/null +++ b/prdoc/pr_6267.prdoc @@ -0,0 +1,135 @@ +# 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: Allow configurable number of genesis accounts with specified balances for benchmarking. + +doc: + - audience: Runtime Dev + description: | + This pull request adds an additional field `dev_accounts` to the `GenesisConfig` + of the balances pallet, feature gated by `runtime-benchmarks`. + + Bringing about an abitrary number of derived dev accounts when building the genesis + state. Runtime developers should supply a derivation path that includes an index placeholder + (i.e. "//Sender/{}") to generate multiple accounts from the same root in a consistent + manner. + +crates: + - name: substrate-test-runtime + bump: minor + - name: pallet-vesting + bump: minor + - name: pallet-utility + bump: minor + - name: pallet-tx-pause + bump: minor + - name: pallet-treasury + bump: minor + - name: pallet-transaction-storage + bump: minor + - name: pallet-transaction-payment + bump: minor + - name: pallet-asset-conversion-tx-payment + bump: minor + - name: pallet-asset-tx-payment + bump: minor + - name: pallet-tips + bump: minor + - name: pallet-state-trie-migration + bump: minor + - name: pallet-staking + bump: minor + - name: pallet-society + bump: minor + - name: pallet-safe-mode + bump: minor + - name: pallet-root-offences + bump: minor + - name: pallet-revive + bump: minor + - name: pallet-revive-mock-network + bump: minor + - name: pallet-referenda + bump: minor + - name: pallet-recovery + bump: minor + - name: pallet-proxy + bump: minor + - name: pallet-preimage + bump: minor + - name: pallet-nis + bump: minor + - name: pallet-multisig + bump: minor + - name: pallet-lottery + bump: minor + - name: pallet-indices + bump: minor + - name: pallet-identity + bump: minor + - name: pallet-grandpa + bump: minor + - name: pallet-fast-unstake + bump: minor + - name: pallet-elections-phragmen + bump: minor + - name: pallet-election-provider-multi-phase + bump: minor + - name: pallet-democracy + bump: minor + - name: pallet-delegated-staking + bump: minor + - name: pallet-conviction-voting + bump: minor + - name: pallet-contracts + bump: minor + - name: pallet-contracts-mock-network + bump: minor + - name: pallet-collective + bump: minor + - name: pallet-child-bounties + bump: minor + - name: pallet-bounties + bump: minor + - name: pallet-balances + bump: minor + - name: pallet-babe + bump: minor + - name: pallet-asset-conversion + bump: minor + - name: pallet-alliance + bump: minor + - name: node-testing + bump: minor + - name: xcm-simulator-fuzzer + bump: minor + - name: xcm-simulator-example + bump: minor + - name: xcm-runtime-apis + bump: minor + - name: staging-xcm-builder + bump: minor + - name: pallet-xcm + bump: minor + - name: westend-runtime + bump: minor + - name: rococo-runtime + bump: minor + - name: polkadot-runtime-common + bump: minor + - name: parachains-runtimes-test-utils + bump: minor + - name: collectives-westend-runtime + bump: minor + - name: bridge-hub-westend-runtime + bump: minor + - name: bridge-hub-rococo-runtime + bump: minor + - name: asset-hub-westend-runtime + bump: minor + - name: asset-hub-rococo-runtime + bump: minor + - name: pallet-collator-selection + bump: minor + - name: pallet-bridge-messages + bump: minor diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 26154ae66793..c79ea186487a 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -183,6 +183,7 @@ use sp_runtime::{ #[cfg(feature = "runtime-benchmarks")] use sp_core::{sr25519::Pair as SrPair, Pair}; +use alloc::{format, string::{String, ToString}}; pub use types::{ AccountData, AdjustmentDirection, BalanceLock, DustCleaner, ExtraFlags, Reasons, ReserveData, @@ -1288,6 +1289,11 @@ pub mod pallet { "the balance of any account should always be at least the existential deposit.", ); + assert!( + derivation.contains("{}"), + "Invalid derivation string" + ); + for index in 0..num_accounts { // Replace "{}" in the derivation string with the index. let derivation_string = derivation.replace("{}", &index.to_string()); @@ -1298,10 +1304,10 @@ pub mod pallet { // Convert the public key to AccountId. let who = T::AccountId::decode(&mut &pair.public().encode()[..]) - .expect(&format!("Failed to decode public key from pair: {}", pair.public())); + .expect(&format!("Failed to decode public key from pair: {:?}", pair.public())); frame_system::Pallet::::inc_providers(&who); - // Insert the account into the store and ensure it succeeds. + // Insert the account into the store and ensure it succeeds(uri). assert!(T::AccountStore::insert( &who, AccountData { free: balance, ..Default::default() } diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs index 6ce4652fd42f..76d46aa16471 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs @@ -86,6 +86,7 @@ impl ExtBuilder { } else { vec![] }, + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/transaction-payment/src/tests.rs b/substrate/frame/transaction-payment/src/tests.rs index 572c1d4961dd..1132aa4cf84a 100644 --- a/substrate/frame/transaction-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/src/tests.rs @@ -99,6 +99,7 @@ impl ExtBuilder { } else { vec![] }, + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); From d53d7957619e15495d1e94ebb3c28df71697e31e Mon Sep 17 00:00:00 2001 From: runcomet Date: Sat, 30 Nov 2024 16:17:34 -0800 Subject: [PATCH 11/21] adjust genesisconfig addition --- .../src/genesis_config_presets.rs | 3 +-- .../src/genesis_config_presets.rs | 3 +-- .../src/genesis_config_presets.rs | 3 +-- .../src/genesis_config_presets.rs | 3 +-- .../src/genesis_config_presets.rs | 3 +-- .../parachains/runtimes/test-utils/src/lib.rs | 2 +- .../rococo/src/genesis_config_presets.rs | 6 ++---- .../westend/src/genesis_config_presets.rs | 6 ++---- prdoc/pr_6267.prdoc | 18 ++---------------- substrate/bin/node/testing/src/genesis.rs | 2 +- substrate/frame/balances/src/lib.rs | 3 ++- substrate/test-utils/runtime/Cargo.toml | 2 +- 12 files changed, 16 insertions(+), 38 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs index 36fe0126657c..8f029a5b808d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs @@ -36,8 +36,7 @@ fn asset_hub_rococo_genesis( ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), - ..Default::default() + balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect() }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs index e9837581eeec..d1d98f9d656d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs @@ -38,8 +38,7 @@ fn asset_hub_westend_genesis( ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), - ..Default::default() + balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect() }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index f0373b5df467..22993ef703a7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -41,8 +41,7 @@ fn bridge_hub_rococo_genesis( .iter() .cloned() .map(|k| (k, 1u128 << 60)) - .collect::>(), - ..Default::default() + .collect::>() }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index 9ef8bbb2455f..8a5e96ed9cf7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -41,8 +41,7 @@ fn bridge_hub_westend_genesis( .iter() .cloned() .map(|k| (k, 1u128 << 60)) - .collect::>(), - ..Default::default() + .collect::>() }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs index fee0f2b6f8a7..cb75c43b82b5 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs @@ -37,8 +37,7 @@ fn collectives_westend_genesis( .iter() .cloned() .map(|k| (k, COLLECTIVES_WESTEND_ED * 4096)) - .collect::>(), - ..Default::default() + .collect::>() }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 27691c60d363..3f2e721d13f6 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -230,7 +230,7 @@ impl ExtBuilder { .unwrap(); } - pallet_balances::GenesisConfig:: { balances: self.balances, ..Default::default() } + pallet_balances::GenesisConfig:: { balances: self.balances } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs index d45cf8d91119..dcaf578fd418 100644 --- a/polkadot/runtime/rococo/src/genesis_config_presets.rs +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -166,8 +166,7 @@ fn rococo_testnet_genesis( build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), - ..Default::default() + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>() }, session: SessionConfig { keys: initial_authorities @@ -428,8 +427,7 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { .iter() .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect::>(), - ..Default::default() + .collect::>() }, session: SessionConfig { keys: initial_authorities diff --git a/polkadot/runtime/westend/src/genesis_config_presets.rs b/polkadot/runtime/westend/src/genesis_config_presets.rs index ebacae8b8d41..2cf71d5187bb 100644 --- a/polkadot/runtime/westend/src/genesis_config_presets.rs +++ b/polkadot/runtime/westend/src/genesis_config_presets.rs @@ -173,8 +173,7 @@ fn westend_testnet_genesis( build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), - ..Default::default() + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>() }, session: SessionConfig { keys: initial_authorities @@ -345,8 +344,7 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { .iter() .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect::>(), - ..Default::default() + .collect::>() }, session: SessionConfig { keys: initial_authorities diff --git a/prdoc/pr_6267.prdoc b/prdoc/pr_6267.prdoc index c218e2a5093b..e5d7e4cb937b 100644 --- a/prdoc/pr_6267.prdoc +++ b/prdoc/pr_6267.prdoc @@ -97,6 +97,8 @@ crates: bump: minor - name: pallet-asset-conversion bump: minor + - name: pallet-asset-conversion-ops + bump: minor - name: pallet-alliance bump: minor - name: node-testing @@ -111,24 +113,8 @@ crates: bump: minor - name: pallet-xcm bump: minor - - name: westend-runtime - bump: minor - - name: rococo-runtime - bump: minor - name: polkadot-runtime-common bump: minor - - name: parachains-runtimes-test-utils - bump: minor - - name: collectives-westend-runtime - bump: minor - - name: bridge-hub-westend-runtime - bump: minor - - name: bridge-hub-rococo-runtime - bump: minor - - name: asset-hub-westend-runtime - bump: minor - - name: asset-hub-rococo-runtime - bump: minor - name: pallet-collator-selection bump: minor - name: pallet-bridge-messages diff --git a/substrate/bin/node/testing/src/genesis.rs b/substrate/bin/node/testing/src/genesis.rs index 606349e0bd6b..7f5364744c66 100644 --- a/substrate/bin/node/testing/src/genesis.rs +++ b/substrate/bin/node/testing/src/genesis.rs @@ -47,7 +47,7 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig { RuntimeGenesisConfig { indices: IndicesConfig { indices: vec![] }, - balances: BalancesConfig { balances: endowed, ..Default::default() }, + balances: BalancesConfig { balances: endowed }, session: SessionConfig { keys: vec![ (alice(), dave(), session_keys_from_seed(Ed25519Keyring::Alice.into())), diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index c79ea186487a..e875796af16e 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -183,6 +183,7 @@ use sp_runtime::{ #[cfg(feature = "runtime-benchmarks")] use sp_core::{sr25519::Pair as SrPair, Pair}; +#[cfg(feature = "runtime-benchmarks")] use alloc::{format, string::{String, ToString}}; pub use types::{ @@ -521,7 +522,7 @@ pub mod pallet { balances: Default::default(), #[cfg(feature = "runtime-benchmarks")] - dev_accounts: (One::one(), >::ExistentialDeposit::get(), None), + dev_accounts: (One::one(), >::ExistentialDeposit::get(), Some("//Sender/{}".to_string())), } } } diff --git a/substrate/test-utils/runtime/Cargo.toml b/substrate/test-utils/runtime/Cargo.toml index 96a888052876..1412d4b164e0 100644 --- a/substrate/test-utils/runtime/Cargo.toml +++ b/substrate/test-utils/runtime/Cargo.toml @@ -35,7 +35,7 @@ sp-session = { workspace = true } sp-api = { workspace = true } sp-runtime = { features = ["serde"], workspace = true } pallet-babe = { workspace = true } -pallet-balances = { workspace = true } +pallet-balances = { workspace = true, features = ["runtime-benchmarks"] } frame-executive = { workspace = true } frame-metadata-hash-extension = { workspace = true } frame-system = { workspace = true } From 9128ab918b1c7b1bd461d3cf618d449721513016 Mon Sep 17 00:00:00 2001 From: runcomet Date: Sun, 1 Dec 2024 16:21:14 -0800 Subject: [PATCH 12/21] nit --- .../assets/asset-hub-rococo/src/genesis_config_presets.rs | 2 +- .../asset-hub-westend/src/genesis_config_presets.rs | 2 +- .../bridge-hub-rococo/src/genesis_config_presets.rs | 2 +- .../bridge-hub-westend/src/genesis_config_presets.rs | 2 +- .../collectives-westend/src/genesis_config_presets.rs | 2 +- polkadot/runtime/rococo/src/genesis_config_presets.rs | 4 ++-- polkadot/runtime/westend/src/genesis_config_presets.rs | 4 ++-- prdoc/pr_6267.prdoc | 8 ++------ substrate/test-utils/runtime/Cargo.toml | 2 +- substrate/test-utils/runtime/src/genesismap.rs | 2 +- 10 files changed, 13 insertions(+), 17 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs index 8f029a5b808d..d58d2f6d5f4d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs @@ -36,7 +36,7 @@ fn asset_hub_rococo_genesis( ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect() + balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs index d1d98f9d656d..824544e3b687 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs @@ -38,7 +38,7 @@ fn asset_hub_westend_genesis( ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect() + balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index 22993ef703a7..98e2450ee832 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -41,7 +41,7 @@ fn bridge_hub_rococo_genesis( .iter() .cloned() .map(|k| (k, 1u128 << 60)) - .collect::>() + .collect::>(), }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index 8a5e96ed9cf7..69ba9ca9ece7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -41,7 +41,7 @@ fn bridge_hub_westend_genesis( .iter() .cloned() .map(|k| (k, 1u128 << 60)) - .collect::>() + .collect::>(), }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs index cb75c43b82b5..007ff6164a74 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs @@ -37,7 +37,7 @@ fn collectives_westend_genesis( .iter() .cloned() .map(|k| (k, COLLECTIVES_WESTEND_ED * 4096)) - .collect::>() + .collect::>(), }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs index dcaf578fd418..bdbf6f37d92c 100644 --- a/polkadot/runtime/rococo/src/genesis_config_presets.rs +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -166,7 +166,7 @@ fn rococo_testnet_genesis( build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>() + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), }, session: SessionConfig { keys: initial_authorities @@ -427,7 +427,7 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { .iter() .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect::>() + .collect::>(), }, session: SessionConfig { keys: initial_authorities diff --git a/polkadot/runtime/westend/src/genesis_config_presets.rs b/polkadot/runtime/westend/src/genesis_config_presets.rs index 2cf71d5187bb..b8f7710089e0 100644 --- a/polkadot/runtime/westend/src/genesis_config_presets.rs +++ b/polkadot/runtime/westend/src/genesis_config_presets.rs @@ -173,7 +173,7 @@ fn westend_testnet_genesis( build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>() + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), }, session: SessionConfig { keys: initial_authorities @@ -344,7 +344,7 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { .iter() .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect::>() + .collect::>(), }, session: SessionConfig { keys: initial_authorities diff --git a/prdoc/pr_6267.prdoc b/prdoc/pr_6267.prdoc index e5d7e4cb937b..71478a122ec6 100644 --- a/prdoc/pr_6267.prdoc +++ b/prdoc/pr_6267.prdoc @@ -15,8 +15,6 @@ doc: manner. crates: - - name: substrate-test-runtime - bump: minor - name: pallet-vesting bump: minor - name: pallet-utility @@ -29,10 +27,10 @@ crates: bump: minor - name: pallet-transaction-payment bump: minor - - name: pallet-asset-conversion-tx-payment - bump: minor - name: pallet-asset-tx-payment bump: minor + - name: pallet-asset-conversion-tx-payment + bump: minor - name: pallet-tips bump: minor - name: pallet-state-trie-migration @@ -101,8 +99,6 @@ crates: bump: minor - name: pallet-alliance bump: minor - - name: node-testing - bump: minor - name: xcm-simulator-fuzzer bump: minor - name: xcm-simulator-example diff --git a/substrate/test-utils/runtime/Cargo.toml b/substrate/test-utils/runtime/Cargo.toml index 1412d4b164e0..96a888052876 100644 --- a/substrate/test-utils/runtime/Cargo.toml +++ b/substrate/test-utils/runtime/Cargo.toml @@ -35,7 +35,7 @@ sp-session = { workspace = true } sp-api = { workspace = true } sp-runtime = { features = ["serde"], workspace = true } pallet-babe = { workspace = true } -pallet-balances = { workspace = true, features = ["runtime-benchmarks"] } +pallet-balances = { workspace = true } frame-executive = { workspace = true } frame-metadata-hash-extension = { workspace = true } frame-system = { workspace = true } diff --git a/substrate/test-utils/runtime/src/genesismap.rs b/substrate/test-utils/runtime/src/genesismap.rs index 1e20699e2faa..9e972886b377 100644 --- a/substrate/test-utils/runtime/src/genesismap.rs +++ b/substrate/test-utils/runtime/src/genesismap.rs @@ -130,7 +130,7 @@ impl GenesisStorageBuilder { authorities: authorities_sr25519.clone(), ..Default::default() }, - balances: pallet_balances::GenesisConfig { balances: self.balances.clone(), ..Default::default() }, + balances: pallet_balances::GenesisConfig { balances: self.balances.clone() }, } } From be5acd623f42dc1d41cddd66055c6f2403ee8c12 Mon Sep 17 00:00:00 2001 From: runcomet Date: Fri, 27 Dec 2024 05:39:02 -0800 Subject: [PATCH 13/21] remove feature flag --- substrate/frame/balances/src/lib.rs | 33 +++++++---------------- substrate/frame/balances/src/tests/mod.rs | 7 ----- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index e875796af16e..285b28f96795 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -180,10 +180,7 @@ use sp_runtime::{ }, ArithmeticError, DispatchError, FixedPointOperand, Perbill, RuntimeDebug, TokenError, }; - -#[cfg(feature = "runtime-benchmarks")] use sp_core::{sr25519::Pair as SrPair, Pair}; -#[cfg(feature = "runtime-benchmarks")] use alloc::{format, string::{String, ToString}}; pub use types::{ @@ -511,8 +508,6 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig, I: 'static = ()> { pub balances: Vec<(T::AccountId, T::Balance)>, - - #[cfg(feature = "runtime-benchmarks")] pub dev_accounts: (u32, T::Balance, Option), } @@ -520,8 +515,6 @@ pub mod pallet { fn default() -> Self { Self { balances: Default::default(), - - #[cfg(feature = "runtime-benchmarks")] dev_accounts: (One::one(), >::ExistentialDeposit::get(), Some("//Sender/{}".to_string())), } } @@ -555,19 +548,14 @@ pub mod pallet { ); // Generate additional dev accounts. - #[cfg(feature = "runtime-benchmarks")] - { - let (num_accounts, balance, ref derivation) = self.dev_accounts; + let (num_accounts, balance, ref derivation) = self.dev_accounts; - // Check if `derivation` is `Some` and generate key pair - if let Some(derivation_string) = &derivation { - Pallet::::derive_dev_account(num_accounts, balance, derivation_string); - } else { - // Derivation string is missing, using default.. - let default_derivation = "//Sender/{}".to_string(); - - Pallet::::derive_dev_account(num_accounts, balance, &default_derivation); - } + // Check if `derivation` is `Some` and generate key pair + if let Some(derivation_string) = derivation { + Pallet::::derive_dev_account(num_accounts, balance, derivation_string); + } else { + // Derivation string is missing, using default.. + Pallet::::derive_dev_account(num_accounts, balance, derivation.as_deref().unwrap_or("//Sender/{}")); } for &(ref who, free) in self.balances.iter() { @@ -1280,8 +1268,7 @@ pub mod pallet { } /// Generate dev account from derivation string. - #[cfg(feature = "runtime-benchmarks")] - pub fn derive_dev_account(num_accounts: u32, balance: T::Balance, derivation: &String) { + pub fn derive_dev_account(num_accounts: u32, balance: T::Balance, derivation: &str) { // Ensure that the number of accounts is not zero assert!(num_accounts > 0, "num_accounts must be greater than zero"); @@ -1292,7 +1279,7 @@ pub mod pallet { assert!( derivation.contains("{}"), - "Invalid derivation string" + "Invalid derivation, expected `{{}}` as part of the derivation" ); for index in 0..num_accounts { @@ -1301,7 +1288,7 @@ pub mod pallet { // Attempt to create the key pair from the derivation string with error handling. let pair: SrPair = Pair::from_string(&derivation_string, None) - .expect(&format!("Failed to parse derivation string: {}", derivation_string)); + .expect(&format!("Failed to parse derivation string: {derivation_string}")); // Convert the public key to AccountId. let who = T::AccountId::decode(&mut &pair.public().encode()[..]) diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index f0f4717b44ff..9bee93b5ab6c 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -42,8 +42,6 @@ use sp_runtime::{ TokenError, }; use std::collections::BTreeSet; - -#[cfg(feature = "runtime-benchmarks")] use sp_core::{sr25519::Pair as SrPair, Pair}; mod currency_tests; @@ -172,7 +170,6 @@ impl ExtBuilder { } else { vec![] }, - #[cfg(feature = "runtime-benchmarks")] dev_accounts: (1000, self.existential_deposit, Some("//Sender/{}".to_string())), } .assimilate_storage(&mut t) @@ -287,13 +284,10 @@ pub fn ensure_ti_valid() { let mut sum = 0; // Fetch the dev accounts from Account Storage. - #[cfg(feature = "runtime-benchmarks")] let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, "//Sender/{}".to_string()); // You can customize this as needed - #[cfg(feature = "runtime-benchmarks")] let (num_accounts, _balance, ref derivation) = dev_accounts; // Generate the dev account public keys. - #[cfg(feature = "runtime-benchmarks")] let dev_account_ids: Vec<_> = (0..num_accounts) .map(|index| { let derivation_string = derivation.replace("{}", &index.to_string()); @@ -310,7 +304,6 @@ pub fn ensure_ti_valid() { for acc in frame_system::Account::::iter_keys() { // Skip dev accounts by checking if the account is in the dev_account_ids list. // This also proves dev_accounts exists in storage. - #[cfg(feature = "runtime-benchmarks")] if dev_account_ids.contains(&acc) { continue; } From fed102ff2c9fe7dbd93255edf4179344f4c25649 Mon Sep 17 00:00:00 2001 From: runcomet Date: Fri, 3 Jan 2025 22:37:41 +0100 Subject: [PATCH 14/21] mutate_account --- bridges/modules/messages/src/tests/mock.rs | 9 +++-- .../assets/asset-hub-rococo/src/genesis.rs | 1 + .../assets/asset-hub-westend/src/genesis.rs | 1 + .../bridges/bridge-hub-rococo/src/genesis.rs | 1 + .../bridges/bridge-hub-westend/src/genesis.rs | 1 + .../collectives-westend/src/genesis.rs | 1 + .../coretime/coretime-rococo/src/genesis.rs | 1 + .../coretime/coretime-westend/src/genesis.rs | 1 + .../people/people-rococo/src/genesis.rs | 1 + .../people/people-westend/src/genesis.rs | 1 + .../parachains/testing/penpal/src/genesis.rs | 1 + .../chains/relays/rococo/src/genesis.rs | 1 + .../chains/relays/westend/src/genesis.rs | 1 + .../parachains/runtimes/test-utils/src/lib.rs | 2 +- .../relay_token_transactor/network.rs | 9 +++-- substrate/bin/node/testing/src/genesis.rs | 2 +- substrate/frame/balances/src/lib.rs | 37 ++++++++++++------- substrate/frame/balances/src/tests/mod.rs | 3 +- substrate/frame/bounties/src/tests.rs | 14 +++++-- substrate/frame/collective/src/tests.rs | 5 ++- substrate/frame/safe-mode/src/mock.rs | 3 +- .../frame/state-trie-migration/src/lib.rs | 9 +++-- substrate/frame/tips/src/tests.rs | 5 ++- substrate/frame/treasury/src/tests.rs | 9 +++-- .../test-utils/runtime/src/genesismap.rs | 2 +- 25 files changed, 84 insertions(+), 37 deletions(-) diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index d962fc1dc928..8eebdf3a5081 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -461,9 +461,12 @@ pub fn inbound_unrewarded_relayers_state(lane: TestLaneIdType) -> UnrewardedRela /// Return test externalities to use in tests. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(ENDOWED_ACCOUNT, 1_000_000)], ..Default::default() } - .assimilate_storage(&mut t) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(ENDOWED_ACCOUNT, 1_000_000)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); sp_io::TestExternalities::new(t) } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/genesis.rs index 3ffb9a704b46..4a10a1e10c73 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/genesis.rs @@ -42,6 +42,7 @@ pub fn genesis() -> Storage { .cloned() .map(|k| (k, ED * 4096 * 4096)) .collect(), + ..Default::default() }, parachain_info: asset_hub_rococo_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/genesis.rs index ef7997322da7..0473686081e7 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/genesis.rs @@ -39,6 +39,7 @@ pub fn genesis() -> Storage { system: asset_hub_westend_runtime::SystemConfig::default(), balances: asset_hub_westend_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: asset_hub_westend_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs index 575017f88bb5..62b2e4eed9e7 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs @@ -33,6 +33,7 @@ pub fn genesis() -> Storage { system: bridge_hub_rococo_runtime::SystemConfig::default(), balances: bridge_hub_rococo_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: bridge_hub_rococo_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs index eb4623084f85..5286110bcab9 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs @@ -33,6 +33,7 @@ pub fn genesis() -> Storage { system: bridge_hub_westend_runtime::SystemConfig::default(), balances: bridge_hub_westend_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: bridge_hub_westend_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/src/genesis.rs index d4ef184ea392..51e065a4ae55 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/src/genesis.rs @@ -30,6 +30,7 @@ pub fn genesis() -> Storage { system: collectives_westend_runtime::SystemConfig::default(), balances: collectives_westend_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: collectives_westend_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-rococo/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-rococo/src/genesis.rs index e0f035c368e3..f2035c8654d0 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-rococo/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-rococo/src/genesis.rs @@ -30,6 +30,7 @@ pub fn genesis() -> Storage { system: coretime_rococo_runtime::SystemConfig::default(), balances: coretime_rococo_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: coretime_rococo_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-westend/src/genesis.rs index 239ad3760c11..29894222eff7 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/coretime/coretime-westend/src/genesis.rs @@ -30,6 +30,7 @@ pub fn genesis() -> Storage { system: coretime_westend_runtime::SystemConfig::default(), balances: coretime_westend_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: coretime_westend_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/src/genesis.rs index 36a701d24c27..9772a64d23b3 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/src/genesis.rs @@ -31,6 +31,7 @@ pub fn genesis() -> Storage { system: people_rococo_runtime::SystemConfig::default(), balances: people_rococo_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: people_rococo_runtime::ParachainInfoConfig { parachain_id: ParaId::from(PARA_ID), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/src/genesis.rs index 942ec1b31d2b..377babc59f65 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/src/genesis.rs @@ -31,6 +31,7 @@ pub fn genesis() -> Storage { system: people_westend_runtime::SystemConfig::default(), balances: people_westend_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: people_westend_runtime::ParachainInfoConfig { parachain_id: ParaId::from(PARA_ID), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/genesis.rs index 63510d233d2c..e514d0cb7477 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/genesis.rs @@ -40,6 +40,7 @@ pub fn genesis(para_id: u32) -> Storage { system: penpal_runtime::SystemConfig::default(), balances: penpal_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ED * 4096)).collect(), + ..Default::default() }, parachain_info: penpal_runtime::ParachainInfoConfig { parachain_id: para_id.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/genesis.rs index 3d8b5b1a500f..db9fe19dbdd7 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/genesis.rs @@ -57,6 +57,7 @@ pub fn genesis() -> Storage { system: rococo_runtime::SystemConfig::default(), balances: rococo_runtime::BalancesConfig { balances: accounts::init_balances().iter().map(|k| (k.clone(), ENDOWMENT)).collect(), + ..Default::default() }, session: rococo_runtime::SessionConfig { keys: validators::initial_authorities() diff --git a/cumulus/parachains/integration-tests/emulated/chains/relays/westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/relays/westend/src/genesis.rs index f8d43cf4648d..2f02ca5f1932 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/relays/westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/relays/westend/src/genesis.rs @@ -58,6 +58,7 @@ pub fn genesis() -> Storage { system: westend_runtime::SystemConfig::default(), balances: westend_runtime::BalancesConfig { balances: accounts::init_balances().iter().cloned().map(|k| (k, ENDOWMENT)).collect(), + ..Default::default() }, session: westend_runtime::SessionConfig { keys: validators::initial_authorities() diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 5c33809ba67b..b46a68312aa1 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -230,7 +230,7 @@ impl ExtBuilder { .unwrap(); } - pallet_balances::GenesisConfig:: { balances: self.balances } + pallet_balances::GenesisConfig:: { balances: self.balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/xcm/docs/src/cookbook/relay_token_transactor/network.rs b/polkadot/xcm/docs/src/cookbook/relay_token_transactor/network.rs index 46ac0e5df637..71c14f6b241b 100644 --- a/polkadot/xcm/docs/src/cookbook/relay_token_transactor/network.rs +++ b/polkadot/xcm/docs/src/cookbook/relay_token_transactor/network.rs @@ -78,9 +78,12 @@ pub fn relay_ext() -> TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE)] } - .assimilate_storage(&mut t) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INITIAL_BALANCE)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); let mut ext = TestExternalities::new(t); ext.execute_with(|| { diff --git a/substrate/bin/node/testing/src/genesis.rs b/substrate/bin/node/testing/src/genesis.rs index 7f5364744c66..606349e0bd6b 100644 --- a/substrate/bin/node/testing/src/genesis.rs +++ b/substrate/bin/node/testing/src/genesis.rs @@ -47,7 +47,7 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig { RuntimeGenesisConfig { indices: IndicesConfig { indices: vec![] }, - balances: BalancesConfig { balances: endowed }, + balances: BalancesConfig { balances: endowed, ..Default::default() }, session: SessionConfig { keys: vec![ (alice(), dave(), session_keys_from_seed(Ed25519Keyring::Alice.into())), diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 285b28f96795..b22eb44cf3b1 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -152,7 +152,11 @@ pub mod weights; extern crate alloc; -use alloc::vec::Vec; +use alloc::{ + format, + string::{String, ToString}, + vec::Vec, +}; use codec::{Codec, MaxEncodedLen}; use core::{cmp, fmt::Debug, mem, result}; use frame_support::{ @@ -173,6 +177,7 @@ use frame_support::{ use frame_system as system; pub use impl_currency::{NegativeImbalance, PositiveImbalance}; use scale_info::TypeInfo; +use sp_core::{sr25519::Pair as SrPair, Pair}; use sp_runtime::{ traits::{ AtLeast32BitUnsigned, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Saturating, @@ -180,8 +185,6 @@ use sp_runtime::{ }, ArithmeticError, DispatchError, FixedPointOperand, Perbill, RuntimeDebug, TokenError, }; -use sp_core::{sr25519::Pair as SrPair, Pair}; -use alloc::{format, string::{String, ToString}}; pub use types::{ AccountData, AdjustmentDirection, BalanceLock, DustCleaner, ExtraFlags, Reasons, ReserveData, @@ -508,6 +511,12 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig, I: 'static = ()> { pub balances: Vec<(T::AccountId, T::Balance)>, + /// Derived development accounts: + /// - `u32`: The number of development accounts to generate. + /// - `T::Balance`: The initial balance assigned to each development account. + /// - `Option`: An optional derivation string template. + /// - Must include `{}` as a placeholder for account indices. + /// - Defaults to `"//Sender/{}`" if `None`. pub dev_accounts: (u32, T::Balance, Option), } @@ -515,7 +524,11 @@ pub mod pallet { fn default() -> Self { Self { balances: Default::default(), - dev_accounts: (One::one(), >::ExistentialDeposit::get(), Some("//Sender/{}".to_string())), + dev_accounts: ( + One::one(), + >::ExistentialDeposit::get(), + Some("//Sender/{}".to_string()), + ), } } } @@ -555,7 +568,7 @@ pub mod pallet { Pallet::::derive_dev_account(num_accounts, balance, derivation_string); } else { // Derivation string is missing, using default.. - Pallet::::derive_dev_account(num_accounts, balance, derivation.as_deref().unwrap_or("//Sender/{}")); + Pallet::::derive_dev_account(num_accounts, balance, "//Sender/{}"); } for &(ref who, free) in self.balances.iter() { @@ -1286,7 +1299,7 @@ pub mod pallet { // Replace "{}" in the derivation string with the index. let derivation_string = derivation.replace("{}", &index.to_string()); - // Attempt to create the key pair from the derivation string with error handling. + // Generate the key pair from the derivation string using sr25519. let pair: SrPair = Pair::from_string(&derivation_string, None) .expect(&format!("Failed to parse derivation string: {derivation_string}")); @@ -1294,13 +1307,11 @@ pub mod pallet { let who = T::AccountId::decode(&mut &pair.public().encode()[..]) .expect(&format!("Failed to decode public key from pair: {:?}", pair.public())); - frame_system::Pallet::::inc_providers(&who); - // Insert the account into the store and ensure it succeeds(uri). - assert!(T::AccountStore::insert( - &who, - AccountData { free: balance, ..Default::default() } - ) - .is_ok()); + // Set the balance for the generated account. + Self::mutate_account_handling_dust(&who, |account| { + account.free = balance; + }) + .expect(&format!("Failed to add account to keystore: {:?}", who)); } } } diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 9bee93b5ab6c..491a70e5f813 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -34,7 +34,7 @@ use frame_support::{ use frame_system::{self as system, RawOrigin}; use pallet_transaction_payment::{ChargeTransactionPayment, FungibleAdapter, Multiplier}; use scale_info::TypeInfo; -use sp_core::hexdisplay::HexDisplay; +use sp_core::{hexdisplay::HexDisplay, sr25519::Pair as SrPair, Pair}; use sp_io; use sp_runtime::{ traits::{BadOrigin, Zero}, @@ -42,7 +42,6 @@ use sp_runtime::{ TokenError, }; use std::collections::BTreeSet; -use sp_core::{sr25519::Pair as SrPair, Pair}; mod currency_tests; mod dispatchable_tests; diff --git a/substrate/frame/bounties/src/tests.rs b/substrate/frame/bounties/src/tests.rs index 704a75e3bac1..c9f6c1319ed1 100644 --- a/substrate/frame/bounties/src/tests.rs +++ b/substrate/frame/bounties/src/tests.rs @@ -187,7 +187,10 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], ..Default::default() }, + balances: pallet_balances::GenesisConfig { + balances: vec![(0, 100), (1, 98), (2, 1)], + ..Default::default() + }, treasury: Default::default(), treasury_1: Default::default(), } @@ -338,9 +341,12 @@ fn treasury_account_doesnt_get_deleted() { #[allow(deprecated)] fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], ..Default::default() } - .assimilate_storage(&mut t) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(0, 100), (1, 99), (2, 1)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); // Treasury genesis config is not build thus treasury account does not exist let mut t: sp_io::TestExternalities = t.into(); diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index 23ea0f79d67e..300d5ad3772a 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -203,7 +203,10 @@ impl ExtBuilder { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), // balances: pallet_balances::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(1, 100), (2, 200)], ..Default::default() }, + balances: pallet_balances::GenesisConfig { + balances: vec![(1, 100), (2, 200)], + ..Default::default() + }, collective: pallet_collective::GenesisConfig { members: self.collective_members, phantom: Default::default(), diff --git a/substrate/frame/safe-mode/src/mock.rs b/substrate/frame/safe-mode/src/mock.rs index 4d9469841b90..2980f86abc28 100644 --- a/substrate/frame/safe-mode/src/mock.rs +++ b/substrate/frame/safe-mode/src/mock.rs @@ -232,7 +232,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig:: { // The 0 account is NOT a special origin, the rest may be. - balances: vec![(0, BAL_ACC0), (1, BAL_ACC1), (2, 5678), (3, 5678), (4, 5678)], ..Default::default() + balances: vec![(0, BAL_ACC0), (1, BAL_ACC1), (2, 5678), (3, 5678), (4, 5678)], + ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index cd9c358e91c0..d615697b76d8 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -1297,9 +1297,12 @@ mod mock { frame_system::GenesisConfig::::default() .assimilate_storage(&mut custom_storage) .unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 1000)], ..Default::default() } - .assimilate_storage(&mut custom_storage) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 1000)], + ..Default::default() + } + .assimilate_storage(&mut custom_storage) + .unwrap(); } sp_tracing::try_init_simple(); diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs index 85b67bdb1c61..b769ea5b3e75 100644 --- a/substrate/frame/tips/src/tests.rs +++ b/substrate/frame/tips/src/tests.rs @@ -180,7 +180,10 @@ impl Config for Test { pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { system: frame_system::GenesisConfig::default(), - balances: pallet_balances::GenesisConfig { balances: vec![(0, 100), (1, 98), (2, 1)], ..Default::default() }, + balances: pallet_balances::GenesisConfig { + balances: vec![(0, 100), (1, 98), (2, 1)], + ..Default::default() + }, treasury: Default::default(), treasury_1: Default::default(), } diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs index 6f9f3dc68af2..2c2ceac58624 100644 --- a/substrate/frame/treasury/src/tests.rs +++ b/substrate/frame/treasury/src/tests.rs @@ -407,9 +407,12 @@ fn treasury_account_doesnt_get_deleted() { #[test] fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 99), (2, 1)], ..Default::default() } - .assimilate_storage(&mut t) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(0, 100), (1, 99), (2, 1)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); // Treasury genesis config is not build thus treasury account does not exist let mut t: sp_io::TestExternalities = t.into(); diff --git a/substrate/test-utils/runtime/src/genesismap.rs b/substrate/test-utils/runtime/src/genesismap.rs index 5c0c146d45a5..18e438399952 100644 --- a/substrate/test-utils/runtime/src/genesismap.rs +++ b/substrate/test-utils/runtime/src/genesismap.rs @@ -130,7 +130,7 @@ impl GenesisStorageBuilder { authorities: authorities_sr25519.clone(), ..Default::default() }, - balances: pallet_balances::GenesisConfig { balances: self.balances.clone() }, + balances: pallet_balances::GenesisConfig { balances: self.balances.clone(), ..Default::default() }, } } From 5e8f9e7d6861dd47326a61d03f1429f625a01b02 Mon Sep 17 00:00:00 2001 From: runcomet Date: Fri, 3 Jan 2025 23:24:07 +0100 Subject: [PATCH 15/21] update PR doc --- prdoc/pr_6267.prdoc | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/prdoc/pr_6267.prdoc b/prdoc/pr_6267.prdoc index 71478a122ec6..bc791ef0b2c2 100644 --- a/prdoc/pr_6267.prdoc +++ b/prdoc/pr_6267.prdoc @@ -15,6 +15,8 @@ doc: manner. crates: + - name: substrate-test-runtime + bump: minor - name: pallet-vesting bump: minor - name: pallet-utility @@ -99,6 +101,10 @@ crates: bump: minor - name: pallet-alliance bump: minor + - name: node-testing + bump: minor + - name: xcm-simulator-fuzzer + bump: minor - name: xcm-simulator-fuzzer bump: minor - name: xcm-simulator-example @@ -109,8 +115,36 @@ crates: bump: minor - name: pallet-xcm bump: minor + - name: xcm-docs + bump: minor - name: polkadot-runtime-common bump: minor + - name: parachains-runtimes-test-utils + bump: minor + - name: westend-emulated-chain + bump: minor + - name: rococo-emulated-chain + bump: minor + - name: penpal-emulated-chain + bump: minor + - name: people-westend-emulated-chain + bump: minor + - namne: people-rococo-emulated-chain + bump: minor + - name: coretime-westend-emulated-chain + bump: minor + - name: coretime-rococo-emulated-chain + bump: minor + - name: collectives-westend-emulated-chain + bump: minor + - name: bridge-hub-westend-emulated-chain + bump: minor + - name: bridge-hub-rococo-emulated-chain + bump: minor + - name: asset-hub-westend-emulated-chain + bump: minor + - name: asset-hub-rococo-emulated-chain + bump: minor - name: pallet-collator-selection bump: minor - name: pallet-bridge-messages From 0474e2cf0dc8fa45d5693310b50cfae331b62e10 Mon Sep 17 00:00:00 2001 From: runcomet Date: Thu, 9 Jan 2025 14:36:49 +0100 Subject: [PATCH 16/21] as_deref, dev_accounts --- substrate/frame/balances/src/lib.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index b22eb44cf3b1..7734aabe09aa 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -195,6 +195,8 @@ pub use pallet::*; const LOG_TARGET: &str = "runtime::balances"; +const ADDRESS_URI: &str = "//Sender/{}"; + type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; #[frame_support::pallet] @@ -527,7 +529,7 @@ pub mod pallet { dev_accounts: ( One::one(), >::ExistentialDeposit::get(), - Some("//Sender/{}".to_string()), + Some(ADDRESS_URI.to_string()), ), } } @@ -563,13 +565,12 @@ pub mod pallet { // Generate additional dev accounts. let (num_accounts, balance, ref derivation) = self.dev_accounts; - // Check if `derivation` is `Some` and generate key pair - if let Some(derivation_string) = derivation { - Pallet::::derive_dev_account(num_accounts, balance, derivation_string); - } else { - // Derivation string is missing, using default.. - Pallet::::derive_dev_account(num_accounts, balance, "//Sender/{}"); - } + // Use `derivation` (or default) to generate key pair + Pallet::::derive_dev_account( + num_accounts, + balance, + derivation.as_deref().unwrap_or(ADDRESS_URI), + ); for &(ref who, free) in self.balances.iter() { frame_system::Pallet::::inc_providers(who); From 00a7a0f879ac585a3b1f3f6ac8e525511e103ee5 Mon Sep 17 00:00:00 2001 From: runcomet Date: Thu, 9 Jan 2025 15:02:26 +0100 Subject: [PATCH 17/21] DEFAULT_ADDRESS_URI --- substrate/frame/balances/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 7734aabe09aa..9e30ad005b4c 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -195,7 +195,7 @@ pub use pallet::*; const LOG_TARGET: &str = "runtime::balances"; -const ADDRESS_URI: &str = "//Sender/{}"; +const DEFAULT_ADDRESS_URI: &str = "//Sender/{}"; type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; @@ -529,7 +529,7 @@ pub mod pallet { dev_accounts: ( One::one(), >::ExistentialDeposit::get(), - Some(ADDRESS_URI.to_string()), + Some(DEFAULT_ADDRESS_URI.to_string()), ), } } @@ -569,7 +569,7 @@ pub mod pallet { Pallet::::derive_dev_account( num_accounts, balance, - derivation.as_deref().unwrap_or(ADDRESS_URI), + derivation.as_deref().unwrap_or(DEFAULT_ADDRESS_URI), ); for &(ref who, free) in self.balances.iter() { From 88fc87aec31264abf2958c9385e3bb519e5bbe87 Mon Sep 17 00:00:00 2001 From: runcomet Date: Sat, 11 Jan 2025 00:57:37 +0100 Subject: [PATCH 18/21] fix conficts + Optional dev_accounts + hard derivation --- polkadot/runtime/common/src/auctions.rs | 1981 ----------------- .../common/src/auctions/benchmarking.rs | 282 +++ polkadot/runtime/common/src/auctions/mock.rs | 259 +++ polkadot/runtime/common/src/auctions/mod.rs | 677 ++++++ polkadot/runtime/common/src/auctions/tests.rs | 821 +++++++ .../src/paras_registrar/benchmarking.rs | 171 ++ .../common/src/paras_registrar/mock.rs | 255 +++ .../runtime/common/src/paras_registrar/mod.rs | 997 +-------- .../common/src/paras_registrar/tests.rs | 588 +++++ substrate/frame/balances/Cargo.toml | 14 +- substrate/frame/balances/src/lib.rs | 43 +- substrate/frame/balances/src/tests/mod.rs | 13 +- 12 files changed, 3108 insertions(+), 2993 deletions(-) delete mode 100644 polkadot/runtime/common/src/auctions.rs create mode 100644 polkadot/runtime/common/src/auctions/benchmarking.rs create mode 100644 polkadot/runtime/common/src/auctions/mock.rs create mode 100644 polkadot/runtime/common/src/auctions/mod.rs create mode 100644 polkadot/runtime/common/src/auctions/tests.rs create mode 100644 polkadot/runtime/common/src/paras_registrar/benchmarking.rs create mode 100644 polkadot/runtime/common/src/paras_registrar/mock.rs create mode 100644 polkadot/runtime/common/src/paras_registrar/tests.rs diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs deleted file mode 100644 index 1f04378a8887..000000000000 --- a/polkadot/runtime/common/src/auctions.rs +++ /dev/null @@ -1,1981 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot 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. - -// Polkadot 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 Polkadot. If not, see . - -//! Auctioning system to determine the set of Parachains in operation. This includes logic for the -//! auctioning mechanism and for reserving balance as part of the "payment". Unreserving the balance -//! happens elsewhere. - -use crate::{ - slot_range::SlotRange, - traits::{AuctionStatus, Auctioneer, LeaseError, Leaser, Registrar}, -}; -use alloc::{vec, vec::Vec}; -use codec::Decode; -use core::mem::swap; -use frame_support::{ - dispatch::DispatchResult, - ensure, - traits::{Currency, Get, Randomness, ReservableCurrency}, - weights::Weight, -}; -use frame_system::pallet_prelude::BlockNumberFor; -pub use pallet::*; -use polkadot_primitives::Id as ParaId; -use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; - -type CurrencyOf = <::Leaser as Leaser>>::Currency; -type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< - ::AccountId, ->>::Balance; - -pub trait WeightInfo { - fn new_auction() -> Weight; - fn bid() -> Weight; - fn cancel_auction() -> Weight; - fn on_initialize() -> Weight; -} - -pub struct TestWeightInfo; -impl WeightInfo for TestWeightInfo { - fn new_auction() -> Weight { - Weight::zero() - } - fn bid() -> Weight { - Weight::zero() - } - fn cancel_auction() -> Weight { - Weight::zero() - } - fn on_initialize() -> Weight { - Weight::zero() - } -} - -/// An auction index. We count auctions in this type. -pub type AuctionIndex = u32; - -type LeasePeriodOf = <::Leaser as Leaser>>::LeasePeriod; - -// Winning data type. This encodes the top bidders of each range together with their bid. -type WinningData = [Option<(::AccountId, ParaId, BalanceOf)>; - SlotRange::SLOT_RANGE_COUNT]; -// Winners data type. This encodes each of the final winners of a parachain auction, the parachain -// index assigned to them, their winning bid and the range that they won. -type WinnersData = - Vec<(::AccountId, ParaId, BalanceOf, SlotRange)>; - -#[frame_support::pallet] -pub mod pallet { - use super::*; - use frame_support::{dispatch::DispatchClass, pallet_prelude::*, traits::EnsureOrigin}; - use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; - - #[pallet::pallet] - pub struct Pallet(_); - - /// The module's configuration trait. - #[pallet::config] - pub trait Config: frame_system::Config { - /// The overarching event type. - type RuntimeEvent: From> + IsType<::RuntimeEvent>; - - /// The type representing the leasing system. - type Leaser: Leaser< - BlockNumberFor, - AccountId = Self::AccountId, - LeasePeriod = BlockNumberFor, - >; - - /// The parachain registrar type. - type Registrar: Registrar; - - /// The number of blocks over which an auction may be retroactively ended. - #[pallet::constant] - type EndingPeriod: Get>; - - /// The length of each sample to take during the ending period. - /// - /// `EndingPeriod` / `SampleLength` = Total # of Samples - #[pallet::constant] - type SampleLength: Get>; - - /// Something that provides randomness in the runtime. - type Randomness: Randomness>; - - /// The origin which may initiate auctions. - type InitiateOrigin: EnsureOrigin; - - /// Weight Information for the Extrinsics in the Pallet - type WeightInfo: WeightInfo; - } - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - /// An auction started. Provides its index and the block number where it will begin to - /// close and the first lease period of the quadruplet that is auctioned. - AuctionStarted { - auction_index: AuctionIndex, - lease_period: LeasePeriodOf, - ending: BlockNumberFor, - }, - /// An auction ended. All funds become unreserved. - AuctionClosed { auction_index: AuctionIndex }, - /// Funds were reserved for a winning bid. First balance is the extra amount reserved. - /// Second is the total. - Reserved { bidder: T::AccountId, extra_reserved: BalanceOf, total_amount: BalanceOf }, - /// Funds were unreserved since bidder is no longer active. `[bidder, amount]` - Unreserved { bidder: T::AccountId, amount: BalanceOf }, - /// Someone attempted to lease the same slot twice for a parachain. The amount is held in - /// reserve but no parachain slot has been leased. - ReserveConfiscated { para_id: ParaId, leaser: T::AccountId, amount: BalanceOf }, - /// A new bid has been accepted as the current winner. - BidAccepted { - bidder: T::AccountId, - para_id: ParaId, - amount: BalanceOf, - first_slot: LeasePeriodOf, - last_slot: LeasePeriodOf, - }, - /// The winning offset was chosen for an auction. This will map into the `Winning` storage - /// map. - WinningOffset { auction_index: AuctionIndex, block_number: BlockNumberFor }, - } - - #[pallet::error] - pub enum Error { - /// This auction is already in progress. - AuctionInProgress, - /// The lease period is in the past. - LeasePeriodInPast, - /// Para is not registered - ParaNotRegistered, - /// Not a current auction. - NotCurrentAuction, - /// Not an auction. - NotAuction, - /// Auction has already ended. - AuctionEnded, - /// The para is already leased out for part of this range. - AlreadyLeasedOut, - } - - /// Number of auctions started so far. - #[pallet::storage] - pub type AuctionCounter = StorageValue<_, AuctionIndex, ValueQuery>; - - /// Information relating to the current auction, if there is one. - /// - /// The first item in the tuple is the lease period index that the first of the four - /// contiguous lease periods on auction is for. The second is the block number when the - /// auction will "begin to end", i.e. the first block of the Ending Period of the auction. - #[pallet::storage] - pub type AuctionInfo = StorageValue<_, (LeasePeriodOf, BlockNumberFor)>; - - /// Amounts currently reserved in the accounts of the bidders currently winning - /// (sub-)ranges. - #[pallet::storage] - pub type ReservedAmounts = - StorageMap<_, Twox64Concat, (T::AccountId, ParaId), BalanceOf>; - - /// The winning bids for each of the 10 ranges at each sample in the final Ending Period of - /// the current auction. The map's key is the 0-based index into the Sample Size. The - /// first sample of the ending period is 0; the last is `Sample Size - 1`. - #[pallet::storage] - pub type Winning = StorageMap<_, Twox64Concat, BlockNumberFor, WinningData>; - - #[pallet::extra_constants] - impl Pallet { - #[pallet::constant_name(SlotRangeCount)] - fn slot_range_count() -> u32 { - SlotRange::SLOT_RANGE_COUNT as u32 - } - - #[pallet::constant_name(LeasePeriodsPerSlot)] - fn lease_periods_per_slot() -> u32 { - SlotRange::LEASE_PERIODS_PER_SLOT as u32 - } - } - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(n: BlockNumberFor) -> Weight { - let mut weight = T::DbWeight::get().reads(1); - - // If the current auction was in its ending period last block, then ensure that the - // (sub-)range winner information is duplicated from the previous block in case no bids - // happened in the last block. - if let AuctionStatus::EndingPeriod(offset, _sub_sample) = Self::auction_status(n) { - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - if !Winning::::contains_key(&offset) { - weight = weight.saturating_add(T::DbWeight::get().writes(1)); - let winning_data = offset - .checked_sub(&One::one()) - .and_then(Winning::::get) - .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); - Winning::::insert(offset, winning_data); - } - } - - // Check to see if an auction just ended. - if let Some((winning_ranges, auction_lease_period_index)) = Self::check_auction_end(n) { - // Auction is ended now. We have the winning ranges and the lease period index which - // acts as the offset. Handle it. - Self::manage_auction_end(auction_lease_period_index, winning_ranges); - weight = weight.saturating_add(T::WeightInfo::on_initialize()); - } - - weight - } - } - - #[pallet::call] - impl Pallet { - /// Create a new auction. - /// - /// This can only happen when there isn't already an auction in progress and may only be - /// called by the root origin. Accepts the `duration` of this auction and the - /// `lease_period_index` of the initial lease period of the four that are to be auctioned. - #[pallet::call_index(0)] - #[pallet::weight((T::WeightInfo::new_auction(), DispatchClass::Operational))] - pub fn new_auction( - origin: OriginFor, - #[pallet::compact] duration: BlockNumberFor, - #[pallet::compact] lease_period_index: LeasePeriodOf, - ) -> DispatchResult { - T::InitiateOrigin::ensure_origin(origin)?; - Self::do_new_auction(duration, lease_period_index) - } - - /// Make a new bid from an account (including a parachain account) for deploying a new - /// parachain. - /// - /// Multiple simultaneous bids from the same bidder are allowed only as long as all active - /// bids overlap each other (i.e. are mutually exclusive). Bids cannot be redacted. - /// - /// - `sub` is the sub-bidder ID, allowing for multiple competing bids to be made by (and - /// funded by) the same account. - /// - `auction_index` is the index of the auction to bid on. Should just be the present - /// value of `AuctionCounter`. - /// - `first_slot` is the first lease period index of the range to bid on. This is the - /// absolute lease period index value, not an auction-specific offset. - /// - `last_slot` is the last lease period index of the range to bid on. This is the - /// absolute lease period index value, not an auction-specific offset. - /// - `amount` is the amount to bid to be held as deposit for the parachain should the - /// bid win. This amount is held throughout the range. - #[pallet::call_index(1)] - #[pallet::weight(T::WeightInfo::bid())] - pub fn bid( - origin: OriginFor, - #[pallet::compact] para: ParaId, - #[pallet::compact] auction_index: AuctionIndex, - #[pallet::compact] first_slot: LeasePeriodOf, - #[pallet::compact] last_slot: LeasePeriodOf, - #[pallet::compact] amount: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::handle_bid(who, para, auction_index, first_slot, last_slot, amount)?; - Ok(()) - } - - /// Cancel an in-progress auction. - /// - /// Can only be called by Root origin. - #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::cancel_auction())] - pub fn cancel_auction(origin: OriginFor) -> DispatchResult { - ensure_root(origin)?; - // Unreserve all bids. - for ((bidder, _), amount) in ReservedAmounts::::drain() { - CurrencyOf::::unreserve(&bidder, amount); - } - #[allow(deprecated)] - Winning::::remove_all(None); - AuctionInfo::::kill(); - Ok(()) - } - } -} - -impl Auctioneer> for Pallet { - type AccountId = T::AccountId; - type LeasePeriod = BlockNumberFor; - type Currency = CurrencyOf; - - fn new_auction( - duration: BlockNumberFor, - lease_period_index: LeasePeriodOf, - ) -> DispatchResult { - Self::do_new_auction(duration, lease_period_index) - } - - // Returns the status of the auction given the current block number. - fn auction_status(now: BlockNumberFor) -> AuctionStatus> { - let early_end = match AuctionInfo::::get() { - Some((_, early_end)) => early_end, - None => return AuctionStatus::NotStarted, - }; - - let after_early_end = match now.checked_sub(&early_end) { - Some(after_early_end) => after_early_end, - None => return AuctionStatus::StartingPeriod, - }; - - let ending_period = T::EndingPeriod::get(); - if after_early_end < ending_period { - let sample_length = T::SampleLength::get().max(One::one()); - let sample = after_early_end / sample_length; - let sub_sample = after_early_end % sample_length; - return AuctionStatus::EndingPeriod(sample, sub_sample); - } else { - // This is safe because of the comparison operator above - return AuctionStatus::VrfDelay(after_early_end - ending_period); - } - } - - fn place_bid( - bidder: T::AccountId, - para: ParaId, - first_slot: LeasePeriodOf, - last_slot: LeasePeriodOf, - amount: BalanceOf, - ) -> DispatchResult { - Self::handle_bid(bidder, para, AuctionCounter::::get(), first_slot, last_slot, amount) - } - - fn lease_period_index(b: BlockNumberFor) -> Option<(Self::LeasePeriod, bool)> { - T::Leaser::lease_period_index(b) - } - - #[cfg(any(feature = "runtime-benchmarks", test))] - fn lease_period_length() -> (BlockNumberFor, BlockNumberFor) { - T::Leaser::lease_period_length() - } - - fn has_won_an_auction(para: ParaId, bidder: &T::AccountId) -> bool { - !T::Leaser::deposit_held(para, bidder).is_zero() - } -} - -impl Pallet { - // A trick to allow me to initialize large arrays with nothing in them. - const EMPTY: Option<(::AccountId, ParaId, BalanceOf)> = None; - - /// Create a new auction. - /// - /// This can only happen when there isn't already an auction in progress. Accepts the `duration` - /// of this auction and the `lease_period_index` of the initial lease period of the four that - /// are to be auctioned. - fn do_new_auction( - duration: BlockNumberFor, - lease_period_index: LeasePeriodOf, - ) -> DispatchResult { - let maybe_auction = AuctionInfo::::get(); - ensure!(maybe_auction.is_none(), Error::::AuctionInProgress); - let now = frame_system::Pallet::::block_number(); - if let Some((current_lease_period, _)) = T::Leaser::lease_period_index(now) { - // If there is no active lease period, then we don't need to make this check. - ensure!(lease_period_index >= current_lease_period, Error::::LeasePeriodInPast); - } - - // Bump the counter. - let n = AuctionCounter::::mutate(|n| { - *n += 1; - *n - }); - - // Set the information. - let ending = frame_system::Pallet::::block_number().saturating_add(duration); - AuctionInfo::::put((lease_period_index, ending)); - - Self::deposit_event(Event::::AuctionStarted { - auction_index: n, - lease_period: lease_period_index, - ending, - }); - Ok(()) - } - - /// Actually place a bid in the current auction. - /// - /// - `bidder`: The account that will be funding this bid. - /// - `auction_index`: The auction index of the bid. For this to succeed, must equal - /// the current value of `AuctionCounter`. - /// - `first_slot`: The first lease period index of the range to be bid on. - /// - `last_slot`: The last lease period index of the range to be bid on (inclusive). - /// - `amount`: The total amount to be the bid for deposit over the range. - pub fn handle_bid( - bidder: T::AccountId, - para: ParaId, - auction_index: u32, - first_slot: LeasePeriodOf, - last_slot: LeasePeriodOf, - amount: BalanceOf, - ) -> DispatchResult { - // Ensure para is registered before placing a bid on it. - ensure!(T::Registrar::is_registered(para), Error::::ParaNotRegistered); - // Bidding on latest auction. - ensure!(auction_index == AuctionCounter::::get(), Error::::NotCurrentAuction); - // Assume it's actually an auction (this should never fail because of above). - let (first_lease_period, _) = AuctionInfo::::get().ok_or(Error::::NotAuction)?; - - // Get the auction status and the current sample block. For the starting period, the sample - // block is zero. - let auction_status = Self::auction_status(frame_system::Pallet::::block_number()); - // The offset into the ending samples of the auction. - let offset = match auction_status { - AuctionStatus::NotStarted => return Err(Error::::AuctionEnded.into()), - AuctionStatus::StartingPeriod => Zero::zero(), - AuctionStatus::EndingPeriod(o, _) => o, - AuctionStatus::VrfDelay(_) => return Err(Error::::AuctionEnded.into()), - }; - - // We also make sure that the bid is not for any existing leases the para already has. - ensure!( - !T::Leaser::already_leased(para, first_slot, last_slot), - Error::::AlreadyLeasedOut - ); - - // Our range. - let range = SlotRange::new_bounded(first_lease_period, first_slot, last_slot)?; - // Range as an array index. - let range_index = range as u8 as usize; - - // The current winning ranges. - let mut current_winning = Winning::::get(offset) - .or_else(|| offset.checked_sub(&One::one()).and_then(Winning::::get)) - .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); - - // If this bid beat the previous winner of our range. - if current_winning[range_index].as_ref().map_or(true, |last| amount > last.2) { - // Ok; we are the new winner of this range - reserve the additional amount and record. - - // Get the amount already held on deposit if this is a renewal bid (i.e. there's - // an existing lease on the same para by the same leaser). - let existing_lease_deposit = T::Leaser::deposit_held(para, &bidder); - let reserve_required = amount.saturating_sub(existing_lease_deposit); - - // Get the amount already reserved in any prior and still active bids by us. - let bidder_para = (bidder.clone(), para); - let already_reserved = ReservedAmounts::::get(&bidder_para).unwrap_or_default(); - - // If these don't already cover the bid... - if let Some(additional) = reserve_required.checked_sub(&already_reserved) { - // ...then reserve some more funds from their account, failing if there's not - // enough funds. - CurrencyOf::::reserve(&bidder, additional)?; - // ...and record the amount reserved. - ReservedAmounts::::insert(&bidder_para, reserve_required); - - Self::deposit_event(Event::::Reserved { - bidder: bidder.clone(), - extra_reserved: additional, - total_amount: reserve_required, - }); - } - - // Return any funds reserved for the previous winner if we are not in the ending period - // and they no longer have any active bids. - let mut outgoing_winner = Some((bidder.clone(), para, amount)); - swap(&mut current_winning[range_index], &mut outgoing_winner); - if let Some((who, para, _amount)) = outgoing_winner { - if auction_status.is_starting() && - current_winning - .iter() - .filter_map(Option::as_ref) - .all(|&(ref other, other_para, _)| other != &who || other_para != para) - { - // Previous bidder is no longer winning any ranges: unreserve their funds. - if let Some(amount) = ReservedAmounts::::take(&(who.clone(), para)) { - // It really should be reserved; there's not much we can do here on fail. - let err_amt = CurrencyOf::::unreserve(&who, amount); - debug_assert!(err_amt.is_zero()); - Self::deposit_event(Event::::Unreserved { bidder: who, amount }); - } - } - } - - // Update the range winner. - Winning::::insert(offset, ¤t_winning); - Self::deposit_event(Event::::BidAccepted { - bidder, - para_id: para, - amount, - first_slot, - last_slot, - }); - } - Ok(()) - } - - /// Some when the auction's end is known (with the end block number). None if it is unknown. - /// If `Some` then the block number must be at most the previous block and at least the - /// previous block minus `T::EndingPeriod::get()`. - /// - /// This mutates the state, cleaning up `AuctionInfo` and `Winning` in the case of an auction - /// ending. An immediately subsequent call with the same argument will always return `None`. - fn check_auction_end(now: BlockNumberFor) -> Option<(WinningData, LeasePeriodOf)> { - if let Some((lease_period_index, early_end)) = AuctionInfo::::get() { - let ending_period = T::EndingPeriod::get(); - let late_end = early_end.saturating_add(ending_period); - let is_ended = now >= late_end; - if is_ended { - // auction definitely ended. - // check to see if we can determine the actual ending point. - let (raw_offset, known_since) = T::Randomness::random(&b"para_auction"[..]); - - if late_end <= known_since { - // Our random seed was known only after the auction ended. Good to use. - let raw_offset_block_number = >::decode( - &mut raw_offset.as_ref(), - ) - .expect("secure hashes should always be bigger than the block number; qed"); - let offset = (raw_offset_block_number % ending_period) / - T::SampleLength::get().max(One::one()); - - let auction_counter = AuctionCounter::::get(); - Self::deposit_event(Event::::WinningOffset { - auction_index: auction_counter, - block_number: offset, - }); - let res = Winning::::get(offset) - .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); - // This `remove_all` statement should remove at most `EndingPeriod` / - // `SampleLength` items, which should be bounded and sensibly configured in the - // runtime. - #[allow(deprecated)] - Winning::::remove_all(None); - AuctionInfo::::kill(); - return Some((res, lease_period_index)); - } - } - } - None - } - - /// Auction just ended. We have the current lease period, the auction's lease period (which - /// is guaranteed to be at least the current period) and the bidders that were winning each - /// range at the time of the auction's close. - fn manage_auction_end( - auction_lease_period_index: LeasePeriodOf, - winning_ranges: WinningData, - ) { - // First, unreserve all amounts that were reserved for the bids. We will later re-reserve - // the amounts from the bidders that ended up being assigned the slot so there's no need to - // special-case them here. - for ((bidder, _), amount) in ReservedAmounts::::drain() { - CurrencyOf::::unreserve(&bidder, amount); - } - - // Next, calculate the winning combination of slots and thus the final winners of the - // auction. - let winners = Self::calculate_winners(winning_ranges); - - // Go through those winners and re-reserve their bid, updating our table of deposits - // accordingly. - for (leaser, para, amount, range) in winners.into_iter() { - let begin_offset = LeasePeriodOf::::from(range.as_pair().0 as u32); - let period_begin = auction_lease_period_index + begin_offset; - let period_count = LeasePeriodOf::::from(range.len() as u32); - - match T::Leaser::lease_out(para, &leaser, amount, period_begin, period_count) { - Err(LeaseError::ReserveFailed) | - Err(LeaseError::AlreadyEnded) | - Err(LeaseError::NoLeasePeriod) => { - // Should never happen since we just unreserved this amount (and our offset is - // from the present period). But if it does, there's not much we can do. - }, - Err(LeaseError::AlreadyLeased) => { - // The leaser attempted to get a second lease on the same para ID, possibly - // griefing us. Let's keep the amount reserved and let governance sort it out. - if CurrencyOf::::reserve(&leaser, amount).is_ok() { - Self::deposit_event(Event::::ReserveConfiscated { - para_id: para, - leaser, - amount, - }); - } - }, - Ok(()) => {}, // Nothing to report. - } - } - - Self::deposit_event(Event::::AuctionClosed { - auction_index: AuctionCounter::::get(), - }); - } - - /// Calculate the final winners from the winning slots. - /// - /// This is a simple dynamic programming algorithm designed by Al, the original code is at: - /// `https://github.com/w3f/consensus/blob/master/NPoS/auctiondynamicthing.py` - fn calculate_winners(mut winning: WinningData) -> WinnersData { - let winning_ranges = { - let mut best_winners_ending_at: [(Vec, BalanceOf); - SlotRange::LEASE_PERIODS_PER_SLOT] = Default::default(); - let best_bid = |range: SlotRange| { - winning[range as u8 as usize] - .as_ref() - .map(|(_, _, amount)| *amount * (range.len() as u32).into()) - }; - for i in 0..SlotRange::LEASE_PERIODS_PER_SLOT { - let r = SlotRange::new_bounded(0, 0, i as u32).expect("`i < LPPS`; qed"); - if let Some(bid) = best_bid(r) { - best_winners_ending_at[i] = (vec![r], bid); - } - for j in 0..i { - let r = SlotRange::new_bounded(0, j as u32 + 1, i as u32) - .expect("`i < LPPS`; `j < i`; `j + 1 < LPPS`; qed"); - if let Some(mut bid) = best_bid(r) { - bid += best_winners_ending_at[j].1; - if bid > best_winners_ending_at[i].1 { - let mut new_winners = best_winners_ending_at[j].0.clone(); - new_winners.push(r); - best_winners_ending_at[i] = (new_winners, bid); - } - } else { - if best_winners_ending_at[j].1 > best_winners_ending_at[i].1 { - best_winners_ending_at[i] = best_winners_ending_at[j].clone(); - } - } - } - } - best_winners_ending_at[SlotRange::LEASE_PERIODS_PER_SLOT - 1].0.clone() - }; - - winning_ranges - .into_iter() - .filter_map(|range| { - winning[range as u8 as usize] - .take() - .map(|(bidder, para, amount)| (bidder, para, amount, range)) - }) - .collect::>() - } -} - -/// tests for this module -#[cfg(test)] -mod tests { - use super::*; - use crate::{auctions, mock::TestRegistrar}; - use frame_support::{ - assert_noop, assert_ok, assert_storage_noop, derive_impl, ord_parameter_types, - parameter_types, - traits::{EitherOfDiverse, OnFinalize, OnInitialize}, - }; - use frame_system::{EnsureRoot, EnsureSignedBy}; - use pallet_balances; - use polkadot_primitives::{BlockNumber, Id as ParaId}; - use polkadot_primitives_test_helpers::{dummy_hash, dummy_head_data, dummy_validation_code}; - use sp_core::H256; - use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, - BuildStorage, - DispatchError::BadOrigin, - }; - use std::{cell::RefCell, collections::BTreeMap}; - - type Block = frame_system::mocking::MockBlockU32; - - frame_support::construct_runtime!( - pub enum Test - { - System: frame_system, - Balances: pallet_balances, - Auctions: auctions, - } - ); - - #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] - impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Nonce = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Block = Block; - type RuntimeEvent = RuntimeEvent; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; - } - - #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] - impl pallet_balances::Config for Test { - type AccountStore = System; - } - - #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)] - pub struct LeaseData { - leaser: u64, - amount: u64, - } - - thread_local! { - pub static LEASES: - RefCell> = RefCell::new(BTreeMap::new()); - } - - fn leases() -> Vec<((ParaId, BlockNumber), LeaseData)> { - LEASES.with(|p| (&*p.borrow()).clone().into_iter().collect::>()) - } - - pub struct TestLeaser; - impl Leaser for TestLeaser { - type AccountId = u64; - type LeasePeriod = BlockNumber; - type Currency = Balances; - - fn lease_out( - para: ParaId, - leaser: &Self::AccountId, - amount: >::Balance, - period_begin: Self::LeasePeriod, - period_count: Self::LeasePeriod, - ) -> Result<(), LeaseError> { - LEASES.with(|l| { - let mut leases = l.borrow_mut(); - let now = System::block_number(); - let (current_lease_period, _) = - Self::lease_period_index(now).ok_or(LeaseError::NoLeasePeriod)?; - if period_begin < current_lease_period { - return Err(LeaseError::AlreadyEnded); - } - for period in period_begin..(period_begin + period_count) { - if leases.contains_key(&(para, period)) { - return Err(LeaseError::AlreadyLeased); - } - leases.insert((para, period), LeaseData { leaser: *leaser, amount }); - } - Ok(()) - }) - } - - fn deposit_held( - para: ParaId, - leaser: &Self::AccountId, - ) -> >::Balance { - leases() - .iter() - .filter_map(|((id, _period), data)| { - if id == ¶ && &data.leaser == leaser { - Some(data.amount) - } else { - None - } - }) - .max() - .unwrap_or_default() - } - - fn lease_period_length() -> (BlockNumber, BlockNumber) { - (10, 0) - } - - fn lease_period_index(b: BlockNumber) -> Option<(Self::LeasePeriod, bool)> { - let (lease_period_length, offset) = Self::lease_period_length(); - let b = b.checked_sub(offset)?; - - let lease_period = b / lease_period_length; - let first_block = (b % lease_period_length).is_zero(); - - Some((lease_period, first_block)) - } - - fn already_leased( - para_id: ParaId, - first_period: Self::LeasePeriod, - last_period: Self::LeasePeriod, - ) -> bool { - leases().into_iter().any(|((para, period), _data)| { - para == para_id && first_period <= period && period <= last_period - }) - } - } - - ord_parameter_types! { - pub const Six: u64 = 6; - } - - type RootOrSix = EitherOfDiverse, EnsureSignedBy>; - - thread_local! { - pub static LAST_RANDOM: RefCell> = RefCell::new(None); - } - fn set_last_random(output: H256, known_since: u32) { - LAST_RANDOM.with(|p| *p.borrow_mut() = Some((output, known_since))) - } - pub struct TestPastRandomness; - impl Randomness for TestPastRandomness { - fn random(_subject: &[u8]) -> (H256, u32) { - LAST_RANDOM.with(|p| { - if let Some((output, known_since)) = &*p.borrow() { - (*output, *known_since) - } else { - (H256::zero(), frame_system::Pallet::::block_number()) - } - }) - } - } - - parameter_types! { - pub static EndingPeriod: BlockNumber = 3; - pub static SampleLength: BlockNumber = 1; - } - - impl Config for Test { - type RuntimeEvent = RuntimeEvent; - type Leaser = TestLeaser; - type Registrar = TestRegistrar; - type EndingPeriod = EndingPeriod; - type SampleLength = SampleLength; - type Randomness = TestPastRandomness; - type InitiateOrigin = RootOrSix; - type WeightInfo = crate::auctions::TestWeightInfo; - } - - // This function basically just builds a genesis storage key/value store according to - // our desired mock up. - pub fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { - balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - ..Default::default() - } - .assimilate_storage(&mut t) - .unwrap(); - let mut ext: sp_io::TestExternalities = t.into(); - ext.execute_with(|| { - // Register para 0, 1, 2, and 3 for tests - assert_ok!(TestRegistrar::::register( - 1, - 0.into(), - dummy_head_data(), - dummy_validation_code() - )); - assert_ok!(TestRegistrar::::register( - 1, - 1.into(), - dummy_head_data(), - dummy_validation_code() - )); - assert_ok!(TestRegistrar::::register( - 1, - 2.into(), - dummy_head_data(), - dummy_validation_code() - )); - assert_ok!(TestRegistrar::::register( - 1, - 3.into(), - dummy_head_data(), - dummy_validation_code() - )); - }); - ext - } - - fn run_to_block(n: BlockNumber) { - while System::block_number() < n { - Auctions::on_finalize(System::block_number()); - Balances::on_finalize(System::block_number()); - System::on_finalize(System::block_number()); - System::set_block_number(System::block_number() + 1); - System::on_initialize(System::block_number()); - Balances::on_initialize(System::block_number()); - Auctions::on_initialize(System::block_number()); - } - } - - #[test] - fn basic_setup_works() { - new_test_ext().execute_with(|| { - assert_eq!(AuctionCounter::::get(), 0); - assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::NotStarted - ); - - run_to_block(10); - - assert_eq!(AuctionCounter::::get(), 0); - assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::NotStarted - ); - }); - } - - #[test] - fn can_start_auction() { - new_test_ext().execute_with(|| { - run_to_block(1); - - assert_noop!(Auctions::new_auction(RuntimeOrigin::signed(1), 5, 1), BadOrigin); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - - assert_eq!(AuctionCounter::::get(), 1); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - }); - } - - #[test] - fn bidding_works() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); - - assert_eq!(Balances::reserved_balance(1), 5); - assert_eq!(Balances::free_balance(1), 5); - assert_eq!( - Winning::::get(0).unwrap()[SlotRange::ZeroThree as u8 as usize], - Some((1, 0.into(), 5)) - ); - }); - } - - #[test] - fn under_bidding_works() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); - - assert_storage_noop!({ - assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 1, 4, 1)); - }); - }); - } - - #[test] - fn over_bidding_works() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 1, 4, 6)); - - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(Balances::free_balance(1), 10); - assert_eq!(Balances::reserved_balance(2), 6); - assert_eq!(Balances::free_balance(2), 14); - assert_eq!( - Winning::::get(0).unwrap()[SlotRange::ZeroThree as u8 as usize], - Some((2, 0.into(), 6)) - ); - }); - } - - #[test] - fn auction_proceeds_correctly() { - new_test_ext().execute_with(|| { - run_to_block(1); - - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - - assert_eq!(AuctionCounter::::get(), 1); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(2); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(3); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(4); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(5); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(6); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(0, 0) - ); - - run_to_block(7); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(1, 0) - ); - - run_to_block(8); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(2, 0) - ); - - run_to_block(9); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::NotStarted - ); - }); - } - - #[test] - fn can_win_auction() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); - assert_eq!(Balances::reserved_balance(1), 1); - assert_eq!(Balances::free_balance(1), 9); - run_to_block(9); - - assert_eq!( - leases(), - vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), - ] - ); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); - }); - } - - #[test] - fn can_win_auction_with_late_randomness() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); - assert_eq!(Balances::reserved_balance(1), 1); - assert_eq!(Balances::free_balance(1), 9); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - run_to_block(8); - // Auction has not yet ended. - assert_eq!(leases(), vec![]); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(2, 0) - ); - // This will prevent the auction's winner from being decided in the next block, since - // the random seed was known before the final bids were made. - set_last_random(H256::zero(), 8); - // Auction definitely ended now, but we don't know exactly when in the last 3 blocks yet - // since no randomness available yet. - run_to_block(9); - // Auction has now ended... But auction winner still not yet decided, so no leases yet. - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::VrfDelay(0) - ); - assert_eq!(leases(), vec![]); - - // Random seed now updated to a value known at block 9, when the auction ended. This - // means that the winner can now be chosen. - set_last_random(H256::zero(), 9); - run_to_block(10); - // Auction ended and winner selected - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::NotStarted - ); - assert_eq!( - leases(), - vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), - ] - ); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); - }); - } - - #[test] - fn can_win_incomplete_auction() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 4, 4, 5)); - run_to_block(9); - - assert_eq!(leases(), vec![((0.into(), 4), LeaseData { leaser: 1, amount: 5 }),]); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); - }); - } - - #[test] - fn should_choose_best_combination() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 2, 3, 4)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), 0.into(), 1, 4, 4, 2)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 1, 1, 4, 2)); - run_to_block(9); - - assert_eq!( - leases(), - vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 2), LeaseData { leaser: 2, amount: 4 }), - ((0.into(), 3), LeaseData { leaser: 2, amount: 4 }), - ((0.into(), 4), LeaseData { leaser: 3, amount: 2 }), - ] - ); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); - assert_eq!(TestLeaser::deposit_held(1.into(), &1), 0); - assert_eq!(TestLeaser::deposit_held(0.into(), &2), 4); - assert_eq!(TestLeaser::deposit_held(0.into(), &3), 2); - }); - } - - #[test] - fn gap_bid_works() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - - // User 1 will make a bid for period 1 and 4 for the same Para 0 - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 4, 4, 4)); - - // User 2 and 3 will make a bid for para 1 on period 2 and 3 respectively - assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 1.into(), 1, 2, 2, 2)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), 1.into(), 1, 3, 3, 3)); - - // Total reserved should be the max of the two - assert_eq!(Balances::reserved_balance(1), 4); - - // Other people are reserved correctly too - assert_eq!(Balances::reserved_balance(2), 2); - assert_eq!(Balances::reserved_balance(3), 3); - - // End the auction. - run_to_block(9); - - assert_eq!( - leases(), - vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 4), LeaseData { leaser: 1, amount: 4 }), - ((1.into(), 2), LeaseData { leaser: 2, amount: 2 }), - ((1.into(), 3), LeaseData { leaser: 3, amount: 3 }), - ] - ); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 4); - assert_eq!(TestLeaser::deposit_held(1.into(), &2), 2); - assert_eq!(TestLeaser::deposit_held(1.into(), &3), 3); - }); - } - - #[test] - fn deposit_credit_should_work() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5)); - assert_eq!(Balances::reserved_balance(1), 5); - run_to_block(10); - - assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); - - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 2)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 2, 2, 6)); - // Only 1 reserved since we have a deposit credit of 5. - assert_eq!(Balances::reserved_balance(1), 1); - run_to_block(20); - - assert_eq!( - leases(), - vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), - ((0.into(), 2), LeaseData { leaser: 1, amount: 6 }), - ] - ); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 6); - }); - } - - #[test] - fn deposit_credit_on_alt_para_should_not_count() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5)); - assert_eq!(Balances::reserved_balance(1), 5); - run_to_block(10); - - assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); - - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 2)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 2, 2, 2, 6)); - // 6 reserved since we are bidding on a new para; only works because we don't - assert_eq!(Balances::reserved_balance(1), 6); - run_to_block(20); - - assert_eq!( - leases(), - vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), - ((1.into(), 2), LeaseData { leaser: 1, amount: 6 }), - ] - ); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); - assert_eq!(TestLeaser::deposit_held(1.into(), &1), 6); - }); - } - - #[test] - fn multiple_bids_work_pre_ending() { - new_test_ext().execute_with(|| { - run_to_block(1); - - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - - for i in 1..6u64 { - run_to_block(i as _); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i)); - for j in 1..6 { - assert_eq!(Balances::reserved_balance(j), if j == i { j } else { 0 }); - assert_eq!(Balances::free_balance(j), if j == i { j * 9 } else { j * 10 }); - } - } - - run_to_block(9); - assert_eq!( - leases(), - vec![ - ((0.into(), 1), LeaseData { leaser: 5, amount: 5 }), - ((0.into(), 2), LeaseData { leaser: 5, amount: 5 }), - ((0.into(), 3), LeaseData { leaser: 5, amount: 5 }), - ((0.into(), 4), LeaseData { leaser: 5, amount: 5 }), - ] - ); - }); - } - - #[test] - fn multiple_bids_work_post_ending() { - new_test_ext().execute_with(|| { - run_to_block(1); - - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 0, 1)); - - for i in 1..6u64 { - run_to_block(((i - 1) / 2 + 1) as _); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i)); - for j in 1..6 { - assert_eq!(Balances::reserved_balance(j), if j <= i { j } else { 0 }); - assert_eq!(Balances::free_balance(j), if j <= i { j * 9 } else { j * 10 }); - } - } - for i in 1..6u64 { - assert_eq!(ReservedAmounts::::get((i, ParaId::from(0))).unwrap(), i); - } - - run_to_block(5); - assert_eq!( - leases(), - (1..=4) - .map(|i| ((0.into(), i), LeaseData { leaser: 2, amount: 2 })) - .collect::>() - ); - }); - } - - #[test] - fn incomplete_calculate_winners_works() { - let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; - winning[SlotRange::ThreeThree as u8 as usize] = Some((1, 0.into(), 1)); - - let winners = vec![(1, 0.into(), 1, SlotRange::ThreeThree)]; - - assert_eq!(Auctions::calculate_winners(winning), winners); - } - - #[test] - fn first_incomplete_calculate_winners_works() { - let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; - winning[0] = Some((1, 0.into(), 1)); - - let winners = vec![(1, 0.into(), 1, SlotRange::ZeroZero)]; - - assert_eq!(Auctions::calculate_winners(winning), winners); - } - - #[test] - fn calculate_winners_works() { - let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; - winning[SlotRange::ZeroZero as u8 as usize] = Some((2, 0.into(), 2)); - winning[SlotRange::ZeroThree as u8 as usize] = Some((1, 100.into(), 1)); - winning[SlotRange::OneOne as u8 as usize] = Some((3, 1.into(), 1)); - winning[SlotRange::TwoTwo as u8 as usize] = Some((1, 2.into(), 53)); - winning[SlotRange::ThreeThree as u8 as usize] = Some((5, 3.into(), 1)); - - let winners = vec![ - (2, 0.into(), 2, SlotRange::ZeroZero), - (3, 1.into(), 1, SlotRange::OneOne), - (1, 2.into(), 53, SlotRange::TwoTwo), - (5, 3.into(), 1, SlotRange::ThreeThree), - ]; - assert_eq!(Auctions::calculate_winners(winning), winners); - - winning[SlotRange::ZeroOne as u8 as usize] = Some((4, 10.into(), 3)); - let winners = vec![ - (4, 10.into(), 3, SlotRange::ZeroOne), - (1, 2.into(), 53, SlotRange::TwoTwo), - (5, 3.into(), 1, SlotRange::ThreeThree), - ]; - assert_eq!(Auctions::calculate_winners(winning), winners); - - winning[SlotRange::ZeroThree as u8 as usize] = Some((1, 100.into(), 100)); - let winners = vec![(1, 100.into(), 100, SlotRange::ZeroThree)]; - assert_eq!(Auctions::calculate_winners(winning), winners); - } - - #[test] - fn lower_bids_are_correctly_refunded() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 1, 1)); - let para_1 = ParaId::from(1_u32); - let para_2 = ParaId::from(2_u32); - - // Make a bid and reserve a balance - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 1, 4, 9)); - assert_eq!(Balances::reserved_balance(1), 9); - assert_eq!(ReservedAmounts::::get((1, para_1)), Some(9)); - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(ReservedAmounts::::get((2, para_2)), None); - - // Bigger bid, reserves new balance and returns funds - assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 1, 4, 19)); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(ReservedAmounts::::get((1, para_1)), None); - assert_eq!(Balances::reserved_balance(2), 19); - assert_eq!(ReservedAmounts::::get((2, para_2)), Some(19)); - }); - } - - #[test] - fn initialize_winners_in_ending_period_works() { - new_test_ext().execute_with(|| { - let ed: u64 = ::ExistentialDeposit::get(); - assert_eq!(ed, 1); - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 1)); - let para_1 = ParaId::from(1_u32); - let para_2 = ParaId::from(2_u32); - let para_3 = ParaId::from(3_u32); - - // Make bids - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 1, 4, 9)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 3, 4, 19)); - - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; - winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 9)); - winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19)); - assert_eq!(Winning::::get(0), Some(winning)); - - run_to_block(9); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(10); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(0, 0) - ); - assert_eq!(Winning::::get(0), Some(winning)); - - run_to_block(11); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(1, 0) - ); - assert_eq!(Winning::::get(1), Some(winning)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 3, 4, 29)); - - run_to_block(12); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(2, 0) - ); - winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 29)); - assert_eq!(Winning::::get(2), Some(winning)); - }); - } - - #[test] - fn handle_bid_requires_registered_para() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_noop!( - Auctions::bid(RuntimeOrigin::signed(1), 1337.into(), 1, 1, 4, 1), - Error::::ParaNotRegistered - ); - assert_ok!(TestRegistrar::::register( - 1, - 1337.into(), - dummy_head_data(), - dummy_validation_code() - )); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1337.into(), 1, 1, 4, 1)); - }); - } - - #[test] - fn handle_bid_checks_existing_lease_periods() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 2, 3, 1)); - assert_eq!(Balances::reserved_balance(1), 1); - assert_eq!(Balances::free_balance(1), 9); - run_to_block(9); - - assert_eq!( - leases(), - vec![ - ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), - ] - ); - assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); - - // Para 1 just won an auction above and won some lease periods. - // No bids can work which overlap these periods. - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_noop!( - Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 4, 1), - Error::::AlreadyLeasedOut, - ); - assert_noop!( - Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 2, 1), - Error::::AlreadyLeasedOut, - ); - assert_noop!( - Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 3, 4, 1), - Error::::AlreadyLeasedOut, - ); - // This is okay, not an overlapping bid. - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 1, 1)); - }); - } - - // Here we will test that taking only 10 samples during the ending period works as expected. - #[test] - fn less_winning_samples_work() { - new_test_ext().execute_with(|| { - let ed: u64 = ::ExistentialDeposit::get(); - assert_eq!(ed, 1); - EndingPeriod::set(30); - SampleLength::set(10); - - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11)); - let para_1 = ParaId::from(1_u32); - let para_2 = ParaId::from(2_u32); - let para_3 = ParaId::from(3_u32); - - // Make bids - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 11, 14, 9)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 13, 14, 19)); - - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; - winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 9)); - winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19)); - assert_eq!(Winning::::get(0), Some(winning)); - - run_to_block(9); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(10); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(0, 0) - ); - assert_eq!(Winning::::get(0), Some(winning)); - - // New bids update the current winning - assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 14, 14, 29)); - winning[SlotRange::ThreeThree as u8 as usize] = Some((3, para_3, 29)); - assert_eq!(Winning::::get(0), Some(winning)); - - run_to_block(20); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(1, 0) - ); - assert_eq!(Winning::::get(1), Some(winning)); - run_to_block(25); - // Overbid mid sample - assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 13, 14, 29)); - winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 29)); - assert_eq!(Winning::::get(1), Some(winning)); - - run_to_block(30); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(2, 0) - ); - assert_eq!(Winning::::get(2), Some(winning)); - - set_last_random(H256::from([254; 32]), 40); - run_to_block(40); - // Auction ended and winner selected - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::NotStarted - ); - assert_eq!( - leases(), - vec![ - ((3.into(), 13), LeaseData { leaser: 3, amount: 29 }), - ((3.into(), 14), LeaseData { leaser: 3, amount: 29 }), - ] - ); - }); - } - - #[test] - fn auction_status_works() { - new_test_ext().execute_with(|| { - EndingPeriod::set(30); - SampleLength::set(10); - set_last_random(dummy_hash(), 0); - - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::NotStarted - ); - - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11)); - - run_to_block(9); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::StartingPeriod - ); - - run_to_block(10); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(0, 0) - ); - - run_to_block(11); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(0, 1) - ); - - run_to_block(19); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(0, 9) - ); - - run_to_block(20); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(1, 0) - ); - - run_to_block(25); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(1, 5) - ); - - run_to_block(30); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(2, 0) - ); - - run_to_block(39); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::EndingPeriod(2, 9) - ); - - run_to_block(40); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::VrfDelay(0) - ); - - run_to_block(44); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::VrfDelay(4) - ); - - set_last_random(dummy_hash(), 45); - run_to_block(45); - assert_eq!( - Auctions::auction_status(System::block_number()), - AuctionStatus::::NotStarted - ); - }); - } - - #[test] - fn can_cancel_auction() { - new_test_ext().execute_with(|| { - run_to_block(1); - assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); - assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); - assert_eq!(Balances::reserved_balance(1), 1); - assert_eq!(Balances::free_balance(1), 9); - - assert_noop!(Auctions::cancel_auction(RuntimeOrigin::signed(6)), BadOrigin); - assert_ok!(Auctions::cancel_auction(RuntimeOrigin::root())); - - assert!(AuctionInfo::::get().is_none()); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(ReservedAmounts::::iter().count(), 0); - assert_eq!(Winning::::iter().count(), 0); - }); - } -} - -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking { - use super::{Pallet as Auctions, *}; - use frame_support::{ - assert_ok, - traits::{EnsureOrigin, OnInitialize}, - }; - use frame_system::RawOrigin; - use polkadot_runtime_parachains::paras; - use sp_runtime::{traits::Bounded, SaturatedConversion}; - - use frame_benchmarking::v2::*; - - fn assert_last_event(generic_event: ::RuntimeEvent) { - let events = frame_system::Pallet::::events(); - let system_event: ::RuntimeEvent = generic_event.into(); - // compare to the last event record - let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; - assert_eq!(event, &system_event); - } - - fn fill_winners(lease_period_index: LeasePeriodOf) { - let auction_index = AuctionCounter::::get(); - let minimum_balance = CurrencyOf::::minimum_balance(); - - for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { - let owner = account("owner", n, 0); - let worst_validation_code = T::Registrar::worst_validation_code(); - let worst_head_data = T::Registrar::worst_head_data(); - CurrencyOf::::make_free_balance_be(&owner, BalanceOf::::max_value()); - - assert!(T::Registrar::register( - owner, - ParaId::from(n), - worst_head_data, - worst_validation_code - ) - .is_ok()); - } - assert_ok!(paras::Pallet::::add_trusted_validation_code( - frame_system::Origin::::Root.into(), - T::Registrar::worst_validation_code(), - )); - - T::Registrar::execute_pending_transitions(); - - for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { - let bidder = account("bidder", n, 0); - CurrencyOf::::make_free_balance_be(&bidder, BalanceOf::::max_value()); - - let slot_range = SlotRange::n((n - 1) as u8).unwrap(); - let (start, end) = slot_range.as_pair(); - - assert!(Auctions::::bid( - RawOrigin::Signed(bidder).into(), - ParaId::from(n), - auction_index, - lease_period_index + start.into(), // First Slot - lease_period_index + end.into(), // Last slot - minimum_balance.saturating_mul(n.into()), // Amount - ) - .is_ok()); - } - } - - #[benchmarks( - where T: pallet_babe::Config + paras::Config, - )] - mod benchmarks { - use super::*; - - #[benchmark] - fn new_auction() -> Result<(), BenchmarkError> { - let duration = BlockNumberFor::::max_value(); - let lease_period_index = LeasePeriodOf::::max_value(); - let origin = T::InitiateOrigin::try_successful_origin() - .map_err(|_| BenchmarkError::Weightless)?; - - #[extrinsic_call] - _(origin as T::RuntimeOrigin, duration, lease_period_index); - - assert_last_event::( - Event::::AuctionStarted { - auction_index: AuctionCounter::::get(), - lease_period: LeasePeriodOf::::max_value(), - ending: BlockNumberFor::::max_value(), - } - .into(), - ); - - Ok(()) - } - - // Worst case scenario a new bid comes in which kicks out an existing bid for the same slot. - #[benchmark] - fn bid() -> Result<(), BenchmarkError> { - // If there is an offset, we need to be on that block to be able to do lease things. - let (_, offset) = T::Leaser::lease_period_length(); - frame_system::Pallet::::set_block_number(offset + One::one()); - - // Create a new auction - let duration = BlockNumberFor::::max_value(); - let lease_period_index = LeasePeriodOf::::zero(); - let origin = T::InitiateOrigin::try_successful_origin() - .expect("InitiateOrigin has no successful origin required for the benchmark"); - Auctions::::new_auction(origin, duration, lease_period_index)?; - - let para = ParaId::from(0); - let new_para = ParaId::from(1_u32); - - // Register the paras - let owner = account("owner", 0, 0); - CurrencyOf::::make_free_balance_be(&owner, BalanceOf::::max_value()); - let worst_head_data = T::Registrar::worst_head_data(); - let worst_validation_code = T::Registrar::worst_validation_code(); - T::Registrar::register( - owner.clone(), - para, - worst_head_data.clone(), - worst_validation_code.clone(), - )?; - T::Registrar::register( - owner, - new_para, - worst_head_data, - worst_validation_code.clone(), - )?; - assert_ok!(paras::Pallet::::add_trusted_validation_code( - frame_system::Origin::::Root.into(), - worst_validation_code, - )); - - T::Registrar::execute_pending_transitions(); - - // Make an existing bid - let auction_index = AuctionCounter::::get(); - let first_slot = AuctionInfo::::get().unwrap().0; - let last_slot = first_slot + 3u32.into(); - let first_amount = CurrencyOf::::minimum_balance(); - let first_bidder: T::AccountId = account("first_bidder", 0, 0); - CurrencyOf::::make_free_balance_be(&first_bidder, BalanceOf::::max_value()); - Auctions::::bid( - RawOrigin::Signed(first_bidder.clone()).into(), - para, - auction_index, - first_slot, - last_slot, - first_amount, - )?; - - let caller: T::AccountId = whitelisted_caller(); - CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); - let bigger_amount = CurrencyOf::::minimum_balance().saturating_mul(10u32.into()); - assert_eq!(CurrencyOf::::reserved_balance(&first_bidder), first_amount); - - #[extrinsic_call] - _( - RawOrigin::Signed(caller.clone()), - new_para, - auction_index, - first_slot, - last_slot, - bigger_amount, - ); - - // Confirms that we unreserved funds from a previous bidder, which is worst case - // scenario. - assert_eq!(CurrencyOf::::reserved_balance(&caller), bigger_amount); - - Ok(()) - } - - // Worst case: 10 bidders taking all wining spots, and we need to calculate the winner for - // auction end. Entire winner map should be full and removed at the end of the benchmark. - #[benchmark] - fn on_initialize() -> Result<(), BenchmarkError> { - // If there is an offset, we need to be on that block to be able to do lease things. - let (lease_length, offset) = T::Leaser::lease_period_length(); - frame_system::Pallet::::set_block_number(offset + One::one()); - - // Create a new auction - let duration: BlockNumberFor = lease_length / 2u32.into(); - let lease_period_index = LeasePeriodOf::::zero(); - let now = frame_system::Pallet::::block_number(); - let origin = T::InitiateOrigin::try_successful_origin() - .expect("InitiateOrigin has no successful origin required for the benchmark"); - Auctions::::new_auction(origin, duration, lease_period_index)?; - - fill_winners::(lease_period_index); - - for winner in Winning::::get(BlockNumberFor::::from(0u32)).unwrap().iter() { - assert!(winner.is_some()); - } - - let winning_data = Winning::::get(BlockNumberFor::::from(0u32)).unwrap(); - // Make winning map full - for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { - Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); - } - - // Move ahead to the block we want to initialize - frame_system::Pallet::::set_block_number(duration + now + T::EndingPeriod::get()); - - // Trigger epoch change for new random number value: - { - pallet_babe::EpochStart::::set((Zero::zero(), u32::MAX.into())); - pallet_babe::Pallet::::on_initialize(duration + now + T::EndingPeriod::get()); - let authorities = pallet_babe::Pallet::::authorities(); - // Check for non empty authority set since it otherwise emits a No-OP warning. - if !authorities.is_empty() { - pallet_babe::Pallet::::enact_epoch_change( - authorities.clone(), - authorities, - None, - ); - } - } - - #[block] - { - Auctions::::on_initialize(duration + now + T::EndingPeriod::get()); - } - - let auction_index = AuctionCounter::::get(); - assert_last_event::(Event::::AuctionClosed { auction_index }.into()); - assert!(Winning::::iter().count().is_zero()); - - Ok(()) - } - - // Worst case: 10 bidders taking all wining spots, and winning data is full. - #[benchmark] - fn cancel_auction() -> Result<(), BenchmarkError> { - // If there is an offset, we need to be on that block to be able to do lease things. - let (lease_length, offset) = T::Leaser::lease_period_length(); - frame_system::Pallet::::set_block_number(offset + One::one()); - - // Create a new auction - let duration: BlockNumberFor = lease_length / 2u32.into(); - let lease_period_index = LeasePeriodOf::::zero(); - let origin = T::InitiateOrigin::try_successful_origin() - .expect("InitiateOrigin has no successful origin required for the benchmark"); - Auctions::::new_auction(origin, duration, lease_period_index)?; - - fill_winners::(lease_period_index); - - let winning_data = Winning::::get(BlockNumberFor::::from(0u32)).unwrap(); - for winner in winning_data.iter() { - assert!(winner.is_some()); - } - - // Make winning map full - for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { - Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); - } - assert!(AuctionInfo::::get().is_some()); - - #[extrinsic_call] - _(RawOrigin::Root); - - assert!(AuctionInfo::::get().is_none()); - Ok(()) - } - - impl_benchmark_test_suite!( - Auctions, - crate::integration_tests::new_test_ext(), - crate::integration_tests::Test, - ); - } -} diff --git a/polkadot/runtime/common/src/auctions/benchmarking.rs b/polkadot/runtime/common/src/auctions/benchmarking.rs new file mode 100644 index 000000000000..6d52cd850b6f --- /dev/null +++ b/polkadot/runtime/common/src/auctions/benchmarking.rs @@ -0,0 +1,282 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Benchmarking for auctions pallet + +#![cfg(feature = "runtime-benchmarks")] +use super::{Pallet as Auctions, *}; +use frame_support::{ + assert_ok, + traits::{EnsureOrigin, OnInitialize}, +}; +use frame_system::RawOrigin; +use polkadot_runtime_parachains::paras; +use sp_runtime::{traits::Bounded, SaturatedConversion}; + +use frame_benchmarking::v2::*; + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +fn fill_winners(lease_period_index: LeasePeriodOf) { + let auction_index = AuctionCounter::::get(); + let minimum_balance = CurrencyOf::::minimum_balance(); + + for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { + let owner = account("owner", n, 0); + let worst_validation_code = T::Registrar::worst_validation_code(); + let worst_head_data = T::Registrar::worst_head_data(); + CurrencyOf::::make_free_balance_be(&owner, BalanceOf::::max_value()); + + assert!(T::Registrar::register( + owner, + ParaId::from(n), + worst_head_data, + worst_validation_code + ) + .is_ok()); + } + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + T::Registrar::worst_validation_code(), + )); + + T::Registrar::execute_pending_transitions(); + + for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { + let bidder = account("bidder", n, 0); + CurrencyOf::::make_free_balance_be(&bidder, BalanceOf::::max_value()); + + let slot_range = SlotRange::n((n - 1) as u8).unwrap(); + let (start, end) = slot_range.as_pair(); + + assert!(Auctions::::bid( + RawOrigin::Signed(bidder).into(), + ParaId::from(n), + auction_index, + lease_period_index + start.into(), // First Slot + lease_period_index + end.into(), // Last slot + minimum_balance.saturating_mul(n.into()), // Amount + ) + .is_ok()); + } +} + +#[benchmarks( + where T: pallet_babe::Config + paras::Config, + )] +mod benchmarks { + use super::*; + + #[benchmark] + fn new_auction() -> Result<(), BenchmarkError> { + let duration = BlockNumberFor::::max_value(); + let lease_period_index = LeasePeriodOf::::max_value(); + let origin = + T::InitiateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, duration, lease_period_index); + + assert_last_event::( + Event::::AuctionStarted { + auction_index: AuctionCounter::::get(), + lease_period: LeasePeriodOf::::max_value(), + ending: BlockNumberFor::::max_value(), + } + .into(), + ); + + Ok(()) + } + + // Worst case scenario a new bid comes in which kicks out an existing bid for the same slot. + #[benchmark] + fn bid() -> Result<(), BenchmarkError> { + // If there is an offset, we need to be on that block to be able to do lease things. + let (_, offset) = T::Leaser::lease_period_length(); + frame_system::Pallet::::set_block_number(offset + One::one()); + + // Create a new auction + let duration = BlockNumberFor::::max_value(); + let lease_period_index = LeasePeriodOf::::zero(); + let origin = T::InitiateOrigin::try_successful_origin() + .expect("InitiateOrigin has no successful origin required for the benchmark"); + Auctions::::new_auction(origin, duration, lease_period_index)?; + + let para = ParaId::from(0); + let new_para = ParaId::from(1_u32); + + // Register the paras + let owner = account("owner", 0, 0); + CurrencyOf::::make_free_balance_be(&owner, BalanceOf::::max_value()); + let worst_head_data = T::Registrar::worst_head_data(); + let worst_validation_code = T::Registrar::worst_validation_code(); + T::Registrar::register( + owner.clone(), + para, + worst_head_data.clone(), + worst_validation_code.clone(), + )?; + T::Registrar::register(owner, new_para, worst_head_data, worst_validation_code.clone())?; + assert_ok!(paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + worst_validation_code, + )); + + T::Registrar::execute_pending_transitions(); + + // Make an existing bid + let auction_index = AuctionCounter::::get(); + let first_slot = AuctionInfo::::get().unwrap().0; + let last_slot = first_slot + 3u32.into(); + let first_amount = CurrencyOf::::minimum_balance(); + let first_bidder: T::AccountId = account("first_bidder", 0, 0); + CurrencyOf::::make_free_balance_be(&first_bidder, BalanceOf::::max_value()); + Auctions::::bid( + RawOrigin::Signed(first_bidder.clone()).into(), + para, + auction_index, + first_slot, + last_slot, + first_amount, + )?; + + let caller: T::AccountId = whitelisted_caller(); + CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); + let bigger_amount = CurrencyOf::::minimum_balance().saturating_mul(10u32.into()); + assert_eq!(CurrencyOf::::reserved_balance(&first_bidder), first_amount); + + #[extrinsic_call] + _( + RawOrigin::Signed(caller.clone()), + new_para, + auction_index, + first_slot, + last_slot, + bigger_amount, + ); + + // Confirms that we unreserved funds from a previous bidder, which is worst case + // scenario. + assert_eq!(CurrencyOf::::reserved_balance(&caller), bigger_amount); + + Ok(()) + } + + // Worst case: 10 bidders taking all wining spots, and we need to calculate the winner for + // auction end. Entire winner map should be full and removed at the end of the benchmark. + #[benchmark] + fn on_initialize() -> Result<(), BenchmarkError> { + // If there is an offset, we need to be on that block to be able to do lease things. + let (lease_length, offset) = T::Leaser::lease_period_length(); + frame_system::Pallet::::set_block_number(offset + One::one()); + + // Create a new auction + let duration: BlockNumberFor = lease_length / 2u32.into(); + let lease_period_index = LeasePeriodOf::::zero(); + let now = frame_system::Pallet::::block_number(); + let origin = T::InitiateOrigin::try_successful_origin() + .expect("InitiateOrigin has no successful origin required for the benchmark"); + Auctions::::new_auction(origin, duration, lease_period_index)?; + + fill_winners::(lease_period_index); + + for winner in Winning::::get(BlockNumberFor::::from(0u32)).unwrap().iter() { + assert!(winner.is_some()); + } + + let winning_data = Winning::::get(BlockNumberFor::::from(0u32)).unwrap(); + // Make winning map full + for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { + Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); + } + + // Move ahead to the block we want to initialize + frame_system::Pallet::::set_block_number(duration + now + T::EndingPeriod::get()); + + // Trigger epoch change for new random number value: + { + pallet_babe::EpochStart::::set((Zero::zero(), u32::MAX.into())); + pallet_babe::Pallet::::on_initialize(duration + now + T::EndingPeriod::get()); + let authorities = pallet_babe::Pallet::::authorities(); + // Check for non empty authority set since it otherwise emits a No-OP warning. + if !authorities.is_empty() { + pallet_babe::Pallet::::enact_epoch_change( + authorities.clone(), + authorities, + None, + ); + } + } + + #[block] + { + Auctions::::on_initialize(duration + now + T::EndingPeriod::get()); + } + + let auction_index = AuctionCounter::::get(); + assert_last_event::(Event::::AuctionClosed { auction_index }.into()); + assert!(Winning::::iter().count().is_zero()); + + Ok(()) + } + + // Worst case: 10 bidders taking all wining spots, and winning data is full. + #[benchmark] + fn cancel_auction() -> Result<(), BenchmarkError> { + // If there is an offset, we need to be on that block to be able to do lease things. + let (lease_length, offset) = T::Leaser::lease_period_length(); + frame_system::Pallet::::set_block_number(offset + One::one()); + + // Create a new auction + let duration: BlockNumberFor = lease_length / 2u32.into(); + let lease_period_index = LeasePeriodOf::::zero(); + let origin = T::InitiateOrigin::try_successful_origin() + .expect("InitiateOrigin has no successful origin required for the benchmark"); + Auctions::::new_auction(origin, duration, lease_period_index)?; + + fill_winners::(lease_period_index); + + let winning_data = Winning::::get(BlockNumberFor::::from(0u32)).unwrap(); + for winner in winning_data.iter() { + assert!(winner.is_some()); + } + + // Make winning map full + for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { + Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); + } + assert!(AuctionInfo::::get().is_some()); + + #[extrinsic_call] + _(RawOrigin::Root); + + assert!(AuctionInfo::::get().is_none()); + Ok(()) + } + + impl_benchmark_test_suite!( + Auctions, + crate::integration_tests::new_test_ext(), + crate::integration_tests::Test, + ); +} diff --git a/polkadot/runtime/common/src/auctions/mock.rs b/polkadot/runtime/common/src/auctions/mock.rs new file mode 100644 index 000000000000..e66ebab96b29 --- /dev/null +++ b/polkadot/runtime/common/src/auctions/mock.rs @@ -0,0 +1,259 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Mocking utilities for testing in auctions pallet. + +#[cfg(test)] +use super::*; +use crate::{auctions, mock::TestRegistrar}; +use frame_support::{ + assert_ok, derive_impl, ord_parameter_types, parameter_types, + traits::{EitherOfDiverse, OnFinalize, OnInitialize}, +}; +use frame_system::{EnsureRoot, EnsureSignedBy}; +use pallet_balances; +use polkadot_primitives::{BlockNumber, Id as ParaId}; +use polkadot_primitives_test_helpers::{dummy_head_data, dummy_validation_code}; +use sp_core::H256; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, +}; +use std::{cell::RefCell, collections::BTreeMap}; + +type Block = frame_system::mocking::MockBlockU32; + +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Balances: pallet_balances, + Auctions: auctions, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Test { + type AccountStore = System; +} + +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)] +pub struct LeaseData { + pub leaser: u64, + pub amount: u64, +} + +thread_local! { + pub static LEASES: + RefCell> = RefCell::new(BTreeMap::new()); +} + +pub fn leases() -> Vec<((ParaId, BlockNumber), LeaseData)> { + LEASES.with(|p| (&*p.borrow()).clone().into_iter().collect::>()) +} + +pub struct TestLeaser; +impl Leaser for TestLeaser { + type AccountId = u64; + type LeasePeriod = BlockNumber; + type Currency = Balances; + + fn lease_out( + para: ParaId, + leaser: &Self::AccountId, + amount: >::Balance, + period_begin: Self::LeasePeriod, + period_count: Self::LeasePeriod, + ) -> Result<(), LeaseError> { + LEASES.with(|l| { + let mut leases = l.borrow_mut(); + let now = System::block_number(); + let (current_lease_period, _) = + Self::lease_period_index(now).ok_or(LeaseError::NoLeasePeriod)?; + if period_begin < current_lease_period { + return Err(LeaseError::AlreadyEnded); + } + for period in period_begin..(period_begin + period_count) { + if leases.contains_key(&(para, period)) { + return Err(LeaseError::AlreadyLeased); + } + leases.insert((para, period), LeaseData { leaser: *leaser, amount }); + } + Ok(()) + }) + } + + fn deposit_held( + para: ParaId, + leaser: &Self::AccountId, + ) -> >::Balance { + leases() + .iter() + .filter_map(|((id, _period), data)| { + if id == ¶ && &data.leaser == leaser { + Some(data.amount) + } else { + None + } + }) + .max() + .unwrap_or_default() + } + + fn lease_period_length() -> (BlockNumber, BlockNumber) { + (10, 0) + } + + fn lease_period_index(b: BlockNumber) -> Option<(Self::LeasePeriod, bool)> { + let (lease_period_length, offset) = Self::lease_period_length(); + let b = b.checked_sub(offset)?; + + let lease_period = b / lease_period_length; + let first_block = (b % lease_period_length).is_zero(); + + Some((lease_period, first_block)) + } + + fn already_leased( + para_id: ParaId, + first_period: Self::LeasePeriod, + last_period: Self::LeasePeriod, + ) -> bool { + leases().into_iter().any(|((para, period), _data)| { + para == para_id && first_period <= period && period <= last_period + }) + } +} + +ord_parameter_types! { + pub const Six: u64 = 6; +} + +type RootOrSix = EitherOfDiverse, EnsureSignedBy>; + +thread_local! { + pub static LAST_RANDOM: RefCell> = RefCell::new(None); +} +pub fn set_last_random(output: H256, known_since: u32) { + LAST_RANDOM.with(|p| *p.borrow_mut() = Some((output, known_since))) +} +pub struct TestPastRandomness; +impl Randomness for TestPastRandomness { + fn random(_subject: &[u8]) -> (H256, u32) { + LAST_RANDOM.with(|p| { + if let Some((output, known_since)) = &*p.borrow() { + (*output, *known_since) + } else { + (H256::zero(), frame_system::Pallet::::block_number()) + } + }) + } +} + +parameter_types! { + pub static EndingPeriod: BlockNumber = 3; + pub static SampleLength: BlockNumber = 1; +} + +impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type Leaser = TestLeaser; + type Registrar = TestRegistrar; + type EndingPeriod = EndingPeriod; + type SampleLength = SampleLength; + type Randomness = TestPastRandomness; + type InitiateOrigin = RootOrSix; + type WeightInfo = crate::auctions::TestWeightInfo; +} + +// This function basically just builds a genesis storage key/value store according to +// our desired mock up. +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext: sp_io::TestExternalities = t.into(); + ext.execute_with(|| { + // Register para 0, 1, 2, and 3 for tests + assert_ok!(TestRegistrar::::register( + 1, + 0.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + 1.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + 2.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(TestRegistrar::::register( + 1, + 3.into(), + dummy_head_data(), + dummy_validation_code() + )); + }); + ext +} + +pub fn run_to_block(n: BlockNumber) { + while System::block_number() < n { + Auctions::on_finalize(System::block_number()); + Balances::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + Balances::on_initialize(System::block_number()); + Auctions::on_initialize(System::block_number()); + } +} diff --git a/polkadot/runtime/common/src/auctions/mod.rs b/polkadot/runtime/common/src/auctions/mod.rs new file mode 100644 index 000000000000..84d8a3846d40 --- /dev/null +++ b/polkadot/runtime/common/src/auctions/mod.rs @@ -0,0 +1,677 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Auctioning system to determine the set of Parachains in operation. This includes logic for the +//! auctioning mechanism and for reserving balance as part of the "payment". Unreserving the balance +//! happens elsewhere. + +use crate::{ + slot_range::SlotRange, + traits::{AuctionStatus, Auctioneer, LeaseError, Leaser, Registrar}, +}; +use alloc::{vec, vec::Vec}; +use codec::Decode; +use core::mem::swap; +use frame_support::{ + dispatch::DispatchResult, + ensure, + traits::{Currency, Get, Randomness, ReservableCurrency}, + weights::Weight, +}; +use frame_system::pallet_prelude::BlockNumberFor; +pub use pallet::*; +use polkadot_primitives::Id as ParaId; +use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; + +type CurrencyOf = <::Leaser as Leaser>>::Currency; +type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< + ::AccountId, +>>::Balance; + +pub trait WeightInfo { + fn new_auction() -> Weight; + fn bid() -> Weight; + fn cancel_auction() -> Weight; + fn on_initialize() -> Weight; +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn new_auction() -> Weight { + Weight::zero() + } + fn bid() -> Weight { + Weight::zero() + } + fn cancel_auction() -> Weight { + Weight::zero() + } + fn on_initialize() -> Weight { + Weight::zero() + } +} + +/// An auction index. We count auctions in this type. +pub type AuctionIndex = u32; + +type LeasePeriodOf = <::Leaser as Leaser>>::LeasePeriod; + +// Winning data type. This encodes the top bidders of each range together with their bid. +type WinningData = [Option<(::AccountId, ParaId, BalanceOf)>; + SlotRange::SLOT_RANGE_COUNT]; +// Winners data type. This encodes each of the final winners of a parachain auction, the parachain +// index assigned to them, their winning bid and the range that they won. +type WinnersData = + Vec<(::AccountId, ParaId, BalanceOf, SlotRange)>; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::{dispatch::DispatchClass, pallet_prelude::*, traits::EnsureOrigin}; + use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; + + #[pallet::pallet] + pub struct Pallet(_); + + /// The module's configuration trait. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The type representing the leasing system. + type Leaser: Leaser< + BlockNumberFor, + AccountId = Self::AccountId, + LeasePeriod = BlockNumberFor, + >; + + /// The parachain registrar type. + type Registrar: Registrar; + + /// The number of blocks over which an auction may be retroactively ended. + #[pallet::constant] + type EndingPeriod: Get>; + + /// The length of each sample to take during the ending period. + /// + /// `EndingPeriod` / `SampleLength` = Total # of Samples + #[pallet::constant] + type SampleLength: Get>; + + /// Something that provides randomness in the runtime. + type Randomness: Randomness>; + + /// The origin which may initiate auctions. + type InitiateOrigin: EnsureOrigin; + + /// Weight Information for the Extrinsics in the Pallet + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// An auction started. Provides its index and the block number where it will begin to + /// close and the first lease period of the quadruplet that is auctioned. + AuctionStarted { + auction_index: AuctionIndex, + lease_period: LeasePeriodOf, + ending: BlockNumberFor, + }, + /// An auction ended. All funds become unreserved. + AuctionClosed { auction_index: AuctionIndex }, + /// Funds were reserved for a winning bid. First balance is the extra amount reserved. + /// Second is the total. + Reserved { bidder: T::AccountId, extra_reserved: BalanceOf, total_amount: BalanceOf }, + /// Funds were unreserved since bidder is no longer active. `[bidder, amount]` + Unreserved { bidder: T::AccountId, amount: BalanceOf }, + /// Someone attempted to lease the same slot twice for a parachain. The amount is held in + /// reserve but no parachain slot has been leased. + ReserveConfiscated { para_id: ParaId, leaser: T::AccountId, amount: BalanceOf }, + /// A new bid has been accepted as the current winner. + BidAccepted { + bidder: T::AccountId, + para_id: ParaId, + amount: BalanceOf, + first_slot: LeasePeriodOf, + last_slot: LeasePeriodOf, + }, + /// The winning offset was chosen for an auction. This will map into the `Winning` storage + /// map. + WinningOffset { auction_index: AuctionIndex, block_number: BlockNumberFor }, + } + + #[pallet::error] + pub enum Error { + /// This auction is already in progress. + AuctionInProgress, + /// The lease period is in the past. + LeasePeriodInPast, + /// Para is not registered + ParaNotRegistered, + /// Not a current auction. + NotCurrentAuction, + /// Not an auction. + NotAuction, + /// Auction has already ended. + AuctionEnded, + /// The para is already leased out for part of this range. + AlreadyLeasedOut, + } + + /// Number of auctions started so far. + #[pallet::storage] + pub type AuctionCounter = StorageValue<_, AuctionIndex, ValueQuery>; + + /// Information relating to the current auction, if there is one. + /// + /// The first item in the tuple is the lease period index that the first of the four + /// contiguous lease periods on auction is for. The second is the block number when the + /// auction will "begin to end", i.e. the first block of the Ending Period of the auction. + #[pallet::storage] + pub type AuctionInfo = StorageValue<_, (LeasePeriodOf, BlockNumberFor)>; + + /// Amounts currently reserved in the accounts of the bidders currently winning + /// (sub-)ranges. + #[pallet::storage] + pub type ReservedAmounts = + StorageMap<_, Twox64Concat, (T::AccountId, ParaId), BalanceOf>; + + /// The winning bids for each of the 10 ranges at each sample in the final Ending Period of + /// the current auction. The map's key is the 0-based index into the Sample Size. The + /// first sample of the ending period is 0; the last is `Sample Size - 1`. + #[pallet::storage] + pub type Winning = StorageMap<_, Twox64Concat, BlockNumberFor, WinningData>; + + #[pallet::extra_constants] + impl Pallet { + #[pallet::constant_name(SlotRangeCount)] + fn slot_range_count() -> u32 { + SlotRange::SLOT_RANGE_COUNT as u32 + } + + #[pallet::constant_name(LeasePeriodsPerSlot)] + fn lease_periods_per_slot() -> u32 { + SlotRange::LEASE_PERIODS_PER_SLOT as u32 + } + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: BlockNumberFor) -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + // If the current auction was in its ending period last block, then ensure that the + // (sub-)range winner information is duplicated from the previous block in case no bids + // happened in the last block. + if let AuctionStatus::EndingPeriod(offset, _sub_sample) = Self::auction_status(n) { + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + if !Winning::::contains_key(&offset) { + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + let winning_data = offset + .checked_sub(&One::one()) + .and_then(Winning::::get) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + Winning::::insert(offset, winning_data); + } + } + + // Check to see if an auction just ended. + if let Some((winning_ranges, auction_lease_period_index)) = Self::check_auction_end(n) { + // Auction is ended now. We have the winning ranges and the lease period index which + // acts as the offset. Handle it. + Self::manage_auction_end(auction_lease_period_index, winning_ranges); + weight = weight.saturating_add(T::WeightInfo::on_initialize()); + } + + weight + } + } + + #[pallet::call] + impl Pallet { + /// Create a new auction. + /// + /// This can only happen when there isn't already an auction in progress and may only be + /// called by the root origin. Accepts the `duration` of this auction and the + /// `lease_period_index` of the initial lease period of the four that are to be auctioned. + #[pallet::call_index(0)] + #[pallet::weight((T::WeightInfo::new_auction(), DispatchClass::Operational))] + pub fn new_auction( + origin: OriginFor, + #[pallet::compact] duration: BlockNumberFor, + #[pallet::compact] lease_period_index: LeasePeriodOf, + ) -> DispatchResult { + T::InitiateOrigin::ensure_origin(origin)?; + Self::do_new_auction(duration, lease_period_index) + } + + /// Make a new bid from an account (including a parachain account) for deploying a new + /// parachain. + /// + /// Multiple simultaneous bids from the same bidder are allowed only as long as all active + /// bids overlap each other (i.e. are mutually exclusive). Bids cannot be redacted. + /// + /// - `sub` is the sub-bidder ID, allowing for multiple competing bids to be made by (and + /// funded by) the same account. + /// - `auction_index` is the index of the auction to bid on. Should just be the present + /// value of `AuctionCounter`. + /// - `first_slot` is the first lease period index of the range to bid on. This is the + /// absolute lease period index value, not an auction-specific offset. + /// - `last_slot` is the last lease period index of the range to bid on. This is the + /// absolute lease period index value, not an auction-specific offset. + /// - `amount` is the amount to bid to be held as deposit for the parachain should the + /// bid win. This amount is held throughout the range. + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::bid())] + pub fn bid( + origin: OriginFor, + #[pallet::compact] para: ParaId, + #[pallet::compact] auction_index: AuctionIndex, + #[pallet::compact] first_slot: LeasePeriodOf, + #[pallet::compact] last_slot: LeasePeriodOf, + #[pallet::compact] amount: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::handle_bid(who, para, auction_index, first_slot, last_slot, amount)?; + Ok(()) + } + + /// Cancel an in-progress auction. + /// + /// Can only be called by Root origin. + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::cancel_auction())] + pub fn cancel_auction(origin: OriginFor) -> DispatchResult { + ensure_root(origin)?; + // Unreserve all bids. + for ((bidder, _), amount) in ReservedAmounts::::drain() { + CurrencyOf::::unreserve(&bidder, amount); + } + #[allow(deprecated)] + Winning::::remove_all(None); + AuctionInfo::::kill(); + Ok(()) + } + } +} + +impl Auctioneer> for Pallet { + type AccountId = T::AccountId; + type LeasePeriod = BlockNumberFor; + type Currency = CurrencyOf; + + fn new_auction( + duration: BlockNumberFor, + lease_period_index: LeasePeriodOf, + ) -> DispatchResult { + Self::do_new_auction(duration, lease_period_index) + } + + // Returns the status of the auction given the current block number. + fn auction_status(now: BlockNumberFor) -> AuctionStatus> { + let early_end = match AuctionInfo::::get() { + Some((_, early_end)) => early_end, + None => return AuctionStatus::NotStarted, + }; + + let after_early_end = match now.checked_sub(&early_end) { + Some(after_early_end) => after_early_end, + None => return AuctionStatus::StartingPeriod, + }; + + let ending_period = T::EndingPeriod::get(); + if after_early_end < ending_period { + let sample_length = T::SampleLength::get().max(One::one()); + let sample = after_early_end / sample_length; + let sub_sample = after_early_end % sample_length; + return AuctionStatus::EndingPeriod(sample, sub_sample) + } else { + // This is safe because of the comparison operator above + return AuctionStatus::VrfDelay(after_early_end - ending_period) + } + } + + fn place_bid( + bidder: T::AccountId, + para: ParaId, + first_slot: LeasePeriodOf, + last_slot: LeasePeriodOf, + amount: BalanceOf, + ) -> DispatchResult { + Self::handle_bid(bidder, para, AuctionCounter::::get(), first_slot, last_slot, amount) + } + + fn lease_period_index(b: BlockNumberFor) -> Option<(Self::LeasePeriod, bool)> { + T::Leaser::lease_period_index(b) + } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn lease_period_length() -> (BlockNumberFor, BlockNumberFor) { + T::Leaser::lease_period_length() + } + + fn has_won_an_auction(para: ParaId, bidder: &T::AccountId) -> bool { + !T::Leaser::deposit_held(para, bidder).is_zero() + } +} + +impl Pallet { + // A trick to allow me to initialize large arrays with nothing in them. + const EMPTY: Option<(::AccountId, ParaId, BalanceOf)> = None; + + /// Create a new auction. + /// + /// This can only happen when there isn't already an auction in progress. Accepts the `duration` + /// of this auction and the `lease_period_index` of the initial lease period of the four that + /// are to be auctioned. + fn do_new_auction( + duration: BlockNumberFor, + lease_period_index: LeasePeriodOf, + ) -> DispatchResult { + let maybe_auction = AuctionInfo::::get(); + ensure!(maybe_auction.is_none(), Error::::AuctionInProgress); + let now = frame_system::Pallet::::block_number(); + if let Some((current_lease_period, _)) = T::Leaser::lease_period_index(now) { + // If there is no active lease period, then we don't need to make this check. + ensure!(lease_period_index >= current_lease_period, Error::::LeasePeriodInPast); + } + + // Bump the counter. + let n = AuctionCounter::::mutate(|n| { + *n += 1; + *n + }); + + // Set the information. + let ending = frame_system::Pallet::::block_number().saturating_add(duration); + AuctionInfo::::put((lease_period_index, ending)); + + Self::deposit_event(Event::::AuctionStarted { + auction_index: n, + lease_period: lease_period_index, + ending, + }); + Ok(()) + } + + /// Actually place a bid in the current auction. + /// + /// - `bidder`: The account that will be funding this bid. + /// - `auction_index`: The auction index of the bid. For this to succeed, must equal + /// the current value of `AuctionCounter`. + /// - `first_slot`: The first lease period index of the range to be bid on. + /// - `last_slot`: The last lease period index of the range to be bid on (inclusive). + /// - `amount`: The total amount to be the bid for deposit over the range. + pub fn handle_bid( + bidder: T::AccountId, + para: ParaId, + auction_index: u32, + first_slot: LeasePeriodOf, + last_slot: LeasePeriodOf, + amount: BalanceOf, + ) -> DispatchResult { + // Ensure para is registered before placing a bid on it. + ensure!(T::Registrar::is_registered(para), Error::::ParaNotRegistered); + // Bidding on latest auction. + ensure!(auction_index == AuctionCounter::::get(), Error::::NotCurrentAuction); + // Assume it's actually an auction (this should never fail because of above). + let (first_lease_period, _) = AuctionInfo::::get().ok_or(Error::::NotAuction)?; + + // Get the auction status and the current sample block. For the starting period, the sample + // block is zero. + let auction_status = Self::auction_status(frame_system::Pallet::::block_number()); + // The offset into the ending samples of the auction. + let offset = match auction_status { + AuctionStatus::NotStarted => return Err(Error::::AuctionEnded.into()), + AuctionStatus::StartingPeriod => Zero::zero(), + AuctionStatus::EndingPeriod(o, _) => o, + AuctionStatus::VrfDelay(_) => return Err(Error::::AuctionEnded.into()), + }; + + // We also make sure that the bid is not for any existing leases the para already has. + ensure!( + !T::Leaser::already_leased(para, first_slot, last_slot), + Error::::AlreadyLeasedOut + ); + + // Our range. + let range = SlotRange::new_bounded(first_lease_period, first_slot, last_slot)?; + // Range as an array index. + let range_index = range as u8 as usize; + + // The current winning ranges. + let mut current_winning = Winning::::get(offset) + .or_else(|| offset.checked_sub(&One::one()).and_then(Winning::::get)) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + + // If this bid beat the previous winner of our range. + if current_winning[range_index].as_ref().map_or(true, |last| amount > last.2) { + // Ok; we are the new winner of this range - reserve the additional amount and record. + + // Get the amount already held on deposit if this is a renewal bid (i.e. there's + // an existing lease on the same para by the same leaser). + let existing_lease_deposit = T::Leaser::deposit_held(para, &bidder); + let reserve_required = amount.saturating_sub(existing_lease_deposit); + + // Get the amount already reserved in any prior and still active bids by us. + let bidder_para = (bidder.clone(), para); + let already_reserved = ReservedAmounts::::get(&bidder_para).unwrap_or_default(); + + // If these don't already cover the bid... + if let Some(additional) = reserve_required.checked_sub(&already_reserved) { + // ...then reserve some more funds from their account, failing if there's not + // enough funds. + CurrencyOf::::reserve(&bidder, additional)?; + // ...and record the amount reserved. + ReservedAmounts::::insert(&bidder_para, reserve_required); + + Self::deposit_event(Event::::Reserved { + bidder: bidder.clone(), + extra_reserved: additional, + total_amount: reserve_required, + }); + } + + // Return any funds reserved for the previous winner if we are not in the ending period + // and they no longer have any active bids. + let mut outgoing_winner = Some((bidder.clone(), para, amount)); + swap(&mut current_winning[range_index], &mut outgoing_winner); + if let Some((who, para, _amount)) = outgoing_winner { + if auction_status.is_starting() && + current_winning + .iter() + .filter_map(Option::as_ref) + .all(|&(ref other, other_para, _)| other != &who || other_para != para) + { + // Previous bidder is no longer winning any ranges: unreserve their funds. + if let Some(amount) = ReservedAmounts::::take(&(who.clone(), para)) { + // It really should be reserved; there's not much we can do here on fail. + let err_amt = CurrencyOf::::unreserve(&who, amount); + debug_assert!(err_amt.is_zero()); + Self::deposit_event(Event::::Unreserved { bidder: who, amount }); + } + } + } + + // Update the range winner. + Winning::::insert(offset, ¤t_winning); + Self::deposit_event(Event::::BidAccepted { + bidder, + para_id: para, + amount, + first_slot, + last_slot, + }); + } + Ok(()) + } + + /// Some when the auction's end is known (with the end block number). None if it is unknown. + /// If `Some` then the block number must be at most the previous block and at least the + /// previous block minus `T::EndingPeriod::get()`. + /// + /// This mutates the state, cleaning up `AuctionInfo` and `Winning` in the case of an auction + /// ending. An immediately subsequent call with the same argument will always return `None`. + fn check_auction_end(now: BlockNumberFor) -> Option<(WinningData, LeasePeriodOf)> { + if let Some((lease_period_index, early_end)) = AuctionInfo::::get() { + let ending_period = T::EndingPeriod::get(); + let late_end = early_end.saturating_add(ending_period); + let is_ended = now >= late_end; + if is_ended { + // auction definitely ended. + // check to see if we can determine the actual ending point. + let (raw_offset, known_since) = T::Randomness::random(&b"para_auction"[..]); + + if late_end <= known_since { + // Our random seed was known only after the auction ended. Good to use. + let raw_offset_block_number = >::decode( + &mut raw_offset.as_ref(), + ) + .expect("secure hashes should always be bigger than the block number; qed"); + let offset = (raw_offset_block_number % ending_period) / + T::SampleLength::get().max(One::one()); + + let auction_counter = AuctionCounter::::get(); + Self::deposit_event(Event::::WinningOffset { + auction_index: auction_counter, + block_number: offset, + }); + let res = Winning::::get(offset) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + // This `remove_all` statement should remove at most `EndingPeriod` / + // `SampleLength` items, which should be bounded and sensibly configured in the + // runtime. + #[allow(deprecated)] + Winning::::remove_all(None); + AuctionInfo::::kill(); + return Some((res, lease_period_index)) + } + } + } + None + } + + /// Auction just ended. We have the current lease period, the auction's lease period (which + /// is guaranteed to be at least the current period) and the bidders that were winning each + /// range at the time of the auction's close. + fn manage_auction_end( + auction_lease_period_index: LeasePeriodOf, + winning_ranges: WinningData, + ) { + // First, unreserve all amounts that were reserved for the bids. We will later re-reserve + // the amounts from the bidders that ended up being assigned the slot so there's no need to + // special-case them here. + for ((bidder, _), amount) in ReservedAmounts::::drain() { + CurrencyOf::::unreserve(&bidder, amount); + } + + // Next, calculate the winning combination of slots and thus the final winners of the + // auction. + let winners = Self::calculate_winners(winning_ranges); + + // Go through those winners and re-reserve their bid, updating our table of deposits + // accordingly. + for (leaser, para, amount, range) in winners.into_iter() { + let begin_offset = LeasePeriodOf::::from(range.as_pair().0 as u32); + let period_begin = auction_lease_period_index + begin_offset; + let period_count = LeasePeriodOf::::from(range.len() as u32); + + match T::Leaser::lease_out(para, &leaser, amount, period_begin, period_count) { + Err(LeaseError::ReserveFailed) | + Err(LeaseError::AlreadyEnded) | + Err(LeaseError::NoLeasePeriod) => { + // Should never happen since we just unreserved this amount (and our offset is + // from the present period). But if it does, there's not much we can do. + }, + Err(LeaseError::AlreadyLeased) => { + // The leaser attempted to get a second lease on the same para ID, possibly + // griefing us. Let's keep the amount reserved and let governance sort it out. + if CurrencyOf::::reserve(&leaser, amount).is_ok() { + Self::deposit_event(Event::::ReserveConfiscated { + para_id: para, + leaser, + amount, + }); + } + }, + Ok(()) => {}, // Nothing to report. + } + } + + Self::deposit_event(Event::::AuctionClosed { + auction_index: AuctionCounter::::get(), + }); + } + + /// Calculate the final winners from the winning slots. + /// + /// This is a simple dynamic programming algorithm designed by Al, the original code is at: + /// `https://github.com/w3f/consensus/blob/master/NPoS/auctiondynamicthing.py` + fn calculate_winners(mut winning: WinningData) -> WinnersData { + let winning_ranges = { + let mut best_winners_ending_at: [(Vec, BalanceOf); + SlotRange::LEASE_PERIODS_PER_SLOT] = Default::default(); + let best_bid = |range: SlotRange| { + winning[range as u8 as usize] + .as_ref() + .map(|(_, _, amount)| *amount * (range.len() as u32).into()) + }; + for i in 0..SlotRange::LEASE_PERIODS_PER_SLOT { + let r = SlotRange::new_bounded(0, 0, i as u32).expect("`i < LPPS`; qed"); + if let Some(bid) = best_bid(r) { + best_winners_ending_at[i] = (vec![r], bid); + } + for j in 0..i { + let r = SlotRange::new_bounded(0, j as u32 + 1, i as u32) + .expect("`i < LPPS`; `j < i`; `j + 1 < LPPS`; qed"); + if let Some(mut bid) = best_bid(r) { + bid += best_winners_ending_at[j].1; + if bid > best_winners_ending_at[i].1 { + let mut new_winners = best_winners_ending_at[j].0.clone(); + new_winners.push(r); + best_winners_ending_at[i] = (new_winners, bid); + } + } else { + if best_winners_ending_at[j].1 > best_winners_ending_at[i].1 { + best_winners_ending_at[i] = best_winners_ending_at[j].clone(); + } + } + } + } + best_winners_ending_at[SlotRange::LEASE_PERIODS_PER_SLOT - 1].0.clone() + }; + + winning_ranges + .into_iter() + .filter_map(|range| { + winning[range as u8 as usize] + .take() + .map(|(bidder, para, amount)| (bidder, para, amount, range)) + }) + .collect::>() + } +} + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; diff --git a/polkadot/runtime/common/src/auctions/tests.rs b/polkadot/runtime/common/src/auctions/tests.rs new file mode 100644 index 000000000000..07574eeb295d --- /dev/null +++ b/polkadot/runtime/common/src/auctions/tests.rs @@ -0,0 +1,821 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the auctions pallet. + +#[cfg(test)] +use super::*; +use crate::{auctions::mock::*, mock::TestRegistrar}; +use frame_support::{assert_noop, assert_ok, assert_storage_noop}; +use pallet_balances; +use polkadot_primitives::Id as ParaId; +use polkadot_primitives_test_helpers::{dummy_hash, dummy_head_data, dummy_validation_code}; +use sp_core::H256; +use sp_runtime::DispatchError::BadOrigin; + +#[test] +fn basic_setup_works() { + new_test_ext().execute_with(|| { + assert_eq!(AuctionCounter::::get(), 0); + assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + + run_to_block(10); + + assert_eq!(AuctionCounter::::get(), 0); + assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + }); +} + +#[test] +fn can_start_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_noop!(Auctions::new_auction(RuntimeOrigin::signed(1), 5, 1), BadOrigin); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + assert_eq!(AuctionCounter::::get(), 1); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + }); +} + +#[test] +fn bidding_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); + + assert_eq!(Balances::reserved_balance(1), 5); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!( + Winning::::get(0).unwrap()[SlotRange::ZeroThree as u8 as usize], + Some((1, 0.into(), 5)) + ); + }); +} + +#[test] +fn under_bidding_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); + + assert_storage_noop!({ + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 1, 4, 1)); + }); + }); +} + +#[test] +fn over_bidding_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 1, 4, 6)); + + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::reserved_balance(2), 6); + assert_eq!(Balances::free_balance(2), 14); + assert_eq!( + Winning::::get(0).unwrap()[SlotRange::ZeroThree as u8 as usize], + Some((2, 0.into(), 6)) + ); + }); +} + +#[test] +fn auction_proceeds_correctly() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + assert_eq!(AuctionCounter::::get(), 1); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(2); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(3); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(4); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(5); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(6); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + + run_to_block(7); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + + run_to_block(8); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + }); +} + +#[test] +fn can_win_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + }); +} + +#[test] +fn can_win_auction_with_late_randomness() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + run_to_block(8); + // Auction has not yet ended. + assert_eq!(leases(), vec![]); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + // This will prevent the auction's winner from being decided in the next block, since + // the random seed was known before the final bids were made. + set_last_random(H256::zero(), 8); + // Auction definitely ended now, but we don't know exactly when in the last 3 blocks yet + // since no randomness available yet. + run_to_block(9); + // Auction has now ended... But auction winner still not yet decided, so no leases yet. + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(0) + ); + assert_eq!(leases(), vec![]); + + // Random seed now updated to a value known at block 9, when the auction ended. This + // means that the winner can now be chosen. + set_last_random(H256::zero(), 9); + run_to_block(10); + // Auction ended and winner selected + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + }); +} + +#[test] +fn can_win_incomplete_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 4, 4, 5)); + run_to_block(9); + + assert_eq!(leases(), vec![((0.into(), 4), LeaseData { leaser: 1, amount: 5 }),]); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + }); +} + +#[test] +fn should_choose_best_combination() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 2, 3, 4)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), 0.into(), 1, 4, 4, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 1, 1, 4, 2)); + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 2, amount: 4 }), + ((0.into(), 3), LeaseData { leaser: 2, amount: 4 }), + ((0.into(), 4), LeaseData { leaser: 3, amount: 2 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + assert_eq!(TestLeaser::deposit_held(1.into(), &1), 0); + assert_eq!(TestLeaser::deposit_held(0.into(), &2), 4); + assert_eq!(TestLeaser::deposit_held(0.into(), &3), 2); + }); +} + +#[test] +fn gap_bid_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + // User 1 will make a bid for period 1 and 4 for the same Para 0 + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 4, 4, 4)); + + // User 2 and 3 will make a bid for para 1 on period 2 and 3 respectively + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 1.into(), 1, 2, 2, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), 1.into(), 1, 3, 3, 3)); + + // Total reserved should be the max of the two + assert_eq!(Balances::reserved_balance(1), 4); + + // Other people are reserved correctly too + assert_eq!(Balances::reserved_balance(2), 2); + assert_eq!(Balances::reserved_balance(3), 3); + + // End the auction. + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 4 }), + ((1.into(), 2), LeaseData { leaser: 2, amount: 2 }), + ((1.into(), 3), LeaseData { leaser: 3, amount: 3 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 4); + assert_eq!(TestLeaser::deposit_held(1.into(), &2), 2); + assert_eq!(TestLeaser::deposit_held(1.into(), &3), 3); + }); +} + +#[test] +fn deposit_credit_should_work() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5)); + assert_eq!(Balances::reserved_balance(1), 5); + run_to_block(10); + + assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 2, 2, 6)); + // Only 1 reserved since we have a deposit credit of 5. + assert_eq!(Balances::reserved_balance(1), 1); + run_to_block(20); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 6 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 6); + }); +} + +#[test] +fn deposit_credit_on_alt_para_should_not_count() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5)); + assert_eq!(Balances::reserved_balance(1), 5); + run_to_block(10); + + assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 2)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 2, 2, 2, 6)); + // 6 reserved since we are bidding on a new para; only works because we don't + assert_eq!(Balances::reserved_balance(1), 6); + run_to_block(20); + + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), + ((1.into(), 2), LeaseData { leaser: 1, amount: 6 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); + assert_eq!(TestLeaser::deposit_held(1.into(), &1), 6); + }); +} + +#[test] +fn multiple_bids_work_pre_ending() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + + for i in 1..6u64 { + run_to_block(i as _); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i)); + for j in 1..6 { + assert_eq!(Balances::reserved_balance(j), if j == i { j } else { 0 }); + assert_eq!(Balances::free_balance(j), if j == i { j * 9 } else { j * 10 }); + } + } + + run_to_block(9); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 2), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 3), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 4), LeaseData { leaser: 5, amount: 5 }), + ] + ); + }); +} + +#[test] +fn multiple_bids_work_post_ending() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 0, 1)); + + for i in 1..6u64 { + run_to_block(((i - 1) / 2 + 1) as _); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i)); + for j in 1..6 { + assert_eq!(Balances::reserved_balance(j), if j <= i { j } else { 0 }); + assert_eq!(Balances::free_balance(j), if j <= i { j * 9 } else { j * 10 }); + } + } + for i in 1..6u64 { + assert_eq!(ReservedAmounts::::get((i, ParaId::from(0))).unwrap(), i); + } + + run_to_block(5); + assert_eq!( + leases(), + (1..=4) + .map(|i| ((0.into(), i), LeaseData { leaser: 2, amount: 2 })) + .collect::>() + ); + }); +} + +#[test] +fn incomplete_calculate_winners_works() { + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ThreeThree as u8 as usize] = Some((1, 0.into(), 1)); + + let winners = vec![(1, 0.into(), 1, SlotRange::ThreeThree)]; + + assert_eq!(Auctions::calculate_winners(winning), winners); +} + +#[test] +fn first_incomplete_calculate_winners_works() { + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[0] = Some((1, 0.into(), 1)); + + let winners = vec![(1, 0.into(), 1, SlotRange::ZeroZero)]; + + assert_eq!(Auctions::calculate_winners(winning), winners); +} + +#[test] +fn calculate_winners_works() { + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ZeroZero as u8 as usize] = Some((2, 0.into(), 2)); + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, 100.into(), 1)); + winning[SlotRange::OneOne as u8 as usize] = Some((3, 1.into(), 1)); + winning[SlotRange::TwoTwo as u8 as usize] = Some((1, 2.into(), 53)); + winning[SlotRange::ThreeThree as u8 as usize] = Some((5, 3.into(), 1)); + + let winners = vec![ + (2, 0.into(), 2, SlotRange::ZeroZero), + (3, 1.into(), 1, SlotRange::OneOne), + (1, 2.into(), 53, SlotRange::TwoTwo), + (5, 3.into(), 1, SlotRange::ThreeThree), + ]; + assert_eq!(Auctions::calculate_winners(winning), winners); + + winning[SlotRange::ZeroOne as u8 as usize] = Some((4, 10.into(), 3)); + let winners = vec![ + (4, 10.into(), 3, SlotRange::ZeroOne), + (1, 2.into(), 53, SlotRange::TwoTwo), + (5, 3.into(), 1, SlotRange::ThreeThree), + ]; + assert_eq!(Auctions::calculate_winners(winning), winners); + + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, 100.into(), 100)); + let winners = vec![(1, 100.into(), 100, SlotRange::ZeroThree)]; + assert_eq!(Auctions::calculate_winners(winning), winners); +} + +#[test] +fn lower_bids_are_correctly_refunded() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 1, 1)); + let para_1 = ParaId::from(1_u32); + let para_2 = ParaId::from(2_u32); + + // Make a bid and reserve a balance + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 1, 4, 9)); + assert_eq!(Balances::reserved_balance(1), 9); + assert_eq!(ReservedAmounts::::get((1, para_1)), Some(9)); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(ReservedAmounts::::get((2, para_2)), None); + + // Bigger bid, reserves new balance and returns funds + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 1, 4, 19)); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(ReservedAmounts::::get((1, para_1)), None); + assert_eq!(Balances::reserved_balance(2), 19); + assert_eq!(ReservedAmounts::::get((2, para_2)), Some(19)); + }); +} + +#[test] +fn initialize_winners_in_ending_period_works() { + new_test_ext().execute_with(|| { + let ed: u64 = ::ExistentialDeposit::get(); + assert_eq!(ed, 1); + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 1)); + let para_1 = ParaId::from(1_u32); + let para_2 = ParaId::from(2_u32); + let para_3 = ParaId::from(3_u32); + + // Make bids + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 1, 4, 9)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 3, 4, 19)); + + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 9)); + winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19)); + assert_eq!(Winning::::get(0), Some(winning)); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(10); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + assert_eq!(Winning::::get(0), Some(winning)); + + run_to_block(11); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + assert_eq!(Winning::::get(1), Some(winning)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 3, 4, 29)); + + run_to_block(12); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 29)); + assert_eq!(Winning::::get(2), Some(winning)); + }); +} + +#[test] +fn handle_bid_requires_registered_para() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 1337.into(), 1, 1, 4, 1), + Error::::ParaNotRegistered + ); + assert_ok!(TestRegistrar::::register( + 1, + 1337.into(), + dummy_head_data(), + dummy_validation_code() + )); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1337.into(), 1, 1, 4, 1)); + }); +} + +#[test] +fn handle_bid_checks_existing_lease_periods() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 2, 3, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + run_to_block(9); + + assert_eq!( + leases(), + vec![ + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ] + ); + assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); + + // Para 1 just won an auction above and won some lease periods. + // No bids can work which overlap these periods. + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 4, 1), + Error::::AlreadyLeasedOut, + ); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 2, 1), + Error::::AlreadyLeasedOut, + ); + assert_noop!( + Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 3, 4, 1), + Error::::AlreadyLeasedOut, + ); + // This is okay, not an overlapping bid. + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 1, 1, 1)); + }); +} + +// Here we will test that taking only 10 samples during the ending period works as expected. +#[test] +fn less_winning_samples_work() { + new_test_ext().execute_with(|| { + let ed: u64 = ::ExistentialDeposit::get(); + assert_eq!(ed, 1); + EndingPeriod::set(30); + SampleLength::set(10); + + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11)); + let para_1 = ParaId::from(1_u32); + let para_2 = ParaId::from(2_u32); + let para_3 = ParaId::from(3_u32); + + // Make bids + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), para_1, 1, 11, 14, 9)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), para_2, 1, 13, 14, 19)); + + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; + winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 9)); + winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19)); + assert_eq!(Winning::::get(0), Some(winning)); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(10); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + assert_eq!(Winning::::get(0), Some(winning)); + + // New bids update the current winning + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 14, 14, 29)); + winning[SlotRange::ThreeThree as u8 as usize] = Some((3, para_3, 29)); + assert_eq!(Winning::::get(0), Some(winning)); + + run_to_block(20); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + assert_eq!(Winning::::get(1), Some(winning)); + run_to_block(25); + // Overbid mid sample + assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 13, 14, 29)); + winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 29)); + assert_eq!(Winning::::get(1), Some(winning)); + + run_to_block(30); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + assert_eq!(Winning::::get(2), Some(winning)); + + set_last_random(H256::from([254; 32]), 40); + run_to_block(40); + // Auction ended and winner selected + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + assert_eq!( + leases(), + vec![ + ((3.into(), 13), LeaseData { leaser: 3, amount: 29 }), + ((3.into(), 14), LeaseData { leaser: 3, amount: 29 }), + ] + ); + }); +} + +#[test] +fn auction_status_works() { + new_test_ext().execute_with(|| { + EndingPeriod::set(30); + SampleLength::set(10); + set_last_random(dummy_hash(), 0); + + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11)); + + run_to_block(9); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); + + run_to_block(10); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); + + run_to_block(11); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 1) + ); + + run_to_block(19); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 9) + ); + + run_to_block(20); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); + + run_to_block(25); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 5) + ); + + run_to_block(30); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); + + run_to_block(39); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 9) + ); + + run_to_block(40); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(0) + ); + + run_to_block(44); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(4) + ); + + set_last_random(dummy_hash(), 45); + run_to_block(45); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + }); +} + +#[test] +fn can_cancel_auction() { + new_test_ext().execute_with(|| { + run_to_block(1); + assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1)); + assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1)); + assert_eq!(Balances::reserved_balance(1), 1); + assert_eq!(Balances::free_balance(1), 9); + + assert_noop!(Auctions::cancel_auction(RuntimeOrigin::signed(6)), BadOrigin); + assert_ok!(Auctions::cancel_auction(RuntimeOrigin::root())); + + assert!(AuctionInfo::::get().is_none()); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(ReservedAmounts::::iter().count(), 0); + assert_eq!(Winning::::iter().count(), 0); + }); +} diff --git a/polkadot/runtime/common/src/paras_registrar/benchmarking.rs b/polkadot/runtime/common/src/paras_registrar/benchmarking.rs new file mode 100644 index 000000000000..95df8a969576 --- /dev/null +++ b/polkadot/runtime/common/src/paras_registrar/benchmarking.rs @@ -0,0 +1,171 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Benchmarking for paras_registrar pallet + +#[cfg(feature = "runtime-benchmarks")] +use super::{Pallet as Registrar, *}; +use crate::traits::Registrar as RegistrarT; +use frame_support::assert_ok; +use frame_system::RawOrigin; +use polkadot_primitives::{MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MIN_CODE_SIZE}; +use polkadot_runtime_parachains::{paras, shared, Origin as ParaOrigin}; +use sp_runtime::traits::Bounded; + +use frame_benchmarking::{account, benchmarks, whitelisted_caller}; + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +fn register_para(id: u32) -> ParaId { + let para = ParaId::from(id); + let genesis_head = Registrar::::worst_head_data(); + let validation_code = Registrar::::worst_validation_code(); + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + assert_ok!(Registrar::::reserve(RawOrigin::Signed(caller.clone()).into())); + assert_ok!(Registrar::::register( + RawOrigin::Signed(caller).into(), + para, + genesis_head, + validation_code.clone() + )); + assert_ok!(polkadot_runtime_parachains::paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + return para +} + +fn para_origin(id: u32) -> ParaOrigin { + ParaOrigin::Parachain(id.into()) +} + +// This function moves forward to the next scheduled session for parachain lifecycle upgrades. +fn next_scheduled_session() { + shared::Pallet::::set_session_index(shared::Pallet::::scheduled_session()); + paras::Pallet::::test_on_new_session(); +} + +benchmarks! { + where_clause { where ParaOrigin: Into<::RuntimeOrigin> } + + reserve { + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert_last_event::(Event::::Reserved { para_id: LOWEST_PUBLIC_ID, who: caller }.into()); + assert!(Paras::::get(LOWEST_PUBLIC_ID).is_some()); + assert_eq!(paras::Pallet::::lifecycle(LOWEST_PUBLIC_ID), None); + } + + register { + let para = LOWEST_PUBLIC_ID; + let genesis_head = Registrar::::worst_head_data(); + let validation_code = Registrar::::worst_validation_code(); + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + assert_ok!(Registrar::::reserve(RawOrigin::Signed(caller.clone()).into())); + }: _(RawOrigin::Signed(caller.clone()), para, genesis_head, validation_code.clone()) + verify { + assert_last_event::(Event::::Registered{ para_id: para, manager: caller }.into()); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Onboarding)); + assert_ok!(polkadot_runtime_parachains::paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + next_scheduled_session::(); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Parathread)); + } + + force_register { + let manager: T::AccountId = account("manager", 0, 0); + let deposit = 0u32.into(); + let para = ParaId::from(69); + let genesis_head = Registrar::::worst_head_data(); + let validation_code = Registrar::::worst_validation_code(); + }: _(RawOrigin::Root, manager.clone(), deposit, para, genesis_head, validation_code.clone()) + verify { + assert_last_event::(Event::::Registered { para_id: para, manager }.into()); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Onboarding)); + assert_ok!(polkadot_runtime_parachains::paras::Pallet::::add_trusted_validation_code( + frame_system::Origin::::Root.into(), + validation_code, + )); + next_scheduled_session::(); + assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Parathread)); + } + + deregister { + let para = register_para::(LOWEST_PUBLIC_ID.into()); + next_scheduled_session::(); + let caller: T::AccountId = whitelisted_caller(); + }: _(RawOrigin::Signed(caller), para) + verify { + assert_last_event::(Event::::Deregistered { para_id: para }.into()); + } + + swap { + // On demand parachain + let parathread = register_para::(LOWEST_PUBLIC_ID.into()); + let parachain = register_para::((LOWEST_PUBLIC_ID + 1).into()); + + let parachain_origin = para_origin(parachain.into()); + + // Actually finish registration process + next_scheduled_session::(); + + // Upgrade the parachain + Registrar::::make_parachain(parachain)?; + next_scheduled_session::(); + + assert_eq!(paras::Pallet::::lifecycle(parachain), Some(ParaLifecycle::Parachain)); + assert_eq!(paras::Pallet::::lifecycle(parathread), Some(ParaLifecycle::Parathread)); + + let caller: T::AccountId = whitelisted_caller(); + Registrar::::swap(parachain_origin.into(), parachain, parathread)?; + }: _(RawOrigin::Signed(caller.clone()), parathread, parachain) + verify { + next_scheduled_session::(); + // Swapped! + assert_eq!(paras::Pallet::::lifecycle(parachain), Some(ParaLifecycle::Parathread)); + assert_eq!(paras::Pallet::::lifecycle(parathread), Some(ParaLifecycle::Parachain)); + } + + schedule_code_upgrade { + let b in MIN_CODE_SIZE .. MAX_CODE_SIZE; + let new_code = ValidationCode(vec![0; b as usize]); + let para_id = ParaId::from(1000); + }: _(RawOrigin::Root, para_id, new_code) + + set_current_head { + let b in 1 .. MAX_HEAD_DATA_SIZE; + let new_head = HeadData(vec![0; b as usize]); + let para_id = ParaId::from(1000); + }: _(RawOrigin::Root, para_id, new_head) + + impl_benchmark_test_suite!( + Registrar, + crate::integration_tests::new_test_ext(), + crate::integration_tests::Test, + ); +} diff --git a/polkadot/runtime/common/src/paras_registrar/mock.rs b/polkadot/runtime/common/src/paras_registrar/mock.rs new file mode 100644 index 000000000000..f256d594bad9 --- /dev/null +++ b/polkadot/runtime/common/src/paras_registrar/mock.rs @@ -0,0 +1,255 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Mocking utilities for testing in paras_registrar pallet. + +#[cfg(test)] +use super::*; +use crate::paras_registrar; +use alloc::collections::btree_map::BTreeMap; +use frame_support::{ + derive_impl, parameter_types, + traits::{OnFinalize, OnInitialize}, +}; +use frame_system::limits; +use polkadot_primitives::{Balance, BlockNumber, MAX_CODE_SIZE}; +use polkadot_runtime_parachains::{configuration, origin, shared}; +use sp_core::H256; +use sp_io::TestExternalities; +use sp_keyring::Sr25519Keyring; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + transaction_validity::TransactionPriority, + BuildStorage, Perbill, +}; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlockU32; + +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Balances: pallet_balances, + Configuration: configuration, + Parachains: paras, + ParasShared: shared, + Registrar: paras_registrar, + ParachainsOrigin: origin, + } +); + +impl frame_system::offchain::CreateTransactionBase for Test +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type RuntimeCall = RuntimeCall; +} + +impl frame_system::offchain::CreateInherent for Test +where + RuntimeCall: From, +{ + fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic { + UncheckedExtrinsic::new_bare(call) + } +} + +const NORMAL_RATIO: Perbill = Perbill::from_percent(75); +parameter_types! { + pub BlockWeights: limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); + pub BlockLength: limits::BlockLength = + limits::BlockLength::max_with_normal_ratio(4 * 1024 * 1024, NORMAL_RATIO); +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type DbWeight = (); + type BlockWeights = BlockWeights; + type BlockLength = BlockLength; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Test { + type Balance = Balance; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} + +impl shared::Config for Test { + type DisabledValidators = (); +} + +impl origin::Config for Test {} + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); +} + +impl paras::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = paras::TestWeightInfo; + type UnsignedPriority = ParasUnsignedPriority; + type QueueFootprinter = (); + type NextSessionRotation = crate::mock::TestNextSessionRotation; + type OnNewHead = (); + type AssignCoretime = (); +} + +impl configuration::Config for Test { + type WeightInfo = configuration::TestWeightInfo; +} + +parameter_types! { + pub const ParaDeposit: Balance = 10; + pub const DataDepositPerByte: Balance = 1; + pub const MaxRetries: u32 = 3; +} + +impl Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type OnSwap = MockSwap; + type ParaDeposit = ParaDeposit; + type DataDepositPerByte = DataDepositPerByte; + type WeightInfo = TestWeightInfo; +} + +pub fn new_test_ext() -> TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + configuration::GenesisConfig:: { + config: configuration::HostConfiguration { + max_code_size: MAX_CODE_SIZE, + max_head_data_size: 1 * 1024 * 1024, // 1 MB + ..Default::default() + }, + } + .assimilate_storage(&mut t) + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10_000_000), (2, 10_000_000), (3, 10_000_000)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); + + t.into() +} + +parameter_types! { + pub static SwapData: BTreeMap = BTreeMap::new(); +} + +pub struct MockSwap; +impl OnSwap for MockSwap { + fn on_swap(one: ParaId, other: ParaId) { + let mut swap_data = SwapData::get(); + let one_data = swap_data.remove(&one).unwrap_or_default(); + let other_data = swap_data.remove(&other).unwrap_or_default(); + swap_data.insert(one, other_data); + swap_data.insert(other, one_data); + SwapData::set(swap_data); + } +} + +pub const BLOCKS_PER_SESSION: u32 = 3; + +pub const VALIDATORS: &[Sr25519Keyring] = &[ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Ferdie, +]; + +pub fn run_to_block(n: BlockNumber) { + // NOTE that this function only simulates modules of interest. Depending on new pallet may + // require adding it here. + assert!(System::block_number() < n); + while System::block_number() < n { + let b = System::block_number(); + + if System::block_number() > 1 { + System::on_finalize(System::block_number()); + } + // Session change every 3 blocks. + if (b + 1) % BLOCKS_PER_SESSION == 0 { + let session_index = shared::CurrentSessionIndex::::get() + 1; + let validators_pub_keys = VALIDATORS.iter().map(|v| v.public().into()).collect(); + + shared::Pallet::::set_session_index(session_index); + shared::Pallet::::set_active_validators_ascending(validators_pub_keys); + + Parachains::test_on_new_session(); + } + System::set_block_number(b + 1); + System::on_initialize(System::block_number()); + } +} + +pub fn run_to_session(n: BlockNumber) { + let block_number = n * BLOCKS_PER_SESSION; + run_to_block(block_number); +} + +pub fn test_genesis_head(size: usize) -> HeadData { + HeadData(vec![0u8; size]) +} + +pub fn test_validation_code(size: usize) -> ValidationCode { + let validation_code = vec![0u8; size as usize]; + ValidationCode(validation_code) +} + +pub fn para_origin(id: ParaId) -> RuntimeOrigin { + polkadot_runtime_parachains::Origin::Parachain(id).into() +} + +pub fn max_code_size() -> u32 { + configuration::ActiveConfig::::get().max_code_size +} + +pub fn max_head_size() -> u32 { + configuration::ActiveConfig::::get().max_head_data_size +} diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 0dae1c98cd60..aed0729c9d51 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -561,15 +561,16 @@ impl Pallet { origin: ::RuntimeOrigin, id: ParaId, ) -> DispatchResult { - ensure_signed(origin.clone()) - .map_err(|e| e.into()) - .and_then(|who| -> DispatchResult { - let para_info = Paras::::get(id).ok_or(Error::::NotRegistered)?; + if let Ok(who) = ensure_signed(origin.clone()) { + let para_info = Paras::::get(id).ok_or(Error::::NotRegistered)?; + + if para_info.manager == who { ensure!(!para_info.is_locked(), Error::::ParaLocked); - ensure!(para_info.manager == who, Error::::NotOwner); - Ok(()) - }) - .or_else(|_| -> DispatchResult { Self::ensure_root_or_para(origin, id) }) + return Ok(()) + } + } + + Self::ensure_root_or_para(origin, id) } /// Ensure the origin is one of Root or the `para` itself. @@ -577,14 +578,14 @@ impl Pallet { origin: ::RuntimeOrigin, id: ParaId, ) -> DispatchResult { - if let Ok(caller_id) = ensure_parachain(::RuntimeOrigin::from(origin.clone())) - { - // Check if matching para id... - ensure!(caller_id == id, Error::::NotOwner); - } else { - // Check if root... - ensure_root(origin.clone())?; + if ensure_root(origin.clone()).is_ok() { + return Ok(()) } + + let caller_id = ensure_parachain(::RuntimeOrigin::from(origin))?; + // Check if matching para id... + ensure!(caller_id == id, Error::::NotOwner); + Ok(()) } @@ -713,968 +714,10 @@ impl OnNewHead for Pallet { } #[cfg(test)] -mod tests { - use super::*; - use crate::{ - mock::conclude_pvf_checking, paras_registrar, traits::Registrar as RegistrarTrait, - }; - use alloc::collections::btree_map::BTreeMap; - use frame_support::{ - assert_noop, assert_ok, derive_impl, parameter_types, - traits::{OnFinalize, OnInitialize}, - }; - use frame_system::limits; - use pallet_balances::Error as BalancesError; - use polkadot_primitives::{Balance, BlockNumber, SessionIndex, MAX_CODE_SIZE}; - use polkadot_runtime_parachains::{configuration, origin, shared}; - use sp_core::H256; - use sp_io::TestExternalities; - use sp_keyring::Sr25519Keyring; - use sp_runtime::{ - traits::{BadOrigin, BlakeTwo256, IdentityLookup}, - transaction_validity::TransactionPriority, - BuildStorage, Perbill, - }; - - type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; - type Block = frame_system::mocking::MockBlockU32; - - frame_support::construct_runtime!( - pub enum Test - { - System: frame_system, - Balances: pallet_balances, - Configuration: configuration, - Parachains: paras, - ParasShared: shared, - Registrar: paras_registrar, - ParachainsOrigin: origin, - } - ); - - impl frame_system::offchain::CreateTransactionBase for Test - where - RuntimeCall: From, - { - type Extrinsic = UncheckedExtrinsic; - type RuntimeCall = RuntimeCall; - } - - impl frame_system::offchain::CreateInherent for Test - where - RuntimeCall: From, - { - fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic { - UncheckedExtrinsic::new_bare(call) - } - } - - const NORMAL_RATIO: Perbill = Perbill::from_percent(75); - parameter_types! { - pub BlockWeights: limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); - pub BlockLength: limits::BlockLength = - limits::BlockLength::max_with_normal_ratio(4 * 1024 * 1024, NORMAL_RATIO); - } - - #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] - impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Nonce = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Block = Block; - type RuntimeEvent = RuntimeEvent; - type DbWeight = (); - type BlockWeights = BlockWeights; - type BlockLength = BlockLength; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; - } - - parameter_types! { - pub const ExistentialDeposit: Balance = 1; - } - - #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] - impl pallet_balances::Config for Test { - type Balance = Balance; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - } - - impl shared::Config for Test { - type DisabledValidators = (); - } - - impl origin::Config for Test {} - - parameter_types! { - pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); - } - - impl paras::Config for Test { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = paras::TestWeightInfo; - type UnsignedPriority = ParasUnsignedPriority; - type QueueFootprinter = (); - type NextSessionRotation = crate::mock::TestNextSessionRotation; - type OnNewHead = (); - type AssignCoretime = (); - } - - impl configuration::Config for Test { - type WeightInfo = configuration::TestWeightInfo; - } - - parameter_types! { - pub const ParaDeposit: Balance = 10; - pub const DataDepositPerByte: Balance = 1; - pub const MaxRetries: u32 = 3; - } - - impl Config for Test { - type RuntimeOrigin = RuntimeOrigin; - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type OnSwap = MockSwap; - type ParaDeposit = ParaDeposit; - type DataDepositPerByte = DataDepositPerByte; - type WeightInfo = TestWeightInfo; - } - - pub fn new_test_ext() -> TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - - configuration::GenesisConfig:: { - config: configuration::HostConfiguration { - max_code_size: MAX_CODE_SIZE, - max_head_data_size: 1 * 1024 * 1024, // 1 MB - ..Default::default() - }, - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_balances::GenesisConfig:: { - balances: vec![(1, 10_000_000), (2, 10_000_000), (3, 10_000_000)], - ..Default::default() - } - .assimilate_storage(&mut t) - .unwrap(); - - t.into() - } - - parameter_types! { - pub static SwapData: BTreeMap = BTreeMap::new(); - } - - pub struct MockSwap; - impl OnSwap for MockSwap { - fn on_swap(one: ParaId, other: ParaId) { - let mut swap_data = SwapData::get(); - let one_data = swap_data.remove(&one).unwrap_or_default(); - let other_data = swap_data.remove(&other).unwrap_or_default(); - swap_data.insert(one, other_data); - swap_data.insert(other, one_data); - SwapData::set(swap_data); - } - } - - const BLOCKS_PER_SESSION: u32 = 3; - - const VALIDATORS: &[Sr25519Keyring] = &[ - Sr25519Keyring::Alice, - Sr25519Keyring::Bob, - Sr25519Keyring::Charlie, - Sr25519Keyring::Dave, - Sr25519Keyring::Ferdie, - ]; - - fn run_to_block(n: BlockNumber) { - // NOTE that this function only simulates modules of interest. Depending on new pallet may - // require adding it here. - assert!(System::block_number() < n); - while System::block_number() < n { - let b = System::block_number(); - - if System::block_number() > 1 { - System::on_finalize(System::block_number()); - } - // Session change every 3 blocks. - if (b + 1) % BLOCKS_PER_SESSION == 0 { - let session_index = shared::CurrentSessionIndex::::get() + 1; - let validators_pub_keys = VALIDATORS.iter().map(|v| v.public().into()).collect(); - - shared::Pallet::::set_session_index(session_index); - shared::Pallet::::set_active_validators_ascending(validators_pub_keys); - - Parachains::test_on_new_session(); - } - System::set_block_number(b + 1); - System::on_initialize(System::block_number()); - } - } - - fn run_to_session(n: BlockNumber) { - let block_number = n * BLOCKS_PER_SESSION; - run_to_block(block_number); - } - - fn test_genesis_head(size: usize) -> HeadData { - HeadData(vec![0u8; size]) - } +mod mock; - fn test_validation_code(size: usize) -> ValidationCode { - let validation_code = vec![0u8; size as usize]; - ValidationCode(validation_code) - } - - fn para_origin(id: ParaId) -> RuntimeOrigin { - polkadot_runtime_parachains::Origin::Parachain(id).into() - } - - fn max_code_size() -> u32 { - configuration::ActiveConfig::::get().max_code_size - } - - fn max_head_size() -> u32 { - configuration::ActiveConfig::::get().max_head_data_size - } - - #[test] - fn basic_setup_works() { - new_test_ext().execute_with(|| { - assert_eq!(PendingSwap::::get(&ParaId::from(0u32)), None); - assert_eq!(Paras::::get(&ParaId::from(0u32)), None); - }); - } - - #[test] - fn end_to_end_scenario_works() { - new_test_ext().execute_with(|| { - let para_id = LOWEST_PUBLIC_ID; - - const START_SESSION_INDEX: SessionIndex = 1; - run_to_session(START_SESSION_INDEX); - - // first para is not yet registered - assert!(!Parachains::is_parathread(para_id)); - // We register the Para ID - let validation_code = test_validation_code(32); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(32), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); - - run_to_session(START_SESSION_INDEX + 2); - // It is now a parathread (on-demand parachain). - assert!(Parachains::is_parathread(para_id)); - assert!(!Parachains::is_parachain(para_id)); - // Some other external process will elevate on-demand to lease holding parachain - assert_ok!(Registrar::make_parachain(para_id)); - run_to_session(START_SESSION_INDEX + 4); - // It is now a lease holding parachain. - assert!(!Parachains::is_parathread(para_id)); - assert!(Parachains::is_parachain(para_id)); - // Turn it back into a parathread (on-demand parachain) - assert_ok!(Registrar::make_parathread(para_id)); - run_to_session(START_SESSION_INDEX + 6); - assert!(Parachains::is_parathread(para_id)); - assert!(!Parachains::is_parachain(para_id)); - // Deregister it - assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id,)); - run_to_session(START_SESSION_INDEX + 8); - // It is nothing - assert!(!Parachains::is_parathread(para_id)); - assert!(!Parachains::is_parachain(para_id)); - }); - } - - #[test] - fn register_works() { - new_test_ext().execute_with(|| { - const START_SESSION_INDEX: SessionIndex = 1; - run_to_session(START_SESSION_INDEX); - - let para_id = LOWEST_PUBLIC_ID; - assert!(!Parachains::is_parathread(para_id)); - - let validation_code = test_validation_code(32); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - assert_eq!(Balances::reserved_balance(&1), ::ParaDeposit::get()); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(32), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); - - run_to_session(START_SESSION_INDEX + 2); - assert!(Parachains::is_parathread(para_id)); - // Even though the registered validation code has a smaller size than the maximum the - // para manager's deposit is reserved as though they registered the maximum-sized code. - // Consequently, they can upgrade their code to the maximum size at any point without - // additional cost. - let validation_code_deposit = - max_code_size() as BalanceOf * ::DataDepositPerByte::get(); - let head_deposit = 32 * ::DataDepositPerByte::get(); - assert_eq!( - Balances::reserved_balance(&1), - ::ParaDeposit::get() + head_deposit + validation_code_deposit - ); - }); - } - - #[test] - fn schedule_code_upgrade_validates_code() { - new_test_ext().execute_with(|| { - const START_SESSION_INDEX: SessionIndex = 1; - run_to_session(START_SESSION_INDEX); - - let para_id = LOWEST_PUBLIC_ID; - assert!(!Parachains::is_parathread(para_id)); - - let validation_code = test_validation_code(32); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - assert_eq!(Balances::reserved_balance(&1), ::ParaDeposit::get()); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(32), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); - - run_to_session(START_SESSION_INDEX + 2); - assert!(Parachains::is_parathread(para_id)); - - let new_code = test_validation_code(0); - assert_noop!( - Registrar::schedule_code_upgrade( - RuntimeOrigin::signed(1), - para_id, - new_code.clone(), - ), - paras::Error::::InvalidCode - ); - - let new_code = test_validation_code(max_code_size() as usize + 1); - assert_noop!( - Registrar::schedule_code_upgrade( - RuntimeOrigin::signed(1), - para_id, - new_code.clone(), - ), - paras::Error::::InvalidCode - ); - }); - } - - #[test] - fn register_handles_basic_errors() { - new_test_ext().execute_with(|| { - let para_id = LOWEST_PUBLIC_ID; - - assert_noop!( - Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(max_head_size() as usize), - test_validation_code(max_code_size() as usize), - ), - Error::::NotReserved - ); - - // Successfully register para - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - - assert_noop!( - Registrar::register( - RuntimeOrigin::signed(2), - para_id, - test_genesis_head(max_head_size() as usize), - test_validation_code(max_code_size() as usize), - ), - Error::::NotOwner - ); - - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(max_head_size() as usize), - test_validation_code(max_code_size() as usize), - )); - // Can skip pre-check and deregister para which's still onboarding. - run_to_session(2); - - assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id)); - - // Can't do it again - assert_noop!( - Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(max_head_size() as usize), - test_validation_code(max_code_size() as usize), - ), - Error::::NotReserved - ); - - // Head Size Check - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2))); - assert_noop!( - Registrar::register( - RuntimeOrigin::signed(2), - para_id + 1, - test_genesis_head((max_head_size() + 1) as usize), - test_validation_code(max_code_size() as usize), - ), - Error::::HeadDataTooLarge - ); - - // Code Size Check - assert_noop!( - Registrar::register( - RuntimeOrigin::signed(2), - para_id + 1, - test_genesis_head(max_head_size() as usize), - test_validation_code((max_code_size() + 1) as usize), - ), - Error::::CodeTooLarge - ); - - // Needs enough funds for deposit - assert_noop!( - Registrar::reserve(RuntimeOrigin::signed(1337)), - BalancesError::::InsufficientBalance - ); - }); - } - - #[test] - fn deregister_works() { - new_test_ext().execute_with(|| { - const START_SESSION_INDEX: SessionIndex = 1; - run_to_session(START_SESSION_INDEX); - - let para_id = LOWEST_PUBLIC_ID; - assert!(!Parachains::is_parathread(para_id)); - - let validation_code = test_validation_code(32); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(32), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); - - run_to_session(START_SESSION_INDEX + 2); - assert!(Parachains::is_parathread(para_id)); - assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id,)); - run_to_session(START_SESSION_INDEX + 4); - assert!(paras::Pallet::::lifecycle(para_id).is_none()); - assert_eq!(Balances::reserved_balance(&1), 0); - }); - } - - #[test] - fn deregister_handles_basic_errors() { - new_test_ext().execute_with(|| { - const START_SESSION_INDEX: SessionIndex = 1; - run_to_session(START_SESSION_INDEX); - - let para_id = LOWEST_PUBLIC_ID; - assert!(!Parachains::is_parathread(para_id)); - - let validation_code = test_validation_code(32); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_id, - test_genesis_head(32), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); - - run_to_session(START_SESSION_INDEX + 2); - assert!(Parachains::is_parathread(para_id)); - // Owner check - assert_noop!(Registrar::deregister(RuntimeOrigin::signed(2), para_id,), BadOrigin); - assert_ok!(Registrar::make_parachain(para_id)); - run_to_session(START_SESSION_INDEX + 4); - // Cant directly deregister parachain - assert_noop!( - Registrar::deregister(RuntimeOrigin::root(), para_id,), - Error::::NotParathread - ); - }); - } - - #[test] - fn swap_works() { - new_test_ext().execute_with(|| { - const START_SESSION_INDEX: SessionIndex = 1; - run_to_session(START_SESSION_INDEX); - - // Successfully register first two parachains - let para_1 = LOWEST_PUBLIC_ID; - let para_2 = LOWEST_PUBLIC_ID + 1; - - let validation_code = test_validation_code(max_code_size() as usize); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_1, - test_genesis_head(max_head_size() as usize), - validation_code.clone(), - )); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2))); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(2), - para_2, - test_genesis_head(max_head_size() as usize), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); - - run_to_session(START_SESSION_INDEX + 2); - - // Upgrade para 1 into a parachain - assert_ok!(Registrar::make_parachain(para_1)); - - // Set some mock swap data. - let mut swap_data = SwapData::get(); - swap_data.insert(para_1, 69); - swap_data.insert(para_2, 1337); - SwapData::set(swap_data); - - run_to_session(START_SESSION_INDEX + 4); - - // Roles are as we expect - assert!(Parachains::is_parachain(para_1)); - assert!(!Parachains::is_parathread(para_1)); - assert!(!Parachains::is_parachain(para_2)); - assert!(Parachains::is_parathread(para_2)); - - // Both paras initiate a swap - // Swap between parachain and parathread - assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,)); - assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,)); - System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { - para_id: para_2, - other_id: para_1, - })); - - run_to_session(START_SESSION_INDEX + 6); - - // Roles are swapped - assert!(!Parachains::is_parachain(para_1)); - assert!(Parachains::is_parathread(para_1)); - assert!(Parachains::is_parachain(para_2)); - assert!(!Parachains::is_parathread(para_2)); - - // Data is swapped - assert_eq!(SwapData::get().get(¶_1).unwrap(), &1337); - assert_eq!(SwapData::get().get(¶_2).unwrap(), &69); - - // Both paras initiate a swap - // Swap between parathread and parachain - assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,)); - assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,)); - System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { - para_id: para_2, - other_id: para_1, - })); - - // Data is swapped - assert_eq!(SwapData::get().get(¶_1).unwrap(), &69); - assert_eq!(SwapData::get().get(¶_2).unwrap(), &1337); - - // Parachain to parachain swap - let para_3 = LOWEST_PUBLIC_ID + 2; - let validation_code = test_validation_code(max_code_size() as usize); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(3))); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(3), - para_3, - test_genesis_head(max_head_size() as usize), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX + 6); - - run_to_session(START_SESSION_INDEX + 8); - - // Upgrade para 3 into a parachain - assert_ok!(Registrar::make_parachain(para_3)); - - // Set some mock swap data. - let mut swap_data = SwapData::get(); - swap_data.insert(para_3, 777); - SwapData::set(swap_data); - - run_to_session(START_SESSION_INDEX + 10); - - // Both are parachains - assert!(Parachains::is_parachain(para_3)); - assert!(!Parachains::is_parathread(para_3)); - assert!(Parachains::is_parachain(para_1)); - assert!(!Parachains::is_parathread(para_1)); - - // Both paras initiate a swap - // Swap between parachain and parachain - assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_3,)); - assert_ok!(Registrar::swap(para_origin(para_3), para_3, para_1,)); - System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { - para_id: para_3, - other_id: para_1, - })); - - // Data is swapped - assert_eq!(SwapData::get().get(¶_3).unwrap(), &69); - assert_eq!(SwapData::get().get(¶_1).unwrap(), &777); - }); - } - - #[test] - fn para_lock_works() { - new_test_ext().execute_with(|| { - run_to_block(1); - - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - let para_id = LOWEST_PUBLIC_ID; - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_id, - vec![1; 3].into(), - test_validation_code(32) - )); - - assert_noop!(Registrar::add_lock(RuntimeOrigin::signed(2), para_id), BadOrigin); - - // Once they produces new block, we lock them in. - Registrar::on_new_head(para_id, &Default::default()); - - // Owner cannot pass origin check when checking lock - assert_noop!( - Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id), - BadOrigin - ); - // Owner cannot remove lock. - assert_noop!(Registrar::remove_lock(RuntimeOrigin::signed(1), para_id), BadOrigin); - // Para can. - assert_ok!(Registrar::remove_lock(para_origin(para_id), para_id)); - // Owner can pass origin check again - assert_ok!(Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id)); - - // Won't lock again after it is unlocked - Registrar::on_new_head(para_id, &Default::default()); - - assert_ok!(Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id)); - }); - } - - #[test] - fn swap_handles_bad_states() { - new_test_ext().execute_with(|| { - const START_SESSION_INDEX: SessionIndex = 1; - run_to_session(START_SESSION_INDEX); - - let para_1 = LOWEST_PUBLIC_ID; - let para_2 = LOWEST_PUBLIC_ID + 1; - - // paras are not yet registered - assert!(!Parachains::is_parathread(para_1)); - assert!(!Parachains::is_parathread(para_2)); - - // Cannot even start a swap - assert_noop!( - Registrar::swap(RuntimeOrigin::root(), para_1, para_2), - Error::::NotRegistered - ); - - // We register Paras 1 and 2 - let validation_code = test_validation_code(32); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1))); - assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2))); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(1), - para_1, - test_genesis_head(32), - validation_code.clone(), - )); - assert_ok!(Registrar::register( - RuntimeOrigin::signed(2), - para_2, - test_genesis_head(32), - validation_code.clone(), - )); - conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); - - // Cannot swap - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); - assert_noop!( - Registrar::swap(RuntimeOrigin::root(), para_2, para_1), - Error::::CannotSwap - ); - - run_to_session(START_SESSION_INDEX + 2); - - // They are now parathreads (on-demand parachains). - assert!(Parachains::is_parathread(para_1)); - assert!(Parachains::is_parathread(para_2)); - - // Cannot swap - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); - assert_noop!( - Registrar::swap(RuntimeOrigin::root(), para_2, para_1), - Error::::CannotSwap - ); - - // Some other external process will elevate one on-demand - // parachain to a lease holding parachain - assert_ok!(Registrar::make_parachain(para_1)); - - // Cannot swap - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); - assert_noop!( - Registrar::swap(RuntimeOrigin::root(), para_2, para_1), - Error::::CannotSwap - ); - - run_to_session(START_SESSION_INDEX + 3); - - // Cannot swap - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); - assert_noop!( - Registrar::swap(RuntimeOrigin::root(), para_2, para_1), - Error::::CannotSwap - ); - - run_to_session(START_SESSION_INDEX + 4); - - // It is now a lease holding parachain. - assert!(Parachains::is_parachain(para_1)); - assert!(Parachains::is_parathread(para_2)); - - // Swap works here. - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_2, para_1)); - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. }) - ))); - - run_to_session(START_SESSION_INDEX + 5); - - // Cannot swap - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); - assert_noop!( - Registrar::swap(RuntimeOrigin::root(), para_2, para_1), - Error::::CannotSwap - ); - - run_to_session(START_SESSION_INDEX + 6); - - // Swap worked! - assert!(Parachains::is_parachain(para_2)); - assert!(Parachains::is_parathread(para_1)); - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. }) - ))); - - // Something starts to downgrade a para - assert_ok!(Registrar::make_parathread(para_2)); - - run_to_session(START_SESSION_INDEX + 7); - - // Cannot swap - assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); - assert_noop!( - Registrar::swap(RuntimeOrigin::root(), para_2, para_1), - Error::::CannotSwap - ); - - run_to_session(START_SESSION_INDEX + 8); - - assert!(Parachains::is_parathread(para_1)); - assert!(Parachains::is_parathread(para_2)); - }); - } -} +#[cfg(test)] +mod tests; #[cfg(feature = "runtime-benchmarks")] -mod benchmarking { - use super::{Pallet as Registrar, *}; - use crate::traits::Registrar as RegistrarT; - use frame_support::assert_ok; - use frame_system::RawOrigin; - use polkadot_primitives::{MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MIN_CODE_SIZE}; - use polkadot_runtime_parachains::{paras, shared, Origin as ParaOrigin}; - use sp_runtime::traits::Bounded; - - use frame_benchmarking::{account, benchmarks, whitelisted_caller}; - - fn assert_last_event(generic_event: ::RuntimeEvent) { - let events = frame_system::Pallet::::events(); - let system_event: ::RuntimeEvent = generic_event.into(); - // compare to the last event record - let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; - assert_eq!(event, &system_event); - } - - fn register_para(id: u32) -> ParaId { - let para = ParaId::from(id); - let genesis_head = Registrar::::worst_head_data(); - let validation_code = Registrar::::worst_validation_code(); - let caller: T::AccountId = whitelisted_caller(); - T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); - assert_ok!(Registrar::::reserve(RawOrigin::Signed(caller.clone()).into())); - assert_ok!(Registrar::::register( - RawOrigin::Signed(caller).into(), - para, - genesis_head, - validation_code.clone() - )); - assert_ok!(polkadot_runtime_parachains::paras::Pallet::::add_trusted_validation_code( - frame_system::Origin::::Root.into(), - validation_code, - )); - return para - } - - fn para_origin(id: u32) -> ParaOrigin { - ParaOrigin::Parachain(id.into()) - } - - // This function moves forward to the next scheduled session for parachain lifecycle upgrades. - fn next_scheduled_session() { - shared::Pallet::::set_session_index(shared::Pallet::::scheduled_session()); - paras::Pallet::::test_on_new_session(); - } - - benchmarks! { - where_clause { where ParaOrigin: Into<::RuntimeOrigin> } - - reserve { - let caller: T::AccountId = whitelisted_caller(); - T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert_last_event::(Event::::Reserved { para_id: LOWEST_PUBLIC_ID, who: caller }.into()); - assert!(Paras::::get(LOWEST_PUBLIC_ID).is_some()); - assert_eq!(paras::Pallet::::lifecycle(LOWEST_PUBLIC_ID), None); - } - - register { - let para = LOWEST_PUBLIC_ID; - let genesis_head = Registrar::::worst_head_data(); - let validation_code = Registrar::::worst_validation_code(); - let caller: T::AccountId = whitelisted_caller(); - T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); - assert_ok!(Registrar::::reserve(RawOrigin::Signed(caller.clone()).into())); - }: _(RawOrigin::Signed(caller.clone()), para, genesis_head, validation_code.clone()) - verify { - assert_last_event::(Event::::Registered{ para_id: para, manager: caller }.into()); - assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Onboarding)); - assert_ok!(polkadot_runtime_parachains::paras::Pallet::::add_trusted_validation_code( - frame_system::Origin::::Root.into(), - validation_code, - )); - next_scheduled_session::(); - assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Parathread)); - } - - force_register { - let manager: T::AccountId = account("manager", 0, 0); - let deposit = 0u32.into(); - let para = ParaId::from(69); - let genesis_head = Registrar::::worst_head_data(); - let validation_code = Registrar::::worst_validation_code(); - }: _(RawOrigin::Root, manager.clone(), deposit, para, genesis_head, validation_code.clone()) - verify { - assert_last_event::(Event::::Registered { para_id: para, manager }.into()); - assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Onboarding)); - assert_ok!(polkadot_runtime_parachains::paras::Pallet::::add_trusted_validation_code( - frame_system::Origin::::Root.into(), - validation_code, - )); - next_scheduled_session::(); - assert_eq!(paras::Pallet::::lifecycle(para), Some(ParaLifecycle::Parathread)); - } - - deregister { - let para = register_para::(LOWEST_PUBLIC_ID.into()); - next_scheduled_session::(); - let caller: T::AccountId = whitelisted_caller(); - }: _(RawOrigin::Signed(caller), para) - verify { - assert_last_event::(Event::::Deregistered { para_id: para }.into()); - } - - swap { - // On demand parachain - let parathread = register_para::(LOWEST_PUBLIC_ID.into()); - let parachain = register_para::((LOWEST_PUBLIC_ID + 1).into()); - - let parachain_origin = para_origin(parachain.into()); - - // Actually finish registration process - next_scheduled_session::(); - - // Upgrade the parachain - Registrar::::make_parachain(parachain)?; - next_scheduled_session::(); - - assert_eq!(paras::Pallet::::lifecycle(parachain), Some(ParaLifecycle::Parachain)); - assert_eq!(paras::Pallet::::lifecycle(parathread), Some(ParaLifecycle::Parathread)); - - let caller: T::AccountId = whitelisted_caller(); - Registrar::::swap(parachain_origin.into(), parachain, parathread)?; - }: _(RawOrigin::Signed(caller.clone()), parathread, parachain) - verify { - next_scheduled_session::(); - // Swapped! - assert_eq!(paras::Pallet::::lifecycle(parachain), Some(ParaLifecycle::Parathread)); - assert_eq!(paras::Pallet::::lifecycle(parathread), Some(ParaLifecycle::Parachain)); - } - - schedule_code_upgrade { - let b in MIN_CODE_SIZE .. MAX_CODE_SIZE; - let new_code = ValidationCode(vec![0; b as usize]); - let para_id = ParaId::from(1000); - }: _(RawOrigin::Root, para_id, new_code) - - set_current_head { - let b in 1 .. MAX_HEAD_DATA_SIZE; - let new_head = HeadData(vec![0; b as usize]); - let para_id = ParaId::from(1000); - }: _(RawOrigin::Root, para_id, new_head) - - impl_benchmark_test_suite!( - Registrar, - crate::integration_tests::new_test_ext(), - crate::integration_tests::Test, - ); - } -} +mod benchmarking; diff --git a/polkadot/runtime/common/src/paras_registrar/tests.rs b/polkadot/runtime/common/src/paras_registrar/tests.rs new file mode 100644 index 000000000000..66fef31c9afd --- /dev/null +++ b/polkadot/runtime/common/src/paras_registrar/tests.rs @@ -0,0 +1,588 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tests for the paras_registrar pallet. + +#[cfg(test)] +use super::*; +use crate::{ + mock::conclude_pvf_checking, paras_registrar, paras_registrar::mock::*, + traits::Registrar as RegistrarTrait, +}; +use frame_support::{assert_noop, assert_ok}; +use pallet_balances::Error as BalancesError; +use polkadot_primitives::SessionIndex; +use sp_runtime::traits::BadOrigin; + +#[test] +fn end_to_end_scenario_works() { + new_test_ext().execute_with(|| { + let para_id = LOWEST_PUBLIC_ID; + + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // first para is not yet registered + assert!(!Parachains::is_parathread(para_id)); + // We register the Para ID + let validation_code = test_validation_code(32); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + // It is now a parathread (on-demand parachain). + assert!(Parachains::is_parathread(para_id)); + assert!(!Parachains::is_parachain(para_id)); + // Some other external process will elevate on-demand to lease holding parachain + assert_ok!(mock::Registrar::make_parachain(para_id)); + run_to_session(START_SESSION_INDEX + 4); + // It is now a lease holding parachain. + assert!(!Parachains::is_parathread(para_id)); + assert!(Parachains::is_parachain(para_id)); + // Turn it back into a parathread (on-demand parachain) + assert_ok!(mock::Registrar::make_parathread(para_id)); + run_to_session(START_SESSION_INDEX + 6); + assert!(Parachains::is_parathread(para_id)); + assert!(!Parachains::is_parachain(para_id)); + // Deregister it + assert_ok!(mock::Registrar::deregister(RuntimeOrigin::root(), para_id,)); + run_to_session(START_SESSION_INDEX + 8); + // It is nothing + assert!(!Parachains::is_parathread(para_id)); + assert!(!Parachains::is_parachain(para_id)); + }); +} + +#[test] +fn register_works() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_id = LOWEST_PUBLIC_ID; + assert!(!Parachains::is_parathread(para_id)); + + let validation_code = test_validation_code(32); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + assert_eq!(Balances::reserved_balance(&1), ::ParaDeposit::get()); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + assert!(Parachains::is_parathread(para_id)); + // Even though the registered validation code has a smaller size than the maximum the + // para manager's deposit is reserved as though they registered the maximum-sized code. + // Consequently, they can upgrade their code to the maximum size at any point without + // additional cost. + let validation_code_deposit = + max_code_size() as BalanceOf * ::DataDepositPerByte::get(); + let head_deposit = 32 * ::DataDepositPerByte::get(); + assert_eq!( + Balances::reserved_balance(&1), + ::ParaDeposit::get() + head_deposit + validation_code_deposit + ); + }); +} + +#[test] +fn schedule_code_upgrade_validates_code() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_id = LOWEST_PUBLIC_ID; + assert!(!Parachains::is_parathread(para_id)); + + let validation_code = test_validation_code(32); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + assert_eq!(Balances::reserved_balance(&1), ::ParaDeposit::get()); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + assert!(Parachains::is_parathread(para_id)); + + let new_code = test_validation_code(0); + assert_noop!( + mock::Registrar::schedule_code_upgrade( + RuntimeOrigin::signed(1), + para_id, + new_code.clone(), + ), + paras::Error::::InvalidCode + ); + + let new_code = test_validation_code(max_code_size() as usize + 1); + assert_noop!( + mock::Registrar::schedule_code_upgrade( + RuntimeOrigin::signed(1), + para_id, + new_code.clone(), + ), + paras::Error::::InvalidCode + ); + }); +} + +#[test] +fn register_handles_basic_errors() { + new_test_ext().execute_with(|| { + let para_id = LOWEST_PUBLIC_ID; + + assert_noop!( + mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotReserved + ); + + // Successfully register para + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + + assert_noop!( + mock::Registrar::register( + RuntimeOrigin::signed(2), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotOwner + ); + + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + )); + // Can skip pre-check and deregister para which's still onboarding. + run_to_session(2); + + assert_ok!(mock::Registrar::deregister(RuntimeOrigin::root(), para_id)); + + // Can't do it again + assert_noop!( + mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotReserved + ); + + // Head Size Check + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(2))); + assert_noop!( + mock::Registrar::register( + RuntimeOrigin::signed(2), + para_id + 1, + test_genesis_head((max_head_size() + 1) as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::HeadDataTooLarge + ); + + // Code Size Check + assert_noop!( + mock::Registrar::register( + RuntimeOrigin::signed(2), + para_id + 1, + test_genesis_head(max_head_size() as usize), + test_validation_code((max_code_size() + 1) as usize), + ), + Error::::CodeTooLarge + ); + + // Needs enough funds for deposit + assert_noop!( + mock::Registrar::reserve(RuntimeOrigin::signed(1337)), + BalancesError::::InsufficientBalance + ); + }); +} + +#[test] +fn deregister_works() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_id = LOWEST_PUBLIC_ID; + assert!(!Parachains::is_parathread(para_id)); + + let validation_code = test_validation_code(32); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + assert!(Parachains::is_parathread(para_id)); + assert_ok!(mock::Registrar::deregister(RuntimeOrigin::root(), para_id,)); + run_to_session(START_SESSION_INDEX + 4); + assert!(paras::Pallet::::lifecycle(para_id).is_none()); + assert_eq!(Balances::reserved_balance(&1), 0); + }); +} + +#[test] +fn deregister_handles_basic_errors() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_id = LOWEST_PUBLIC_ID; + assert!(!Parachains::is_parathread(para_id)); + + let validation_code = test_validation_code(32); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + assert!(Parachains::is_parathread(para_id)); + // Owner check + assert_noop!(mock::Registrar::deregister(RuntimeOrigin::signed(2), para_id,), BadOrigin); + assert_ok!(mock::Registrar::make_parachain(para_id)); + run_to_session(START_SESSION_INDEX + 4); + // Cant directly deregister parachain + assert_noop!( + mock::Registrar::deregister(RuntimeOrigin::root(), para_id,), + Error::::NotParathread + ); + }); +} + +#[test] +fn swap_works() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + // Successfully register first two parachains + let para_1 = LOWEST_PUBLIC_ID; + let para_2 = LOWEST_PUBLIC_ID + 1; + + let validation_code = test_validation_code(max_code_size() as usize); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_1, + test_genesis_head(max_head_size() as usize), + validation_code.clone(), + )); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(2))); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(2), + para_2, + test_genesis_head(max_head_size() as usize), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + run_to_session(START_SESSION_INDEX + 2); + + // Upgrade para 1 into a parachain + assert_ok!(mock::Registrar::make_parachain(para_1)); + + // Set some mock swap data. + let mut swap_data = SwapData::get(); + swap_data.insert(para_1, 69); + swap_data.insert(para_2, 1337); + SwapData::set(swap_data); + + run_to_session(START_SESSION_INDEX + 4); + + // Roles are as we expect + assert!(Parachains::is_parachain(para_1)); + assert!(!Parachains::is_parathread(para_1)); + assert!(!Parachains::is_parachain(para_2)); + assert!(Parachains::is_parathread(para_2)); + + // Both paras initiate a swap + // Swap between parachain and parathread + assert_ok!(mock::Registrar::swap(para_origin(para_1), para_1, para_2,)); + assert_ok!(mock::Registrar::swap(para_origin(para_2), para_2, para_1,)); + System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { + para_id: para_2, + other_id: para_1, + })); + + run_to_session(START_SESSION_INDEX + 6); + + // Roles are swapped + assert!(!Parachains::is_parachain(para_1)); + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parachain(para_2)); + assert!(!Parachains::is_parathread(para_2)); + + // Data is swapped + assert_eq!(SwapData::get().get(¶_1).unwrap(), &1337); + assert_eq!(SwapData::get().get(¶_2).unwrap(), &69); + + // Both paras initiate a swap + // Swap between parathread and parachain + assert_ok!(mock::Registrar::swap(para_origin(para_1), para_1, para_2,)); + assert_ok!(mock::Registrar::swap(para_origin(para_2), para_2, para_1,)); + System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { + para_id: para_2, + other_id: para_1, + })); + + // Data is swapped + assert_eq!(SwapData::get().get(¶_1).unwrap(), &69); + assert_eq!(SwapData::get().get(¶_2).unwrap(), &1337); + + // Parachain to parachain swap + let para_3 = LOWEST_PUBLIC_ID + 2; + let validation_code = test_validation_code(max_code_size() as usize); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(3))); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(3), + para_3, + test_genesis_head(max_head_size() as usize), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX + 6); + + run_to_session(START_SESSION_INDEX + 8); + + // Upgrade para 3 into a parachain + assert_ok!(mock::Registrar::make_parachain(para_3)); + + // Set some mock swap data. + let mut swap_data = SwapData::get(); + swap_data.insert(para_3, 777); + SwapData::set(swap_data); + + run_to_session(START_SESSION_INDEX + 10); + + // Both are parachains + assert!(Parachains::is_parachain(para_3)); + assert!(!Parachains::is_parathread(para_3)); + assert!(Parachains::is_parachain(para_1)); + assert!(!Parachains::is_parathread(para_1)); + + // Both paras initiate a swap + // Swap between parachain and parachain + assert_ok!(mock::Registrar::swap(para_origin(para_1), para_1, para_3,)); + assert_ok!(mock::Registrar::swap(para_origin(para_3), para_3, para_1,)); + System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped { + para_id: para_3, + other_id: para_1, + })); + + // Data is swapped + assert_eq!(SwapData::get().get(¶_3).unwrap(), &69); + assert_eq!(SwapData::get().get(¶_1).unwrap(), &777); + }); +} + +#[test] +fn para_lock_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + let para_id = LOWEST_PUBLIC_ID; + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_id, + vec![1; 3].into(), + test_validation_code(32) + )); + + assert_noop!(mock::Registrar::add_lock(RuntimeOrigin::signed(2), para_id), BadOrigin); + + // Once they produces new block, we lock them in. + mock::Registrar::on_new_head(para_id, &Default::default()); + + // Owner cannot pass origin check when checking lock + assert_noop!( + mock::Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id), + Error::::ParaLocked, + ); + // Owner cannot remove lock. + assert_noop!(mock::Registrar::remove_lock(RuntimeOrigin::signed(1), para_id), BadOrigin); + // Para can. + assert_ok!(mock::Registrar::remove_lock(para_origin(para_id), para_id)); + // Owner can pass origin check again + assert_ok!(mock::Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id)); + + // Won't lock again after it is unlocked + mock::Registrar::on_new_head(para_id, &Default::default()); + + assert_ok!(mock::Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id)); + }); +} + +#[test] +fn swap_handles_bad_states() { + new_test_ext().execute_with(|| { + const START_SESSION_INDEX: SessionIndex = 1; + run_to_session(START_SESSION_INDEX); + + let para_1 = LOWEST_PUBLIC_ID; + let para_2 = LOWEST_PUBLIC_ID + 1; + + // paras are not yet registered + assert!(!Parachains::is_parathread(para_1)); + assert!(!Parachains::is_parathread(para_2)); + + // Cannot even start a swap + assert_noop!( + mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2), + Error::::NotRegistered + ); + + // We register Paras 1 and 2 + let validation_code = test_validation_code(32); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(1))); + assert_ok!(mock::Registrar::reserve(RuntimeOrigin::signed(2))); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(1), + para_1, + test_genesis_head(32), + validation_code.clone(), + )); + assert_ok!(mock::Registrar::register( + RuntimeOrigin::signed(2), + para_2, + test_genesis_head(32), + validation_code.clone(), + )); + conclude_pvf_checking::(&validation_code, VALIDATORS, START_SESSION_INDEX); + + // Cannot swap + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + mock::Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 2); + + // They are now parathreads (on-demand parachains). + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parathread(para_2)); + + // Cannot swap + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + mock::Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + // Some other external process will elevate one on-demand + // parachain to a lease holding parachain + assert_ok!(mock::Registrar::make_parachain(para_1)); + + // Cannot swap + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + mock::Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 3); + + // Cannot swap + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + mock::Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 4); + + // It is now a lease holding parachain. + assert!(Parachains::is_parachain(para_1)); + assert!(Parachains::is_parathread(para_2)); + + // Swap works here. + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_2, para_1)); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. }) + ))); + + run_to_session(START_SESSION_INDEX + 5); + + // Cannot swap + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + mock::Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 6); + + // Swap worked! + assert!(Parachains::is_parachain(para_2)); + assert!(Parachains::is_parathread(para_1)); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. }) + ))); + + // Something starts to downgrade a para + assert_ok!(mock::Registrar::make_parathread(para_2)); + + run_to_session(START_SESSION_INDEX + 7); + + // Cannot swap + assert_ok!(mock::Registrar::swap(RuntimeOrigin::root(), para_1, para_2)); + assert_noop!( + mock::Registrar::swap(RuntimeOrigin::root(), para_2, para_1), + Error::::CannotSwap + ); + + run_to_session(START_SESSION_INDEX + 8); + + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parathread(para_2)); + }); +} diff --git a/substrate/frame/balances/Cargo.toml b/substrate/frame/balances/Cargo.toml index ee35ab74b737..090bcf5e2a65 100644 --- a/substrate/frame/balances/Cargo.toml +++ b/substrate/frame/balances/Cargo.toml @@ -17,20 +17,20 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { features = ["derive", "max-encoded-len"], workspace = true } -log = { workspace = true } -scale-info = { features = ["derive"], workspace = true } +docify = { workspace = true } frame-benchmarking = { optional = true, workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } -sp-runtime = { workspace = true } -docify = { workspace = true } +log = { workspace = true } +scale-info = { features = ["derive"], workspace = true } sp-core = { workspace = true } +sp-runtime = { workspace = true } [dev-dependencies] -pallet-transaction-payment = { workspace = true, default-features = true } frame-support = { features = ["experimental"], workspace = true, default-features = true } -sp-io = { workspace = true, default-features = true } +pallet-transaction-payment = { workspace = true, default-features = true } paste = { workspace = true, default-features = true } +sp-io = { workspace = true } [features] default = ["std"] @@ -60,4 +60,4 @@ try-runtime = [ "frame-system/try-runtime", "pallet-transaction-payment/try-runtime", "sp-runtime/try-runtime", -] +] \ No newline at end of file diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 9e30ad005b4c..e994f05a77c5 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -195,7 +195,8 @@ pub use pallet::*; const LOG_TARGET: &str = "runtime::balances"; -const DEFAULT_ADDRESS_URI: &str = "//Sender/{}"; +// Default derivation(hard) for development accounts. +const DEFAULT_ADDRESS_URI: &str = "//Sender//{}"; type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; @@ -513,25 +514,18 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig, I: 'static = ()> { pub balances: Vec<(T::AccountId, T::Balance)>, - /// Derived development accounts: + /// Derived development accounts(Optional): /// - `u32`: The number of development accounts to generate. /// - `T::Balance`: The initial balance assigned to each development account. - /// - `Option`: An optional derivation string template. - /// - Must include `{}` as a placeholder for account indices. - /// - Defaults to `"//Sender/{}`" if `None`. - pub dev_accounts: (u32, T::Balance, Option), + /// - `String`: An optional derivation(hard) string template. + /// - Must include `{}` as a placeholder for account indices. + /// - Defaults to `"//Sender//{}`" if `None`. + pub dev_accounts: Option<(u32, T::Balance, Option)>, } impl, I: 'static> Default for GenesisConfig { fn default() -> Self { - Self { - balances: Default::default(), - dev_accounts: ( - One::one(), - >::ExistentialDeposit::get(), - Some(DEFAULT_ADDRESS_URI.to_string()), - ), - } + Self { balances: Default::default(), dev_accounts: None } } } @@ -563,15 +557,14 @@ pub mod pallet { ); // Generate additional dev accounts. - let (num_accounts, balance, ref derivation) = self.dev_accounts; - - // Use `derivation` (or default) to generate key pair - Pallet::::derive_dev_account( - num_accounts, - balance, - derivation.as_deref().unwrap_or(DEFAULT_ADDRESS_URI), - ); - + if let Some((num_accounts, balance, ref derivation)) = self.dev_accounts { + // Using the provided derivation string or default to `"//Sender//{}`". + Pallet::::derive_dev_account( + num_accounts, + balance, + derivation.as_deref().unwrap_or(DEFAULT_ADDRESS_URI), + ); + } for &(ref who, free) in self.balances.iter() { frame_system::Pallet::::inc_providers(who); assert!(T::AccountStore::insert(who, AccountData { free, ..Default::default() }) @@ -1281,9 +1274,9 @@ pub mod pallet { Ok(actual) } - /// Generate dev account from derivation string. + /// Generate dev account from derivation(hard) string. pub fn derive_dev_account(num_accounts: u32, balance: T::Balance, derivation: &str) { - // Ensure that the number of accounts is not zero + // Ensure that the number of accounts is not zero. assert!(num_accounts > 0, "num_accounts must be greater than zero"); assert!( diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 491a70e5f813..ceb8e8134f0a 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -19,7 +19,10 @@ #![cfg(test)] -use crate::{self as pallet_balances, AccountData, Config, CreditOf, Error, Pallet, TotalIssuance}; +use crate::{ + self as pallet_balances, AccountData, Config, CreditOf, Error, Pallet, TotalIssuance, + DEFAULT_ADDRESS_URI, +}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ assert_err, assert_noop, assert_ok, assert_storage_noop, derive_impl, @@ -169,7 +172,11 @@ impl ExtBuilder { } else { vec![] }, - dev_accounts: (1000, self.existential_deposit, Some("//Sender/{}".to_string())), + dev_accounts: Some(( + 1000, + self.existential_deposit, + Some(DEFAULT_ADDRESS_URI.to_string()), + )), } .assimilate_storage(&mut t) .unwrap(); @@ -283,7 +290,7 @@ pub fn ensure_ti_valid() { let mut sum = 0; // Fetch the dev accounts from Account Storage. - let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, "//Sender/{}".to_string()); // You can customize this as needed + let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, DEFAULT_ADDRESS_URI.to_string()); let (num_accounts, _balance, ref derivation) = dev_accounts; // Generate the dev account public keys. From 589af1f5c9d8c3c44cbf68e39a7a99be6241c6dd Mon Sep 17 00:00:00 2001 From: runcomet Date: Sat, 11 Jan 2025 02:03:19 +0100 Subject: [PATCH 19/21] cargo +nightly fmt --- prdoc/pr_6267.prdoc | 10 +++++++++- substrate/frame/atomic-swap/src/tests.rs | 5 ++++- substrate/frame/beefy/src/mock.rs | 2 +- .../test-staking-e2e/src/mock.rs | 1 + .../nomination-pools/test-delegate-stake/src/mock.rs | 1 + .../nomination-pools/test-transfer-stake/src/mock.rs | 1 + 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/prdoc/pr_6267.prdoc b/prdoc/pr_6267.prdoc index bc791ef0b2c2..ad460ad59c2f 100644 --- a/prdoc/pr_6267.prdoc +++ b/prdoc/pr_6267.prdoc @@ -59,6 +59,10 @@ crates: bump: minor - name: pallet-nis bump: minor + - name: pallet-nomination-pools-test-delegate-stake + bump: minor + - name: pallet-nomination-pools-test-transfer-stake + bump: minor - name: pallet-multisig bump: minor - name: pallet-lottery @@ -73,6 +77,8 @@ crates: bump: minor - name: pallet-elections-phragmen bump: minor + - name: pallet-election-provider-e2e-test + bump: minor - name: pallet-election-provider-multi-phase bump: minor - name: pallet-democracy @@ -99,6 +105,8 @@ crates: bump: minor - name: pallet-asset-conversion-ops bump: minor + - name: pallet-atomic-swap + bump: minor - name: pallet-alliance bump: minor - name: node-testing @@ -129,7 +137,7 @@ crates: bump: minor - name: people-westend-emulated-chain bump: minor - - namne: people-rococo-emulated-chain + - name: people-rococo-emulated-chain bump: minor - name: coretime-westend-emulated-chain bump: minor diff --git a/substrate/frame/atomic-swap/src/tests.rs b/substrate/frame/atomic-swap/src/tests.rs index 6fcc5571a523..d6384fab343d 100644 --- a/substrate/frame/atomic-swap/src/tests.rs +++ b/substrate/frame/atomic-swap/src/tests.rs @@ -54,7 +54,10 @@ const B: u64 = 2; pub fn new_test_ext() -> TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let genesis = pallet_balances::GenesisConfig:: { balances: vec![(A, 100), (B, 200)] }; + let genesis = pallet_balances::GenesisConfig:: { + balances: vec![(A, 100), (B, 200)], + ..Default::default() + }; genesis.assimilate_storage(&mut t).unwrap(); t.into() } diff --git a/substrate/frame/beefy/src/mock.rs b/substrate/frame/beefy/src/mock.rs index 7ae41c609180..f92f77ebac3d 100644 --- a/substrate/frame/beefy/src/mock.rs +++ b/substrate/frame/beefy/src/mock.rs @@ -272,7 +272,7 @@ impl ExtBuilder { let balances: Vec<_> = (0..self.authorities.len()).map(|i| (i as u64, 10_000_000)).collect(); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs index eaab848c1694..497f168925ee 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs @@ -546,6 +546,7 @@ impl ExtBuilder { let _ = pallet_balances::GenesisConfig:: { balances: self.balances_builder.balances.clone(), + ..Dfault::default() } .assimilate_storage(&mut storage); diff --git a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs index d1bc4ef8ff28..50e1c5326313 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs @@ -310,6 +310,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let _ = pallet_balances::GenesisConfig:: { balances: vec![(10, 100), (20, 100), (21, 100), (22, 100)], + ..Default::default() } .assimilate_storage(&mut storage) .unwrap(); diff --git a/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs index d913c5fe6948..c9dd3fe0baab 100644 --- a/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs @@ -176,6 +176,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let _ = pallet_balances::GenesisConfig:: { balances: vec![(10, 100), (20, 100), (21, 100), (22, 100)], + ..Default::default() } .assimilate_storage(&mut storage) .unwrap(); From d13f0d692eb4545d9a0b5356dec9a99a9cf53364 Mon Sep 17 00:00:00 2001 From: runcomet Date: Sat, 11 Jan 2025 02:52:57 +0100 Subject: [PATCH 20/21] add dev_accounts field in missing pallet tests --- prdoc/pr_6267.prdoc | 6 ++++++ .../test-staking-e2e/src/mock.rs | 2 +- substrate/frame/executive/src/tests.rs | 20 ++++++++++++------- substrate/frame/scored-pool/src/mock.rs | 2 +- substrate/frame/statement/src/mock.rs | 1 + .../test-utils/runtime/src/genesismap.rs | 5 ++++- 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/prdoc/pr_6267.prdoc b/prdoc/pr_6267.prdoc index ad460ad59c2f..60b55955d8ba 100644 --- a/prdoc/pr_6267.prdoc +++ b/prdoc/pr_6267.prdoc @@ -43,6 +43,10 @@ crates: bump: minor - name: pallet-safe-mode bump: minor + - name: pallet-scored-pool + bump: minor + - name: pallet-statement + bump: minor - name: pallet-root-offences bump: minor - name: pallet-revive @@ -75,6 +79,8 @@ crates: bump: minor - name: pallet-fast-unstake bump: minor + - name: frame-executive + bump: minor - name: pallet-elections-phragmen bump: minor - name: pallet-election-provider-e2e-test diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs index 497f168925ee..2b975d8ed9cc 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs @@ -546,7 +546,7 @@ impl ExtBuilder { let _ = pallet_balances::GenesisConfig:: { balances: self.balances_builder.balances.clone(), - ..Dfault::default() + ..Default::default() } .assimilate_storage(&mut storage); diff --git a/substrate/frame/executive/src/tests.rs b/substrate/frame/executive/src/tests.rs index 882d875f3d80..dd12a85a1114 100644 --- a/substrate/frame/executive/src/tests.rs +++ b/substrate/frame/executive/src/tests.rs @@ -576,7 +576,7 @@ fn call_transfer(dest: u64, value: u64) -> RuntimeCall { #[test] fn balance_transfer_dispatch_works() { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 211)] } + pallet_balances::GenesisConfig:: { balances: vec![(1, 211)], ..Default::default() } .assimilate_storage(&mut t) .unwrap(); let xt = UncheckedXt::new_signed(call_transfer(2, 69), 1, 1.into(), tx_ext(0, 0)); @@ -598,9 +598,12 @@ fn balance_transfer_dispatch_works() { fn new_test_ext(balance_factor: Balance) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } - .assimilate_storage(&mut t) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 111 * balance_factor)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); let mut ext: sp_io::TestExternalities = t.into(); ext.execute_with(|| { SystemCallbacksCalled::set(0); @@ -610,9 +613,12 @@ fn new_test_ext(balance_factor: Balance) -> sp_io::TestExternalities { fn new_test_ext_v0(balance_factor: Balance) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } - .assimilate_storage(&mut t) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 111 * balance_factor)], + ..Default::default() + } + .assimilate_storage(&mut t) + .unwrap(); (t, sp_runtime::StateVersion::V0).into() } diff --git a/substrate/frame/scored-pool/src/mock.rs b/substrate/frame/scored-pool/src/mock.rs index 7708c06e56bd..5eb9df528924 100644 --- a/substrate/frame/scored-pool/src/mock.rs +++ b/substrate/frame/scored-pool/src/mock.rs @@ -109,7 +109,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { balances.push((40, 500_000)); balances.push((99, 1)); - pallet_balances::GenesisConfig:: { balances } + pallet_balances::GenesisConfig:: { balances, ..Default::default() } .assimilate_storage(&mut t) .unwrap(); pallet_scored_pool::GenesisConfig:: { diff --git a/substrate/frame/statement/src/mock.rs b/substrate/frame/statement/src/mock.rs index 34afd332c083..db9d19dbbab7 100644 --- a/substrate/frame/statement/src/mock.rs +++ b/substrate/frame/statement/src/mock.rs @@ -82,6 +82,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { 500000, ), ], + ..Default::default() }; balances.assimilate_storage(&mut t).unwrap(); t.into() diff --git a/substrate/test-utils/runtime/src/genesismap.rs b/substrate/test-utils/runtime/src/genesismap.rs index 18e438399952..e9a0e4815a2b 100644 --- a/substrate/test-utils/runtime/src/genesismap.rs +++ b/substrate/test-utils/runtime/src/genesismap.rs @@ -130,7 +130,10 @@ impl GenesisStorageBuilder { authorities: authorities_sr25519.clone(), ..Default::default() }, - balances: pallet_balances::GenesisConfig { balances: self.balances.clone(), ..Default::default() }, + balances: pallet_balances::GenesisConfig { + balances: self.balances.clone(), + ..Default::default() + }, } } From dea66764b841bb854bb1d2ba599d0c34f8682f17 Mon Sep 17 00:00:00 2001 From: runcomet Date: Sat, 11 Jan 2025 04:34:48 +0100 Subject: [PATCH 21/21] CI check to confirm chain-spec issue --- substrate/client/chain-spec/src/genesis_config_builder.rs | 2 +- substrate/test-utils/runtime/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/client/chain-spec/src/genesis_config_builder.rs b/substrate/client/chain-spec/src/genesis_config_builder.rs index 5fe8f9dc053c..2c5e5a5c0020 100644 --- a/substrate/client/chain-spec/src/genesis_config_builder.rs +++ b/substrate/client/chain-spec/src/genesis_config_builder.rs @@ -196,7 +196,7 @@ mod tests { ::new(substrate_test_runtime::wasm_binary_unwrap()) .get_default_config() .unwrap(); - let expected = r#"{"babe": {"authorities": [], "epochConfig": {"allowed_slots": "PrimaryAndSecondaryVRFSlots", "c": [1, 4]}}, "balances": {"balances": []}, "substrateTest": {"authorities": []}, "system": {}}"#; + let expected = r#"{"babe": {"authorities": [], "epochConfig": {"allowed_slots": "PrimaryAndSecondaryVRFSlots", "c": [1, 4]}}, "balances": {"balances": [], "devAccounts": Null}, "substrateTest": {"authorities": []}, "system": {}}"#; assert_eq!(from_str::(expected).unwrap(), config); } diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index 4d24354f99a7..5c172d8de4c9 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -1329,7 +1329,7 @@ mod tests { .expect("default config is there"); let json = String::from_utf8(r.into()).expect("returned value is json. qed."); - let expected = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c":[1,4],"allowed_slots":"PrimaryAndSecondaryVRFSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#; + let expected = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c":[1,4],"allowed_slots":"PrimaryAndSecondaryVRFSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[], "devAccounts":null}}"#; assert_eq!(expected.to_string(), json); }