Skip to content

Commit

Permalink
Add democracy migration and fix contracts migration (#12)
Browse files Browse the repository at this point in the history
* log current blocknumber during migration

* improve phragmen migration logs and docs

* add combined democracy migration

* re-add ReferendumInfo hasher migration and fix compile issues

* add more logging for democracy migration

* add migration from democracy weights PR paritytech#5828

* log key used for PublicProps

* migrate preimages

* correct logging and rename variables

* add block number for block hash migration

* log decode errors

* add decode error log label

* remove extra logging

* re-add contracts migration

* remove weight todos and just assume MaximumBlockWeight

* fix compile errors

* replace some todos with comments

* log decode error

* fix contracts migration

* remove grandpa authority migration
  • Loading branch information
apopiak authored Jul 2, 2020
1 parent 50eb114 commit 0ad4f35
Show file tree
Hide file tree
Showing 19 changed files with 290 additions and 169 deletions.
4 changes: 2 additions & 2 deletions frame/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,12 @@ decl_module! {
Lateness::<T>::kill();
}

// The edgeware migration is so big we just assume it consumes the whole block.
fn on_runtime_upgrade() -> Weight {
for i in 0..=SegmentIndex::get() {
UnderConstruction::migrate_key_from_blake(i);
}
// TODO: determine weight
0
T::MaximumBlockWeight::get()
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion frame/balances/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub fn on_runtime_upgrade<T: Trait<I>, I: Instance>() -> Weight {
}

// Upgrade from the pre-#4649 balances/vesting into the new balances.
// The accounts migration is so big we just assume it consumes the whole block.
fn upgrade_v1_to_v2<T: Trait<I>, I: Instance>() -> Weight {
sp_runtime::print("🕊️ Migrating Account Balances...");
// First, migrate from old FreeBalance to new Account.
Expand Down Expand Up @@ -140,6 +141,5 @@ fn upgrade_v1_to_v2<T: Trait<I>, I: Instance>() -> Weight {
StorageVersion::<I>::put(Releases::V2_0_0);

sp_runtime::print("🕊️ Done Account Balances.");
// TODO determine actual weight?
T::MaximumBlockWeight::get()
}
4 changes: 2 additions & 2 deletions frame/collective/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,10 @@ decl_module! {

fn deposit_event() = default;

// The edgeware migration is so big we just assume it consumes the whole block.
fn on_runtime_upgrade() -> Weight {
migration::migrate::<T, I>();
// TODO: determine actual weight
0
T::MaximumBlockWeight::get()
}

/// Set the collective's membership.
Expand Down
133 changes: 95 additions & 38 deletions frame/contracts/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,65 +17,122 @@
//! Migration code to update storage.

use super::*;
use frame_support::storage::migration::{put_storage_value, take_storage_value, StorageIterator};
use frame_support::storage::migration::{ remove_storage_prefix, take_storage_value, StorageIterator};
use frame_support::weights::Weight;
use frame_support::runtime_print;

use crate::gas::Gas;

pub fn on_runtime_upgrade<T: Trait>() -> Weight {
// TODO: removed for now because it's failing
// change_name_contract_to_contracts::<T>()
0
change_name_contract_to_contracts::<T>()
}

mod deprecated {
use super::*;

#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)]
pub struct Schedule {
/// Version of the schedule.
pub version: u32,

/// Cost of putting a byte of code into storage.
pub put_code_per_byte_cost: Gas,

/// Gas cost of a growing memory by single page.
pub grow_mem_cost: Gas,

/// Gas cost of a regular operation.
pub regular_op_cost: Gas,

/// Gas cost per one byte returned.
pub return_data_per_byte_cost: Gas,

/// Gas cost to deposit an event; the per-byte portion.
pub event_data_per_byte_cost: Gas,

/// Gas cost to deposit an event; the cost per topic.
pub event_per_topic_cost: Gas,

/// Gas cost to deposit an event; the base.
pub event_base_cost: Gas,

/// Base gas cost to call into a contract.
pub call_base_cost: Gas,

/// Base gas cost to instantiate a contract.
pub instantiate_base_cost: Gas,

/// Gas cost per one byte read from the sandbox memory.
pub sandbox_data_read_cost: Gas,

/// Gas cost per one byte written to the sandbox memory.
pub sandbox_data_write_cost: Gas,

/// Cost for a simple balance transfer.
pub transfer_cost: Gas,

/// The maximum number of topics supported by an event.
pub max_event_topics: u32,

/// Maximum allowed stack height.
///
/// See https://wiki.parity.io/WebAssembly-StackHeight to find out
/// how the stack frame cost is calculated.
pub max_stack_height: u32,

/// Maximum number of memory pages allowed for a contract.
pub max_memory_pages: u32,

/// Maximum allowed size of a declared table.
pub max_table_size: u32,

/// Whether the `ext_println` function is allowed to be used contracts.
/// MUST only be enabled for `dev` chains, NOT for production chains
pub enable_println: bool,

/// The maximum length of a subject used for PRNG generation.
pub max_subject_len: u32,
}
}

// Change the storage name used by this pallet from `Contract` to `Contracts`.
//
// Since the format of the storage items themselves have not changed, we do not
// need to keep track of a storage version. If the runtime does not need to be
// upgraded, nothing here will happen anyway.

fn change_name_contract_to_contracts<T: Trait>() -> Weight {
sp_runtime::print("🕊️ Migrating Contracts.");

let mut weight = 0;
let db = T::DbWeight::get();
if let Some(gas_spent) = take_storage_value::<Gas>(b"Contract", b"GasSpent", &[]) {
put_storage_value(b"Contracts", b"GasSpent", &[], gas_spent);
weight += db.writes(2);
}
weight += db.reads(1);
// Remove `GasSpent` because it doesn't exist anymore.
remove_storage_prefix(b"Contract", b"GasSpent", &[]);

if let Some(current_schedule) = take_storage_value::<Schedule>(b"Contract", b"CurrentSchedule", &[]) {
put_storage_value(b"Contracts", b"CurrentSchedule", &[], current_schedule);
weight += db.writes(2);
}
weight += db.reads(1);
// Replace the old with the new schedule.
take_storage_value::<deprecated::Schedule>(b"Contract", b"CurrentSchedule", &[]);
CurrentSchedule::put(Schedule::default());

for (hash, pristine_code) in StorageIterator::<Vec<u8>>::new(b"Contract", b"PristineCode").drain() {
put_storage_value(b"Contracts", b"PristineCode", &hash, pristine_code);
weight += db.reads_writes(1, 2);
// There are currently no contracts on Edgeware so this should just do nothing.
// Include logging just in case.
for (hash, _code) in StorageIterator::<Vec<u8>>::new(b"Contract", b"PristineCode").drain() {
runtime_print!("Contracts: Discarding PristinceCode at hash {:?}", hash);
}

for (hash, code_storage) in StorageIterator::<wasm::PrefabWasmModule>::new(b"Contract", b"CodeStorage").drain() {
put_storage_value(b"Contracts", b"CodeStorage", &hash, code_storage);
weight += db.reads_writes(1, 2);
for (hash, _storage) in StorageIterator::<wasm::PrefabWasmModule>::new(b"Contract", b"CodeStorage").drain() {
runtime_print!("Contracts: Discarding CodeStorage at hash {:?}", hash);
}

if let Some(current_schedule) = take_storage_value::<u64>(b"Contract", b"AccountCounter", &[]) {
put_storage_value(b"Contracts", b"AccountCounter", &[], current_schedule);
weight += db.writes(2);
for (hash, _info) in StorageIterator::<ContractInfo<T>>::new(b"Contract", b"ContractInfoOf").drain() {
runtime_print!("Contracts: Discarding ContractInfoOf at hash {:?}", hash);
}
weight += db.reads(1);

for (hash, contract_info_of) in StorageIterator::<ContractInfo<T>>::new(b"Contract", b"ContractInfoOf").drain() {
put_storage_value(b"Contracts", b"ContractInfoOf", &hash, contract_info_of);
weight += db.reads_writes(1, 2);
// (Re-)Set the AccountCounter.
if let Some(counter) = take_storage_value::<u64>(b"Contract", b"AccountCounter", &[]) {
AccountCounter::put(counter);
} else {
AccountCounter::put(0);
}

if let Some(get_price) = take_storage_value::<BalanceOf<T>>(b"Contract", b"GetPrice", &[]) {
put_storage_value(b"Contracts", b"GetPrice", &[], get_price);
weight += db.writes(2);
}
weight += db.reads(1);
// Remove `GetPrice` because it doesn't exist anymore.
remove_storage_prefix(b"Contract", b"GetPrice", &[]);

sp_runtime::print("🕊️ Done Contracts.");
weight
T::MaximumBlockWeight::get()
}
99 changes: 4 additions & 95 deletions frame/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ mod tests;
#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;

pub mod migration;

const DEMOCRACY_ID: LockIdentifier = *b"democrac";

/// The maximum number of vetoers on a single proposal used to compute Weight.
Expand Down Expand Up @@ -569,100 +571,7 @@ mod weight_for {

impl<T: Trait> MigrateAccount<T::AccountId> for Module<T> {
fn migrate_account(a: &T::AccountId) {
mod deprecated {
use sp_std::prelude::*;

use codec::{Encode, EncodeLike, Decode, Input, Output};
use frame_support::{decl_module, decl_storage};
use sp_runtime::RuntimeDebug;
use sp_std::convert::TryFrom;

use crate::{Trait, ReferendumIndex, Conviction};

#[derive(Copy, Clone, Eq, PartialEq, Default, RuntimeDebug)]
pub struct Vote {
pub aye: bool,
pub conviction: Conviction,
}

impl Encode for Vote {
fn encode_to<T: Output>(&self, output: &mut T) {
output.push_byte(u8::from(self.conviction) | if self.aye { 0b1000_0000 } else { 0 });
}
}

impl EncodeLike for Vote {}

impl Decode for Vote {
fn decode<I: Input>(input: &mut I) -> core::result::Result<Self, codec::Error> {
let b = input.read_byte()?;
Ok(Vote {
aye: (b & 0b1000_0000) == 0b1000_0000,
conviction: Conviction::try_from(b & 0b0111_1111)
.map_err(|_| codec::Error::from("Invalid conviction"))?,
})
}
}

decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin { }
}
decl_storage! {
trait Store for Module<T: Trait> as Democracy {
pub VoteOf get(fn vote_of):
map hasher(opaque_blake2_256) (ReferendumIndex, T::AccountId) => Vote;
pub Delegations get(fn delegations):
map hasher(opaque_blake2_256) T::AccountId => (T::AccountId, Conviction);
}
}
}

Locks::<T>::migrate_key_from_blake(a);
// TODO: will not actually do any useful migration
deprecated::Delegations::<T>::migrate_key_from_blake(a);
for i in LowestUnbaked::get()..ReferendumCount::get() {
// TODO: will not actually do any useful migration
deprecated::VoteOf::<T>::migrate_key_from_blake((i, a));
}
}
}

mod migration {
use super::*;

pub fn migrate<T: Trait>() -> Weight {
mod deprecated {
use super::*;

decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin { }
}
decl_storage! {
trait Store for Module<T: Trait> as Democracy {
pub VotersFor get(fn voters_for):
map hasher(opaque_blake2_256) ReferendumIndex => Vec<T::AccountId>;
pub Proxy get(fn proxy):
map hasher(opaque_blake2_256) T::AccountId => Option<T::AccountId>;
}
}
}

// proxies were removed
deprecated::Proxy::<T>::remove_all();
Blacklist::<T>::remove_all();
Cancellations::<T>::remove_all();
for i in LowestUnbaked::get()..ReferendumCount::get() {
// TODO: will not actually do any useful migration
deprecated::VotersFor::<T>::migrate_key_from_blake(i);
ReferendumInfoOf::<T>::migrate_key_from_blake(i);
}
for (p, h, _) in PublicProps::<T>::get().into_iter() {
DepositOf::<T>::migrate_key_from_blake(p);
Preimages::<T>::migrate_key_from_blake(h);
}

// TODO: figure out actual weight
0
migration::migrate_account::<T>(a)
}
}

Expand Down Expand Up @@ -701,7 +610,7 @@ decl_module! {
fn deposit_event() = default;

fn on_runtime_upgrade() -> Weight {
migration::migrate::<T>()
migration::migrate_all::<T>()
}

/// Propose a sensitive action to be taken.
Expand Down
Loading

0 comments on commit 0ad4f35

Please sign in to comment.