From fd778cfad4ccfbd1e26258678258a1c3710e66b7 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 01:05:43 -0500 Subject: [PATCH 01/22] add support for parachain to parachain swap --- runtime/common/src/paras_registrar.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/runtime/common/src/paras_registrar.rs b/runtime/common/src/paras_registrar.rs index 3946e7d9aec5..8af70e9b120e 100644 --- a/runtime/common/src/paras_registrar.rs +++ b/runtime/common/src/paras_registrar.rs @@ -275,7 +275,7 @@ pub mod pallet { if let Some(other_lifecycle) = paras::Pallet::::lifecycle(other) { if let Some(id_lifecycle) = paras::Pallet::::lifecycle(id) { // identify which is a parachain and which is a parathread - if id_lifecycle.is_parachain() && other_lifecycle.is_parathread() { + if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parathread { // We check that both paras are in an appropriate lifecycle for a swap, // so these should never fail. let res1 = runtime_parachains::schedule_parachain_downgrade::(id); @@ -283,7 +283,7 @@ pub mod pallet { let res2 = runtime_parachains::schedule_parathread_upgrade::(other); debug_assert!(res2.is_ok()); T::OnSwap::on_swap(id, other); - } else if id_lifecycle.is_parathread() && other_lifecycle.is_parachain() { + } else if id_lifecycle == ParaLifecycle::Parathread && other_lifecycle == ParaLifecycle::Parachain { // We check that both paras are in an appropriate lifecycle for a swap, // so these should never fail. let res1 = runtime_parachains::schedule_parachain_downgrade::(other); @@ -291,6 +291,11 @@ pub mod pallet { let res2 = runtime_parachains::schedule_parathread_upgrade::(id); debug_assert!(res2.is_ok()); T::OnSwap::on_swap(id, other); + } else if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parachain { + // If both chains are currently parachains, there is nothing funny we + // need to do for their lifecycle management, just swap the underlying + // data. + T::OnSwap::on_swap(id, other); } PendingSwap::::remove(other); From 3eaa61921e35caa695742da91d5096403b844e06 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 01:12:41 -0500 Subject: [PATCH 02/22] enable swaps on kusama --- runtime/kusama/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index fc6adac24983..d98faa470f7b 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -138,11 +138,11 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } -/// Don't allow swaps until parathread story is more mature. +/// We currently allow all calls. pub struct BaseFilter; impl Contains for BaseFilter { fn contains(c: &Call) -> bool { - !matches!(c, Call::Registrar(paras_registrar::Call::swap { .. })) + true } } From 31426cf13b6cc972575a0f32f8f15bfd87ec7f61 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 01:36:36 -0500 Subject: [PATCH 03/22] sanity test in paras_registrar --- runtime/common/src/paras_registrar.rs | 99 +++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/runtime/common/src/paras_registrar.rs b/runtime/common/src/paras_registrar.rs index 8af70e9b120e..b69e391939c8 100644 --- a/runtime/common/src/paras_registrar.rs +++ b/runtime/common/src/paras_registrar.rs @@ -160,6 +160,9 @@ pub mod pallet { NotReserved, /// Registering parachain with empty code is not allowed. EmptyCode, + /// Cannot perform a parachain slot / lifecycle swap. Check that the state of both paras are + /// correct for the swap to work. + CannotSwap, } /// Pending swap operations. @@ -296,6 +299,8 @@ pub mod pallet { // need to do for their lifecycle management, just swap the underlying // data. T::OnSwap::on_swap(id, other); + } else { + return Error::::CannotSwap; } PendingSwap::::remove(other); @@ -1064,6 +1069,100 @@ mod tests { assert_noop!(Registrar::swap(Origin::signed(1), para_id, para_id + 2), BadOrigin); }); } + + #[test] + fn swap_handles_bad_states() { + new_test_ext().execute_with(|| { + let para_1 = LOWEST_PUBLIC_ID; + let para_2 = LOWEST_PUBLIC_ID + 1; + run_to_block(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(Origin::root(), para_1, para_2), Error::::NotRegistered); + + // We register Paras 1 and 2 + assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(Origin::signed(2))); + assert_ok!(Registrar::register( + Origin::signed(1), + para_1, + test_genesis_head(32), + test_validation_code(32), + )); + assert_ok!(Registrar::register( + Origin::signed(2), + para_2, + test_genesis_head(32), + test_validation_code(32), + )); + + // Cannot swap + assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); + assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + + run_to_session(2); + + // They are now a parathread. + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parathread(para_2)); + + // Cannot swap + assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); + assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + + // Some other external process will elevate one parathread to parachain + assert_ok!(Registrar::make_parachain(para_1)); + + // Cannot swap + assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); + assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + + run_to_session(3); + + // Cannot swap + assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); + assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + + run_to_session(4); + + // It is now a parachain. + assert!(Parachains::is_parachain(para_1)); + assert!(Parachains::is_parathread(para_2)); + + // Swap works here. + assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); + assert_ok!(Registrar::swap(Origin::root(), para_2, para_1)); + + run_to_session(5); + + // Cannot swap + assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); + assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + + run_to_session(6); + + // Swap worked! + assert!(Parachains::is_parachain(para_2)); + assert!(Parachains::is_parathread(para_1)); + + // Something starts to downgrade a para + assert_ok!(Registrar::make_parathread(para_2)); + + run_to_session(7); + + // Cannot swap + assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); + assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + + run_to_session(8); + + assert!(Parachains::is_parathread(para_1)); + assert!(Parachains::is_parathread(para_2)); + }); + } } #[cfg(feature = "runtime-benchmarks")] From d457803b390f0d79c0cc1199e8abec3ce1ce9bb6 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 01:52:23 -0500 Subject: [PATCH 04/22] express more errors --- runtime/common/src/paras_registrar.rs | 65 ++++++++++++++------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/runtime/common/src/paras_registrar.rs b/runtime/common/src/paras_registrar.rs index b69e391939c8..d30c434f54e7 100644 --- a/runtime/common/src/paras_registrar.rs +++ b/runtime/common/src/paras_registrar.rs @@ -274,38 +274,43 @@ pub mod pallet { pub fn swap(origin: OriginFor, id: ParaId, other: ParaId) -> DispatchResult { Self::ensure_root_para_or_owner(origin, id)?; + // If `id` and `other` is the same id, we treat this as a "clear" function, and exit + // early, since swapping the same id would otherwise be a noop. + if id == other { + PendingSwap::::remove(id); + return Ok(()) + } + if PendingSwap::::get(other) == Some(id) { - if let Some(other_lifecycle) = paras::Pallet::::lifecycle(other) { - if let Some(id_lifecycle) = paras::Pallet::::lifecycle(id) { - // identify which is a parachain and which is a parathread - if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parathread { - // We check that both paras are in an appropriate lifecycle for a swap, - // so these should never fail. - let res1 = runtime_parachains::schedule_parachain_downgrade::(id); - debug_assert!(res1.is_ok()); - let res2 = runtime_parachains::schedule_parathread_upgrade::(other); - debug_assert!(res2.is_ok()); - T::OnSwap::on_swap(id, other); - } else if id_lifecycle == ParaLifecycle::Parathread && other_lifecycle == ParaLifecycle::Parachain { - // We check that both paras are in an appropriate lifecycle for a swap, - // so these should never fail. - let res1 = runtime_parachains::schedule_parachain_downgrade::(other); - debug_assert!(res1.is_ok()); - let res2 = runtime_parachains::schedule_parathread_upgrade::(id); - debug_assert!(res2.is_ok()); - T::OnSwap::on_swap(id, other); - } else if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parachain { - // If both chains are currently parachains, there is nothing funny we - // need to do for their lifecycle management, just swap the underlying - // data. - T::OnSwap::on_swap(id, other); - } else { - return Error::::CannotSwap; - } - - PendingSwap::::remove(other); - } + let other_lifecycle = paras::Pallet::::lifecycle(other).ok_or(Error::::NotRegistered)?; + let id_lifecycle = paras::Pallet::::lifecycle(id).ok_or(Error::::NotRegistered)?; + + // identify which is a parachain and which is a parathread + if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parathread { + // We check that both paras are in an appropriate lifecycle for a swap, + // so these should never fail. + let res1 = runtime_parachains::schedule_parachain_downgrade::(id); + debug_assert!(res1.is_ok()); + let res2 = runtime_parachains::schedule_parathread_upgrade::(other); + debug_assert!(res2.is_ok()); + T::OnSwap::on_swap(id, other); + } else if id_lifecycle == ParaLifecycle::Parathread && other_lifecycle == ParaLifecycle::Parachain { + // We check that both paras are in an appropriate lifecycle for a swap, + // so these should never fail. + let res1 = runtime_parachains::schedule_parachain_downgrade::(other); + debug_assert!(res1.is_ok()); + let res2 = runtime_parachains::schedule_parathread_upgrade::(id); + debug_assert!(res2.is_ok()); + T::OnSwap::on_swap(id, other); + } else if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parachain { + // If both chains are currently parachains, there is nothing funny we + // need to do for their lifecycle management, just swap the underlying + // data. + T::OnSwap::on_swap(id, other); + } else { + return Err(Error::::CannotSwap); } + PendingSwap::::remove(other); } else { PendingSwap::::insert(id, other); } From 331a83575a70c356fa41bb956ae1c29ee5851928 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 05:19:08 -0500 Subject: [PATCH 05/22] finish up tests --- runtime/common/src/paras_registrar.rs | 52 +++++++++++++++++++-------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/runtime/common/src/paras_registrar.rs b/runtime/common/src/paras_registrar.rs index d30c434f54e7..943111d9b0ff 100644 --- a/runtime/common/src/paras_registrar.rs +++ b/runtime/common/src/paras_registrar.rs @@ -281,10 +281,11 @@ pub mod pallet { return Ok(()) } + // Sanity check that `id` is even a para. + let id_lifecycle = paras::Pallet::::lifecycle(id).ok_or(Error::::NotRegistered)?; + if PendingSwap::::get(other) == Some(id) { let other_lifecycle = paras::Pallet::::lifecycle(other).ok_or(Error::::NotRegistered)?; - let id_lifecycle = paras::Pallet::::lifecycle(id).ok_or(Error::::NotRegistered)?; - // identify which is a parachain and which is a parathread if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parathread { // We check that both paras are in an appropriate lifecycle for a swap, @@ -308,7 +309,7 @@ pub mod pallet { // data. T::OnSwap::on_swap(id, other); } else { - return Err(Error::::CannotSwap); + return Err(Error::::CannotSwap.into()); } PendingSwap::::remove(other); } else { @@ -602,6 +603,7 @@ mod tests { transaction_validity::TransactionPriority, Perbill, }; + use sp_std::collections::btree_map::BTreeMap; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -711,7 +713,7 @@ mod tests { type Event = Event; type Origin = Origin; type Currency = Balances; - type OnSwap = (); + type OnSwap = MockSwap; type ParaDeposit = ParaDeposit; type DataDepositPerByte = DataDepositPerByte; type WeightInfo = TestWeightInfo; @@ -739,6 +741,22 @@ mod tests { 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; fn run_to_block(n: BlockNumber) { @@ -1012,9 +1030,15 @@ mod tests { )); run_to_session(2); - // Upgrade 1023 into a parachain + // 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(4); // Roles are as we expect @@ -1029,20 +1053,15 @@ mod tests { run_to_session(6); - // Deregister a parathread that was originally a parachain - assert_eq!(Parachains::lifecycle(para_1), Some(ParaLifecycle::Parathread)); - assert_ok!(Registrar::deregister( - runtime_parachains::Origin::Parachain(para_1).into(), - para_1 - )); - - run_to_block(21); - // 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); }); } @@ -1085,8 +1104,11 @@ mod tests { assert!(!Parachains::is_parathread(para_1)); assert!(!Parachains::is_parathread(para_2)); + println!("{:?}", paras::Pallet::::lifecycle(para_1)); + println!("{:?}", paras::Pallet::::lifecycle(para_2)); + // Cannot even start a swap - assert_noop!(Registrar::swap(Origin::root(), para_1, para_2), Error::::NotRegistered); + assert_noop!(Registrar::swap(Origin::root(), para_1, para_2), Error::::NotRegistered); // We register Paras 1 and 2 assert_ok!(Registrar::reserve(Origin::signed(1))); From bc23e47be5f36a99e3c61bb53bcf00836e34f765 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 05:22:01 -0500 Subject: [PATCH 06/22] fmt --- runtime/common/src/paras_registrar.rs | 55 ++++++++++++++++++++------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/runtime/common/src/paras_registrar.rs b/runtime/common/src/paras_registrar.rs index 943111d9b0ff..fc0f5eaf94b7 100644 --- a/runtime/common/src/paras_registrar.rs +++ b/runtime/common/src/paras_registrar.rs @@ -282,12 +282,16 @@ pub mod pallet { } // Sanity check that `id` is even a para. - let id_lifecycle = paras::Pallet::::lifecycle(id).ok_or(Error::::NotRegistered)?; + let id_lifecycle = + paras::Pallet::::lifecycle(id).ok_or(Error::::NotRegistered)?; if PendingSwap::::get(other) == Some(id) { - let other_lifecycle = paras::Pallet::::lifecycle(other).ok_or(Error::::NotRegistered)?; + let other_lifecycle = + paras::Pallet::::lifecycle(other).ok_or(Error::::NotRegistered)?; // identify which is a parachain and which is a parathread - if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parathread { + if id_lifecycle == ParaLifecycle::Parachain && + other_lifecycle == ParaLifecycle::Parathread + { // We check that both paras are in an appropriate lifecycle for a swap, // so these should never fail. let res1 = runtime_parachains::schedule_parachain_downgrade::(id); @@ -295,7 +299,9 @@ pub mod pallet { let res2 = runtime_parachains::schedule_parathread_upgrade::(other); debug_assert!(res2.is_ok()); T::OnSwap::on_swap(id, other); - } else if id_lifecycle == ParaLifecycle::Parathread && other_lifecycle == ParaLifecycle::Parachain { + } else if id_lifecycle == ParaLifecycle::Parathread && + other_lifecycle == ParaLifecycle::Parachain + { // We check that both paras are in an appropriate lifecycle for a swap, // so these should never fail. let res1 = runtime_parachains::schedule_parachain_downgrade::(other); @@ -303,13 +309,15 @@ pub mod pallet { let res2 = runtime_parachains::schedule_parathread_upgrade::(id); debug_assert!(res2.is_ok()); T::OnSwap::on_swap(id, other); - } else if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parachain { + } else if id_lifecycle == ParaLifecycle::Parachain && + other_lifecycle == ParaLifecycle::Parachain + { // If both chains are currently parachains, there is nothing funny we // need to do for their lifecycle management, just swap the underlying // data. T::OnSwap::on_swap(id, other); } else { - return Err(Error::::CannotSwap.into()); + return Err(Error::::CannotSwap.into()) } PendingSwap::::remove(other); } else { @@ -1108,7 +1116,10 @@ mod tests { println!("{:?}", paras::Pallet::::lifecycle(para_2)); // Cannot even start a swap - assert_noop!(Registrar::swap(Origin::root(), para_1, para_2), Error::::NotRegistered); + assert_noop!( + Registrar::swap(Origin::root(), para_1, para_2), + Error::::NotRegistered + ); // We register Paras 1 and 2 assert_ok!(Registrar::reserve(Origin::signed(1))); @@ -1128,7 +1139,10 @@ mod tests { // Cannot swap assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); - assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + assert_noop!( + Registrar::swap(Origin::root(), para_2, para_1), + Error::::CannotSwap + ); run_to_session(2); @@ -1138,20 +1152,29 @@ mod tests { // Cannot swap assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); - assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + assert_noop!( + Registrar::swap(Origin::root(), para_2, para_1), + Error::::CannotSwap + ); // Some other external process will elevate one parathread to parachain assert_ok!(Registrar::make_parachain(para_1)); // Cannot swap assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); - assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + assert_noop!( + Registrar::swap(Origin::root(), para_2, para_1), + Error::::CannotSwap + ); run_to_session(3); // Cannot swap assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); - assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + assert_noop!( + Registrar::swap(Origin::root(), para_2, para_1), + Error::::CannotSwap + ); run_to_session(4); @@ -1167,7 +1190,10 @@ mod tests { // Cannot swap assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); - assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + assert_noop!( + Registrar::swap(Origin::root(), para_2, para_1), + Error::::CannotSwap + ); run_to_session(6); @@ -1182,7 +1208,10 @@ mod tests { // Cannot swap assert_ok!(Registrar::swap(Origin::root(), para_1, para_2)); - assert_noop!(Registrar::swap(Origin::root(), para_2, para_1), Error::::CannotSwap); + assert_noop!( + Registrar::swap(Origin::root(), para_2, para_1), + Error::::CannotSwap + ); run_to_session(8); From 578ad43a133920673083915ce1faed561ca6838c Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 20:00:32 +0000 Subject: [PATCH 07/22] make fields pub --- runtime/common/src/crowdloan.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/runtime/common/src/crowdloan.rs b/runtime/common/src/crowdloan.rs index 84b1be08f7ef..86fc53f8d59b 100644 --- a/runtime/common/src/crowdloan.rs +++ b/runtime/common/src/crowdloan.rs @@ -145,33 +145,33 @@ pub enum LastContribution { #[codec(dumb_trait_bound)] pub struct FundInfo { /// The owning account who placed the deposit. - depositor: AccountId, + pub depositor: AccountId, /// An optional verifier. If exists, contributions must be signed by verifier. - verifier: Option, + pub verifier: Option, /// The amount of deposit placed. - deposit: Balance, + pub deposit: Balance, /// The total amount raised. - raised: Balance, + pub raised: Balance, /// Block number after which the funding must have succeeded. If not successful at this number /// then everyone may withdraw their funds. - end: BlockNumber, + pub end: BlockNumber, /// A hard-cap on the amount that may be contributed. - cap: Balance, + pub cap: Balance, /// The most recent block that this had a contribution. Determines if we make a bid or not. /// If this is `Never`, this fund has never received a contribution. /// If this is `PreEnding(n)`, this fund received a contribution sometime in auction /// number `n` before the ending period. /// If this is `Ending(n)`, this fund received a contribution during the current ending period, /// where `n` is how far into the ending period the contribution was made. - last_contribution: LastContribution, + pub last_contribution: LastContribution, /// First lease period in range to bid on; it's actually a `LeasePeriod`, but that's the same type /// as `BlockNumber`. - first_period: LeasePeriod, + pub first_period: LeasePeriod, /// Last lease period in range to bid on; it's actually a `LeasePeriod`, but that's the same type /// as `BlockNumber`. - last_period: LeasePeriod, + pub last_period: LeasePeriod, /// Index used for the child trie of this fund - trie_index: TrieIndex, + pub trie_index: TrieIndex, } #[frame_support::pallet] From 4981fdbedba002e2f486a64d1d031a9d2c7e853c Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 23 Jan 2022 20:58:00 +0000 Subject: [PATCH 08/22] refactor integration tests to use real accounts --- runtime/common/src/integration_tests.rs | 472 ++++++++++++++++-------- 1 file changed, 328 insertions(+), 144 deletions(-) diff --git a/runtime/common/src/integration_tests.rs b/runtime/common/src/integration_tests.rs index 370073fa4de0..5c1dc9f13251 100644 --- a/runtime/common/src/integration_tests.rs +++ b/runtime/common/src/integration_tests.rs @@ -20,7 +20,7 @@ use crate::{ auctions, crowdloan, paras_registrar, slot_range::SlotRange, slots, - traits::{AuctionStatus, Auctioneer, Registrar as RegistrarT}, + traits::{AuctionStatus, Auctioneer, Registrar as RegistrarT, Leaser}, }; use frame_support::{ assert_noop, assert_ok, parameter_types, @@ -39,18 +39,32 @@ use sp_core::{crypto::KeyTypeId, H256}; use sp_io::TestExternalities; use sp_keystore::{testing::KeyStore, KeystoreExt}; use sp_runtime::{ + AccountId32, traits::{BlakeTwo256, IdentityLookup, One}, transaction_validity::TransactionPriority, }; -use sp_std::sync::Arc; +use sp_std::{sync::Arc, convert::TryInto}; +use parity_scale_codec::Encode; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; -type AccountId = u32; +type AccountId = AccountId32; type Balance = u32; type Moment = u32; +fn account_id(i: u32) -> AccountId32 { + let b4 = i.encode(); + let b32 = [&b4[..], &b4[..], &b4[..], &b4[..], &b4[..], &b4[..], &b4[..], &b4[..]].concat(); + let array: [u8; 32] = b32.try_into().unwrap(); + array.into() +} + +fn signed(i: u32) -> Origin { + let account_id = account_id(i); + Origin::signed(account_id) +} + frame_support::construct_runtime!( pub enum Test where Block = Block, @@ -342,21 +356,21 @@ fn basic_end_to_end_works() { let para_2 = LOWEST_PUBLIC_ID + 1; assert!(System::block_number().is_one()); // User 1 and 2 will own parachains - Balances::make_free_balance_be(&1, 1_000_000_000); - Balances::make_free_balance_be(&2, 1_000_000_000); + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads let genesis_head = Registrar::worst_head_data(); let validation_code = Registrar::worst_validation_code(); - assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(signed(1))); assert_ok!(Registrar::register( - Origin::signed(1), + signed(1), ParaId::from(para_1), genesis_head.clone(), validation_code.clone(), )); - assert_ok!(Registrar::reserve(Origin::signed(2))); + assert_ok!(Registrar::reserve(signed(2))); assert_ok!(Registrar::register( - Origin::signed(2), + signed(2), ParaId::from(2001), genesis_head, validation_code, @@ -379,7 +393,7 @@ fn basic_end_to_end_works() { // Para 1 will bid directly for slot 1, 2 // Open a crowdloan for Para 2 for slot 3, 4 assert_ok!(Crowdloan::create( - Origin::signed(2), + signed(2), ParaId::from(para_2), 1_000, // Cap lease_period_index_start + 2, // First Slot @@ -392,12 +406,12 @@ fn basic_end_to_end_works() { // Auction ending begins on block 100 + offset, so we make a bid before then. run_to_block(90 + offset); - Balances::make_free_balance_be(&10, 1_000_000_000); - Balances::make_free_balance_be(&20, 1_000_000_000); + Balances::make_free_balance_be(&account_id(10), 1_000_000_000); + Balances::make_free_balance_be(&account_id(20), 1_000_000_000); // User 10 will bid directly for parachain 1 assert_ok!(Auctions::bid( - Origin::signed(10), + signed(10), ParaId::from(para_1), 1, // Auction Index lease_period_index_start + 0, // First Slot @@ -406,8 +420,8 @@ fn basic_end_to_end_works() { )); // User 2 will be a contribute to crowdloan for parachain 2 - Balances::make_free_balance_be(&2, 1_000_000_000); - assert_ok!(Crowdloan::contribute(Origin::signed(2), ParaId::from(para_2), 920, None)); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(2), ParaId::from(para_2), 920, None)); // Auction ends at block 110 + offset run_to_block(109 + offset); @@ -421,7 +435,7 @@ fn basic_end_to_end_works() { assert_eq!( slots::Leases::::get(ParaId::from(para_1)), // -- 1 --- 2 --- 3 --------- 4 ------------ 5 -------- - vec![None, None, None, Some((10, 910)), Some((10, 910))], + vec![None, None, None, Some((account_id(10), 910)), Some((account_id(10), 910))], ); assert_eq!( slots::Leases::::get(ParaId::from(para_2)), @@ -432,15 +446,15 @@ fn basic_end_to_end_works() { None, None, None, - Some((crowdloan_account, 920)), - Some((crowdloan_account, 920)) + Some((crowdloan_account.clone(), 920)), + Some((crowdloan_account.clone(), 920)) ], ); // Should not be able to contribute to a winning crowdloan - Balances::make_free_balance_be(&3, 1_000_000_000); + Balances::make_free_balance_be(&account_id(3), 1_000_000_000); assert_noop!( - Crowdloan::contribute(Origin::signed(3), ParaId::from(2001), 10, None), + Crowdloan::contribute(signed(3), ParaId::from(2001), 10, None), CrowdloanError::::BidOrLeaseActive ); @@ -508,21 +522,21 @@ fn basic_errors_fail() { assert!(System::block_number().is_one()); let para_id = LOWEST_PUBLIC_ID; // Can't double register - Balances::make_free_balance_be(&1, 1_000_000_000); - Balances::make_free_balance_be(&2, 1_000_000_000); + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); let genesis_head = Registrar::worst_head_data(); let validation_code = Registrar::worst_validation_code(); - assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(signed(1))); assert_ok!(Registrar::register( - Origin::signed(1), + signed(1), para_id, genesis_head.clone(), validation_code.clone(), )); - assert_ok!(Registrar::reserve(Origin::signed(2))); + assert_ok!(Registrar::reserve(signed(2))); assert_noop!( - Registrar::register(Origin::signed(2), para_id, genesis_head, validation_code,), + Registrar::register(signed(2), para_id, genesis_head, validation_code,), paras_registrar::Error::::NotOwner ); @@ -534,7 +548,7 @@ fn basic_errors_fail() { // Cannot create a crowdloan if you do not own the para assert_noop!( Crowdloan::create( - Origin::signed(2), + signed(2), para_id, 1_000, // Cap lease_period_index_start + 2, // First Slot @@ -557,12 +571,12 @@ fn competing_slots() { // Create n paras and owners for n in 1..=max_bids { - Balances::make_free_balance_be(&n, 1_000_000_000); + Balances::make_free_balance_be(&account_id(n), 1_000_000_000); let genesis_head = Registrar::worst_head_data(); let validation_code = Registrar::worst_validation_code(); - assert_ok!(Registrar::reserve(Origin::signed(n))); + assert_ok!(Registrar::reserve(signed(n))); assert_ok!(Registrar::register( - Origin::signed(n), + signed(n), para_id + n - 1, genesis_head, validation_code, @@ -581,7 +595,7 @@ fn competing_slots() { // Increment block number run_to_block(System::block_number() + 10); - Balances::make_free_balance_be(&(n * 10), n * 1_000); + Balances::make_free_balance_be(&account_id(n * 10), n * 1_000); let (start, end) = match n { 1 => (0, 0), @@ -599,7 +613,7 @@ fn competing_slots() { // Users will bid directly for parachain assert_ok!(Auctions::bid( - Origin::signed(n * 10), + signed(n * 10), para_id + n - 1, 1, // Auction Index lease_period_index_start + start, // First Slot @@ -617,18 +631,18 @@ fn competing_slots() { assert_eq!( slots::Leases::::get(para_id), // -- 1 --- 2 --- 3 ---------- 4 ------ - vec![None, None, None, Some((10, 900))], + vec![None, None, None, Some((account_id(10), 900))], ); assert_eq!( slots::Leases::::get(para_id + 4), // -- 1 --- 2 --- 3 --- 4 ---------- 5 ------- - vec![None, None, None, None, Some((50, 4500))], + vec![None, None, None, None, Some((account_id(50), 4500))], ); // TODO: Is this right? assert_eq!( slots::Leases::::get(para_id + 8), // -- 1 --- 2 --- 3 --- 4 --- 5 ---------- 6 --------------- 7 ------- - vec![None, None, None, None, None, Some((90, 8100)), Some((90, 8100))], + vec![None, None, None, None, None, Some((account_id(90), 8100)), Some((account_id(90), 8100))], ); }); } @@ -642,12 +656,12 @@ fn competing_bids() { let start_para = LOWEST_PUBLIC_ID - 1; // Create 3 paras and owners for n in 1..=3 { - Balances::make_free_balance_be(&n, 1_000_000_000); + Balances::make_free_balance_be(&account_id(n), 1_000_000_000); let genesis_head = Registrar::worst_head_data(); let validation_code = Registrar::worst_validation_code(); - assert_ok!(Registrar::reserve(Origin::signed(n))); + assert_ok!(Registrar::reserve(signed(n))); assert_ok!(Registrar::register( - Origin::signed(n), + signed(n), ParaId::from(start_para + n), genesis_head, validation_code, @@ -666,7 +680,7 @@ fn competing_bids() { for n in 1..=3 { // Create a crowdloan for each para assert_ok!(Crowdloan::create( - Origin::signed(n), + signed(n), ParaId::from(start_para + n), 100_000, // Cap lease_period_index_start + 2, // First Slot @@ -680,14 +694,14 @@ fn competing_bids() { // Increment block number run_to_block(starting_block + n * 10); - Balances::make_free_balance_be(&(n * 10), n * 1_000); + Balances::make_free_balance_be(&account_id(n * 10), n * 1_000); let para = start_para + n % 3 + 1; if n % 2 == 0 { // User 10 will bid directly for parachain 1 assert_ok!(Auctions::bid( - Origin::signed(n * 10), + signed(n * 10), ParaId::from(para), 1, // Auction Index lease_period_index_start + 0, // First Slot @@ -697,7 +711,7 @@ fn competing_bids() { } else { // User 20 will be a contribute to crowdloan for parachain 2 assert_ok!(Crowdloan::contribute( - Origin::signed(n * 10), + signed(n * 10), ParaId::from(para), n + 900, None, @@ -709,7 +723,7 @@ fn competing_bids() { run_to_block(starting_block + 110); // Appropriate Paras should have won slots - let crowdloan_2 = Crowdloan::fund_account_id(ParaId::from(2001)); + let crowdloan_1 = Crowdloan::fund_account_id(ParaId::from(2000)); assert_eq!( slots::Leases::::get(ParaId::from(2000)), // -- 1 --- 2 --- 3 --- 4 --- 5 ------------- 6 ------------------------ 7 ------------- @@ -719,14 +733,14 @@ fn competing_bids() { None, None, None, - Some((crowdloan_2, 1812)), - Some((crowdloan_2, 1812)) + Some((crowdloan_1.clone(), 1812)), + Some((crowdloan_1.clone(), 1812)) ], ); assert_eq!( slots::Leases::::get(ParaId::from(2002)), // -- 1 --- 2 --- 3 ---------- 4 --------------- 5 ------- - vec![None, None, None, Some((80, 7200)), Some((80, 7200))], + vec![None, None, None, Some((account_id(80), 7200)), Some((account_id(80), 7200))], ); }); } @@ -736,20 +750,20 @@ fn basic_swap_works() { // This test will test a swap between a parachain and parathread works successfully. new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras - Balances::make_free_balance_be(&1, 1_000_000_000); - Balances::make_free_balance_be(&2, 1_000_000_000); + // User 1 and 2 will own paras + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads with different data - assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(signed(1))); assert_ok!(Registrar::register( - Origin::signed(1), + signed(1), ParaId::from(2000), test_genesis_head(10), test_validation_code(10), )); - assert_ok!(Registrar::reserve(Origin::signed(2))); + assert_ok!(Registrar::reserve(signed(2))); assert_ok!(Registrar::register( - Origin::signed(2), + signed(2), ParaId::from(2001), test_genesis_head(20), test_validation_code(20), @@ -771,7 +785,7 @@ fn basic_swap_works() { // Open a crowdloan for Para 1 for slots 0-3 assert_ok!(Crowdloan::create( - Origin::signed(1), + signed(1), ParaId::from(2000), 1_000_000, // Cap lease_period_index_start + 0, // First Slot @@ -784,8 +798,8 @@ fn basic_swap_works() { // Bunch of contributions let mut total = 0; for i in 10..20 { - Balances::make_free_balance_be(&i, 1_000_000_000); - assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None)); + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(2000), 900 - i, None)); total += 900 - i; } assert!(total > 0); @@ -796,8 +810,8 @@ fn basic_swap_works() { // Deposit is appropriately taken // ----------------------------------------- para deposit --- crowdloan - assert_eq!(Balances::reserved_balance(&1), (500 + 10 * 2 * 1) + 100); - assert_eq!(Balances::reserved_balance(&2), 500 + 20 * 2 * 1); + assert_eq!(Balances::reserved_balance(&account_id(1)), (500 + 10 * 2 * 1) + 100); + assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); assert_eq!(Balances::reserved_balance(&crowdloan_account), total); // Crowdloan is appropriately set assert!(Crowdloan::funds(ParaId::from(2000)).is_some()); @@ -839,8 +853,8 @@ fn basic_swap_works() { // Deregister parathread assert_ok!(Registrar::deregister(para_origin(2000).into(), ParaId::from(2000))); // Correct deposit is unreserved - assert_eq!(Balances::reserved_balance(&1), 100); // crowdloan deposit left over - assert_eq!(Balances::reserved_balance(&2), 500 + 20 * 2 * 1); + assert_eq!(Balances::reserved_balance(&account_id(1)), 100); // crowdloan deposit left over + assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); // Crowdloan ownership is swapped assert!(Crowdloan::funds(ParaId::from(2000)).is_none()); assert!(Crowdloan::funds(ParaId::from(2001)).is_some()); @@ -850,11 +864,11 @@ fn basic_swap_works() { // Cant dissolve assert_noop!( - Crowdloan::dissolve(Origin::signed(1), ParaId::from(2000)), + Crowdloan::dissolve(signed(1), ParaId::from(2000)), CrowdloanError::::InvalidParaId ); assert_noop!( - Crowdloan::dissolve(Origin::signed(2), ParaId::from(2001)), + Crowdloan::dissolve(signed(2), ParaId::from(2001)), CrowdloanError::::NotReadyToDissolve ); @@ -864,18 +878,187 @@ fn basic_swap_works() { // Withdraw of contributions works assert_eq!(Balances::free_balance(&crowdloan_account), total); for i in 10..20 { - assert_ok!(Crowdloan::withdraw(Origin::signed(i), i, ParaId::from(2001))); + assert_ok!(Crowdloan::withdraw(signed(i), account_id(i), ParaId::from(2001))); } assert_eq!(Balances::free_balance(&crowdloan_account), 0); // Dissolve returns the balance of the person who put a deposit for crowdloan - assert_ok!(Crowdloan::dissolve(Origin::signed(1), ParaId::from(2001))); - assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(Balances::reserved_balance(&2), 500 + 20 * 2 * 1); + assert_ok!(Crowdloan::dissolve(signed(1), ParaId::from(2001))); + assert_eq!(Balances::reserved_balance(&account_id(1)), 0); + assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); // Final deregister sets everything back to the start assert_ok!(Registrar::deregister(para_origin(2001).into(), ParaId::from(2001))); - assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::reserved_balance(&account_id(2)), 0); + }) +} + +#[test] +fn parachain_swap_works() { + // This test will test a swap between two parachains works successfully. + new_test_ext().execute_with(|| { + assert!(System::block_number().is_one()); // So events are emitted + // User 1 and 2 will own paras + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); + // First register 2 parathreads with different data + assert_ok!(Registrar::reserve(signed(1))); + assert_ok!(Registrar::register( + signed(1), + ParaId::from(2000), + test_genesis_head(10), + test_validation_code(10), + )); + assert_ok!(Registrar::reserve(signed(2))); + assert_ok!(Registrar::register( + signed(2), + ParaId::from(2001), + test_genesis_head(20), + test_validation_code(20), + )); + + // Paras should be onboarding + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding)); + + assert_eq!(Balances::total_balance(&Crowdloan::fund_account_id(ParaId::from(2000))), 0); + + + // Start a new auction in the future + let start_auction = |lease_period_index_start, winner, end| { + let unique_id = winner - 1999u32; + let starting_block = System::block_number(); + let duration = 99u32; + assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start)); + + // 2 sessions later they are parathreads + run_to_block(starting_block + 20); + assert_eq!(Paras::lifecycle(ParaId::from(winner)), Some(ParaLifecycle::Parathread)); + + // Open a crowdloan for Para 1 for slots 0-3 + assert_ok!(Crowdloan::create( + signed(unique_id), + ParaId::from(winner), + 1_000_000, // Cap + lease_period_index_start + 0, // First Slot + lease_period_index_start + 7, // Last Slot + end, // Block End + None, + )); + let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(winner)); + + // Bunch of contributions + let mut total = 0; + for i in (unique_id * 10) .. (unique_id + 1) * 10 { + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(winner), 900 - i, None)); + total += 900 - i; + } + assert!(total > 0); + assert_eq!(Balances::free_balance(&crowdloan_account), total); + + // Go to end of auction where everyone won their slots + run_to_block(end); + + // Crowdloan is appropriately set + assert!(Crowdloan::funds(ParaId::from(winner)).is_some()); + + // New leases will start on block lease period index * 100 + let lease_start_block = lease_period_index_start * 100; + run_to_block(lease_start_block); + }; + + start_auction(4u32, 2000, 200); + // Slots are won by Para 1 + assert!(!Slots::lease(ParaId::from(2000)).is_empty()); + assert!(Slots::lease(ParaId::from(2001)).is_empty()); + + // 2 sessions later it is a parachain + run_to_block(4 * 100 + 20); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread)); + + // Let's repeat the process now for another parachain. + start_auction(6u32, 2001, 500); + // Slots are won by Para 1 + assert!(!Slots::lease(ParaId::from(2000)).is_empty()); + assert!(!Slots::lease(ParaId::from(2001)).is_empty()); + + // 2 sessions later it is a parachain + run_to_block(6 * 100 + 20); + assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parachain)); + assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parachain)); + + // Currently we are on lease 6 + assert_eq!(>::lease_period_index(System::block_number()), Some((6u32, false))); + + // This means that parachain 1 should only have 6 slots left, and parachain 2 has all 8. + assert_eq!(slots::Leases::::get(ParaId::from(2000)).len(), 6); + assert_eq!(slots::Leases::::get(ParaId::from(2001)).len(), 8); + + let fund_1 = Crowdloan::funds(ParaId::from(2000)).unwrap(); + assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(ParaId::from(2000))), fund_1.raised); + + // Now we swap them. + assert_ok!(Registrar::swap( + para_origin(2000).into(), + ParaId::from(2000), + ParaId::from(2001) + )); + assert_ok!(Registrar::swap( + para_origin(2001).into(), + ParaId::from(2001), + ParaId::from(2000) + )); + + // assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::DowngradingParachain)); + // assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::UpgradingParathread)); + + // // 2 session later they have swapped + // run_to_block(lease_start_block + 40); + // assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread)); + // assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parachain)); + + // // Deregister parathread + // assert_ok!(Registrar::deregister(para_origin(2000).into(), ParaId::from(2000))); + // // Correct deposit is unreserved + // assert_eq!(Balances::reserved_balance(&account_id(1)), 100); // crowdloan deposit left over + // assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); + // // Crowdloan ownership is swapped + // assert!(Crowdloan::funds(ParaId::from(2000)).is_none()); + // assert!(Crowdloan::funds(ParaId::from(2001)).is_some()); + // // Slot is swapped + // assert!(Slots::lease(ParaId::from(2000)).is_empty()); + // assert!(!Slots::lease(ParaId::from(2001)).is_empty()); + + // // Cant dissolve + // assert_noop!( + // Crowdloan::dissolve(signed(1), ParaId::from(2000)), + // CrowdloanError::::InvalidParaId + // ); + // assert_noop!( + // Crowdloan::dissolve(signed(2), ParaId::from(2001)), + // CrowdloanError::::NotReadyToDissolve + // ); + + // // Go way in the future when the para is offboarded + // run_to_block(lease_start_block + 1000); + + // // Withdraw of contributions works + // assert_eq!(Balances::free_balance(&crowdloan_account), total); + // for i in 10..20 { + // assert_ok!(Crowdloan::withdraw(signed(i), account_id(i), ParaId::from(2001))); + // } + // assert_eq!(Balances::free_balance(&crowdloan_account), 0); + + // // Dissolve returns the balance of the person who put a deposit for crowdloan + // assert_ok!(Crowdloan::dissolve(signed(1), ParaId::from(2001))); + // assert_eq!(Balances::reserved_balance(&account_id(1)), 0); + // assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); + + // // Final deregister sets everything back to the start + // assert_ok!(Registrar::deregister(para_origin(2001).into(), ParaId::from(2001))); + // assert_eq!(Balances::reserved_balance(&account_id(2)), 0); }) } @@ -883,20 +1066,20 @@ fn basic_swap_works() { fn crowdloan_ending_period_bid() { new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras - Balances::make_free_balance_be(&1, 1_000_000_000); - Balances::make_free_balance_be(&2, 1_000_000_000); + // User 1 and 2 will own paras + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads - assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(signed(1))); assert_ok!(Registrar::register( - Origin::signed(1), + signed(1), ParaId::from(2000), test_genesis_head(10), test_validation_code(10), )); - assert_ok!(Registrar::reserve(Origin::signed(2))); + assert_ok!(Registrar::reserve(signed(2))); assert_ok!(Registrar::register( - Origin::signed(2), + signed(2), ParaId::from(2001), test_genesis_head(20), test_validation_code(20), @@ -918,7 +1101,7 @@ fn crowdloan_ending_period_bid() { // Open a crowdloan for Para 1 for slots 0-3 assert_ok!(Crowdloan::create( - Origin::signed(1), + signed(1), ParaId::from(2000), 1_000_000, // Cap lease_period_index_start + 0, // First Slot @@ -931,17 +1114,17 @@ fn crowdloan_ending_period_bid() { // Bunch of contributions let mut total = 0; for i in 10..20 { - Balances::make_free_balance_be(&i, 1_000_000_000); - assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None)); + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(2000), 900 - i, None)); total += 900 - i; } assert!(total > 0); assert_eq!(Balances::free_balance(&crowdloan_account), total); // Bid for para 2 directly - Balances::make_free_balance_be(&2, 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); assert_ok!(Auctions::bid( - Origin::signed(2), + signed(2), ParaId::from(2001), 1, // Auction Index lease_period_index_start + 0, // First Slot @@ -953,24 +1136,25 @@ fn crowdloan_ending_period_bid() { run_to_block(100); assert_eq!(Auctions::auction_status(100), AuctionStatus::::EndingPeriod(0, 0)); - let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; - winning[SlotRange::ZeroOne as u8 as usize] = Some((2, ParaId::from(2001), 900)); + let mut winning = [(); SlotRange::SLOT_RANGE_COUNT].map(|_| None); + + winning[SlotRange::ZeroOne as u8 as usize] = Some((account_id(2), ParaId::from(2001), 900)); winning[SlotRange::ZeroThree as u8 as usize] = - Some((crowdloan_account, ParaId::from(2000), total)); + Some((crowdloan_account.clone(), ParaId::from(2000), total)); assert_eq!(Auctions::winning(0), Some(winning)); run_to_block(101); - Balances::make_free_balance_be(&1234, 1_000_000_000); - assert_ok!(Crowdloan::contribute(Origin::signed(1234), ParaId::from(2000), 900, None)); + Balances::make_free_balance_be(&account_id(1234), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(1234), ParaId::from(2000), 900, None)); // Data propagates correctly run_to_block(102); - let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; - winning[SlotRange::ZeroOne as u8 as usize] = Some((2, ParaId::from(2001), 900)); + let mut winning = [(); SlotRange::SLOT_RANGE_COUNT].map(|_| None); + winning[SlotRange::ZeroOne as u8 as usize] = Some((account_id(2), ParaId::from(2001), 900)); winning[SlotRange::ZeroThree as u8 as usize] = - Some((crowdloan_account, ParaId::from(2000), total + 900)); + Some((crowdloan_account.clone(), ParaId::from(2000), total + 900)); assert_eq!(Auctions::winning(2), Some(winning)); }) } @@ -986,10 +1170,10 @@ fn auction_bid_requires_registered_para() { assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start)); // Can't bid with non-registered paras - Balances::make_free_balance_be(&1, 1_000_000_000); + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); assert_noop!( Auctions::bid( - Origin::signed(1), + signed(1), ParaId::from(2000), 1, // Auction Index lease_period_index_start + 0, // First Slot @@ -1000,9 +1184,9 @@ fn auction_bid_requires_registered_para() { ); // Now we register the para - assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(signed(1))); assert_ok!(Registrar::register( - Origin::signed(1), + signed(1), ParaId::from(2000), test_genesis_head(10), test_validation_code(10), @@ -1011,7 +1195,7 @@ fn auction_bid_requires_registered_para() { // Still can't bid until it is fully onboarded assert_noop!( Auctions::bid( - Origin::signed(1), + signed(1), ParaId::from(2000), 1, // Auction Index lease_period_index_start + 0, // First Slot @@ -1025,9 +1209,9 @@ fn auction_bid_requires_registered_para() { run_to_session(2); // Success - Balances::make_free_balance_be(&1, 1_000_000_000); + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); assert_ok!(Auctions::bid( - Origin::signed(1), + signed(1), ParaId::from(2000), 1, // Auction Index lease_period_index_start + 0, // First Slot @@ -1046,20 +1230,20 @@ fn gap_bids_work() { let duration = 99u32; let lease_period_index_start = 4u32; assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start)); - Balances::make_free_balance_be(&1, 1_000_000_000); - Balances::make_free_balance_be(&2, 1_000_000_000); + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); + Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // Now register 2 paras - assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(signed(1))); assert_ok!(Registrar::register( - Origin::signed(1), + signed(1), ParaId::from(2000), test_genesis_head(10), test_validation_code(10), )); - assert_ok!(Registrar::reserve(Origin::signed(2))); + assert_ok!(Registrar::reserve(signed(2))); assert_ok!(Registrar::register( - Origin::signed(2), + signed(2), ParaId::from(2001), test_genesis_head(10), test_validation_code(10), @@ -1069,11 +1253,11 @@ fn gap_bids_work() { run_to_session(2); // Make bids - Balances::make_free_balance_be(&10, 1_000_000_000); - Balances::make_free_balance_be(&20, 1_000_000_000); + Balances::make_free_balance_be(&account_id(10), 1_000_000_000); + Balances::make_free_balance_be(&account_id(20), 1_000_000_000); // Slot 1 for 100 from 10 assert_ok!(Auctions::bid( - Origin::signed(10), + signed(10), ParaId::from(2000), 1, // Auction Index lease_period_index_start + 0, // First Slot @@ -1082,7 +1266,7 @@ fn gap_bids_work() { )); // Slot 4 for 400 from 10 assert_ok!(Auctions::bid( - Origin::signed(10), + signed(10), ParaId::from(2000), 1, // Auction Index lease_period_index_start + 3, // First Slot @@ -1092,18 +1276,18 @@ fn gap_bids_work() { // A bid for another para is counted separately. assert_ok!(Auctions::bid( - Origin::signed(10), + signed(10), ParaId::from(2001), 1, // Auction Index lease_period_index_start + 1, // First Slot lease_period_index_start + 1, // Last slot 555, // Amount )); - assert_eq!(Balances::reserved_balance(&10), 400 + 555); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400 + 555); // Slot 2 for 800 from 20, overtaking 10's bid assert_ok!(Auctions::bid( - Origin::signed(20), + signed(20), ParaId::from(2000), 1, // Auction Index lease_period_index_start + 1, // First Slot @@ -1112,7 +1296,7 @@ fn gap_bids_work() { )); // Slot 3 for 200 from 20 assert_ok!(Auctions::bid( - Origin::signed(20), + signed(20), ParaId::from(2000), 1, // Auction Index lease_period_index_start + 2, // First Slot @@ -1131,16 +1315,16 @@ fn gap_bids_work() { None, None, None, - Some((10, 100)), - Some((20, 800)), - Some((20, 200)), - Some((10, 400)) + Some((account_id(10), 100)), + Some((account_id(20), 800)), + Some((account_id(20), 200)), + Some((account_id(10), 400)) ], ); // Appropriate amount is reserved (largest of the values) - assert_eq!(Balances::reserved_balance(&10), 400); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); // Appropriate amount is reserved (largest of the values) - assert_eq!(Balances::reserved_balance(&20), 800); + assert_eq!(Balances::reserved_balance(&account_id(20)), 800); // Progress through the leases and note the correct amount of balance is reserved. @@ -1148,48 +1332,48 @@ fn gap_bids_work() { assert_eq!( slots::Leases::::get(ParaId::from(2000)), // --------- 4 -------------- 5 -------------- 6 -------------- 7 ------- - vec![Some((10, 100)), Some((20, 800)), Some((20, 200)), Some((10, 400))], + vec![Some((account_id(10), 100)), Some((account_id(20), 800)), Some((account_id(20), 200)), Some((account_id(10), 400))], ); // Nothing changed. - assert_eq!(Balances::reserved_balance(&10), 400); - assert_eq!(Balances::reserved_balance(&20), 800); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 800); // Lease period 4 is done, but nothing is unreserved since user 1 has a debt on lease 7 run_to_block(500); assert_eq!( slots::Leases::::get(ParaId::from(2000)), // --------- 5 -------------- 6 -------------- 7 ------- - vec![Some((20, 800)), Some((20, 200)), Some((10, 400))], + vec![Some((account_id(20), 800)), Some((account_id(20), 200)), Some((account_id(10), 400))], ); // Nothing changed. - assert_eq!(Balances::reserved_balance(&10), 400); - assert_eq!(Balances::reserved_balance(&20), 800); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 800); // Lease period 5 is done, and 20 will unreserve down to 200. run_to_block(600); assert_eq!( slots::Leases::::get(ParaId::from(2000)), // --------- 6 -------------- 7 ------- - vec![Some((20, 200)), Some((10, 400))], + vec![Some((account_id(20), 200)), Some((account_id(10), 400))], ); - assert_eq!(Balances::reserved_balance(&10), 400); - assert_eq!(Balances::reserved_balance(&20), 200); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 200); // Lease period 6 is done, and 20 will unreserve everything. run_to_block(700); assert_eq!( slots::Leases::::get(ParaId::from(2000)), // --------- 7 ------- - vec![Some((10, 400))], + vec![Some((account_id(10), 400))], ); - assert_eq!(Balances::reserved_balance(&10), 400); - assert_eq!(Balances::reserved_balance(&20), 0); + assert_eq!(Balances::reserved_balance(&account_id(10)), 400); + assert_eq!(Balances::reserved_balance(&account_id(20)), 0); // All leases are done. Everything is unreserved. run_to_block(800); assert_eq!(slots::Leases::::get(ParaId::from(2000)), vec![]); - assert_eq!(Balances::reserved_balance(&10), 0); - assert_eq!(Balances::reserved_balance(&20), 0); + assert_eq!(Balances::reserved_balance(&account_id(10)), 0); + assert_eq!(Balances::reserved_balance(&account_id(20)), 0); }); } @@ -1199,11 +1383,11 @@ fn gap_bids_work() { fn cant_bid_on_existing_lease_periods() { new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - Balances::make_free_balance_be(&1, 1_000_000_000); + Balances::make_free_balance_be(&account_id(1), 1_000_000_000); // First register a parathread - assert_ok!(Registrar::reserve(Origin::signed(1))); + assert_ok!(Registrar::reserve(signed(1))); assert_ok!(Registrar::register( - Origin::signed(1), + signed(1), ParaId::from(2000), test_genesis_head(10), test_validation_code(10), @@ -1220,7 +1404,7 @@ fn cant_bid_on_existing_lease_periods() { // Open a crowdloan for Para 1 for slots 0-3 assert_ok!(Crowdloan::create( - Origin::signed(1), + signed(1), ParaId::from(2000), 1_000_000, // Cap lease_period_index_start + 0, // First Slot @@ -1233,8 +1417,8 @@ fn cant_bid_on_existing_lease_periods() { // Bunch of contributions let mut total = 0; for i in 10..20 { - Balances::make_free_balance_be(&i, 1_000_000_000); - assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None)); + Balances::make_free_balance_be(&account_id(i), 1_000_000_000); + assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(2000), 900 - i, None)); total += 900 - i; } assert!(total > 0); @@ -1251,8 +1435,8 @@ fn cant_bid_on_existing_lease_periods() { None, None, None, - Some((crowdloan_account, 8855)), - Some((crowdloan_account, 8855)) + Some((crowdloan_account.clone(), 8855)), + Some((crowdloan_account.clone(), 8855)) ], ); @@ -1263,7 +1447,7 @@ fn cant_bid_on_existing_lease_periods() { assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start)); // Poke the crowdloan into `NewRaise` - assert_ok!(Crowdloan::poke(Origin::signed(1), ParaId::from(2000))); + assert_ok!(Crowdloan::poke(signed(1), ParaId::from(2000))); assert_eq!(Crowdloan::new_raise(), vec![ParaId::from(2000)]); // Beginning of ending block. @@ -1272,7 +1456,7 @@ fn cant_bid_on_existing_lease_periods() { // Bids cannot be made which intersect assert_noop!( Auctions::bid( - Origin::signed(crowdloan_account), + Origin::signed(crowdloan_account.clone()), ParaId::from(2000), 2, lease_period_index_start + 0, @@ -1284,7 +1468,7 @@ fn cant_bid_on_existing_lease_periods() { assert_noop!( Auctions::bid( - Origin::signed(crowdloan_account), + Origin::signed(crowdloan_account.clone()), ParaId::from(2000), 2, lease_period_index_start + 1, @@ -1296,7 +1480,7 @@ fn cant_bid_on_existing_lease_periods() { assert_noop!( Auctions::bid( - Origin::signed(crowdloan_account), + Origin::signed(crowdloan_account.clone()), ParaId::from(2000), 2, lease_period_index_start - 1, @@ -1308,7 +1492,7 @@ fn cant_bid_on_existing_lease_periods() { assert_noop!( Auctions::bid( - Origin::signed(crowdloan_account), + Origin::signed(crowdloan_account.clone()), ParaId::from(2000), 2, lease_period_index_start + 0, @@ -1320,7 +1504,7 @@ fn cant_bid_on_existing_lease_periods() { assert_noop!( Auctions::bid( - Origin::signed(crowdloan_account), + Origin::signed(crowdloan_account.clone()), ParaId::from(2000), 2, lease_period_index_start + 1, @@ -1332,7 +1516,7 @@ fn cant_bid_on_existing_lease_periods() { assert_noop!( Auctions::bid( - Origin::signed(crowdloan_account), + Origin::signed(crowdloan_account.clone()), ParaId::from(2000), 2, lease_period_index_start - 1, @@ -1344,7 +1528,7 @@ fn cant_bid_on_existing_lease_periods() { // Will work when not overlapping assert_ok!(Auctions::bid( - Origin::signed(crowdloan_account), + Origin::signed(crowdloan_account.clone()), ParaId::from(2000), 2, lease_period_index_start + 2, From 9548b0abe78a7f5253cf47aa47852d6c7417ebdd Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 11:55:42 +0100 Subject: [PATCH 09/22] Update Crowdloan Account to FundIndex (#4824) * update fund account to use index * fix integration tests * Update runtime/common/src/crowdloan.rs --- runtime/common/src/crowdloan.rs | 96 ++++++++++++++----------- runtime/common/src/integration_tests.rs | 23 +++--- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/runtime/common/src/crowdloan.rs b/runtime/common/src/crowdloan.rs index 86fc53f8d59b..a500a2583562 100644 --- a/runtime/common/src/crowdloan.rs +++ b/runtime/common/src/crowdloan.rs @@ -87,7 +87,7 @@ type BalanceOf = as Currency<::Acco type NegativeImbalanceOf = as Currency<::AccountId>>::NegativeImbalance; -type TrieIndex = u32; +type FundIndex = u32; pub trait WeightInfo { fn create() -> Weight; @@ -170,8 +170,8 @@ pub struct FundInfo { /// Last lease period in range to bid on; it's actually a `LeasePeriod`, but that's the same type /// as `BlockNumber`. pub last_period: LeasePeriod, - /// Index used for the child trie of this fund - pub trie_index: TrieIndex, + /// Unique index used to represent this fund. + pub fund_index: FundIndex, } #[frame_support::pallet] @@ -246,8 +246,8 @@ pub mod pallet { /// Tracker for the next available trie index #[pallet::storage] - #[pallet::getter(fn next_trie_index)] - pub(super) type NextTrieIndex = StorageValue<_, u32, ValueQuery>; + #[pallet::getter(fn next_fund_index)] + pub(super) type NextFundIndex = StorageValue<_, u32, ValueQuery>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -342,7 +342,7 @@ pub mod pallet { // Care needs to be taken by the crowdloan creator that this function will succeed given // the crowdloaning configuration. We do some checks ahead of time in crowdloan `create`. let result = T::Auctioneer::place_bid( - Self::fund_account_id(para_id), + Self::fund_account_id(fund.fund_index), para_id, fund.first_period, fund.last_period, @@ -408,8 +408,8 @@ pub mod pallet { ensure!(depositor == manager, Error::::InvalidOrigin); ensure!(T::Registrar::is_registered(index), Error::::InvalidParaId); - let trie_index = Self::next_trie_index(); - let new_trie_index = trie_index.checked_add(1).ok_or(Error::::Overflow)?; + let fund_index = Self::next_fund_index(); + let new_fund_index = fund_index.checked_add(1).ok_or(Error::::Overflow)?; let deposit = T::SubmissionDeposit::get(); @@ -427,11 +427,11 @@ pub mod pallet { last_contribution: LastContribution::Never, first_period, last_period, - trie_index, + fund_index, }, ); - NextTrieIndex::::put(new_trie_index); + NextFundIndex::::put(new_fund_index); // Add a lock to the para so that the configuration cannot be changed. T::Registrar::apply_lock(index); @@ -479,15 +479,15 @@ pub mod pallet { let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; let now = frame_system::Pallet::::block_number(); - let fund_account = Self::fund_account_id(index); + let fund_account = Self::fund_account_id(fund.fund_index); Self::ensure_crowdloan_ended(now, &fund_account, &fund)?; - let (balance, _) = Self::contribution_get(fund.trie_index, &who); + let (balance, _) = Self::contribution_get(fund.fund_index, &who); ensure!(balance > Zero::zero(), Error::::NoContributions); CurrencyOf::::transfer(&fund_account, &who, balance, AllowDeath)?; - Self::contribution_kill(fund.trie_index, &who); + Self::contribution_kill(fund.fund_index, &who); fund.raised = fund.raised.saturating_sub(balance); Funds::::insert(index, &fund); @@ -510,12 +510,12 @@ pub mod pallet { let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; let now = frame_system::Pallet::::block_number(); - let fund_account = Self::fund_account_id(index); + let fund_account = Self::fund_account_id(fund.fund_index); Self::ensure_crowdloan_ended(now, &fund_account, &fund)?; let mut refund_count = 0u32; // Try killing the crowdloan child trie - let contributions = Self::contribution_iterator(fund.trie_index); + let contributions = Self::contribution_iterator(fund.fund_index); // Assume everyone will be refunded. let mut all_refunded = true; for (who, (balance, _)) in contributions { @@ -525,7 +525,7 @@ pub mod pallet { break } CurrencyOf::::transfer(&fund_account, &who, balance, AllowDeath)?; - Self::contribution_kill(fund.trie_index, &who); + Self::contribution_kill(fund.fund_index, &who); fund.raised = fund.raised.saturating_sub(balance); refund_count += 1; } @@ -561,7 +561,7 @@ pub mod pallet { // Assuming state is not corrupted, the child trie should already be cleaned up // and all funds in the crowdloan account have been returned. If not, governance // can take care of that. - debug_assert!(Self::contribution_iterator(fund.trie_index).count().is_zero()); + debug_assert!(Self::contribution_iterator(fund.fund_index).count().is_zero()); CurrencyOf::::unreserve(&fund.depositor, fund.deposit); Funds::::remove(index); @@ -598,7 +598,7 @@ pub mod pallet { last_contribution: fund.last_contribution, first_period, last_period, - trie_index: fund.trie_index, + fund_index: fund.fund_index, }, ); @@ -616,10 +616,10 @@ pub mod pallet { ensure!(memo.len() <= T::MaxMemoLength::get().into(), Error::::MemoTooLarge); let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - let (balance, _) = Self::contribution_get(fund.trie_index, &who); + let (balance, _) = Self::contribution_get(fund.fund_index, &who); ensure!(balance > Zero::zero(), Error::::NoContributions); - Self::contribution_put(fund.trie_index, &who, &balance, &memo); + Self::contribution_put(fund.fund_index, &who, &balance, &memo); Self::deposit_event(Event::::MemoUpdated(who, index, memo)); Ok(()) } @@ -658,11 +658,11 @@ impl Pallet { /// /// This actually does computation. If you need to keep using it, then make sure you cache the /// value and only call this once. - pub fn fund_account_id(index: ParaId) -> T::AccountId { + pub fn fund_account_id(index: FundIndex) -> T::AccountId { T::PalletId::get().into_sub_account(index) } - pub fn id_from_index(index: TrieIndex) -> child::ChildInfo { + pub fn id_from_index(index: FundIndex) -> child::ChildInfo { let mut buf = Vec::new(); buf.extend_from_slice(b"crowdloan"); buf.extend_from_slice(&index.encode()[..]); @@ -670,7 +670,7 @@ impl Pallet { } pub fn contribution_put( - index: TrieIndex, + index: FundIndex, who: &T::AccountId, balance: &BalanceOf, memo: &[u8], @@ -678,22 +678,22 @@ impl Pallet { who.using_encoded(|b| child::put(&Self::id_from_index(index), b, &(balance, memo))); } - pub fn contribution_get(index: TrieIndex, who: &T::AccountId) -> (BalanceOf, Vec) { + pub fn contribution_get(index: FundIndex, who: &T::AccountId) -> (BalanceOf, Vec) { who.using_encoded(|b| { child::get_or_default::<(BalanceOf, Vec)>(&Self::id_from_index(index), b) }) } - pub fn contribution_kill(index: TrieIndex, who: &T::AccountId) { + pub fn contribution_kill(index: FundIndex, who: &T::AccountId) { who.using_encoded(|b| child::kill(&Self::id_from_index(index), b)); } - pub fn crowdloan_kill(index: TrieIndex) -> child::KillStorageResult { + pub fn crowdloan_kill(index: FundIndex) -> child::KillStorageResult { child::kill_storage(&Self::id_from_index(index), Some(T::RemoveKeysLimit::get())) } pub fn contribution_iterator( - index: TrieIndex, + index: FundIndex, ) -> ChildTriePrefixIterator<(T::AccountId, (BalanceOf, Vec))> { ChildTriePrefixIterator::<_>::with_prefix_over_key::( &Self::id_from_index(index), @@ -752,7 +752,7 @@ impl Pallet { ensure!(current_lease_period <= fund.first_period, Error::::ContributionPeriodOver); // Make sure crowdloan has not already won. - let fund_account = Self::fund_account_id(index); + let fund_account = Self::fund_account_id(fund.fund_index); ensure!( !T::Auctioneer::has_won_an_auction(index, &fund_account), Error::::BidOrLeaseActive @@ -762,7 +762,7 @@ impl Pallet { // contributions into the auction when it would not impact the outcome. ensure!(!T::Auctioneer::auction_status(now).is_vrf(), Error::::VrfDelayInProgress); - let (old_balance, memo) = Self::contribution_get(fund.trie_index, &who); + let (old_balance, memo) = Self::contribution_get(fund.fund_index, &who); if let Some(ref verifier) = fund.verifier { let signature = signature.ok_or(Error::::InvalidSignature)?; @@ -776,7 +776,7 @@ impl Pallet { CurrencyOf::::transfer(&who, &fund_account, value, existence)?; let balance = old_balance.saturating_add(value); - Self::contribution_put(fund.trie_index, &who, &balance, &memo); + Self::contribution_put(fund.fund_index, &who, &balance, &memo); if T::Auctioneer::auction_status(now).is_ending().is_some() { match fund.last_contribution { @@ -966,7 +966,8 @@ mod tests { // Emulate what would happen if we won an auction: // balance is reserved and a deposit_held is recorded fn set_winner(para: ParaId, who: u64, winner: bool) { - let account_id = Crowdloan::fund_account_id(para); + let fund = Funds::::get(para).unwrap(); + let account_id = Crowdloan::fund_account_id(fund.fund_index); if winner { let free_balance = Balances::free_balance(&account_id); Balances::reserve(&account_id, free_balance) @@ -1177,7 +1178,7 @@ mod tests { last_contribution: LastContribution::Never, first_period: 1, last_period: 4, - trie_index: 0, + fund_index: 0, }; assert_eq!(Crowdloan::funds(para), Some(fund_info)); // User has deposit removed from their free balance @@ -1217,7 +1218,7 @@ mod tests { last_contribution: LastContribution::Never, first_period: 1, last_period: 4, - trie_index: 0, + fund_index: 0, }; assert_eq!(Crowdloan::funds(ParaId::from(0)), Some(fund_info)); // User has deposit removed from their free balance @@ -1270,6 +1271,7 @@ mod tests { fn contribute_works() { new_test_ext().execute_with(|| { let para = new_para(); + let index = NextFundIndex::::get(); // Set up a crowdloan assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 4, 9, None)); @@ -1284,7 +1286,7 @@ mod tests { // Contributions are stored in the trie assert_eq!(Crowdloan::contribution_get(u32::from(para), &1).0, 49); // Contributions appear in free balance of crowdloan - assert_eq!(Balances::free_balance(Crowdloan::fund_account_id(para)), 49); + assert_eq!(Balances::free_balance(Crowdloan::fund_account_id(index)), 49); // Crowdloan is added to NewRaise assert_eq!(Crowdloan::new_raise(), vec![para]); @@ -1300,6 +1302,7 @@ mod tests { fn contribute_with_verifier_works() { new_test_ext().execute_with(|| { let para = new_para(); + let index = NextFundIndex::::get(); let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); // Set up a crowdloan assert_ok!(Crowdloan::create( @@ -1364,7 +1367,7 @@ mod tests { assert_ok!(Crowdloan::contribute(Origin::signed(1), para, 10, Some(valid_signature_2))); // Contributions appear in free balance of crowdloan - assert_eq!(Balances::free_balance(Crowdloan::fund_account_id(para)), 59); + assert_eq!(Balances::free_balance(Crowdloan::fund_account_id(index)), 59); // Contribution amount is correct let fund = Crowdloan::funds(para).unwrap(); @@ -1409,9 +1412,10 @@ mod tests { // If a crowdloan has already won, it should not allow contributions. let para_2 = new_para(); + let index = NextFundIndex::::get(); assert_ok!(Crowdloan::create(Origin::signed(1), para_2, 1000, 1, 4, 40, None)); // Emulate a win by leasing out and putting a deposit. Slots pallet would normally do this. - let crowdloan_account = Crowdloan::fund_account_id(para_2); + let crowdloan_account = Crowdloan::fund_account_id(index); set_winner(para_2, crowdloan_account, true); assert_noop!( Crowdloan::contribute(Origin::signed(1), para_2, 49, None), @@ -1478,6 +1482,7 @@ mod tests { fn bidding_works() { new_test_ext().execute_with(|| { let para = new_para(); + let index = NextFundIndex::::get(); let first_period = 1; let last_period = 4; @@ -1493,7 +1498,7 @@ mod tests { 9, None )); - let bidder = Crowdloan::fund_account_id(para); + let bidder = Crowdloan::fund_account_id(index); // Fund crowdloan run_to_block(1); @@ -1524,6 +1529,7 @@ mod tests { fn withdraw_from_failed_works() { new_test_ext().execute_with(|| { let para = new_para(); + let index = NextFundIndex::::get(); // Set up a crowdloan assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 1, 9, None)); @@ -1531,7 +1537,7 @@ mod tests { assert_ok!(Crowdloan::contribute(Origin::signed(3), para, 50, None)); run_to_block(10); - let account_id = Crowdloan::fund_account_id(para); + let account_id = Crowdloan::fund_account_id(index); // para has no reserved funds, indicating it did not win the auction. assert_eq!(Balances::reserved_balance(&account_id), 0); // but there's still the funds in its balance. @@ -1553,13 +1559,14 @@ mod tests { fn withdraw_cannot_be_griefed() { new_test_ext().execute_with(|| { let para = new_para(); + let index = NextFundIndex::::get(); // Set up a crowdloan assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 1, 9, None)); assert_ok!(Crowdloan::contribute(Origin::signed(2), para, 100, None)); run_to_block(10); - let account_id = Crowdloan::fund_account_id(para); + let account_id = Crowdloan::fund_account_id(index); // user sends the crowdloan funds trying to make an accounting error assert_ok!(Balances::transfer(Origin::signed(1), account_id, 10)); @@ -1583,7 +1590,8 @@ mod tests { fn refund_works() { new_test_ext().execute_with(|| { let para = new_para(); - let account_id = Crowdloan::fund_account_id(para); + let index = NextFundIndex::::get(); + let account_id = Crowdloan::fund_account_id(index); // Set up a crowdloan ending on 9 assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 1, 9, None)); @@ -1617,7 +1625,8 @@ mod tests { fn multiple_refund_works() { new_test_ext().execute_with(|| { let para = new_para(); - let account_id = Crowdloan::fund_account_id(para); + let index = NextFundIndex::::get(); + let account_id = Crowdloan::fund_account_id(index); // Set up a crowdloan ending on 9 assert_ok!(Crowdloan::create(Origin::signed(1), para, 100000, 1, 1, 9, None)); @@ -1727,7 +1736,8 @@ mod tests { fn withdraw_from_finished_works() { new_test_ext().execute_with(|| { let para = new_para(); - let account_id = Crowdloan::fund_account_id(para); + let index = NextFundIndex::::get(); + let account_id = Crowdloan::fund_account_id(index); // Set up a crowdloan assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 1, 9, None)); @@ -2079,7 +2089,7 @@ mod benchmarking { verify { let fund = Funds::::get(fund_index).expect("fund was created..."); assert_eq!( - Crowdloan::::contribution_get(fund.trie_index, &caller), + Crowdloan::::contribution_get(fund.fund_index, &caller), (T::MinContribution::get(), worst_memo), ); } diff --git a/runtime/common/src/integration_tests.rs b/runtime/common/src/integration_tests.rs index 5c1dc9f13251..b6c89e2294b0 100644 --- a/runtime/common/src/integration_tests.rs +++ b/runtime/common/src/integration_tests.rs @@ -401,7 +401,8 @@ fn basic_end_to_end_works() { 200 + offset, // Block End None, )); - let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(para_2)); + let fund_2 = Crowdloan::funds(ParaId::from(para_2)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund_2.fund_index); // Auction ending begins on block 100 + offset, so we make a bid before then. run_to_block(90 + offset); @@ -723,7 +724,8 @@ fn competing_bids() { run_to_block(starting_block + 110); // Appropriate Paras should have won slots - let crowdloan_1 = Crowdloan::fund_account_id(ParaId::from(2000)); + let fund_1 = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_1 = Crowdloan::fund_account_id(fund_1.fund_index); assert_eq!( slots::Leases::::get(ParaId::from(2000)), // -- 1 --- 2 --- 3 --- 4 --- 5 ------------- 6 ------------------------ 7 ------------- @@ -793,7 +795,8 @@ fn basic_swap_works() { 200, // Block End None, )); - let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000)); + let fund = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund.fund_index); // Bunch of contributions let mut total = 0; @@ -921,8 +924,7 @@ fn parachain_swap_works() { assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding)); assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding)); - assert_eq!(Balances::total_balance(&Crowdloan::fund_account_id(ParaId::from(2000))), 0); - + assert_eq!(Balances::total_balance(&Crowdloan::fund_account_id(Crowdloan::next_fund_index())), 0); // Start a new auction in the future let start_auction = |lease_period_index_start, winner, end| { @@ -945,7 +947,8 @@ fn parachain_swap_works() { end, // Block End None, )); - let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(winner)); + let winner_fund = Crowdloan::funds(ParaId::from(winner)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(winner_fund.fund_index); // Bunch of contributions let mut total = 0; @@ -997,7 +1000,7 @@ fn parachain_swap_works() { assert_eq!(slots::Leases::::get(ParaId::from(2001)).len(), 8); let fund_1 = Crowdloan::funds(ParaId::from(2000)).unwrap(); - assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(ParaId::from(2000))), fund_1.raised); + assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_1.fund_index)), fund_1.raised); // Now we swap them. assert_ok!(Registrar::swap( @@ -1109,7 +1112,8 @@ fn crowdloan_ending_period_bid() { 200, // Block End None, )); - let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000)); + let fund = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund.fund_index); // Bunch of contributions let mut total = 0; @@ -1412,7 +1416,8 @@ fn cant_bid_on_existing_lease_periods() { 400, // Long block end None, )); - let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000)); + let fund = Crowdloan::funds(ParaId::from(2000)).unwrap(); + let crowdloan_account = Crowdloan::fund_account_id(fund.fund_index); // Bunch of contributions let mut total = 0; From c643273d75725ddaf9c2a5beb2ea37cf57b8345e Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 12:54:54 +0100 Subject: [PATCH 10/22] finish parachain swap test --- runtime/common/src/integration_tests.rs | 72 ++++++++----------------- 1 file changed, 22 insertions(+), 50 deletions(-) diff --git a/runtime/common/src/integration_tests.rs b/runtime/common/src/integration_tests.rs index b6c89e2294b0..a04a52a86ee1 100644 --- a/runtime/common/src/integration_tests.rs +++ b/runtime/common/src/integration_tests.rs @@ -999,8 +999,16 @@ fn parachain_swap_works() { assert_eq!(slots::Leases::::get(ParaId::from(2000)).len(), 6); assert_eq!(slots::Leases::::get(ParaId::from(2001)).len(), 8); - let fund_1 = Crowdloan::funds(ParaId::from(2000)).unwrap(); - assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_1.fund_index)), fund_1.raised); + let fund_2000 = Crowdloan::funds(ParaId::from(2000)).unwrap(); + assert_eq!(fund_2000.fund_index, 0); + assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), fund_2000.raised); + + let fund_2001 = Crowdloan::funds(ParaId::from(2001)).unwrap(); + assert_eq!(fund_2001.fund_index, 1); + assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), fund_2001.raised); + + assert_eq!(Slots::lease(ParaId::from(2000)).len(), 6); + assert_eq!(Slots::lease(ParaId::from(2001)).len(), 8); // Now we swap them. assert_ok!(Registrar::swap( @@ -1014,54 +1022,18 @@ fn parachain_swap_works() { ParaId::from(2000) )); - // assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::DowngradingParachain)); - // assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::UpgradingParathread)); - - // // 2 session later they have swapped - // run_to_block(lease_start_block + 40); - // assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread)); - // assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parachain)); - - // // Deregister parathread - // assert_ok!(Registrar::deregister(para_origin(2000).into(), ParaId::from(2000))); - // // Correct deposit is unreserved - // assert_eq!(Balances::reserved_balance(&account_id(1)), 100); // crowdloan deposit left over - // assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); - // // Crowdloan ownership is swapped - // assert!(Crowdloan::funds(ParaId::from(2000)).is_none()); - // assert!(Crowdloan::funds(ParaId::from(2001)).is_some()); - // // Slot is swapped - // assert!(Slots::lease(ParaId::from(2000)).is_empty()); - // assert!(!Slots::lease(ParaId::from(2001)).is_empty()); - - // // Cant dissolve - // assert_noop!( - // Crowdloan::dissolve(signed(1), ParaId::from(2000)), - // CrowdloanError::::InvalidParaId - // ); - // assert_noop!( - // Crowdloan::dissolve(signed(2), ParaId::from(2001)), - // CrowdloanError::::NotReadyToDissolve - // ); - - // // Go way in the future when the para is offboarded - // run_to_block(lease_start_block + 1000); - - // // Withdraw of contributions works - // assert_eq!(Balances::free_balance(&crowdloan_account), total); - // for i in 10..20 { - // assert_ok!(Crowdloan::withdraw(signed(i), account_id(i), ParaId::from(2001))); - // } - // assert_eq!(Balances::free_balance(&crowdloan_account), 0); - - // // Dissolve returns the balance of the person who put a deposit for crowdloan - // assert_ok!(Crowdloan::dissolve(signed(1), ParaId::from(2001))); - // assert_eq!(Balances::reserved_balance(&account_id(1)), 0); - // assert_eq!(Balances::reserved_balance(&account_id(2)), 500 + 20 * 2 * 1); - - // // Final deregister sets everything back to the start - // assert_ok!(Registrar::deregister(para_origin(2001).into(), ParaId::from(2001))); - // assert_eq!(Balances::reserved_balance(&account_id(2)), 0); + // Crowdloan Swapped + let fund_2000 = Crowdloan::funds(ParaId::from(2000)).unwrap(); + assert_eq!(fund_2000.fund_index, 1); + assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), fund_2000.raised); + + let fund_2001 = Crowdloan::funds(ParaId::from(2001)).unwrap(); + assert_eq!(fund_2001.fund_index, 0); + assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), fund_2001.raised); + + // Slots Swapped + assert_eq!(Slots::lease(ParaId::from(2000)).len(), 8); + assert_eq!(Slots::lease(ParaId::from(2001)).len(), 6); }) } From a54d1f24657bb2fa2f035b6433c5daa9b50c6efd Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 12:55:17 +0100 Subject: [PATCH 11/22] format --- runtime/common/src/integration_tests.rs | 69 +++++++++++++++++++------ 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/runtime/common/src/integration_tests.rs b/runtime/common/src/integration_tests.rs index a04a52a86ee1..d476242c9ade 100644 --- a/runtime/common/src/integration_tests.rs +++ b/runtime/common/src/integration_tests.rs @@ -20,7 +20,7 @@ use crate::{ auctions, crowdloan, paras_registrar, slot_range::SlotRange, slots, - traits::{AuctionStatus, Auctioneer, Registrar as RegistrarT, Leaser}, + traits::{AuctionStatus, Auctioneer, Leaser, Registrar as RegistrarT}, }; use frame_support::{ assert_noop, assert_ok, parameter_types, @@ -29,6 +29,7 @@ use frame_support::{ }; use frame_support_test::TestRandomness; use frame_system::EnsureRoot; +use parity_scale_codec::Encode; use primitives::v1::{ BlockNumber, HeadData, Header, Id as ParaId, ValidationCode, LOWEST_PUBLIC_ID, }; @@ -39,12 +40,11 @@ use sp_core::{crypto::KeyTypeId, H256}; use sp_io::TestExternalities; use sp_keystore::{testing::KeyStore, KeystoreExt}; use sp_runtime::{ - AccountId32, traits::{BlakeTwo256, IdentityLookup, One}, transaction_validity::TransactionPriority, + AccountId32, }; -use sp_std::{sync::Arc, convert::TryInto}; -use parity_scale_codec::Encode; +use sp_std::{convert::TryInto, sync::Arc}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -643,7 +643,15 @@ fn competing_slots() { assert_eq!( slots::Leases::::get(para_id + 8), // -- 1 --- 2 --- 3 --- 4 --- 5 ---------- 6 --------------- 7 ------- - vec![None, None, None, None, None, Some((account_id(90), 8100)), Some((account_id(90), 8100))], + vec![ + None, + None, + None, + None, + None, + Some((account_id(90), 8100)), + Some((account_id(90), 8100)) + ], ); }); } @@ -752,7 +760,7 @@ fn basic_swap_works() { // This test will test a swap between a parachain and parathread works successfully. new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads with different data @@ -901,7 +909,7 @@ fn parachain_swap_works() { // This test will test a swap between two parachains works successfully. new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads with different data @@ -924,7 +932,10 @@ fn parachain_swap_works() { assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding)); assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding)); - assert_eq!(Balances::total_balance(&Crowdloan::fund_account_id(Crowdloan::next_fund_index())), 0); + assert_eq!( + Balances::total_balance(&Crowdloan::fund_account_id(Crowdloan::next_fund_index())), + 0 + ); // Start a new auction in the future let start_auction = |lease_period_index_start, winner, end| { @@ -952,7 +963,7 @@ fn parachain_swap_works() { // Bunch of contributions let mut total = 0; - for i in (unique_id * 10) .. (unique_id + 1) * 10 { + for i in (unique_id * 10)..(unique_id + 1) * 10 { Balances::make_free_balance_be(&account_id(i), 1_000_000_000); assert_ok!(Crowdloan::contribute(signed(i), ParaId::from(winner), 900 - i, None)); total += 900 - i; @@ -993,7 +1004,10 @@ fn parachain_swap_works() { assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parachain)); // Currently we are on lease 6 - assert_eq!(>::lease_period_index(System::block_number()), Some((6u32, false))); + assert_eq!( + >::lease_period_index(System::block_number()), + Some((6u32, false)) + ); // This means that parachain 1 should only have 6 slots left, and parachain 2 has all 8. assert_eq!(slots::Leases::::get(ParaId::from(2000)).len(), 6); @@ -1001,11 +1015,17 @@ fn parachain_swap_works() { let fund_2000 = Crowdloan::funds(ParaId::from(2000)).unwrap(); assert_eq!(fund_2000.fund_index, 0); - assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), fund_2000.raised); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), + fund_2000.raised + ); let fund_2001 = Crowdloan::funds(ParaId::from(2001)).unwrap(); assert_eq!(fund_2001.fund_index, 1); - assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), fund_2001.raised); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), + fund_2001.raised + ); assert_eq!(Slots::lease(ParaId::from(2000)).len(), 6); assert_eq!(Slots::lease(ParaId::from(2001)).len(), 8); @@ -1025,11 +1045,17 @@ fn parachain_swap_works() { // Crowdloan Swapped let fund_2000 = Crowdloan::funds(ParaId::from(2000)).unwrap(); assert_eq!(fund_2000.fund_index, 1); - assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), fund_2000.raised); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2000.fund_index)), + fund_2000.raised + ); let fund_2001 = Crowdloan::funds(ParaId::from(2001)).unwrap(); assert_eq!(fund_2001.fund_index, 0); - assert_eq!(Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), fund_2001.raised); + assert_eq!( + Balances::reserved_balance(&Crowdloan::fund_account_id(fund_2001.fund_index)), + fund_2001.raised + ); // Slots Swapped assert_eq!(Slots::lease(ParaId::from(2000)).len(), 8); @@ -1041,7 +1067,7 @@ fn parachain_swap_works() { fn crowdloan_ending_period_bid() { new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads @@ -1308,7 +1334,12 @@ fn gap_bids_work() { assert_eq!( slots::Leases::::get(ParaId::from(2000)), // --------- 4 -------------- 5 -------------- 6 -------------- 7 ------- - vec![Some((account_id(10), 100)), Some((account_id(20), 800)), Some((account_id(20), 200)), Some((account_id(10), 400))], + vec![ + Some((account_id(10), 100)), + Some((account_id(20), 800)), + Some((account_id(20), 200)), + Some((account_id(10), 400)) + ], ); // Nothing changed. assert_eq!(Balances::reserved_balance(&account_id(10)), 400); @@ -1319,7 +1350,11 @@ fn gap_bids_work() { assert_eq!( slots::Leases::::get(ParaId::from(2000)), // --------- 5 -------------- 6 -------------- 7 ------- - vec![Some((account_id(20), 800)), Some((account_id(20), 200)), Some((account_id(10), 400))], + vec![ + Some((account_id(20), 800)), + Some((account_id(20), 200)), + Some((account_id(10), 400)) + ], ); // Nothing changed. assert_eq!(Balances::reserved_balance(&account_id(10)), 400); From c963177298ecc0ac460f43db31006b55745645ce Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 13:13:54 +0100 Subject: [PATCH 12/22] fix warning --- runtime/kusama/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 48193841dfa3..df484f72d520 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -141,7 +141,7 @@ pub fn native_version() -> NativeVersion { /// We currently allow all calls. pub struct BaseFilter; impl Contains for BaseFilter { - fn contains(c: &Call) -> bool { + fn contains(_c: &Call) -> bool { true } } From 3d85c335fe552d68086752d86a8416d50bd17629 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 13:14:28 +0100 Subject: [PATCH 13/22] fix spacing --- runtime/common/src/integration_tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/common/src/integration_tests.rs b/runtime/common/src/integration_tests.rs index d476242c9ade..35922e15feb4 100644 --- a/runtime/common/src/integration_tests.rs +++ b/runtime/common/src/integration_tests.rs @@ -760,7 +760,7 @@ fn basic_swap_works() { // This test will test a swap between a parachain and parathread works successfully. new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads with different data @@ -909,7 +909,7 @@ fn parachain_swap_works() { // This test will test a swap between two parachains works successfully. new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads with different data @@ -1067,7 +1067,7 @@ fn parachain_swap_works() { fn crowdloan_ending_period_bid() { new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); // First register 2 parathreads From 19f7a048aea945c45a0a4c3b3675006c4cd08c80 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 13:22:27 +0100 Subject: [PATCH 14/22] fix formatting --- runtime/common/src/integration_tests.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/common/src/integration_tests.rs b/runtime/common/src/integration_tests.rs index 35922e15feb4..7032c6badc82 100644 --- a/runtime/common/src/integration_tests.rs +++ b/runtime/common/src/integration_tests.rs @@ -759,7 +759,7 @@ fn competing_bids() { fn basic_swap_works() { // This test will test a swap between a parachain and parathread works successfully. new_test_ext().execute_with(|| { - assert!(System::block_number().is_one()); // So events are emitted + assert!(System::block_number().is_one()); /* So events are emitted */ // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); @@ -908,7 +908,7 @@ fn basic_swap_works() { fn parachain_swap_works() { // This test will test a swap between two parachains works successfully. new_test_ext().execute_with(|| { - assert!(System::block_number().is_one()); // So events are emitted + assert!(System::block_number().is_one()); /* So events are emitted */ // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); @@ -1066,7 +1066,7 @@ fn parachain_swap_works() { #[test] fn crowdloan_ending_period_bid() { new_test_ext().execute_with(|| { - assert!(System::block_number().is_one()); // So events are emitted + assert!(System::block_number().is_one()); /* So events are emitted */ // User 1 and 2 will own paras Balances::make_free_balance_be(&account_id(1), 1_000_000_000); Balances::make_free_balance_be(&account_id(2), 1_000_000_000); @@ -1164,7 +1164,7 @@ fn crowdloan_ending_period_bid() { #[test] fn auction_bid_requires_registered_para() { new_test_ext().execute_with(|| { - assert!(System::block_number().is_one()); // So events are emitted + assert!(System::block_number().is_one()); /* So events are emitted */ // Start a new auction in the future let duration = 99u32; @@ -1226,7 +1226,7 @@ fn auction_bid_requires_registered_para() { #[test] fn gap_bids_work() { new_test_ext().execute_with(|| { - assert!(System::block_number().is_one()); // So events are emitted + assert!(System::block_number().is_one()); /* So events are emitted */ // Start a new auction in the future let duration = 99u32; @@ -1393,7 +1393,7 @@ fn gap_bids_work() { #[test] fn cant_bid_on_existing_lease_periods() { new_test_ext().execute_with(|| { - assert!(System::block_number().is_one()); // So events are emitted + assert!(System::block_number().is_one()); /* So events are emitted */ Balances::make_free_balance_be(&account_id(1), 1_000_000_000); // First register a parathread assert_ok!(Registrar::reserve(signed(1))); From ba1dc91206a67dfc126df9e6aec01af2e849a83f Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 14:45:44 +0100 Subject: [PATCH 15/22] write migrations --- runtime/common/src/crowdloan/migration.rs | 84 +++++++++++++++++++ .../src/{crowdloan.rs => crowdloan/mod.rs} | 0 2 files changed, 84 insertions(+) create mode 100644 runtime/common/src/crowdloan/migration.rs rename runtime/common/src/{crowdloan.rs => crowdloan/mod.rs} (100%) diff --git a/runtime/common/src/crowdloan/migration.rs b/runtime/common/src/crowdloan/migration.rs new file mode 100644 index 000000000000..be6ea830cd51 --- /dev/null +++ b/runtime/common/src/crowdloan/migration.rs @@ -0,0 +1,84 @@ +// Copyright 2017-2020 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 . + +use super::*; +use frame_support::generate_storage_alias; + +/// Migrations for using fund index to create fund accounts instead of para ID. +pub mod crowdloan_index_migration { + // The old way we generated fund accounts. + fn old_fund_account_id(index: ParaId) -> T::AccountId { + T::PalletId::get().into_sub_account(index) + } + + pub fn pre_migration() { + // `NextTrieIndex` should have a value. + generate_storage_alias!(Crowdloan, NextTrieIndex => Value); + let next_index = NextTrieIndex::take().unwrap_or_default(); + assert!(next_index > 0); + + // Each fund should have some non-zero balance. + Funds::::iter().for_each(|(para_id, fund)| { + let old_fund_account = old_fund_account_id::(para_id); + let total_balance = T::Currency::total_balance(old_fund_account); + + assert_eq!(total_balance, fund.raised); + assert!(total_balance > Zero::zero()); + }); + } + + /// This migration converts crowdloans to use a crowdloan index rather than the parachain id as a + /// unique identifier. This makes it easier to swap two crowdloans between parachains. + pub fn migrate() { + // First migrate `NextTrieIndex` counter to `NextFundIndex`. + generate_storage_alias!(Crowdloan, NextTrieIndex => Value); + + let next_index = NextTrieIndex::take().unwrap_or_default(); + NextFundIndex::::set(next_index); + + // Migrate all accounts from `old_fund_account` to `fund_account` using `fund_index`. + Funds::::iter().for_each(|(para_id, fund)| { + let old_fund_account = old_fund_account_id::(para_id); + let new_fund_account = Pallet::::fund_account_id(fund.fund_index); + + // Funds should only have a free balance and a reserve balance. Both of these are in the + // `Account` storage item, so we just swap them. + let account_info = frame_system::Account::::take(old_fund_account); + frame_system::Account::::insert(new_fund_account, account_info); + }); + } + + pub fn post_migrate() { + // `NextTrieIndex` should not have a value, and `NextFundIndex` should. + generate_storage_alias!(Crowdloan, NextTrieIndex => Value); + assert!(NextTrieIndex::take().is_none()); + assert!(NextFundIndex::get() > 0); + + // Each fund should have balance migrated correctly. + Funds::::iter().for_each(|(para_id, fund)| { + // Old fund account is deleted. + let old_fund_account = old_fund_account_id::(para_id); + assert_eq!(frame_system::Account::::get(old_fund_account_id), Default::default()); + + // New fund account has the correct balance. + let new_fund_account = Pallet::::fund_account_id(fund.fund_index); + let total_balance = T::Currency::total_balance(new_fund_account); + + assert_eq!(total_balance, fund.raised); + assert!(total_balance > Zero::zero()); + }); + } +} diff --git a/runtime/common/src/crowdloan.rs b/runtime/common/src/crowdloan/mod.rs similarity index 100% rename from runtime/common/src/crowdloan.rs rename to runtime/common/src/crowdloan/mod.rs From ed04dc987e74854646b4c89ef9bdf8697cc0a509 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 14:50:17 +0100 Subject: [PATCH 16/22] add migration --- runtime/kusama/src/lib.rs | 20 +++++++++++++++++++- runtime/polkadot/src/lib.rs | 20 +++++++++++++++++++- runtime/rococo/src/lib.rs | 20 +++++++++++++++++++- runtime/westend/src/lib.rs | 20 +++++++++++++++++++- 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index df484f72d520..669f48804cad 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -1497,7 +1497,7 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, - (SchedulerMigrationV3, RefundNickPalletDeposit), + (SchedulerMigrationV3, RefundNickPalletDeposit, CrowdloanIndexMigration), >; /// The payload being signed in the transactions. pub type SignedPayload = generic::SignedPayload; @@ -2929,6 +2929,24 @@ impl OnRuntimeUpgrade for SchedulerMigrationV3 { } } +// Migration for crowdloan pallet to use fund index for account generation. +pub struct CrowdloanIndexMigration; +impl OnRuntimeUpgrade for CrowdloanIndexMigration { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + crowdloan::migration::crowdloan_index_migration::migrate() + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::pre_migration() + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::post_migration() + } +} + /// Migrate session-historical from `Session` to the new pallet prefix `Historical` pub struct SessionHistoricalPalletPrefixMigration; diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index 71cf2ece1ed3..6e35236e84e1 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -1446,11 +1446,29 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, - (SchedulerMigrationV3, FixCouncilDepositMigration), + (SchedulerMigrationV3, FixCouncilDepositMigration, CrowdloanIndexMigration), >; /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; +// Migration for crowdloan pallet to use fund index for account generation. +pub struct CrowdloanIndexMigration; +impl OnRuntimeUpgrade for CrowdloanIndexMigration { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + crowdloan::migration::crowdloan_index_migration::migrate() + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::pre_migration() + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::post_migration() + } +} + /// A migration struct to fix some deposits in the council election pallet. /// /// See more details here: https://github.com/paritytech/polkadot/issues/4160 diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index fa65abcc23ce..adcb31186347 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -154,11 +154,29 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, - (SessionHistoricalModulePrefixMigration,), + (SessionHistoricalModulePrefixMigration, CrowdloanIndexMigration), >; /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; +// Migration for crowdloan pallet to use fund index for account generation. +pub struct CrowdloanIndexMigration; +impl OnRuntimeUpgrade for CrowdloanIndexMigration { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + crowdloan::migration::crowdloan_index_migration::migrate() + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::pre_migration() + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::post_migration() + } +} + /// Migrate session-historical from `Session` to the new pallet prefix `Historical` pub struct SessionHistoricalModulePrefixMigration; diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index ed63e14cc8db..6b7fec26be3b 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -1084,11 +1084,29 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, - (SessionHistoricalPalletPrefixMigration, SchedulerMigrationV3), + (SessionHistoricalPalletPrefixMigration, SchedulerMigrationV3, CrowdloanIndexMigration), >; /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; +// Migration for crowdloan pallet to use fund index for account generation. +pub struct CrowdloanIndexMigration; +impl OnRuntimeUpgrade for CrowdloanIndexMigration { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + crowdloan::migration::crowdloan_index_migration::migrate() + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::pre_migration() + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + crowdloan::migration::crowdloan_index_migration::post_migration() + } +} + // Migration for scheduler pallet to move from a plain Call to a CallOrHash. pub struct SchedulerMigrationV3; From 61df5dcce2bc59a4b07f08ebadd88c7538c6f69d Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 15:43:32 +0100 Subject: [PATCH 17/22] fixes --- runtime/common/src/crowdloan/migration.rs | 10 ++++++---- runtime/common/src/crowdloan/mod.rs | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/runtime/common/src/crowdloan/migration.rs b/runtime/common/src/crowdloan/migration.rs index be6ea830cd51..3ae238c713fb 100644 --- a/runtime/common/src/crowdloan/migration.rs +++ b/runtime/common/src/crowdloan/migration.rs @@ -19,6 +19,8 @@ use frame_support::generate_storage_alias; /// Migrations for using fund index to create fund accounts instead of para ID. pub mod crowdloan_index_migration { + use super::*; + // The old way we generated fund accounts. fn old_fund_account_id(index: ParaId) -> T::AccountId { T::PalletId::get().into_sub_account(index) @@ -33,7 +35,7 @@ pub mod crowdloan_index_migration { // Each fund should have some non-zero balance. Funds::::iter().for_each(|(para_id, fund)| { let old_fund_account = old_fund_account_id::(para_id); - let total_balance = T::Currency::total_balance(old_fund_account); + let total_balance = CurrencyOf::::total_balance(&old_fund_account); assert_eq!(total_balance, fund.raised); assert!(total_balance > Zero::zero()); @@ -65,17 +67,17 @@ pub mod crowdloan_index_migration { // `NextTrieIndex` should not have a value, and `NextFundIndex` should. generate_storage_alias!(Crowdloan, NextTrieIndex => Value); assert!(NextTrieIndex::take().is_none()); - assert!(NextFundIndex::get() > 0); + assert!(NextFundIndex::::get() > 0); // Each fund should have balance migrated correctly. Funds::::iter().for_each(|(para_id, fund)| { // Old fund account is deleted. let old_fund_account = old_fund_account_id::(para_id); - assert_eq!(frame_system::Account::::get(old_fund_account_id), Default::default()); + assert_eq!(frame_system::Account::::get(&old_fund_account), Default::default()); // New fund account has the correct balance. let new_fund_account = Pallet::::fund_account_id(fund.fund_index); - let total_balance = T::Currency::total_balance(new_fund_account); + let total_balance = CurrencyOf::::total_balance(&new_fund_account); assert_eq!(total_balance, fund.raised); assert!(total_balance > Zero::zero()); diff --git a/runtime/common/src/crowdloan/mod.rs b/runtime/common/src/crowdloan/mod.rs index a500a2583562..8d0beeb8e184 100644 --- a/runtime/common/src/crowdloan/mod.rs +++ b/runtime/common/src/crowdloan/mod.rs @@ -49,6 +49,8 @@ //! the parachain remains active. Users can withdraw their funds once the slot is completed and funds are //! returned to the crowdloan account. +pub mod migration; + use crate::{ slot_range::SlotRange, traits::{Auctioneer, Registrar}, From 603771d4a23b1b17bb1203e11a5ebe0c0f362ef0 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 16:07:45 +0100 Subject: [PATCH 18/22] more fixes to migration --- runtime/common/src/crowdloan/migration.rs | 58 ++++++++++++++++------- runtime/kusama/src/lib.rs | 6 +-- runtime/polkadot/src/lib.rs | 6 +-- runtime/rococo/src/lib.rs | 6 +-- runtime/westend/src/lib.rs | 6 +-- 5 files changed, 53 insertions(+), 29 deletions(-) diff --git a/runtime/common/src/crowdloan/migration.rs b/runtime/common/src/crowdloan/migration.rs index 3ae238c713fb..94518a09a978 100644 --- a/runtime/common/src/crowdloan/migration.rs +++ b/runtime/common/src/crowdloan/migration.rs @@ -26,33 +26,42 @@ pub mod crowdloan_index_migration { T::PalletId::get().into_sub_account(index) } - pub fn pre_migration() { + pub fn pre_migrate() -> Result<(), &'static str> { // `NextTrieIndex` should have a value. generate_storage_alias!(Crowdloan, NextTrieIndex => Value); let next_index = NextTrieIndex::take().unwrap_or_default(); - assert!(next_index > 0); + ensure!(next_index > 0, "Next index is zero, which implies no migration is needed."); // Each fund should have some non-zero balance. - Funds::::iter().for_each(|(para_id, fund)| { + for (para_id, fund) in Funds::::iter() { let old_fund_account = old_fund_account_id::(para_id); let total_balance = CurrencyOf::::total_balance(&old_fund_account); - assert_eq!(total_balance, fund.raised); - assert!(total_balance > Zero::zero()); - }); + ensure!( + total_balance == fund.raised, + "Total balance is not equal to the funds raised." + ); + ensure!(total_balance > Zero::zero(), "Total balance is equal to zero."); + } + + Ok(()) } /// This migration converts crowdloans to use a crowdloan index rather than the parachain id as a /// unique identifier. This makes it easier to swap two crowdloans between parachains. - pub fn migrate() { + pub fn migrate() -> frame_support::weights::Weight { + let mut weight = 0; + // First migrate `NextTrieIndex` counter to `NextFundIndex`. generate_storage_alias!(Crowdloan, NextTrieIndex => Value); let next_index = NextTrieIndex::take().unwrap_or_default(); NextFundIndex::::set(next_index); + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2)); + // Migrate all accounts from `old_fund_account` to `fund_account` using `fund_index`. - Funds::::iter().for_each(|(para_id, fund)| { + for (para_id, fund) in Funds::::iter() { let old_fund_account = old_fund_account_id::(para_id); let new_fund_account = Pallet::::fund_account_id(fund.fund_index); @@ -60,27 +69,42 @@ pub mod crowdloan_index_migration { // `Account` storage item, so we just swap them. let account_info = frame_system::Account::::take(old_fund_account); frame_system::Account::::insert(new_fund_account, account_info); - }); + + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2)); + } + + weight } - pub fn post_migrate() { + pub fn post_migrate() -> Result<(), &'static str> { // `NextTrieIndex` should not have a value, and `NextFundIndex` should. generate_storage_alias!(Crowdloan, NextTrieIndex => Value); - assert!(NextTrieIndex::take().is_none()); - assert!(NextFundIndex::::get() > 0); + ensure!(NextTrieIndex::take().is_none(), "NextTrieIndex still has a value."); + ensure!( + NextFundIndex::::get() > 0, + "NextFundIndex was not migrated or is zero. We assume it cannot be zero else no migration is needed." + ); // Each fund should have balance migrated correctly. - Funds::::iter().for_each(|(para_id, fund)| { + for (para_id, fund) in Funds::::iter() { // Old fund account is deleted. let old_fund_account = old_fund_account_id::(para_id); - assert_eq!(frame_system::Account::::get(&old_fund_account), Default::default()); + ensure!( + frame_system::Account::::get(&old_fund_account) == Default::default(), + "Old account wasn't reset to default value." + ); // New fund account has the correct balance. let new_fund_account = Pallet::::fund_account_id(fund.fund_index); let total_balance = CurrencyOf::::total_balance(&new_fund_account); - assert_eq!(total_balance, fund.raised); - assert!(total_balance > Zero::zero()); - }); + ensure!( + total_balance == fund.raised, + "Total balance in new account is different than the funds raised." + ); + ensure!(total_balance > Zero::zero(), "Total balance in the account is zero."); + } + + Ok(()) } } diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 669f48804cad..1be124a3a602 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -2933,17 +2933,17 @@ impl OnRuntimeUpgrade for SchedulerMigrationV3 { pub struct CrowdloanIndexMigration; impl OnRuntimeUpgrade for CrowdloanIndexMigration { fn on_runtime_upgrade() -> frame_support::weights::Weight { - crowdloan::migration::crowdloan_index_migration::migrate() + crowdloan::migration::crowdloan_index_migration::migrate::() } #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::pre_migration() + crowdloan::migration::crowdloan_index_migration::pre_migrate::() } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::post_migration() + crowdloan::migration::crowdloan_index_migration::post_migrate::() } } diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index 6e35236e84e1..ff94c62556ea 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -1455,17 +1455,17 @@ pub type SignedPayload = generic::SignedPayload; pub struct CrowdloanIndexMigration; impl OnRuntimeUpgrade for CrowdloanIndexMigration { fn on_runtime_upgrade() -> frame_support::weights::Weight { - crowdloan::migration::crowdloan_index_migration::migrate() + crowdloan::migration::crowdloan_index_migration::migrate::() } #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::pre_migration() + crowdloan::migration::crowdloan_index_migration::pre_migrate::() } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::post_migration() + crowdloan::migration::crowdloan_index_migration::post_migrate::() } } diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index adcb31186347..021d66c37418 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -163,17 +163,17 @@ pub type SignedPayload = generic::SignedPayload; pub struct CrowdloanIndexMigration; impl OnRuntimeUpgrade for CrowdloanIndexMigration { fn on_runtime_upgrade() -> frame_support::weights::Weight { - crowdloan::migration::crowdloan_index_migration::migrate() + crowdloan::migration::crowdloan_index_migration::migrate::() } #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::pre_migration() + crowdloan::migration::crowdloan_index_migration::pre_migrate::() } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::post_migration() + crowdloan::migration::crowdloan_index_migration::post_migrate::() } } diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index 6b7fec26be3b..a5a354f27681 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -1093,17 +1093,17 @@ pub type SignedPayload = generic::SignedPayload; pub struct CrowdloanIndexMigration; impl OnRuntimeUpgrade for CrowdloanIndexMigration { fn on_runtime_upgrade() -> frame_support::weights::Weight { - crowdloan::migration::crowdloan_index_migration::migrate() + crowdloan::migration::crowdloan_index_migration::migrate::() } #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::pre_migration() + crowdloan::migration::crowdloan_index_migration::pre_migrate::() } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - crowdloan::migration::crowdloan_index_migration::post_migration() + crowdloan::migration::crowdloan_index_migration::post_migrate::() } } From 0ad9e8f882d2650b4d55d177f740f3e9ed4e98e5 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 22:41:01 +0100 Subject: [PATCH 19/22] Update runtime/common/src/crowdloan/mod.rs Co-authored-by: Zeke Mostov --- runtime/common/src/crowdloan/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/common/src/crowdloan/mod.rs b/runtime/common/src/crowdloan/mod.rs index 8d0beeb8e184..44d45e6ec790 100644 --- a/runtime/common/src/crowdloan/mod.rs +++ b/runtime/common/src/crowdloan/mod.rs @@ -246,7 +246,7 @@ pub mod pallet { #[pallet::getter(fn endings_count)] pub(super) type EndingsCount = StorageValue<_, u32, ValueQuery>; - /// Tracker for the next available trie index + /// Tracker for the next available fund index #[pallet::storage] #[pallet::getter(fn next_fund_index)] pub(super) type NextFundIndex = StorageValue<_, u32, ValueQuery>; From e38d881f9905f0ace105dfe8b87f47de55d68100 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 1 Feb 2022 22:44:10 +0100 Subject: [PATCH 20/22] Update runtime/common/src/paras_registrar.rs --- runtime/common/src/paras_registrar.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/runtime/common/src/paras_registrar.rs b/runtime/common/src/paras_registrar.rs index fc0f5eaf94b7..86b9fe9665d7 100644 --- a/runtime/common/src/paras_registrar.rs +++ b/runtime/common/src/paras_registrar.rs @@ -1112,9 +1112,6 @@ mod tests { assert!(!Parachains::is_parathread(para_1)); assert!(!Parachains::is_parathread(para_2)); - println!("{:?}", paras::Pallet::::lifecycle(para_1)); - println!("{:?}", paras::Pallet::::lifecycle(para_2)); - // Cannot even start a swap assert_noop!( Registrar::swap(Origin::root(), para_1, para_2), From dd2eacad5b444bdc30b9cf0ec1ce43b9fa423a27 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 7 Feb 2022 21:28:32 +0100 Subject: [PATCH 21/22] Update migration.rs --- runtime/common/src/crowdloan/migration.rs | 30 +++++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/runtime/common/src/crowdloan/migration.rs b/runtime/common/src/crowdloan/migration.rs index 94518a09a978..478471454f39 100644 --- a/runtime/common/src/crowdloan/migration.rs +++ b/runtime/common/src/crowdloan/migration.rs @@ -29,16 +29,28 @@ pub mod crowdloan_index_migration { pub fn pre_migrate() -> Result<(), &'static str> { // `NextTrieIndex` should have a value. generate_storage_alias!(Crowdloan, NextTrieIndex => Value); - let next_index = NextTrieIndex::take().unwrap_or_default(); + let next_index = NextTrieIndex::get().unwrap_or_default(); ensure!(next_index > 0, "Next index is zero, which implies no migration is needed."); + log::info!( + target: "runtime", + "next trie index: {:?}", + next_index, + ); + // Each fund should have some non-zero balance. for (para_id, fund) in Funds::::iter() { let old_fund_account = old_fund_account_id::(para_id); let total_balance = CurrencyOf::::total_balance(&old_fund_account); + log::info!( + target: "runtime", + "para_id={:?}, old_fund_account={:?}, total_balance={:?}, fund.raised={:?}", + para_id, old_fund_account, total_balance, fund.raised + ); + ensure!( - total_balance == fund.raised, + total_balance >= fund.raised, "Total balance is not equal to the funds raised." ); ensure!(total_balance > Zero::zero(), "Total balance is equal to zero."); @@ -79,9 +91,17 @@ pub mod crowdloan_index_migration { pub fn post_migrate() -> Result<(), &'static str> { // `NextTrieIndex` should not have a value, and `NextFundIndex` should. generate_storage_alias!(Crowdloan, NextTrieIndex => Value); - ensure!(NextTrieIndex::take().is_none(), "NextTrieIndex still has a value."); + ensure!(NextTrieIndex::get().is_none(), "NextTrieIndex still has a value."); + + let next_index = NextFundIndex::::get(); + log::info!( + target: "runtime", + "next fund index: {:?}", + next_index, + ); + ensure!( - NextFundIndex::::get() > 0, + next_index > 0, "NextFundIndex was not migrated or is zero. We assume it cannot be zero else no migration is needed." ); @@ -99,7 +119,7 @@ pub mod crowdloan_index_migration { let total_balance = CurrencyOf::::total_balance(&new_fund_account); ensure!( - total_balance == fund.raised, + total_balance >= fund.raised, "Total balance in new account is different than the funds raised." ); ensure!(total_balance > Zero::zero(), "Total balance in the account is zero."); From 6217ef5e29023375876460d3e831d6463c074bdd Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 7 Feb 2022 22:42:00 +0100 Subject: [PATCH 22/22] extract swap function --- runtime/common/src/paras_registrar.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/runtime/common/src/paras_registrar.rs b/runtime/common/src/paras_registrar.rs index 86b9fe9665d7..88828283ceee 100644 --- a/runtime/common/src/paras_registrar.rs +++ b/runtime/common/src/paras_registrar.rs @@ -292,23 +292,11 @@ pub mod pallet { if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parathread { - // We check that both paras are in an appropriate lifecycle for a swap, - // so these should never fail. - let res1 = runtime_parachains::schedule_parachain_downgrade::(id); - debug_assert!(res1.is_ok()); - let res2 = runtime_parachains::schedule_parathread_upgrade::(other); - debug_assert!(res2.is_ok()); - T::OnSwap::on_swap(id, other); + Self::do_thread_and_chain_swap(id, other); } else if id_lifecycle == ParaLifecycle::Parathread && other_lifecycle == ParaLifecycle::Parachain { - // We check that both paras are in an appropriate lifecycle for a swap, - // so these should never fail. - let res1 = runtime_parachains::schedule_parachain_downgrade::(other); - debug_assert!(res1.is_ok()); - let res2 = runtime_parachains::schedule_parathread_upgrade::(id); - debug_assert!(res2.is_ok()); - T::OnSwap::on_swap(id, other); + Self::do_thread_and_chain_swap(other, id); } else if id_lifecycle == ParaLifecycle::Parachain && other_lifecycle == ParaLifecycle::Parachain { @@ -588,6 +576,15 @@ impl Pallet { Ok((ParaGenesisArgs { genesis_head, validation_code, parachain }, deposit)) } + + /// Swap a parachain and parathread, which involves scheduling an appropriate lifecycle update. + fn do_thread_and_chain_swap(to_downgrade: ParaId, to_upgrade: ParaId) { + let res1 = runtime_parachains::schedule_parachain_downgrade::(to_downgrade); + debug_assert!(res1.is_ok()); + let res2 = runtime_parachains::schedule_parathread_upgrade::(to_upgrade); + debug_assert!(res2.is_ok()); + T::OnSwap::on_swap(to_upgrade, to_downgrade); + } } #[cfg(test)]