From fa78aff0a029c3b5dc64397e91f20b2609d77357 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 28 Oct 2019 19:49:50 +0100 Subject: [PATCH 1/7] Initial sotrage migration --- srml/elections-phragmen/src/lib.rs | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index f22c05ca45cda..aa515c180b33e 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -159,6 +159,11 @@ decl_storage! { /// The present candidate list. Sorted based on account id. A current member can never enter /// this vector and is always implicitly assumed to be a candidate. pub Candidates get(fn candidates): Vec; + + /// Has the storage format been updated? + /// NOTE: Only use and set to false if you have used an early version of this module. Should + /// be set to true otherwise. + pub DidUpdate: bool = false; } } @@ -373,6 +378,10 @@ decl_module! { /// What to do at the end of each block. Checks if an election needs to happen or not. fn on_initialize(n: T::BlockNumber) { + if !DidUpdate::get() { + DidUpdate::put(true); + Self::do_update(); + } if let Err(e) = Self::end_block(n) { print("Guru meditation"); print(e); @@ -626,6 +635,40 @@ impl Module { ElectionRounds::mutate(|v| *v += 1); } + + /// Perform the storage update needed to migrate the module from the initial version of the + /// storage. + /// + /// If decoding the old storage fails in any way, the consequence is that we start with an empty + /// set. + fn do_update() { + use primitives::twox_128; + use srml_support::storage::hashed::get_raw; + use codec::Decode; + + let members_key = "PhragmenElection Members"; + let runners_key = "PhragmenElection RunnersUp"; + + // old storage format. + let old_members: Vec = get_raw(&twox_128, members_key.as_bytes()) + .map_or_else(|| vec![], |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); + let old_runners: Vec = get_raw(&twox_128, runners_key.as_bytes()) + .map_or_else(|| vec![], |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); + + // new storage format. + let new_runners: Vec<(T::AccountId, BalanceOf)> = old_runners + .into_iter() + .map(|r| (r, Zero::zero())) + .collect(); + let new_members: Vec<(T::AccountId, BalanceOf)> = old_members + .into_iter() + .map(|r| (r, Zero::zero())) + .collect(); + + >::put(new_members); + >::put(new_runners); + + } } #[cfg(test)] From 0004b29c988e7412b9d638ac8701513694b16c09 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 28 Oct 2019 20:00:10 +0100 Subject: [PATCH 2/7] Fix some deps --- srml/elections-phragmen/Cargo.toml | 6 ++---- srml/elections-phragmen/src/lib.rs | 7 +++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/srml/elections-phragmen/Cargo.toml b/srml/elections-phragmen/Cargo.toml index 02898fc754f2e..42940cc471cee 100644 --- a/srml/elections-phragmen/Cargo.toml +++ b/srml/elections-phragmen/Cargo.toml @@ -5,9 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false } @@ -18,13 +16,13 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals [dev-dependencies] hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +serde = { version = "1.0.101" } [features] default = ["std"] std = [ "codec/std", - "primitives/std", - "serde", "runtime_io/std", "srml-support/std", "sr-primitives/std", diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index aa515c180b33e..f6d2d3e30fff4 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -77,15 +77,18 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::prelude::*; +use codec::Decode; use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; use sr_primitives::weights::SimpleDispatchInfo; use srml_support::{ decl_storage, decl_event, ensure, decl_module, dispatch, + storage::hashed::get_raw, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, ChangeMembers, OnUnbalanced, WithdrawReason } }; +use runtime_io::twox_128; use phragmen::ExtendedBalance; use system::{self, ensure_signed, ensure_root}; @@ -642,10 +645,6 @@ impl Module { /// If decoding the old storage fails in any way, the consequence is that we start with an empty /// set. fn do_update() { - use primitives::twox_128; - use srml_support::storage::hashed::get_raw; - use codec::Decode; - let members_key = "PhragmenElection Members"; let runners_key = "PhragmenElection RunnersUp"; From 8599cb56b2a55c7627444164344bce86b4b54ba1 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 28 Oct 2019 20:40:00 +0100 Subject: [PATCH 3/7] test added --- srml/elections-phragmen/src/lib.rs | 50 +++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index f6d2d3e30fff4..eb9f551d6372f 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -82,13 +82,12 @@ use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; use sr_primitives::weights::SimpleDispatchInfo; use srml_support::{ decl_storage, decl_event, ensure, decl_module, dispatch, - storage::hashed::get_raw, + storage::unhashed, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, ChangeMembers, OnUnbalanced, WithdrawReason } }; -use runtime_io::twox_128; use phragmen::ExtendedBalance; use system::{self, ensure_signed, ensure_root}; @@ -166,7 +165,7 @@ decl_storage! { /// Has the storage format been updated? /// NOTE: Only use and set to false if you have used an early version of this module. Should /// be set to true otherwise. - pub DidUpdate: bool = false; + DidMigrate: bool = false; } } @@ -381,9 +380,9 @@ decl_module! { /// What to do at the end of each block. Checks if an election needs to happen or not. fn on_initialize(n: T::BlockNumber) { - if !DidUpdate::get() { - DidUpdate::put(true); - Self::do_update(); + if !DidMigrate::get() { + DidMigrate::put(true); + Self::do_migrate(); } if let Err(e) = Self::end_block(n) { print("Guru meditation"); @@ -644,15 +643,12 @@ impl Module { /// /// If decoding the old storage fails in any way, the consequence is that we start with an empty /// set. - fn do_update() { - let members_key = "PhragmenElection Members"; - let runners_key = "PhragmenElection RunnersUp"; - + fn do_migrate() { // old storage format. - let old_members: Vec = get_raw(&twox_128, members_key.as_bytes()) - .map_or_else(|| vec![], |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); - let old_runners: Vec = get_raw(&twox_128, runners_key.as_bytes()) - .map_or_else(|| vec![], |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); + let old_members: Vec = unhashed::get_raw(&>::hashed_key()) + .map_or_else(Default::default, |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); + let old_runners: Vec = unhashed::get_raw(&>::hashed_key()) + .map_or_else(Default::default, |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); // new storage format. let new_runners: Vec<(T::AccountId, BalanceOf)> = old_runners @@ -678,7 +674,7 @@ mod tests { use primitives::H256; use sr_primitives::{ Perbill, testing::Header, BuildStorage, - traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, + traits::{OnInitialize, BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections; @@ -867,6 +863,30 @@ mod tests { lock.amount } + #[test] + fn temp_migration_works() { + ExtBuilder::default().build().execute_with(|| { + use srml_support::storage::unhashed; + use codec::Encode; + + let old_members = vec![1u64, 2]; + let old_runners = vec![3u64]; + + let members_key = >::hashed_key(); + let runners_key = >::hashed_key(); + + unhashed::put_raw(&members_key, &old_members.encode()[..]); + unhashed::put_raw(&runners_key, &old_runners.encode()[..]); + + assert_eq!(DidMigrate::get(), false); + >::on_initialize(1); + assert_eq!(DidMigrate::get(), true); + + assert_eq!(Elections::members(), vec![(1, 0), (2, 0)]); + assert_eq!(Elections::runners_up(), vec![(3, 0)]); + }); + } + #[test] fn params_should_work() { ExtBuilder::default().build().execute_with(|| { From 46157cdda655fa52b40fb2a11396a4b095c60ba1 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 28 Oct 2019 20:43:30 +0100 Subject: [PATCH 4/7] another dep removed --- srml/elections-phragmen/Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srml/elections-phragmen/Cargo.toml b/srml/elections-phragmen/Cargo.toml index 42940cc471cee..85532849ecc00 100644 --- a/srml/elections-phragmen/Cargo.toml +++ b/srml/elections-phragmen/Cargo.toml @@ -6,7 +6,6 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false } srml-support = { path = "../support", default-features = false } @@ -14,6 +13,7 @@ system = { package = "srml-system", path = "../system", default-features = false rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } [dev-dependencies] +runtime_io = { package = "sr-io", path = "../../core/sr-io" } hex-literal = "0.2.1" balances = { package = "srml-balances", path = "../balances" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } @@ -23,7 +23,6 @@ serde = { version = "1.0.101" } default = ["std"] std = [ "codec/std", - "runtime_io/std", "srml-support/std", "sr-primitives/std", "phragmen/std", From 4bc54417bf7ea4b36ce0bc831dbe321c128085b2 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 29 Oct 2019 10:49:58 +0100 Subject: [PATCH 5/7] Update srml/elections-phragmen/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bastian Köcher --- srml/elections-phragmen/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index eb9f551d6372f..c6753513fb8e1 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -646,7 +646,7 @@ impl Module { fn do_migrate() { // old storage format. let old_members: Vec = unhashed::get_raw(&>::hashed_key()) - .map_or_else(Default::default, |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); + .and_then(|bytes| Decode::decode(&mut &*bytes).ok()).unwrap_or_default(); let old_runners: Vec = unhashed::get_raw(&>::hashed_key()) .map_or_else(Default::default, |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); From 832235f787104cc2d2106134bf39acbf889e0dee Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 29 Oct 2019 10:50:35 +0100 Subject: [PATCH 6/7] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bastian Köcher --- srml/elections-phragmen/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index c6753513fb8e1..747d9cd6bf3b5 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -648,7 +648,7 @@ impl Module { let old_members: Vec = unhashed::get_raw(&>::hashed_key()) .and_then(|bytes| Decode::decode(&mut &*bytes).ok()).unwrap_or_default(); let old_runners: Vec = unhashed::get_raw(&>::hashed_key()) - .map_or_else(Default::default, |bytes| Decode::decode(&mut &*bytes).unwrap_or_default()); + .and_then(|bytes| Decode::decode(&mut &*bytes).ok()).unwrap_or_default(); // new storage format. let new_runners: Vec<(T::AccountId, BalanceOf)> = old_runners @@ -662,7 +662,6 @@ impl Module { >::put(new_members); >::put(new_runners); - } } From 2f2424e100fa38a133f31f3b775864ed24df2bd7 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 29 Oct 2019 11:00:12 +0100 Subject: [PATCH 7/7] a bit nicer --- srml/elections-phragmen/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 747d9cd6bf3b5..9b277815f385a 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -165,7 +165,7 @@ decl_storage! { /// Has the storage format been updated? /// NOTE: Only use and set to false if you have used an early version of this module. Should /// be set to true otherwise. - DidMigrate: bool = false; + DidMigrate: bool; } } @@ -380,7 +380,7 @@ decl_module! { /// What to do at the end of each block. Checks if an election needs to happen or not. fn on_initialize(n: T::BlockNumber) { - if !DidMigrate::get() { + if !DidMigrate::exists() { DidMigrate::put(true); Self::do_migrate(); }