From a83059a95b61ad60e2e7204df51b35009463740c Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 13 Mar 2018 12:34:21 +0100 Subject: [PATCH 01/29] Completely rework dispatch mechanism into something modular. Not yet complete but 75% there. --- Cargo.lock | 2 + demo/primitives/src/block.rs | 33 -- demo/primitives/src/lib.rs | 4 +- demo/primitives/src/transaction.rs | 494 --------------------- demo/runtime/Cargo.toml | 4 + demo/runtime/src/block.rs | 53 +++ demo/runtime/src/dispatch.rs | 295 +++++++++---- demo/runtime/src/lib.rs | 47 +- demo/runtime/src/runtime/council.rs | 518 ++++++++++++----------- demo/runtime/src/runtime/council_vote.rs | 81 ++-- demo/runtime/src/runtime/democracy.rs | 206 ++++++--- demo/runtime/src/runtime/staking.rs | 236 +++++++---- demo/runtime/src/runtime/system.rs | 32 +- demo/runtime/src/runtime/timestamp.rs | 14 +- demo/runtime/src/transaction.rs | 190 +++++++++ substrate/codec/src/slicable.rs | 148 +++++-- 16 files changed, 1222 insertions(+), 1135 deletions(-) delete mode 100644 demo/primitives/src/transaction.rs create mode 100644 demo/runtime/src/block.rs create mode 100644 demo/runtime/src/transaction.rs diff --git a/Cargo.lock b/Cargo.lock index e29aa3a664c20..6307440de042b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -244,6 +244,8 @@ dependencies = [ "integer-sqrt 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-codec 0.1.0", "substrate-keyring 0.1.0", "substrate-primitives 0.1.0", diff --git a/demo/primitives/src/block.rs b/demo/primitives/src/block.rs index 4183498fc7413..f5119ac4b3f22 100644 --- a/demo/primitives/src/block.rs +++ b/demo/primitives/src/block.rs @@ -21,7 +21,6 @@ use primitives::bytes; use primitives::H256; use rstd::vec::Vec; use codec::{Input, Slicable}; -use transaction::UncheckedTransaction; pub use primitives::block::Id; @@ -31,9 +30,6 @@ pub type Number = u64; /// Hash used to refer to a block hash. pub type HeaderHash = H256; -/// Hash used to refer to a transaction hash. -pub type TransactionHash = H256; - /// Execution log (event) #[derive(PartialEq, Eq, Clone)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] @@ -69,35 +65,6 @@ impl Slicable for Digest { } } -/// The block "body": A bunch of transactions. -pub type Body = Vec; - -/// A block on the chain. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct Block { - /// The block header. - pub header: Header, - /// All relay-chain transactions. - pub transactions: Body, -} - -impl Slicable for Block { - fn decode(input: &mut I) -> Option { - let (header, transactions) = try_opt!(Slicable::decode(input)); - Some(Block { header, transactions }) - } - - fn encode(&self) -> Vec { - let mut v = Vec::new(); - - v.extend(self.header.encode()); - v.extend(self.transactions.encode()); - - v - } -} - /// Header for a block. #[derive(PartialEq, Eq, Clone)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] diff --git a/demo/primitives/src/lib.rs b/demo/primitives/src/lib.rs index e68d6d8727208..c65d4a63ef700 100644 --- a/demo/primitives/src/lib.rs +++ b/demo/primitives/src/lib.rs @@ -45,11 +45,9 @@ macro_rules! try_opt { } pub mod block; -pub mod transaction; -pub use self::block::{Header, Block, Log, Digest}; +pub use self::block::{Header, Log, Digest}; pub use self::block::Number as BlockNumber; -pub use self::transaction::{Transaction, UncheckedTransaction, Function, Proposal, VoteThreshold}; /// Alias to Ed25519 pubkey that identifies an account on the relay chain. This will almost /// certainly continue to be the same as the substrate's `AuthorityId`. diff --git a/demo/primitives/src/transaction.rs b/demo/primitives/src/transaction.rs deleted file mode 100644 index cc7e410a72c44..0000000000000 --- a/demo/primitives/src/transaction.rs +++ /dev/null @@ -1,494 +0,0 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. -// This file is part of Substrate Demo. - -// Substrate Demo 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. - -// Substrate Demo 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 Substrate Demo. If not, see . - -//! Transaction type. - -use rstd::vec::Vec; -use codec::{Input, Slicable, NonTrivialSlicable}; -use {AccountId, SessionKey}; - -#[cfg(feature = "std")] -use std::fmt; - -use block::Number as BlockNumber; - -#[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[repr(u8)] -enum InternalFunctionId { - SystemSetCode = 0x00, - - SessionSetLength = 0x10, - SessionForceNewSession = 0x11, - - StakingSetSessionsPerEra = 0x20, - StakingSetBondingDuration = 0x21, - StakingSetValidatorCount = 0x22, - StakingForceNewEra = 0x23, - - DemocracyCancelReferendum = 0x30, - DemocracyStartReferendum = 0x31, - - CouncilSetDesiredSeats = 0x40, - CouncilRemoveMember = 0x41, - CouncilSetPresentationDuration = 0x42, - CouncilSetTermDuration = 0x43, - - CouncilVoteSetCooloffPeriod = 0x50, - CouncilVoteSetVotingPeriod = 0x51, -} - -impl InternalFunctionId { - /// Derive `Some` value from a `u8`, or `None` if it's invalid. - fn from_u8(value: u8) -> Option { - let functions = [ - InternalFunctionId::SystemSetCode, - InternalFunctionId::SessionSetLength, - InternalFunctionId::SessionForceNewSession, - InternalFunctionId::StakingSetSessionsPerEra, - InternalFunctionId::StakingSetBondingDuration, - InternalFunctionId::StakingSetValidatorCount, - InternalFunctionId::StakingForceNewEra, - InternalFunctionId::DemocracyCancelReferendum, - InternalFunctionId::DemocracyStartReferendum, - InternalFunctionId::CouncilSetDesiredSeats, - InternalFunctionId::CouncilRemoveMember, - InternalFunctionId::CouncilSetPresentationDuration, - InternalFunctionId::CouncilSetTermDuration, - InternalFunctionId::CouncilVoteSetCooloffPeriod, - InternalFunctionId::CouncilVoteSetVotingPeriod, - ]; - functions.iter().map(|&f| f).find(|&f| value == f as u8) - } -} - -#[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub enum VoteThreshold { - /// A supermajority of approvals is needed to pass this vote. - SuperMajorityApprove, - /// A supermajority of rejects is needed to fail this vote. - SuperMajorityAgainst, - /// A simple majority of approvals is needed to pass this vote. - SimpleMajority, -} - -impl Slicable for VoteThreshold { - fn decode(input: &mut I) -> Option { - u8::decode(input).and_then(|v| match v { - 0 => Some(VoteThreshold::SuperMajorityApprove), - 1 => Some(VoteThreshold::SuperMajorityAgainst), - 2 => Some(VoteThreshold::SimpleMajority), - _ => None, - }) - } - - fn using_encoded R>(&self, f: F) -> R { - match *self { - VoteThreshold::SuperMajorityApprove => 0u8, - VoteThreshold::SuperMajorityAgainst => 1u8, - VoteThreshold::SimpleMajority => 2u8, - }.using_encoded(f) - } -} -impl NonTrivialSlicable for VoteThreshold {} - -/// Internal functions that can be dispatched to. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[allow(missing_docs)] -pub enum Proposal { - SystemSetCode(Vec), - SessionSetLength(BlockNumber), - SessionForceNewSession, - StakingSetSessionsPerEra(BlockNumber), - StakingSetBondingDuration(BlockNumber), - StakingSetValidatorCount(u32), - StakingForceNewEra, - DemocracyStartReferendum(Box, VoteThreshold), - DemocracyCancelReferendum(u32), - CouncilSetDesiredSeats(u32), - CouncilRemoveMember(AccountId), - CouncilSetPresentationDuration(BlockNumber), - CouncilSetTermDuration(BlockNumber), - CouncilVoteSetCooloffPeriod(BlockNumber), - CouncilVoteSetVotingPeriod(BlockNumber), -} - -impl Slicable for Proposal { - fn decode(input: &mut I) -> Option { - let id = u8::decode(input).and_then(InternalFunctionId::from_u8)?; - let function = match id { - InternalFunctionId::SystemSetCode => - Proposal::SystemSetCode(Slicable::decode(input)?), - InternalFunctionId::SessionSetLength => - Proposal::SessionSetLength(Slicable::decode(input)?), - InternalFunctionId::SessionForceNewSession => - Proposal::SessionForceNewSession, - InternalFunctionId::StakingSetSessionsPerEra => - Proposal::StakingSetSessionsPerEra(Slicable::decode(input)?), - InternalFunctionId::StakingSetBondingDuration => - Proposal::StakingSetBondingDuration(Slicable::decode(input)?), - InternalFunctionId::StakingSetValidatorCount => - Proposal::StakingSetValidatorCount(Slicable::decode(input)?), - InternalFunctionId::StakingForceNewEra => - Proposal::StakingForceNewEra, - InternalFunctionId::DemocracyStartReferendum => { - let a = Slicable::decode(input)?; - let b = Slicable::decode(input)?; - Proposal::DemocracyStartReferendum(Box::new(a), b) - } - InternalFunctionId::DemocracyCancelReferendum => - Proposal::DemocracyCancelReferendum(Slicable::decode(input)?), - InternalFunctionId::CouncilSetDesiredSeats => - Proposal::CouncilSetDesiredSeats(Slicable::decode(input)?), - InternalFunctionId::CouncilRemoveMember => - Proposal::CouncilRemoveMember(Slicable::decode(input)?), - InternalFunctionId::CouncilSetPresentationDuration => - Proposal::CouncilSetPresentationDuration(Slicable::decode(input)?), - InternalFunctionId::CouncilSetTermDuration => - Proposal::CouncilSetTermDuration(Slicable::decode(input)?), - InternalFunctionId::CouncilVoteSetCooloffPeriod => - Proposal::CouncilVoteSetCooloffPeriod(Slicable::decode(input)?), - InternalFunctionId::CouncilVoteSetVotingPeriod => - Proposal::CouncilVoteSetVotingPeriod(Slicable::decode(input)?), - }; - - Some(function) - } - - fn encode(&self) -> Vec { - let mut v = Vec::new(); - match *self { - Proposal::SystemSetCode(ref data) => { - (InternalFunctionId::SystemSetCode as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - Proposal::SessionSetLength(ref data) => { - (InternalFunctionId::SessionSetLength as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - Proposal::SessionForceNewSession => { - (InternalFunctionId::SessionForceNewSession as u8).using_encoded(|s| v.extend(s)); - } - Proposal::StakingSetSessionsPerEra(ref data) => { - (InternalFunctionId::StakingSetSessionsPerEra as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - Proposal::StakingSetBondingDuration(ref data) => { - (InternalFunctionId::StakingSetBondingDuration as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - Proposal::StakingSetValidatorCount(ref data) => { - (InternalFunctionId::StakingSetValidatorCount as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - Proposal::StakingForceNewEra => { - (InternalFunctionId::StakingForceNewEra as u8).using_encoded(|s| v.extend(s)); - } - Proposal::DemocracyCancelReferendum(ref data) => { - (InternalFunctionId::DemocracyCancelReferendum as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - _ => { unimplemented!() } - } - - v - } -} - -/// Public functions that can be dispatched to. -#[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[repr(u8)] -enum FunctionId { - TimestampSet = 0x00, - - SessionSetKey = 0x10, - - StakingStake = 0x20, - StakingUnstake = 0x21, - StakingTransfer = 0x22, - - CouncilVotePropose = 0x30, - CouncilVoteVote = 0x31, - CouncilVoteVeto = 0x32, - - CouncilSetApprovals = 0x40, - CouncilReapInactiveVoter = 0x41, - CouncilRetractVoter = 0x42, - CouncilSubmitCandidacy = 0x43, - CouncilPresentWinner = 0x44, - - DemocracyPropose = 0x50, - DemocracySecond = 0x51, - DemocracyVote = 0x52, -} - -impl FunctionId { - /// Derive `Some` value from a `u8`, or `None` if it's invalid. - fn from_u8(value: u8) -> Option { - use self::*; - let functions = [FunctionId::StakingStake, FunctionId::StakingUnstake, - FunctionId::StakingTransfer, FunctionId::SessionSetKey, FunctionId::TimestampSet, - FunctionId::CouncilVotePropose, FunctionId::CouncilVoteVote, FunctionId::CouncilVoteVeto, - FunctionId::CouncilSetApprovals, FunctionId::CouncilReapInactiveVoter, - FunctionId::CouncilRetractVoter, FunctionId::CouncilSubmitCandidacy, - FunctionId::CouncilPresentWinner, FunctionId::DemocracyPropose, - FunctionId::DemocracySecond, FunctionId::DemocracyVote, - ]; - functions.iter().map(|&f| f).find(|&f| value == f as u8) - } -} - -/// Functions on the runtime. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[allow(missing_docs)] -pub enum Function { - TimestampSet(u64), - - SessionSetKey(SessionKey), - - StakingStake, - StakingUnstake, - StakingTransfer(AccountId, u64), - - CouncilVotePropose(Proposal), - CouncilVoteVote([u8; 32], bool), - CouncilVoteVeto([u8; 32]), - - CouncilSetApprovals(Vec, u32), - CouncilReapInactiveVoter(u32, AccountId, u32, u32), - CouncilRetractVoter(u32), - CouncilSubmitCandidacy(u32), - CouncilPresentWinner(AccountId, u64, u32), - - DemocracyPropose(Proposal, u64), - DemocracySecond(u32), - DemocracyVote(u32, bool), -} - -impl Slicable for Function { - fn decode(input: &mut I) -> Option { - let id = u8::decode(input).and_then(FunctionId::from_u8)?; - Some(match id { - FunctionId::TimestampSet => - Function::TimestampSet(Slicable::decode(input)?), - FunctionId::SessionSetKey => - Function::SessionSetKey(Slicable::decode(input)?), - FunctionId::StakingStake => Function::StakingStake, - FunctionId::StakingUnstake => Function::StakingUnstake, - FunctionId::StakingTransfer => { - let to = Slicable::decode(input)?; - let amount = Slicable::decode(input)?; - Function::StakingTransfer(to, amount) - } - FunctionId::CouncilVotePropose => Function::CouncilVotePropose(Slicable::decode(input)?), - FunctionId::CouncilVoteVote => { - let a = Slicable::decode(input)?; - let b = Slicable::decode(input)?; - Function::CouncilVoteVote(a, b) - } - FunctionId::CouncilVoteVeto => Function::CouncilVoteVeto(Slicable::decode(input)?), - FunctionId::CouncilSetApprovals => { - let a = Slicable::decode(input)?; - let b = Slicable::decode(input)?; - Function::CouncilSetApprovals(a, b) - } - FunctionId::CouncilReapInactiveVoter => { - let a = Slicable::decode(input)?; - let b = Slicable::decode(input)?; - let c = Slicable::decode(input)?; - let d = Slicable::decode(input)?; - Function::CouncilReapInactiveVoter(a, b, c, d) - } - FunctionId::CouncilRetractVoter => Function::CouncilRetractVoter(Slicable::decode(input)?), - FunctionId::CouncilSubmitCandidacy => Function::CouncilSubmitCandidacy(Slicable::decode(input)?), - FunctionId::CouncilPresentWinner => { - let a = Slicable::decode(input)?; - let b = Slicable::decode(input)?; - let c = Slicable::decode(input)?; - Function::CouncilPresentWinner(a, b, c) - } - FunctionId::DemocracyPropose => { - let a = Slicable::decode(input)?; - let b = Slicable::decode(input)?; - Function::DemocracyPropose(a, b) - } - FunctionId::DemocracySecond => Function::DemocracySecond(Slicable::decode(input)?), - FunctionId::DemocracyVote => { - let a = Slicable::decode(input)?; - let b = Slicable::decode(input)?; - Function::DemocracyVote(a, b) - } - }) - } - - fn encode(&self) -> Vec { - let mut v = Vec::new(); - match *self { - Function::TimestampSet(ref data) => { - (FunctionId::TimestampSet as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - Function::SessionSetKey(ref data) => { - (FunctionId::SessionSetKey as u8).using_encoded(|s| v.extend(s)); - data.using_encoded(|s| v.extend(s)); - } - Function::StakingStake => { - (FunctionId::StakingStake as u8).using_encoded(|s| v.extend(s)); - } - Function::StakingUnstake => { - (FunctionId::StakingUnstake as u8).using_encoded(|s| v.extend(s)); - } - Function::StakingTransfer(ref to, ref amount) => { - (FunctionId::StakingTransfer as u8).using_encoded(|s| v.extend(s)); - to.using_encoded(|s| v.extend(s)); - amount.using_encoded(|s| v.extend(s)); - } - _ => { unimplemented!() } - } - - v - } - - fn using_encoded R>(&self, f: F) -> R { - f(self.encode().as_slice()) - } -} - -/// A vetted and verified transaction from the external world. -#[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct Transaction { - /// Who signed it (note this is not a signature). - pub signed: super::AccountId, - /// The number of transactions have come before from the same signer. - pub nonce: super::TxOrder, - /// The function that should be called. - pub function: Function, -} - -impl Slicable for Transaction { - fn decode(input: &mut I) -> Option { - Some(Transaction { - signed: try_opt!(Slicable::decode(input)), - nonce: try_opt!(Slicable::decode(input)), - function: try_opt!(Slicable::decode(input)), - }) - } - - fn encode(&self) -> Vec { - let mut v = Vec::new(); - - self.signed.using_encoded(|s| v.extend(s)); - self.nonce.using_encoded(|s| v.extend(s)); - self.function.using_encoded(|s| v.extend(s)); - - v - } -} - -impl ::codec::NonTrivialSlicable for Transaction {} - -/// A transactions right from the external world. Unchecked. -#[derive(Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct UncheckedTransaction { - /// The actual transaction information. - pub transaction: Transaction, - /// The signature; should be an Ed25519 signature applied to the serialised `transaction` field. - pub signature: super::Signature, -} - -impl Slicable for UncheckedTransaction { - fn decode(input: &mut I) -> Option { - // This is a little more complicated than usual since the binary format must be compatible - // with substrate's generic `Vec` type. Basically this just means accepting that there - // will be a prefix of u32, which has the total number of bytes following (we don't need - // to use this). - let _length_do_not_remove_me_see_above: u32 = try_opt!(Slicable::decode(input)); - - Some(UncheckedTransaction { - transaction: try_opt!(Slicable::decode(input)), - signature: try_opt!(Slicable::decode(input)), - }) - } - - fn encode(&self) -> Vec { - let mut v = Vec::new(); - - // need to prefix with the total length as u32 to ensure it's binary comptible with - // Vec. we'll make room for it here, then overwrite once we know the length. - v.extend(&[0u8; 4]); - - self.transaction.signed.using_encoded(|s| v.extend(s)); - self.transaction.nonce.using_encoded(|s| v.extend(s)); - self.transaction.function.using_encoded(|s| v.extend(s)); - self.signature.using_encoded(|s| v.extend(s)); - - let length = (v.len() - 4) as u32; - length.using_encoded(|s| v[0..4].copy_from_slice(s)); - - v - } -} - -impl ::codec::NonTrivialSlicable for UncheckedTransaction {} - -impl PartialEq for UncheckedTransaction { - fn eq(&self, other: &Self) -> bool { - self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction - } -} - -#[cfg(feature = "std")] -impl fmt::Debug for UncheckedTransaction { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "UncheckedTransaction({:?})", self.transaction) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use primitives; - use ::codec::Slicable; - use primitives::hexdisplay::HexDisplay; - - #[test] - fn serialize_unchecked() { - let tx = UncheckedTransaction { - transaction: Transaction { - signed: [1; 32], - nonce: 999u64, - function: Function::TimestampSet(135135), - }, - signature: primitives::hash::H512([0; 64]), - }; - // 71000000 - // 0101010101010101010101010101010101010101010101010101010101010101 - // e703000000000000 - // 00 - // df0f0200 - // 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - - let v = Slicable::encode(&tx); - println!("{}", HexDisplay::from(&v)); - assert_eq!(UncheckedTransaction::decode(&mut &v[..]).unwrap(), tx); - } -} diff --git a/demo/runtime/Cargo.toml b/demo/runtime/Cargo.toml index bcd3f5dcf00ba..4033111d7d093 100644 --- a/demo/runtime/Cargo.toml +++ b/demo/runtime/Cargo.toml @@ -7,6 +7,8 @@ authors = ["Parity Technologies "] rustc-hex = "1.0" hex-literal = "0.1.0" log = { version = "0.3", optional = true } +serde = { version = "1.0", default_features = false } +serde_derive = { version = "1.0", optional = true } substrate-codec = { path = "../../substrate/codec" } substrate-runtime-std = { path = "../../substrate/runtime-std" } substrate-runtime-io = { path = "../../substrate/runtime-io" } @@ -25,5 +27,7 @@ std = [ "substrate-runtime-support/std", "substrate-primitives/std", "demo-primitives/std", + "serde_derive", + "serde/std", "log" ] diff --git a/demo/runtime/src/block.rs b/demo/runtime/src/block.rs new file mode 100644 index 0000000000000..6e905f88037ab --- /dev/null +++ b/demo/runtime/src/block.rs @@ -0,0 +1,53 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate Demo. + +// Substrate Demo 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. + +// Substrate Demo 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 Substrate Demo. If not, see . + +//! Block and header type definitions. + +#[cfg(feature = "std")] +use rstd::vec::Vec; +use codec::{Input, Slicable}; +use transaction::UncheckedTransaction; + +pub use demo_primitives::block::{Header, Digest, Log, Number, HeaderHash}; + +/// The block "body": A bunch of transactions. +pub type Body = Vec; + +/// A block on the chain. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +pub struct Block { + /// The block header. + pub header: Header, + /// All relay-chain transactions. + pub transactions: Body, +} + +impl Slicable for Block { + fn decode(input: &mut I) -> Option { + let (header, transactions) = try_opt!(Slicable::decode(input)); + Some(Block { header, transactions }) + } + + fn encode(&self) -> Vec { + let mut v = Vec::new(); + + v.extend(self.header.encode()); + v.extend(self.transactions.encode()); + + v + } +} diff --git a/demo/runtime/src/dispatch.rs b/demo/runtime/src/dispatch.rs index 9a9aded039fb1..93be322e520f4 100644 --- a/demo/runtime/src/dispatch.rs +++ b/demo/runtime/src/dispatch.rs @@ -16,81 +16,230 @@ //! Dispatch system. Just dispatches calls. -use demo_primitives::{Function, Proposal, AccountId}; -use runtime::{staking, system, session, democracy, council, council_vote, timestamp}; - -/// Dispatch a proposal. -pub fn proposal(proposal: Proposal) { - match proposal { - Proposal::SystemSetCode(ref a) => - system::privileged::set_code(a), - Proposal::SessionSetLength(a) => - session::privileged::set_length(a), - Proposal::SessionForceNewSession => - session::privileged::force_new_session(), - Proposal::StakingSetSessionsPerEra(a) => - staking::privileged::set_sessions_per_era(a), - Proposal::StakingSetBondingDuration(a) => - staking::privileged::set_bonding_duration(a), - Proposal::StakingSetValidatorCount(a) => - staking::privileged::set_validator_count(a), - Proposal::StakingForceNewEra => - staking::privileged::force_new_era(), - Proposal::DemocracyCancelReferendum(a) => - democracy::privileged::cancel_referendum(a), - Proposal::DemocracyStartReferendum(a, b) => - democracy::privileged::start_referendum(*a, b), - Proposal::DemocracyCancelReferendum(a) => - democracy::privileged::cancel_referendum(a), - Proposal::CouncilSetDesiredSeats(a) => - council::privileged::set_desired_seats(a), - Proposal::CouncilRemoveMember(a) => - council::privileged::remove_member(&a), - Proposal::CouncilSetPresentationDuration(a) => - council::privileged::set_presentation_duration(a), - Proposal::CouncilSetTermDuration(a) => - council::privileged::set_term_duration(a), - Proposal::CouncilVoteSetCooloffPeriod(a) => - council_vote::privileged::set_cooloff_period(a), - Proposal::CouncilVoteSetVotingPeriod(a) => - council_vote::privileged::set_voting_period(a), +use demo_primitives::AccountId; +use runtime::{staking, system, session, democracy, council, council_vote}; +use runtime::staking::public::Dispatch as staking_d; +use runtime::staking::privileged::Dispatch as staking_pd; +use runtime::timestamp::public::Dispatch as timestamp_d; + +pub use rstd::prelude::Vec; +pub use codec::{Slicable, Input, NonTrivialSlicable}; + +#[macro_export] +macro_rules! impl_dispatch { + ( + pub mod $mod_name:ident; + $( + fn $fn_name:ident( + $( + $param_name:ident : $param:ty + ),* + ) + = $id:expr ; + )* + ) => { + pub mod $mod_name { + use super::*; + + #[derive(Clone, Copy, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] + #[repr(u32)] + #[allow(non_camel_case_types)] + enum Id { + $( + #[allow(non_camel_case_types)] + $fn_name = $id, + )* + } + + impl Id { + /// Derive `Some` value from a `u8`, or `None` if it's invalid. + fn from_u8(value: u8) -> Option { + use self::*; + let functions = [ + $( Id::$fn_name ),* + ]; + functions.iter().map(|&f| f).find(|&f| value == f as u8) + } + } + + #[derive(Clone, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] + #[allow(missing_docs)] + pub enum Call { + $( + #[allow(non_camel_case_types)] + $fn_name ( $( $param ),* ) + ,)* + } + + pub trait Dispatch: Sized { + $( + fn $fn_name (self, $( $param_name: $param ),* ); + )* + } + + impl Call { + pub fn dispatch(self, d: D) { + match self { + $( + Call::$fn_name( $( $param_name ),* ) => + d.$fn_name( $( $param_name ),* ), + )* + } + } + } + + impl $crate::dispatch::Slicable for Call { + fn decode(input: &mut I) -> Option { + let id = u8::decode(input).and_then(Id::from_u8)?; + Some(match id { + $( + Id::$fn_name => { + $( + let $param_name = $crate::dispatch::Slicable::decode(input)?; + )* + Call :: $fn_name( $( $param_name ),* ) + } + )* + }) + } + + fn encode(&self) -> Vec { + let mut v = $crate::dispatch::Vec::new(); + match *self { + $( + Call::$fn_name( + $( + ref $param_name + ),* + ) => { + (Id::$fn_name as u8).using_encoded(|s| v.extend(s)); + $( + $param_name.using_encoded(|s| v.extend(s)); + )* + } + )* + } + v + } + + fn using_encoded R>(&self, f: F) -> R { + f(self.encode().as_slice()) + } + } + impl $crate::dispatch::NonTrivialSlicable for Call {} + } } } -/// Dispatch a function. -pub fn function(function: &Function, transactor: &AccountId) { - match *function { - Function::StakingStake => - staking::public::stake(transactor), - Function::StakingUnstake => - staking::public::unstake(transactor), - Function::StakingTransfer(dest, value) => - staking::public::transfer(transactor, &dest, value), - Function::SessionSetKey(session) => - session::public::set_key(transactor, &session), - Function::TimestampSet(t) => - timestamp::public::set(t), - Function::CouncilVotePropose(ref a) => - council_vote::public::propose(transactor, a), - Function::CouncilVoteVote(ref a, b) => - council_vote::public::vote(transactor, a, b), - Function::CouncilVoteVeto(ref a) => - council_vote::public::veto(transactor, a), - Function::CouncilSetApprovals(ref a, b) => - council::public::set_approvals(transactor, a, b), - Function::CouncilReapInactiveVoter(a, ref b, c, d) => - council::public::reap_inactive_voter(transactor, a, b, c, d), - Function::CouncilRetractVoter(a) => - council::public::retract_voter(transactor, a), - Function::CouncilSubmitCandidacy(a) => - council::public::submit_candidacy(transactor, a), - Function::CouncilPresentWinner(ref a, b, c) => - council::public::present_winner(transactor, a, b, c), - Function::DemocracyPropose(ref a, b) => - democracy::public::propose(transactor, a, b), - Function::DemocracySecond(a) => - democracy::public::second(transactor, a), - Function::DemocracyVote(a, b) => - democracy::public::vote(transactor, a, b), +macro_rules! impl_meta_dispatch { + ( + pub mod $super_name:ident; + path $path:ident; + trait $trait:ty; + $( + $camelcase:ident(mod $sub_name:ident) = $id:expr ; + )* + ) => { + pub mod $super_name { + use super::*; + + #[derive(Clone, Copy, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] + #[repr(u32)] + #[allow(non_camel_case_types)] + enum Id { + $( + #[allow(non_camel_case_types)] + $camelcase = $id, + )* + } + + impl Id { + /// Derive `Some` value from a `u8`, or `None` if it's invalid. + fn from_u8(value: u8) -> Option { + use self::*; + let functions = [ + $( Id::$camelcase ),* + ]; + functions.iter().map(|&f| f).find(|&f| value == f as u8) + } + } + + #[derive(Clone, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] + #[allow(missing_docs)] + pub enum Call { + $( + #[allow(non_camel_case_types)] + $camelcase ( $crate::runtime::$sub_name::$path::Call ) + ,)* + } + + impl Call { + pub fn dispatch(self, d: $trait) { + match self { + $( + Call::$camelcase(x) => x.dispatch(d), + )* + } + } + } + + impl $crate::dispatch::Slicable for Call { + fn decode(input: &mut I) -> Option { + let id = u8::decode(input).and_then(Id::from_u8)?; + Some(match id { + $( + Id::$camelcase => + Call::$camelcase( $crate::dispatch::Slicable::decode(input)? ), + )* + }) + } + + fn encode(&self) -> Vec { + let mut v = $crate::dispatch::Vec::new(); + match *self { + $( + Call::$camelcase( ref sub ) => { + (Id::$camelcase as u8).using_encoded(|s| v.extend(s)); + sub.using_encoded(|s| v.extend(s)); + } + )* + } + v + } + + fn using_encoded R>(&self, f: F) -> R { + f(self.encode().as_slice()) + } + } + impl $crate::dispatch::NonTrivialSlicable for Call {} + } } } + +impl_meta_dispatch! { + pub mod public; + path public; + trait staking::PublicPass; + Staking(mod staking) = 0; + Timestamp(mod timestamp) = 1; + Democracy(mod democracy) = 5; + Council(mod council) = 6; + CouncilVote(mod council) = 7; +} + +impl_meta_dispatch! { + pub mod privileged; + path privileged; + trait system::PrivPass; + Staking(mod staking) = 0; + Democracy(mod democracy) = 5; + Council(mod council) = 6; + CouncilVote(mod council) = 7; +} + +pub use self::privileged::Call as PrivCall; +pub use self::public::Call as PubCall; diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index a351da4230daa..b9d0b32912691 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -23,6 +23,9 @@ extern crate substrate_runtime_support as runtime_support; #[cfg(any(feature = "std", test))] extern crate substrate_keyring as keyring; +#[cfg(feature = "std")] #[macro_use] extern crate serde_derive; +#[cfg(feature = "std")] extern crate serde; + #[cfg(feature = "std")] extern crate rustc_hex; extern crate substrate_codec as codec; @@ -33,48 +36,12 @@ extern crate demo_primitives; extern crate integer_sqrt; +#[macro_use] pub mod dispatch; + +pub mod block; +pub mod transaction; pub mod environment; pub mod runtime; pub mod api; -pub mod dispatch; #[cfg(feature = "std")] pub mod genesismap; - -/// Type definitions and helpers for transactions. -pub mod transaction { - use rstd::ops; - use demo_primitives::Signature; - pub use demo_primitives::{Transaction, UncheckedTransaction}; - - /// A type-safe indicator that a transaction has been checked. - #[derive(PartialEq, Eq, Clone)] - #[cfg_attr(feature = "std", derive(Debug))] - pub struct CheckedTransaction(UncheckedTransaction); - - impl CheckedTransaction { - /// Get a reference to the checked signature. - pub fn signature(&self) -> &Signature { - &self.0.signature - } - } - - impl ops::Deref for CheckedTransaction { - type Target = Transaction; - - fn deref(&self) -> &Transaction { - &self.0.transaction - } - } - - /// Check the signature on a transaction. - /// - /// On failure, return the transaction back. - pub fn check(tx: UncheckedTransaction) -> Result { - let msg = ::codec::Slicable::encode(&tx.transaction); - if ::runtime_io::ed25519_verify(&tx.signature.0, &msg, &tx.transaction.signed) { - Ok(CheckedTransaction(tx)) - } else { - Err(tx) - } - } -} diff --git a/demo/runtime/src/runtime/council.rs b/demo/runtime/src/runtime/council.rs index ce922f897179a..777144676f426 100644 --- a/demo/runtime/src/runtime/council.rs +++ b/demo/runtime/src/runtime/council.rs @@ -19,9 +19,10 @@ use rstd::prelude::*; use codec::KeyedVec; use runtime_support::storage; -use demo_primitives::{Proposal, AccountId, Hash, BlockNumber}; +use demo_primitives::{AccountId, Hash, BlockNumber}; use runtime::{staking, system, session}; -use runtime::staking::Balance; +use runtime::system::PrivPass; +use runtime::staking::{PublicPass, Balance}; // no polynomial attacks: // @@ -255,25 +256,33 @@ pub fn leaderboard() -> Option> { storage::get(LEADERBOARD) } -pub mod public { - use super::*; +impl_dispatch! { + pub mod public; + fn set_approvals(votes: Vec, index: VoteIndex) = 0; + fn reap_inactive_voter(signed_index: u32, who: AccountId, who_index: u32, assumed_vote_index: VoteIndex) = 1; + fn retract_voter(index: u32) = 2; + fn submit_candidacy(slot: u32) = 3; + fn present_winner(candidate: AccountId, total: Balance, index: VoteIndex) = 4; +} + +impl<'a> public::Dispatch for PublicPass<'a> { /// Set candidate approvals. Approval slots stay valid as long as candidates in those slots /// are registered. - pub fn set_approvals(signed: &AccountId, votes: &Vec, index: VoteIndex) { + fn set_approvals(self, votes: Vec, index: VoteIndex) { assert!(!presentation_active()); assert_eq!(index, vote_index()); - if !storage::exists(&signed.to_keyed_vec(LAST_ACTIVE_OF)) { + if !storage::exists(&self.to_keyed_vec(LAST_ACTIVE_OF)) { // not yet a voter - deduct bond. - staking::internal::reserve_balance(signed, voting_bond()); + staking::internal::reserve_balance(&self, voting_bond()); storage::put(VOTERS, &{ let mut v: Vec = storage::get_or_default(VOTERS); - v.push(signed.clone()); + v.push(self.clone()); v }); } - storage::put(&signed.to_keyed_vec(APPROVALS_OF), votes); - storage::put(&signed.to_keyed_vec(LAST_ACTIVE_OF), &index); + storage::put(&self.to_keyed_vec(APPROVALS_OF), &votes); + storage::put(&self.to_keyed_vec(LAST_ACTIVE_OF), &index); } /// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices @@ -281,21 +290,21 @@ pub mod public { /// the voter gave their last approval set. /// /// May be called by anyone. Returns the voter deposit to `signed`. - pub fn reap_inactive_voter(signed: &AccountId, signed_index: u32, who: &AccountId, who_index: u32, assumed_vote_index: VoteIndex) { + fn reap_inactive_voter(self, signed_index: u32, who: AccountId, who_index: u32, assumed_vote_index: VoteIndex) { assert!(!presentation_active(), "cannot reap during presentation period"); - assert!(voter_last_active(signed).is_some(), "reaper must be a voter"); - let last_active = voter_last_active(who).expect("target for inactivity cleanup must be active"); + assert!(voter_last_active(&self).is_some(), "reaper must be a voter"); + let last_active = voter_last_active(&who).expect("target for inactivity cleanup must be active"); assert!(assumed_vote_index == vote_index(), "vote index not current"); assert!(last_active < assumed_vote_index - inactivity_grace_period(), "cannot reap during grace perid"); let voters = voters(); let signed_index = signed_index as usize; let who_index = who_index as usize; - assert!(signed_index < voters.len() && voters[signed_index] == *signed, "bad reporter index"); - assert!(who_index < voters.len() && voters[who_index] == *who, "bad target index"); + assert!(signed_index < voters.len() && voters[signed_index] == *self, "bad reporter index"); + assert!(who_index < voters.len() && voters[who_index] == who, "bad target index"); // will definitely kill one of signed or who now. - let valid = !approvals_of(who).iter() + let valid = !approvals_of(&who).iter() .zip(candidates().iter()) .any(|(&appr, addr)| appr && @@ -304,35 +313,35 @@ pub mod public { .expect("all items in candidates list are registered").0 <= last_active); remove_voter( - if valid { who } else { signed }, + if valid { &who } else { &self }, if valid { who_index } else { signed_index }, voters ); if valid { - staking::internal::transfer_reserved_balance(who, signed, voting_bond()); + staking::internal::transfer_reserved_balance(&who, &self, voting_bond()); } else { - staking::internal::slash_reserved(signed, voting_bond()); + staking::internal::slash_reserved(&self, voting_bond()); } } /// Remove a voter. All votes are cancelled and the voter deposit is returned. - pub fn retract_voter(signed: &AccountId, index: u32) { + fn retract_voter(self, index: u32) { assert!(!presentation_active(), "cannot retract when presenting"); - assert!(storage::exists(&signed.to_keyed_vec(LAST_ACTIVE_OF)), "cannot retract non-voter"); + assert!(storage::exists(&self.to_keyed_vec(LAST_ACTIVE_OF)), "cannot retract non-voter"); let voters = voters(); let index = index as usize; assert!(index < voters.len(), "retraction index invalid"); - assert!(voters[index] == *signed, "retraction index mismatch"); - remove_voter(signed, index, voters); - staking::internal::unreserve_balance(signed, voting_bond()); + assert!(voters[index] == *self, "retraction index mismatch"); + remove_voter(&self, index, voters); + staking::internal::unreserve_balance(&self, voting_bond()); } /// Submit oneself for candidacy. /// /// Account must have enough transferrable funds in it to pay the bond. - pub fn submit_candidacy(signed: &AccountId, slot: u32) { - assert!(!is_a_candidate(signed), "duplicate candidate submission"); - assert!(staking::internal::deduct_unbonded(signed, candidacy_bond()), "candidate has not enough funds"); + fn submit_candidacy(self, slot: u32) { + assert!(!is_a_candidate(&self), "duplicate candidate submission"); + assert!(staking::internal::deduct_unbonded(&self, candidacy_bond()), "candidate has not enough funds"); let slot = slot as usize; let count = storage::get_or_default::(CANDIDATE_COUNT) as usize; @@ -345,31 +354,31 @@ pub mod public { let mut candidates = candidates; if slot == candidates.len() { - candidates.push(signed.clone()); + candidates.push(self.clone()); } else { - candidates[slot] = signed.clone(); + candidates[slot] = self.clone(); } storage::put(CANDIDATES, &candidates); storage::put(CANDIDATE_COUNT, &(count as u32 + 1)); - storage::put(&signed.to_keyed_vec(REGISTER_INFO_OF), &(vote_index(), slot)); + storage::put(&self.to_keyed_vec(REGISTER_INFO_OF), &(vote_index(), slot)); } /// Claim that `signed` is one of the top carry_count() + current_vote().1 candidates. /// Only works if the block number >= current_vote().0 and < current_vote().0 + presentation_duration() /// `signed` should have at least - pub fn present_winner(signed: &AccountId, candidate: &AccountId, total: Balance, index: VoteIndex) { + fn present_winner(self, candidate: AccountId, total: Balance, index: VoteIndex) { assert_eq!(index, vote_index(), "index not current"); let (_, _, expiring): (BlockNumber, u32, Vec) = storage::get(NEXT_FINALISE) .expect("cannot present outside of presentation period"); let stakes: Vec = storage::get_or_default(SNAPSHOTED_STAKES); let voters: Vec = storage::get_or_default(VOTERS); let bad_presentation_punishment = present_slash_per_voter() * voters.len() as Balance; - assert!(staking::can_slash(signed, bad_presentation_punishment), "presenter must have sufficient slashable funds"); + assert!(staking::can_slash(&self, bad_presentation_punishment), "presenter must have sufficient slashable funds"); let mut leaderboard = leaderboard().expect("leaderboard must exist while present phase active"); assert!(total > leaderboard[0].0, "candidate not worthy of leaderboard"); - if let Some(p) = active_council().iter().position(|&(ref c, _)| c == candidate) { + if let Some(p) = active_council().iter().position(|&(ref c, _)| c == &candidate) { assert!(p < expiring.len(), "candidate must not form a duplicated member if elected"); } @@ -385,55 +394,60 @@ pub mod public { _ => None, }) .sum(); - let dupe = leaderboard.iter().find(|&&(_, ref c)| c == candidate).is_some(); + let dupe = leaderboard.iter().find(|&&(_, ref c)| c == &candidate).is_some(); if total == actual_total && !dupe { // insert into leaderboard leaderboard[0] = (total, candidate.clone()); leaderboard.sort_by_key(|&(t, _)| t); storage::put(LEADERBOARD, &leaderboard); } else { - staking::internal::slash(signed, bad_presentation_punishment); + staking::internal::slash(&self, bad_presentation_punishment); } } } -pub mod privileged { - use super::*; +impl_dispatch! { + pub mod privileged; + fn set_desired_seats(count: u32) = 0; + fn remove_member(who: AccountId) = 1; + fn set_presentation_duration(count: BlockNumber) = 2; + fn set_term_duration(count: BlockNumber) = 3; +} +impl privileged::Dispatch for PrivPass { /// Set the desired member count; if lower than the current count, then seats will not be up /// election when they expire. If more, then a new vote will be started if one is not already /// in progress. - pub fn set_desired_seats(count: u32) { + fn set_desired_seats(self, count: u32) { storage::put(DESIRED_SEATS, &count); } /// Remove a particular member. A tally will happen instantly (if not already in a presentation /// period) to fill the seat if removal means that the desired members are not met. /// This is effective immediately. - pub fn remove_member(who: &AccountId) { + fn remove_member(self, who: AccountId) { let new_council: Vec<(AccountId, BlockNumber)> = active_council() .into_iter() - .filter(|i| i.0 != *who) + .filter(|i| i.0 != who) .collect(); storage::put(ACTIVE_COUNCIL, &new_council); } /// Set the presentation duration. If there is current a vote being presented for, will /// invoke `finalise_vote`. - pub fn set_presentation_duration(count: BlockNumber) { + fn set_presentation_duration(self, count: BlockNumber) { storage::put(PRESENTATION_DURATION, &count); } /// Set the presentation duration. If there is current a vote being presented for, will /// invoke `finalise_vote`. - pub fn set_term_duration(count: BlockNumber) { + fn set_term_duration(self, count: BlockNumber) { storage::put(TERM_DURATION, &count); } } pub mod internal { use super::*; - use demo_primitives::Proposal; /// Check there's nothing to do this block pub fn end_block() { @@ -578,8 +592,10 @@ mod tests { use codec::{KeyedVec, Joiner}; use keyring::Keyring::*; use environment::with_env; - use demo_primitives::{AccountId, Proposal}; + use demo_primitives::AccountId; use runtime::{staking, session, democracy}; + use super::public::Dispatch; + use super::privileged::Dispatch as PrivDispatch; fn new_test_ext() -> TestExternalities { testing::externalities() @@ -628,14 +644,14 @@ mod tests { assert_eq!(is_a_candidate(&Alice), false); assert_eq!(is_a_candidate(&Bob), false); - public::submit_candidacy(&Alice, 0); + PublicPass::test(&Alice).submit_candidacy(0); assert_eq!(candidates(), vec![Alice.to_raw_public()]); assert_eq!(candidate_reg_info(&Alice), Some((0 as VoteIndex, 0u32))); assert_eq!(candidate_reg_info(&Bob), None); assert_eq!(is_a_candidate(&Alice), true); assert_eq!(is_a_candidate(&Bob), false); - public::submit_candidacy(&Bob, 1); + PublicPass::test(&Bob).submit_candidacy(1); assert_eq!(candidates(), vec![Alice.to_raw_public(), Bob.into()]); assert_eq!(candidate_reg_info(&Alice), Some((0 as VoteIndex, 0u32))); assert_eq!(candidate_reg_info(&Bob), Some((0 as VoteIndex, 1u32))); @@ -660,10 +676,10 @@ mod tests { with_env(|e| e.block_number = 1); assert_eq!(candidates(), vec![AccountId::default(), AccountId::default(), Alice.to_raw_public()]); - public::submit_candidacy(&Bob, 1); + PublicPass::test(&Bob).submit_candidacy(1); assert_eq!(candidates(), vec![AccountId::default(), Bob.into(), Alice.to_raw_public()]); - public::submit_candidacy(&Charlie, 0); + PublicPass::test(&Charlie).submit_candidacy(0); assert_eq!(candidates(), vec![Charlie.into(), Bob.into(), Alice.to_raw_public()]); }); } @@ -676,10 +692,10 @@ mod tests { with_env(|e| e.block_number = 1); assert_eq!(candidates(), vec![AccountId::default(), AccountId::default(), Alice.into()]); - public::submit_candidacy(&Bob, 0); + PublicPass::test(&Bob).submit_candidacy(0); assert_eq!(candidates(), vec![Bob.into(), AccountId::default(), Alice.into()]); - public::submit_candidacy(&Charlie, 1); + PublicPass::test(&Charlie).submit_candidacy(1); assert_eq!(candidates(), vec![Bob.to_raw_public(), Charlie.into(), Alice.into()]); }); } @@ -691,7 +707,7 @@ mod tests { with_externalities(&mut t, || { with_env(|e| e.block_number = 1); - public::submit_candidacy(&Dave, 3); + PublicPass::test(&Dave).submit_candidacy(3); }); } @@ -701,7 +717,7 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); assert_eq!(candidates(), Vec::::new()); - public::submit_candidacy(&Alice, 1); + PublicPass::test(&Alice).submit_candidacy(1); }); } @@ -711,8 +727,8 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); assert_eq!(candidates(), Vec::::new()); - public::submit_candidacy(&Alice, 0); - public::submit_candidacy(&Bob, 0); + PublicPass::test(&Alice).submit_candidacy(0); + PublicPass::test(&Bob).submit_candidacy(0); }); } @@ -722,8 +738,8 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); assert_eq!(candidates(), Vec::::new()); - public::submit_candidacy(&Alice, 0); - public::submit_candidacy(&Alice, 1); + PublicPass::test(&Alice).submit_candidacy(0); + PublicPass::test(&Alice).submit_candidacy(1); }); } @@ -733,7 +749,7 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); assert_eq!(candidates(), Vec::::new()); - public::submit_candidacy(&One, 0); + PublicPass::test(&One).submit_candidacy(0); }); } @@ -742,20 +758,20 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::submit_candidacy(&Eve, 0); + PublicPass::test(&Eve).submit_candidacy(0); - public::set_approvals(&Alice, &vec![true], 0); - public::set_approvals(&Dave, &vec![true], 0); + PublicPass::test(&Alice).set_approvals(vec![true], 0); + PublicPass::test(&Dave).set_approvals(vec![true], 0); assert_eq!(approvals_of(&Alice), vec![true]); assert_eq!(approvals_of(&Dave), vec![true]); assert_eq!(voters(), vec![Alice.to_raw_public(), Dave.into()]); - public::submit_candidacy(&Bob, 1); - public::submit_candidacy(&Charlie, 2); + PublicPass::test(&Bob).submit_candidacy(1); + PublicPass::test(&Charlie).submit_candidacy(2); - public::set_approvals(&Bob, &vec![false, true, true], 0); - public::set_approvals(&Charlie, &vec![false, true, true], 0); + PublicPass::test(&Bob).set_approvals(vec![false, true, true], 0); + PublicPass::test(&Charlie).set_approvals(vec![false, true, true], 0); assert_eq!(approvals_of(&Alice), vec![true]); assert_eq!(approvals_of(&Dave), vec![true]); @@ -763,8 +779,6 @@ mod tests { assert_eq!(approvals_of(&Charlie), vec![false, true, true]); assert_eq!(voters(), vec![Alice.to_raw_public(), Dave.into(), Bob.into(), Charlie.into()]); - - }); } @@ -773,14 +787,14 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::submit_candidacy(&Eve, 0); - public::set_approvals(&Dave, &vec![true], 0); + PublicPass::test(&Eve).submit_candidacy(0); + PublicPass::test(&Dave).set_approvals(vec![true], 0); assert_eq!(approvals_of(&Dave), vec![true]); - public::submit_candidacy(&Bob, 1); - public::submit_candidacy(&Charlie, 2); - public::set_approvals(&Dave, &vec![true, false, true], 0); + PublicPass::test(&Bob).submit_candidacy(1); + PublicPass::test(&Charlie).submit_candidacy(2); + PublicPass::test(&Dave).set_approvals(vec![true, false, true], 0); assert_eq!(approvals_of(&Dave), vec![true, false, true]); }); @@ -791,14 +805,14 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::submit_candidacy(&Eve, 0); - public::submit_candidacy(&Bob, 1); - public::submit_candidacy(&Charlie, 2); + PublicPass::test(&Eve).submit_candidacy(0); + PublicPass::test(&Bob).submit_candidacy(1); + PublicPass::test(&Charlie).submit_candidacy(2); - public::set_approvals(&Alice, &vec![true], 0); - public::set_approvals(&Bob, &vec![false, true, true], 0); - public::set_approvals(&Charlie, &vec![false, true, true], 0); - public::set_approvals(&Dave, &vec![true, false, true], 0); + PublicPass::test(&Alice).set_approvals(vec![true], 0); + PublicPass::test(&Bob).set_approvals(vec![false, true, true], 0); + PublicPass::test(&Charlie).set_approvals(vec![false, true, true], 0); + PublicPass::test(&Dave).set_approvals(vec![true, false, true], 0); assert_eq!(voters(), vec![Alice.to_raw_public(), Bob.into(), Charlie.into(), Dave.into()]); assert_eq!(approvals_of(&Alice), vec![true]); @@ -806,7 +820,7 @@ mod tests { assert_eq!(approvals_of(&Charlie), vec![false, true, true]); assert_eq!(approvals_of(&Dave), vec![true, false, true]); - public::retract_voter(&Alice, 0); + PublicPass::test(&Alice).retract_voter(0); assert_eq!(voters(), vec![Dave.to_raw_public(), Bob.into(), Charlie.into()]); assert_eq!(approvals_of(&Alice), Vec::::new()); @@ -814,7 +828,7 @@ mod tests { assert_eq!(approvals_of(&Charlie), vec![false, true, true]); assert_eq!(approvals_of(&Dave), vec![true, false, true]); - public::retract_voter(&Bob, 1); + PublicPass::test(&Bob).retract_voter(1); assert_eq!(voters(), vec![Dave.to_raw_public(), Charlie.into()]); assert_eq!(approvals_of(&Alice), Vec::::new()); @@ -822,7 +836,7 @@ mod tests { assert_eq!(approvals_of(&Charlie), vec![false, true, true]); assert_eq!(approvals_of(&Dave), vec![true, false, true]); - public::retract_voter(&Charlie, 1); + PublicPass::test(&Charlie).retract_voter(1); assert_eq!(voters(), vec![Dave.to_raw_public()]); assert_eq!(approvals_of(&Alice), Vec::::new()); @@ -837,10 +851,10 @@ mod tests { fn invalid_retraction_index_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::submit_candidacy(&Charlie, 0); - public::set_approvals(&Alice, &vec![true], 0); - public::set_approvals(&Bob, &vec![true], 0); - public::retract_voter(&Alice, 1); + PublicPass::test(&Charlie).submit_candidacy(0); + PublicPass::test(&Alice).set_approvals(vec![true], 0); + PublicPass::test(&Bob).set_approvals(vec![true], 0); + PublicPass::test(&Alice).retract_voter(1); }); } @@ -849,9 +863,9 @@ mod tests { fn overflow_retraction_index_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::submit_candidacy(&Charlie, 0); - public::set_approvals(&Alice, &vec![true], 0); - public::retract_voter(&Alice, 1); + PublicPass::test(&Charlie).submit_candidacy(0); + PublicPass::test(&Alice).set_approvals(vec![true], 0); + PublicPass::test(&Alice).retract_voter(1); }); } @@ -860,9 +874,9 @@ mod tests { fn non_voter_retraction_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::submit_candidacy(&Charlie, 0); - public::set_approvals(&Alice, &vec![true], 0); - public::retract_voter(&Bob, 0); + PublicPass::test(&Charlie).submit_candidacy(0); + PublicPass::test(&Alice).set_approvals(vec![true], 0); + PublicPass::test(&Bob).retract_voter(0); }); } @@ -872,16 +886,16 @@ mod tests { with_env(|e| e.block_number = 4); assert!(!presentation_active()); - public::submit_candidacy(&Bob, 0); - public::submit_candidacy(&Eve, 1); - public::set_approvals(&Bob, &vec![true, false], 0); - public::set_approvals(&Eve, &vec![false, true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Eve).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![true, false], 0); + PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); assert!(presentation_active()); - public::present_winner(&Dave, &Bob, 11, 0); - public::present_winner(&Dave, &Eve, 41, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); assert_eq!(leaderboard(), Some(vec![(0, AccountId::default()), (0, AccountId::default()), (11, Bob.into()), (41, Eve.into())])); internal::end_block(); @@ -903,16 +917,16 @@ mod tests { assert!(staking::can_slash(&Dave, 10)); with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::submit_candidacy(&Eve, 1); - public::set_approvals(&Bob, &vec![true, false], 0); - public::set_approvals(&Eve, &vec![false, true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Eve).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![true, false], 0); + PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 0); - public::present_winner(&Dave, &Eve, 41, 0); - public::present_winner(&Dave, &Eve, 41, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); internal::end_block(); assert_eq!(active_council(), vec![(Eve.to_raw_public(), 11), (Bob.into(), 11)]); @@ -924,26 +938,26 @@ mod tests { fn retracting_inactive_voter_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::set_approvals(&Bob, &vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); with_env(|e| e.block_number = 8); - public::submit_candidacy(&Eve, 0); - public::set_approvals(&Eve, &vec![true], 1); + PublicPass::test(&Eve).submit_candidacy(0); + PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Eve, 41, 1); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1); internal::end_block(); - public::reap_inactive_voter( - &Eve, voters().iter().position(|&i| i == *Eve).unwrap() as u32, - &Bob, voters().iter().position(|&i| i == *Bob).unwrap() as u32, + PublicPass::test(&Eve).reap_inactive_voter( + voters().iter().position(|&i| i == *Eve).unwrap() as u32, + Bob.into(), voters().iter().position(|&i| i == *Bob).unwrap() as u32, 2 ); @@ -959,21 +973,21 @@ mod tests { fn presenting_for_double_election_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::set_approvals(&Bob, &vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); with_env(|e| e.block_number = 8); - public::submit_candidacy(&Bob, 0); - public::set_approvals(&Bob, &vec![true], 1); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Bob).set_approvals(vec![true], 1); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Bob, 11, 1); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1); }); } @@ -981,29 +995,29 @@ mod tests { fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::set_approvals(&Bob, &vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); with_env(|e| e.block_number = 8); - public::submit_candidacy(&Eve, 0); - public::set_approvals(&Eve, &vec![true], 1); + PublicPass::test(&Eve).submit_candidacy(0); + PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Eve, 41, 1); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1); internal::end_block(); with_env(|e| e.block_number = 11); - public::submit_candidacy(&Alice, 0); + PublicPass::test(&Alice).submit_candidacy(0); - public::reap_inactive_voter( - &Eve, voters().iter().position(|&i| i == *Eve).unwrap() as u32, - &Bob, voters().iter().position(|&i| i == *Bob).unwrap() as u32, + PublicPass::test(&Eve).reap_inactive_voter( + voters().iter().position(|&i| i == *Eve).unwrap() as u32, + Bob.into(), voters().iter().position(|&i| i == *Bob).unwrap() as u32, 2 ); @@ -1019,26 +1033,26 @@ mod tests { fn retracting_inactive_voter_with_bad_reporter_index_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::set_approvals(&Bob, &vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 8, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 8, 0); internal::end_block(); with_env(|e| e.block_number = 8); - public::submit_candidacy(&Eve, 0); - public::set_approvals(&Eve, &vec![true], 1); + PublicPass::test(&Eve).submit_candidacy(0); + PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Eve, 38, 1); + PublicPass::test(&Dave).present_winner(Eve.into(), 38, 1); internal::end_block(); - public::reap_inactive_voter( - &Bob, 42, - &Bob, voters().iter().position(|&i| i == *Bob).unwrap() as u32, + PublicPass::test(&Bob).reap_inactive_voter( + 42, + Bob.into(), voters().iter().position(|&i| i == *Bob).unwrap() as u32, 2 ); }); @@ -1049,26 +1063,26 @@ mod tests { fn retracting_inactive_voter_with_bad_target_index_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::set_approvals(&Bob, &vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 8, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 8, 0); internal::end_block(); with_env(|e| e.block_number = 8); - public::submit_candidacy(&Eve, 0); - public::set_approvals(&Eve, &vec![true], 1); + PublicPass::test(&Eve).submit_candidacy(0); + PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Eve, 38, 1); + PublicPass::test(&Dave).present_winner(Eve.into(), 38, 1); internal::end_block(); - public::reap_inactive_voter( - &Bob, voters().iter().position(|&i| i == *Bob).unwrap() as u32, - &Bob, 42, + PublicPass::test(&Bob).reap_inactive_voter( + voters().iter().position(|&i| i == *Bob).unwrap() as u32, + Bob.into(), 42, 2 ); }); @@ -1078,35 +1092,35 @@ mod tests { fn attempting_to_retract_active_voter_should_slash_reporter() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::submit_candidacy(&Charlie, 1); - public::submit_candidacy(&Dave, 2); - public::submit_candidacy(&Eve, 3); - public::set_approvals(&Bob, &vec![true, false, false, false], 0); - public::set_approvals(&Charlie, &vec![false, true, false, false], 0); - public::set_approvals(&Dave, &vec![false, false, true, false], 0); - public::set_approvals(&Eve, &vec![false, false, false, true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Charlie).submit_candidacy(1); + PublicPass::test(&Dave).submit_candidacy(2); + PublicPass::test(&Eve).submit_candidacy(3); + PublicPass::test(&Bob).set_approvals(vec![true, false, false, false], 0); + PublicPass::test(&Charlie).set_approvals(vec![false, true, false, false], 0); + PublicPass::test(&Dave).set_approvals(vec![false, false, true, false], 0); + PublicPass::test(&Eve).set_approvals(vec![false, false, false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 0); - public::present_winner(&Dave, &Charlie, 21, 0); - public::present_winner(&Dave, &Dave, 31, 0); - public::present_winner(&Dave, &Eve, 41, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); + PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); + PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); internal::end_block(); with_env(|e| e.block_number = 8); - privileged::set_desired_seats(3); + PrivPass.set_desired_seats(3); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Bob, 11, 1); - public::present_winner(&Dave, &Charlie, 21, 1); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1); + PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 1); internal::end_block(); - public::reap_inactive_voter( - &Dave, voters().iter().position(|&i| i == *Dave).unwrap() as u32, - &Bob, voters().iter().position(|&i| i == *Bob).unwrap() as u32, + PublicPass::test(&Dave).reap_inactive_voter( + voters().iter().position(|&i| i == *Dave).unwrap() as u32, + Bob.into(), voters().iter().position(|&i| i == *Bob).unwrap() as u32, 2 ); @@ -1121,26 +1135,26 @@ mod tests { fn attempting_to_retract_inactive_voter_by_nonvoter_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::set_approvals(&Bob, &vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); with_env(|e| e.block_number = 8); - public::submit_candidacy(&Eve, 0); - public::set_approvals(&Eve, &vec![true], 1); + PublicPass::test(&Eve).submit_candidacy(0); + PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Eve, 41, 1); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1); internal::end_block(); - public::reap_inactive_voter( - &Dave, 0, - &Bob, voters().iter().position(|&i| i == *Bob).unwrap() as u32, + PublicPass::test(&Dave).reap_inactive_voter( + 0, + Bob.into(), voters().iter().position(|&i| i == *Bob).unwrap() as u32, 2 ); }); @@ -1151,24 +1165,24 @@ mod tests { fn presenting_loser_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Alice, 0); - public::set_approvals(&Ferdie, &vec![true], 0); - public::submit_candidacy(&Bob, 1); - public::set_approvals(&Bob, &vec![false, true], 0); - public::submit_candidacy(&Charlie, 2); - public::set_approvals(&Charlie, &vec![false, false, true], 0); - public::submit_candidacy(&Dave, 3); - public::set_approvals(&Dave, &vec![false, false, false, true], 0); - public::submit_candidacy(&Eve, 4); - public::set_approvals(&Eve, &vec![false, false, false, false, true], 0); + PublicPass::test(&Alice).submit_candidacy(0); + PublicPass::test(&Ferdie).set_approvals(vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![false, true], 0); + PublicPass::test(&Charlie).submit_candidacy(2); + PublicPass::test(&Charlie).set_approvals(vec![false, false, true], 0); + PublicPass::test(&Dave).submit_candidacy(3); + PublicPass::test(&Dave).set_approvals(vec![false, false, false, true], 0); + PublicPass::test(&Eve).submit_candidacy(4); + PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Alice, 60, 0); - public::present_winner(&Dave, &Charlie, 21, 0); - public::present_winner(&Dave, &Dave, 31, 0); - public::present_winner(&Dave, &Eve, 41, 0); - public::present_winner(&Dave, &Bob, 11, 0); + PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); + PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); + PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); }); } @@ -1176,24 +1190,24 @@ mod tests { fn presenting_loser_first_should_not_matter() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Alice, 0); - public::set_approvals(&Ferdie, &vec![true], 0); - public::submit_candidacy(&Bob, 1); - public::set_approvals(&Bob, &vec![false, true], 0); - public::submit_candidacy(&Charlie, 2); - public::set_approvals(&Charlie, &vec![false, false, true], 0); - public::submit_candidacy(&Dave, 3); - public::set_approvals(&Dave, &vec![false, false, false, true], 0); - public::submit_candidacy(&Eve, 4); - public::set_approvals(&Eve, &vec![false, false, false, false, true], 0); + PublicPass::test(&Alice).submit_candidacy(0); + PublicPass::test(&Ferdie).set_approvals(vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![false, true], 0); + PublicPass::test(&Charlie).submit_candidacy(2); + PublicPass::test(&Charlie).set_approvals(vec![false, false, true], 0); + PublicPass::test(&Dave).submit_candidacy(3); + PublicPass::test(&Dave).set_approvals(vec![false, false, false, true], 0); + PublicPass::test(&Eve).submit_candidacy(4); + PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 0); - public::present_winner(&Dave, &Alice, 60, 0); - public::present_winner(&Dave, &Charlie, 21, 0); - public::present_winner(&Dave, &Dave, 31, 0); - public::present_winner(&Dave, &Eve, 41, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); + PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); + PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); + PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); assert_eq!(leaderboard(), Some(vec![ (21, Charlie.into()), @@ -1210,7 +1224,7 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); assert!(!presentation_active()); - public::present_winner(&Eve, &Eve, 1, 0); + PublicPass::test(&Eve).present_winner(Eve.into(), 1, 0); }); } @@ -1219,14 +1233,14 @@ mod tests { fn present_panics_with_invalid_vote_index() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Bob, 0); - public::submit_candidacy(&Eve, 1); - public::set_approvals(&Bob, &vec![true, false], 0); - public::set_approvals(&Eve, &vec![false, true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Eve).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![true, false], 0); + PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 11, 1); + PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1); }); } @@ -1237,15 +1251,15 @@ mod tests { with_env(|e| e.block_number = 4); assert!(!presentation_active()); - public::submit_candidacy(&Alice, 0); - public::submit_candidacy(&Eve, 1); - public::set_approvals(&Bob, &vec![true, false], 0); - public::set_approvals(&Eve, &vec![false, true], 0); + PublicPass::test(&Alice).submit_candidacy(0); + PublicPass::test(&Eve).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![true, false], 0); + PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); assert_eq!(staking::balance(&Alice), 1); - public::present_winner(&Alice, &Alice, 30, 0); + PublicPass::test(&Alice).present_winner(Alice.into(), 30, 0); }); } @@ -1256,14 +1270,14 @@ mod tests { assert!(!presentation_active()); assert_eq!(staking::balance(&Dave), 40); - public::submit_candidacy(&Bob, 0); - public::submit_candidacy(&Eve, 1); - public::set_approvals(&Bob, &vec![true, false], 0); - public::set_approvals(&Eve, &vec![false, true], 0); + PublicPass::test(&Bob).submit_candidacy(0); + PublicPass::test(&Eve).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![true, false], 0); + PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Bob, 80, 0); + PublicPass::test(&Dave).present_winner(Bob.into(), 80, 0); assert_eq!(staking::balance(&Dave), 38); }); @@ -1275,31 +1289,31 @@ mod tests { with_env(|e| e.block_number = 4); assert!(!presentation_active()); - public::submit_candidacy(&Alice, 0); - public::set_approvals(&Ferdie, &vec![true], 0); - public::submit_candidacy(&Bob, 1); - public::set_approvals(&Bob, &vec![false, true], 0); - public::submit_candidacy(&Charlie, 2); - public::set_approvals(&Charlie, &vec![false, false, true], 0); - public::submit_candidacy(&Dave, 3); - public::set_approvals(&Dave, &vec![false, false, false, true], 0); - public::submit_candidacy(&Eve, 4); - public::set_approvals(&Eve, &vec![false, false, false, false, true], 0); + PublicPass::test(&Alice).submit_candidacy(0); + PublicPass::test(&Ferdie).set_approvals(vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![false, true], 0); + PublicPass::test(&Charlie).submit_candidacy(2); + PublicPass::test(&Charlie).set_approvals(vec![false, false, true], 0); + PublicPass::test(&Dave).submit_candidacy(3); + PublicPass::test(&Dave).set_approvals(vec![false, false, false, true], 0); + PublicPass::test(&Eve).submit_candidacy(4); + PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); assert!(presentation_active()); - public::present_winner(&Dave, &Alice, 60, 0); + PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); assert_eq!(leaderboard(), Some(vec![ (0, AccountId::default()), (0, AccountId::default()), (0, AccountId::default()), (60, Alice.to_raw_public()) ])); - public::present_winner(&Dave, &Charlie, 21, 0); - public::present_winner(&Dave, &Dave, 31, 0); - public::present_winner(&Dave, &Eve, 41, 0); + PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); + PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); assert_eq!(leaderboard(), Some(vec![ (21, Charlie.into()), (31, Dave.into()), @@ -1332,33 +1346,33 @@ mod tests { fn second_tally_should_use_runners_up() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 4); - public::submit_candidacy(&Alice, 0); - public::set_approvals(&Ferdie, &vec![true], 0); - public::submit_candidacy(&Bob, 1); - public::set_approvals(&Bob, &vec![false, true], 0); - public::submit_candidacy(&Charlie, 2); - public::set_approvals(&Charlie, &vec![false, false, true], 0); - public::submit_candidacy(&Dave, 3); - public::set_approvals(&Dave, &vec![false, false, false, true], 0); - public::submit_candidacy(&Eve, 4); - public::set_approvals(&Eve, &vec![false, false, false, false, true], 0); + PublicPass::test(&Alice).submit_candidacy(0); + PublicPass::test(&Ferdie).set_approvals(vec![true], 0); + PublicPass::test(&Bob).submit_candidacy(1); + PublicPass::test(&Bob).set_approvals(vec![false, true], 0); + PublicPass::test(&Charlie).submit_candidacy(2); + PublicPass::test(&Charlie).set_approvals(vec![false, false, true], 0); + PublicPass::test(&Dave).submit_candidacy(3); + PublicPass::test(&Dave).set_approvals(vec![false, false, false, true], 0); + PublicPass::test(&Eve).submit_candidacy(4); + PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0); internal::end_block(); with_env(|e| e.block_number = 6); - public::present_winner(&Dave, &Alice, 60, 0); - public::present_winner(&Dave, &Charlie, 21, 0); - public::present_winner(&Dave, &Dave, 31, 0); - public::present_winner(&Dave, &Eve, 41, 0); + PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); + PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); + PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); + PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); internal::end_block(); with_env(|e| e.block_number = 8); - public::set_approvals(&Ferdie, &vec![false, false, true, false], 1); - privileged::set_desired_seats(3); + PublicPass::test(&Ferdie).set_approvals(vec![false, false, true, false], 1); + PrivPass.set_desired_seats(3); internal::end_block(); with_env(|e| e.block_number = 10); - public::present_winner(&Dave, &Charlie, 81, 1); - public::present_winner(&Dave, &Dave, 31, 1); + PublicPass::test(&Dave).present_winner(Charlie.into(), 81, 1); + PublicPass::test(&Dave).present_winner(Dave.into(), 31, 1); internal::end_block(); assert!(!presentation_active()); diff --git a/demo/runtime/src/runtime/council_vote.rs b/demo/runtime/src/runtime/council_vote.rs index b40c79d79b486..19e3ddae20c70 100644 --- a/demo/runtime/src/runtime/council_vote.rs +++ b/demo/runtime/src/runtime/council_vote.rs @@ -20,9 +20,11 @@ use rstd::prelude::*; use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable}; use runtime_support::Hashable; use runtime_support::storage; -use demo_primitives::{Proposal, AccountId, Hash, BlockNumber}; +use demo_primitives::{AccountId, Hash, BlockNumber}; use runtime::{system, democracy, council}; -use runtime::staking::Balance; +use runtime::staking::{PublicPass, Balance}; +use runtime::system::PrivPass; +use dispatch::PrivCall as Proposal; type ProposalHash = [u8; 32]; @@ -119,12 +121,17 @@ fn take_proposal_if_expiring_at(n: BlockNumber) -> Option<(Proposal, ProposalHas } } -pub mod public { - use super::*; +impl_dispatch! { + pub mod public; + fn propose(proposal: Box) = 0; + fn vote(proposal: ProposalHash, approve: bool) = 1; + fn veto(proposal_hash: ProposalHash) = 2; +} - pub fn propose(signed: &AccountId, proposal: &Proposal) { +impl<'a> public::Dispatch for PublicPass<'a> { + fn propose(self, proposal: Box) { let expiry = system::block_number() + voting_period(); - assert!(will_still_be_councillor_at(signed, expiry)); + assert!(will_still_be_councillor_at(&self, expiry)); let proposal_hash = proposal.blake2_256(); @@ -135,65 +142,70 @@ pub mod public { proposals.sort_by_key(|&(expiry, _)| expiry); set_proposals(&proposals); - storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_OF), proposal); - storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS), &vec![*signed]); - storage::put(&(proposal_hash, *signed).to_keyed_vec(COUNCIL_VOTE_OF), &true); + storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_OF), &proposal); + storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS), &vec![*self]); + storage::put(&(proposal_hash, *self).to_keyed_vec(COUNCIL_VOTE_OF), &true); } - pub fn vote(signed: &AccountId, proposal: &ProposalHash, approve: bool) { - if vote_of(signed, proposal).is_none() { - let mut voters = proposal_voters(proposal); - voters.push(*signed); + fn vote(self, proposal: ProposalHash, approve: bool) { + if vote_of(&self, &proposal).is_none() { + let mut voters = proposal_voters(&proposal); + voters.push(*self); storage::put(&proposal.to_keyed_vec(PROPOSAL_VOTERS), &voters); } - storage::put(&(*proposal, *signed).to_keyed_vec(COUNCIL_VOTE_OF), &approve); + storage::put(&(proposal, *self).to_keyed_vec(COUNCIL_VOTE_OF), &approve); } - pub fn veto(signed: &AccountId, proposal_hash: &ProposalHash) { - assert!(is_councillor(signed), "only councillors may veto council proposals"); + fn veto(self, proposal_hash: ProposalHash) { + assert!(is_councillor(&self), "only councillors may veto council proposals"); assert!(storage::exists(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS)), "proposal must exist to be vetoed"); let mut existing_vetoers = veto_of(&proposal_hash) .map(|pair| pair.1) .unwrap_or_else(Vec::new); - let insert_position = existing_vetoers.binary_search(signed) + let insert_position = existing_vetoers.binary_search(&self) .expect_err("a councillor may not veto a proposal twice"); - existing_vetoers.insert(insert_position, *signed); + existing_vetoers.insert(insert_position, *self); set_veto_of(&proposal_hash, system::block_number() + cooloff_period(), existing_vetoers); - set_proposals(&proposals().into_iter().filter(|&(_, h)| h != *proposal_hash).collect::>()); + set_proposals(&proposals().into_iter().filter(|&(_, h)| h != proposal_hash).collect::>()); storage::kill(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS)); storage::kill(&proposal_hash.to_keyed_vec(PROPOSAL_OF)); for (c, _) in council::active_council() { - storage::kill(&(*proposal_hash, c).to_keyed_vec(COUNCIL_VOTE_OF)); + storage::kill(&(proposal_hash, c).to_keyed_vec(COUNCIL_VOTE_OF)); } } } -pub mod privileged { - use super::*; +impl_dispatch! { + pub mod privileged; + fn set_cooloff_period(blocks: BlockNumber) = 0; + fn set_voting_period(blocks: BlockNumber) = 1; +} - pub fn set_cooloff_period(blocks: BlockNumber) { +impl privileged::Dispatch for PrivPass { + fn set_cooloff_period(self, blocks: BlockNumber) { storage::put(COOLOFF_PERIOD, &blocks); } - pub fn set_voting_period(blocks: BlockNumber) { + fn set_voting_period(self, blocks: BlockNumber) { storage::put(VOTING_PERIOD, &blocks); } } pub mod internal { use super::*; - use runtime::democracy::privileged::start_referendum; - use demo_primitives::VoteThreshold; + use runtime::democracy::privileged::Dispatch; + use runtime::democracy::VoteThreshold; + use runtime::democracy::internal::start_referendum; pub fn end_block(now: BlockNumber) { while let Some((proposal, proposal_hash)) = take_proposal_if_expiring_at(now) { let tally = take_tally(&proposal_hash); println!("Executing proposal {:?} {:?}", proposal, tally); - if let &Proposal::DemocracyCancelReferendum(ref_index) = &proposal { + if let &Proposal::Democracy(democracy::privileged::Call::cancel_referendum(ref_index)) = &proposal { if let (_, 0, 0) = tally { - democracy::privileged::cancel_referendum(ref_index); + democracy::privileged::Call::cancel_referendum(ref_index).dispatch(PrivPass); } } else { if tally.0 > tally.1 + tally.2 { @@ -240,7 +252,8 @@ mod tests { use codec::{KeyedVec, Joiner}; use keyring::Keyring::{Alice, Bob, Charlie, Dave}; use environment::with_env; - use demo_primitives::{AccountId, Proposal, VoteThreshold}; + use demo_primitives::AccountId; + use runtime::democracy::VoteThreshold; use runtime::{staking, council, democracy}; fn new_test_ext() -> TestExternalities { @@ -267,11 +280,19 @@ mod tests { }); } + fn sessions_per_era_propsal(value: u64) -> Proposal { + Proposal::Staking(staking::privileged::Call::set_sessions_per_era(value)) + } + + fn bonding_duration_propsal(value: u64) -> Proposal { + Proposal::Staking(staking::privileged::Call::set_bonding_duration(value)) + } + #[test] fn referendum_cancellation_should_work_when_unanimous() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); + let proposal = bonding_duration_propsal(42); democracy::privileged::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index 227362818862f..beb184651de53 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -20,13 +20,46 @@ use rstd::prelude::*; use integer_sqrt::IntegerSquareRoot; use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable}; use runtime_support::storage; -use demo_primitives::{Proposal, AccountId, Hash, BlockNumber, VoteThreshold}; +use demo_primitives::{AccountId, Hash, BlockNumber}; +use dispatch::PrivCall as Proposal; use runtime::{staking, system, session}; -use runtime::staking::Balance; +use runtime::system::PrivPass; +use runtime::staking::{PublicPass, Balance}; pub type PropIndex = u32; pub type ReferendumIndex = u32; +#[derive(Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +pub enum VoteThreshold { + /// A supermajority of approvals is needed to pass this vote. + SuperMajorityApprove, + /// A supermajority of rejects is needed to fail this vote. + SuperMajorityAgainst, + /// A simple majority of approvals is needed to pass this vote. + SimpleMajority, +} + +impl Slicable for VoteThreshold { + fn decode(input: &mut I) -> Option { + u8::decode(input).and_then(|v| match v { + 0 => Some(VoteThreshold::SuperMajorityApprove), + 1 => Some(VoteThreshold::SuperMajorityAgainst), + 2 => Some(VoteThreshold::SimpleMajority), + _ => None, + }) + } + + fn using_encoded R>(&self, f: F) -> R { + match *self { + VoteThreshold::SuperMajorityApprove => 0u8, + VoteThreshold::SuperMajorityAgainst => 1u8, + VoteThreshold::SimpleMajority => 2u8, + }.using_encoded(f) + } +} +impl NonTrivialSlicable for VoteThreshold {} + trait Approved { /// Given `approve` votes for and `against` votes against from a total electorate size of /// `electorate` (`electorate - (approve + against)` are abstainers), then returns true if the @@ -151,72 +184,87 @@ pub fn next_free_ref_index() -> ReferendumIndex { storage::get_or_default(REFERENDUM_COUNT) } -pub mod public { - use super::*; +pub type BoxedProposal = Box; + +impl_dispatch! { + pub mod public; + fn propose(proposal: Box, value: Balance) = 0; + fn second(proposal: PropIndex) = 1; + fn vote(ref_index: ReferendumIndex, approve_proposal: bool) = 2; +} +impl<'a> public::Dispatch for PublicPass<'a> { /// Propose a sensitive action to be taken. - pub fn propose(signed: &AccountId, proposal: &Proposal, value: Balance) { + fn propose(self, proposal: Box, value: Balance) { assert!(value >= minimum_deposit()); - assert!(staking::internal::deduct_unbonded(signed, value)); + assert!(staking::internal::deduct_unbonded(&self, value)); let index: PropIndex = storage::get_or_default(PUBLIC_PROP_COUNT); storage::put(PUBLIC_PROP_COUNT, &(index + 1)); - storage::put(&index.to_keyed_vec(DEPOSIT_OF), &(value, vec![*signed])); + storage::put(&index.to_keyed_vec(DEPOSIT_OF), &(value, vec![*self])); let mut props = public_props(); - props.push((index, proposal.clone(), *signed)); + props.push((index, (*proposal).clone(), *self)); storage::put(PUBLIC_PROPS, &props); } /// Propose a sensitive action to be taken. - pub fn second(signed: &AccountId, proposal: PropIndex) { + fn second(self, proposal: PropIndex) { let key = proposal.to_keyed_vec(DEPOSIT_OF); let mut deposit: (Balance, Vec) = storage::get(&key).expect("can only second an existing proposal"); - assert!(staking::internal::deduct_unbonded(signed, deposit.0)); + assert!(staking::internal::deduct_unbonded(&self, deposit.0)); - deposit.1.push(*signed); + deposit.1.push(*self); storage::put(&key, &deposit); } /// Vote in a referendum. If `approve_proposal` is true, the vote is to enact the proposal; /// false would be a vote to keep the status quo.. - pub fn vote(signed: &AccountId, ref_index: ReferendumIndex, approve_proposal: bool) { + fn vote(self, ref_index: ReferendumIndex, approve_proposal: bool) { if !is_active_referendum(ref_index) { panic!("vote given for invalid referendum.") } - if staking::balance(signed) == 0 { + if staking::balance(&self) == 0 { panic!("transactor must have balance to signal approval."); } - let key = (*signed, ref_index).to_keyed_vec(VOTE_OF); + let key = (*self, ref_index).to_keyed_vec(VOTE_OF); if !storage::exists(&key) { let mut voters = voters_for(ref_index); - voters.push(signed.clone()); + voters.push(self.clone()); storage::put(&ref_index.to_keyed_vec(VOTERS_FOR), &voters); } storage::put(&key, &approve_proposal); } } -pub mod privileged { - use super::*; +impl_dispatch! { + pub mod privileged; + fn start_referendum(proposal: Box, vote_threshold: VoteThreshold) = 0; + fn cancel_referendum(ref_index: ReferendumIndex) = 1; +} - /// Can be called directly by the council. - pub fn start_referendum(proposal: Proposal, vote_threshold: VoteThreshold) { - inject_referendum(system::block_number() + voting_period(), proposal, vote_threshold); +impl privileged::Dispatch for PrivPass { + /// Start a referendum. + fn start_referendum(self, proposal: Box, vote_threshold: VoteThreshold) { + inject_referendum(system::block_number() + voting_period(), *proposal, vote_threshold); } /// Remove a referendum. - pub fn cancel_referendum(ref_index: ReferendumIndex) { + fn cancel_referendum(self, ref_index: ReferendumIndex) { clear_referendum(ref_index); } } pub mod internal { use super::*; - use demo_primitives::Proposal; use dispatch; + /// Can be called directly by the council. + pub fn start_referendum(proposal: Proposal, vote_threshold: VoteThreshold) { + inject_referendum(system::block_number() + voting_period(), proposal, vote_threshold); + } + /// Current era is ending; we should finish up any proposals. pub fn end_block(now: BlockNumber) { // pick out another public referendum if it's time. @@ -245,7 +293,7 @@ pub mod internal { let total_stake = staking::total_stake(); clear_referendum(index); if vote_threshold.approved(approve, against, total_stake) { - dispatch::proposal(proposal); + proposal.dispatch(PrivPass); } storage::put(NEXT_TALLY, &(index + 1)); } @@ -322,7 +370,11 @@ mod tests { use codec::{KeyedVec, Joiner}; use keyring::Keyring::*; use environment::with_env; - use demo_primitives::{AccountId, Proposal}; + use demo_primitives::AccountId; + use dispatch::PrivCall as Proposal; + use runtime::staking::PublicPass; + use super::public::Dispatch; + use super::privileged::Dispatch as PrivDispatch; use runtime::{staking, session, democracy}; fn new_test_ext() -> TestExternalities { @@ -343,13 +395,18 @@ mod tests { // TODO: test VoteThreshold + fn propose_sessions_per_era(who: &AccountId, value: u64, locked: Balance) { + PublicPass::test(who). + propose(Box::new(Proposal::Staking(staking::privileged::Call::set_sessions_per_era(value))), locked); + } + #[test] fn locked_for_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(2), 2u64); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(4), 4u64); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(3), 3u64); + propose_sessions_per_era(&Alice, 2, 2u64); + propose_sessions_per_era(&Alice, 4, 4u64); + propose_sessions_per_era(&Alice, 3, 3u64); assert_eq!(locked_for(0), Some(2)); assert_eq!(locked_for(1), Some(4)); assert_eq!(locked_for(2), Some(3)); @@ -360,12 +417,12 @@ mod tests { fn single_proposal_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(2), 1u64); + propose_sessions_per_era(&Alice, 2, 1u64); democracy::internal::end_block(system::block_number()); with_env(|e| e.block_number = 2); let r = 0; - public::vote(&Alice, r, true); + PublicPass::test(&Alice).vote(r, true); assert_eq!(next_free_ref_index(), 1); assert_eq!(voters_for(r), vec![Alice.to_raw_public()]); @@ -383,11 +440,11 @@ mod tests { fn deposit_for_proposals_should_be_taken() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(2), 5u64); - public::second(&Bob, 0); - public::second(&Eve, 0); - public::second(&Eve, 0); - public::second(&Eve, 0); + propose_sessions_per_era(&Alice, 2, 5u64); + PublicPass::test(&Bob).second(0); + PublicPass::test(&Eve).second(0); + PublicPass::test(&Eve).second(0); + PublicPass::test(&Eve).second(0); assert_eq!(staking::balance(&Alice), 5u64); assert_eq!(staking::balance(&Bob), 15u64); assert_eq!(staking::balance(&Eve), 35u64); @@ -398,11 +455,11 @@ mod tests { fn deposit_for_proposals_should_be_returned() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(2), 5u64); - public::second(&Bob, 0); - public::second(&Eve, 0); - public::second(&Eve, 0); - public::second(&Eve, 0); + propose_sessions_per_era(&Alice, 2, 5u64); + PublicPass::test(&Bob).second(0); + PublicPass::test(&Eve).second(0); + PublicPass::test(&Eve).second(0); + PublicPass::test(&Eve).second(0); democracy::internal::end_block(system::block_number()); assert_eq!(staking::balance(&Alice), 10u64); assert_eq!(staking::balance(&Bob), 20u64); @@ -415,7 +472,7 @@ mod tests { fn proposal_with_deposit_below_minimum_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(2), 0u64); + propose_sessions_per_era(&Alice, 2, 0u64); }); } @@ -424,7 +481,7 @@ mod tests { fn poor_proposer_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetSessionsPerEra(2), 11u64); + propose_sessions_per_era(&Alice, 2, 11u64); }); } @@ -433,46 +490,55 @@ mod tests { fn poor_seconder_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Bob, &Proposal::StakingSetSessionsPerEra(2), 11u64); - public::second(&Alice, 0); + propose_sessions_per_era(&Bob, 2, 11u64); + PublicPass::test(&Alice).second(0); }); } + fn propose_bonding_duration(who: &AccountId, value: u64, locked: Balance) { + PublicPass::test(who). + propose(Box::new(Proposal::Staking(staking::privileged::Call::set_bonding_duration(value))), locked); + } + #[test] fn runners_up_should_come_after() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 0); - public::propose(&Alice, &Proposal::StakingSetBondingDuration(2), 2u64); - public::propose(&Alice, &Proposal::StakingSetBondingDuration(4), 4u64); - public::propose(&Alice, &Proposal::StakingSetBondingDuration(3), 3u64); + propose_bonding_duration(&Alice, 2, 2u64); + propose_bonding_duration(&Alice, 4, 4u64); + propose_bonding_duration(&Alice, 3, 3u64); democracy::internal::end_block(system::block_number()); with_env(|e| e.block_number = 1); - public::vote(&Alice, 0, true); + PublicPass::test(&Alice).vote(0, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); assert_eq!(staking::bonding_duration(), 4u64); with_env(|e| e.block_number = 2); - public::vote(&Alice, 1, true); + PublicPass::test(&Alice).vote(1, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); assert_eq!(staking::bonding_duration(), 3u64); with_env(|e| e.block_number = 3); - public::vote(&Alice, 2, true); + PublicPass::test(&Alice).vote(2, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); assert_eq!(staking::bonding_duration(), 2u64); }); } + fn sessions_per_era_propsal(value: u64) -> Proposal { + Proposal::Staking(staking::privileged::Call::set_sessions_per_era(value)) + } + #[test] fn simple_passing_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove); - public::vote(&Alice, r, true); + let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); + PublicPass::test(&Alice).vote(r, true); assert_eq!(voters_for(r), vec![Alice.to_raw_public()]); assert_eq!(vote_of(&Alice, r), Some(true)); @@ -489,9 +555,9 @@ mod tests { fn cancel_referendum_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove); - public::vote(&Alice, r, true); - privileged::cancel_referendum(r); + let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); + PublicPass::test(&Alice).vote(r, true); + PrivPass.cancel_referendum(r); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); @@ -504,8 +570,8 @@ mod tests { fn simple_failing_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove); - public::vote(&Alice, r, false); + let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); + PublicPass::test(&Alice).vote(r, false); assert_eq!(voters_for(r), vec![Alice.to_raw_public()]); assert_eq!(vote_of(&Alice, r), Some(false)); @@ -522,13 +588,13 @@ mod tests { fn controversial_voting_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove); - public::vote(&Alice, r, true); - public::vote(&Bob, r, false); - public::vote(&Charlie, r, false); - public::vote(&Dave, r, true); - public::vote(&Eve, r, false); - public::vote(&Ferdie, r, true); + let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); + PublicPass::test(&Alice).vote(r, true); + PublicPass::test(&Bob).vote(r, false); + PublicPass::test(&Charlie).vote(r, false); + PublicPass::test(&Dave).vote(r, true); + PublicPass::test(&Eve).vote(r, false); + PublicPass::test(&Ferdie).vote(r, true); assert_eq!(tally(r), (110, 100)); @@ -543,9 +609,9 @@ mod tests { fn controversial_low_turnout_voting_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove); - public::vote(&Eve, r, false); - public::vote(&Ferdie, r, true); + let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); + PublicPass::test(&Eve).vote(r, false); + PublicPass::test(&Ferdie).vote(r, true); assert_eq!(tally(r), (60, 50)); @@ -563,10 +629,10 @@ mod tests { assert_eq!(staking::total_stake(), 210u64); with_env(|e| e.block_number = 1); - let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove); - public::vote(&Dave, r, true); - public::vote(&Eve, r, false); - public::vote(&Ferdie, r, true); + let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); + PublicPass::test(&Dave).vote(r, true); + PublicPass::test(&Eve).vote(r, false); + PublicPass::test(&Ferdie).vote(r, true); assert_eq!(tally(r), (100, 50)); diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index 6a30a743142a3..8fa92dd76ec16 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -17,11 +17,11 @@ //! Staking manager: Handles balances and periodically determines the best set of validators. use rstd::prelude::*; -use rstd::cmp; +use rstd::{ops, cmp}; use rstd::cell::RefCell; use rstd::collections::btree_map::{BTreeMap, Entry}; use runtime_io::{print, blake2_256}; -use codec::KeyedVec; +use codec::{Slicable, Input, KeyedVec}; use runtime_support::{storage, StorageVec}; use demo_primitives::{BlockNumber, AccountId}; use runtime::{system, session}; @@ -41,6 +41,7 @@ pub const LAST_ERA_LENGTH_CHANGE: &[u8] = b"sta:lec"; pub const TOTAL_STAKE: &[u8] = b"sta:tot"; pub const INTENTION_AT: &[u8] = b"sta:wil:"; pub const INTENTION_COUNT: &[u8] = b"sta:wil:len"; +pub const TRANSACTION_FEE: &[u8] = b"sta:fee"; pub const BALANCE_OF: &[u8] = b"sta:bal:"; pub const RESERVED_BALANCE_OF: &[u8] = b"sta:lbo:"; @@ -54,6 +55,11 @@ impl StorageVec for IntentionStorageVec { const PREFIX: &'static[u8] = INTENTION_AT; } +/// The fee to be paid for making a transaction. +pub fn transaction_fee() -> Balance { + storage::get(TRANSACTION_FEE).expect("All basic parameters should be defined") +} + /// The length of the bonding duration in eras. pub fn bonding_duration() -> BlockNumber { storage::get_or_default(BONDING_DURATION) @@ -133,17 +139,131 @@ pub fn total_stake() -> Balance { storage::get_or(TOTAL_STAKE, 0) } +pub struct PublicPass<'a> (&'a AccountId); + +const NOBODY: AccountId = [0u8; 32]; + +impl<'a> PublicPass<'a> { + pub fn new(transactor: &AccountId) -> PublicPass { + let b = free_balance(&transactor); + let transaction_fee = transaction_fee(); + assert!(b >= transaction_fee, "attempt to transact without enough funds to pay fee"); + internal::set_free_balance(&transactor, b - transaction_fee); + PublicPass(transactor) + } + + #[cfg(test)] + pub fn test(signed: &AccountId) -> PublicPass { + PublicPass(signed) + } + + #[cfg(test)] + pub fn nobody() -> PublicPass<'static> { + PublicPass(&NOBODY) + } + + /// Create a smart-contract account. + pub fn create(self, code: &[u8], value: Balance) { + // commit anything that made it this far to storage + if let Some(commit) = private::effect_create(self.0, code, value, private::DirectExt) { + private::commit_state(commit); + } + } +} + +impl<'a> ops::Deref for PublicPass<'a> { + type Target = AccountId; + fn deref(&self) -> &AccountId { + self.0 + } +} + +impl_dispatch! { + pub mod public; + fn transfer(dest: AccountId, value: Balance) = 0; + fn stake() = 1; + fn unstake() = 2; +} + +impl<'a> public::Dispatch for PublicPass<'a> { + /// Transfer some unlocked staking balance to another staker. + /// TODO: probably want to state gas-limit and gas-price. + fn transfer(self, dest: AccountId, value: Balance) { + // commit anything that made it this far to storage + if let Some(commit) = private::effect_transfer(&self, &dest, value, private::DirectExt) { + private::commit_state(commit); + } + } + + /// Declare the desire to stake for the transactor. + /// + /// Effects will be felt at the beginning of the next era. + fn stake(self) { + let mut intentions = IntentionStorageVec::items(); + // can't be in the list twice. + assert!(intentions.iter().find(|&t| *t == *self).is_none(), "Cannot stake if already staked."); + intentions.push(self.clone()); + IntentionStorageVec::set_items(&intentions); + storage::put(&self.to_keyed_vec(BONDAGE_OF), &u64::max_value()); + } + + /// Retract the desire to stake for the transactor. + /// + /// Effects will be felt at the beginning of the next era. + fn unstake(self) { + let mut intentions = IntentionStorageVec::items(); + if let Some(position) = intentions.iter().position(|&t| t == *self) { + intentions.swap_remove(position); + } else { + panic!("Cannot unstake if not already staked."); + } + IntentionStorageVec::set_items(&intentions); + storage::put(&self.to_keyed_vec(BONDAGE_OF), &(current_era() + bonding_duration())); + } +} + +impl_dispatch! { + pub mod privileged; + fn set_sessions_per_era(new: BlockNumber) = 0; + fn set_bonding_duration(new: BlockNumber) = 1; + fn set_validator_count(new: u32) = 2; + fn force_new_era() = 3; +} + +impl privileged::Dispatch for system::PrivPass { + /// Set the number of sessions in an era. + fn set_sessions_per_era(self, new: BlockNumber) { + storage::put(NEXT_SESSIONS_PER_ERA, &new); + } + + /// The length of the bonding duration in eras. + fn set_bonding_duration(self, new: BlockNumber) { + storage::put(BONDING_DURATION, &new); + } + + /// The length of a staking era in sessions. + fn set_validator_count(self, new: u32) { + storage::put(VALIDATOR_COUNT, &new); + } + + /// Force there to be a new era. This also forces a new session immediately after. + fn force_new_era(self) { + new_era(); + session::privileged::force_new_session(); + } +} + // Each identity's stake may be in one of three bondage states, given by an integer: // - n | n <= current_era(): inactive: free to be transferred. // - ~0: active: currently representing a validator. // - n | n > current_era(): deactivating: recently representing a validator and not yet // ready for transfer. -pub mod public { +mod private { use super::*; #[derive(Default)] - struct ChangeEntry { + pub struct ChangeEntry { balance: Option, code: Option>, storage: BTreeMap, Option>>, @@ -157,7 +277,7 @@ pub mod public { type State = BTreeMap; - trait Externalities { + pub trait Externalities { fn get_storage(&self, account: &AccountId, location: &[u8]) -> Option>; fn get_code(&self, account: &AccountId) -> Vec; fn get_balance(&self, account: &AccountId) -> Balance; @@ -173,7 +293,7 @@ pub mod public { do_get_balance: F5, } - struct DirectExt; + pub struct DirectExt; impl Externalities for DirectExt { fn get_storage(&self, account: &AccountId, location: &[u8]) -> Option> { let mut v = account.to_keyed_vec(STORAGE_OF); @@ -204,7 +324,7 @@ pub mod public { } } - fn commit_state(s: State) { + pub fn commit_state(s: State) { for (address, changed) in s.into_iter() { if let Some(balance) = changed.balance { storage::put(&address.to_keyed_vec(BALANCE_OF), &balance); @@ -245,15 +365,7 @@ pub mod public { } } - /// Create a smart-contract account. - pub fn create(transactor: &AccountId, code: &[u8], value: Balance) { - // commit anything that made it this far to storage - if let Some(commit) = effect_create(transactor, code, value, DirectExt) { - commit_state(commit); - } - } - - fn effect_create( + pub fn effect_create( transactor: &AccountId, code: &[u8], value: Balance, @@ -282,16 +394,7 @@ pub mod public { Some(local) } - /// Transfer some unlocked staking balance to another staker. - /// TODO: probably want to state gas-limit and gas-price. - pub fn transfer(transactor: &AccountId, dest: &AccountId, value: Balance) { - // commit anything that made it this far to storage - if let Some(commit) = effect_transfer(transactor, dest, value, DirectExt) { - commit_state(commit); - } - } - - fn effect_transfer( + pub fn effect_transfer( transactor: &AccountId, dest: &AccountId, value: Balance, @@ -362,57 +465,6 @@ pub mod public { None } } - - /// Declare the desire to stake for the transactor. - /// - /// Effects will be felt at the beginning of the next era. - pub fn stake(transactor: &AccountId) { - let mut intentions = IntentionStorageVec::items(); - // can't be in the list twice. - assert!(intentions.iter().find(|t| *t == transactor).is_none(), "Cannot stake if already staked."); - intentions.push(transactor.clone()); - IntentionStorageVec::set_items(&intentions); - storage::put(&transactor.to_keyed_vec(BONDAGE_OF), &u64::max_value()); - } - - /// Retract the desire to stake for the transactor. - /// - /// Effects will be felt at the beginning of the next era. - pub fn unstake(transactor: &AccountId) { - let mut intentions = IntentionStorageVec::items(); - if let Some(position) = intentions.iter().position(|t| t == transactor) { - intentions.swap_remove(position); - } else { - panic!("Cannot unstake if not already staked."); - } - IntentionStorageVec::set_items(&intentions); - storage::put(&transactor.to_keyed_vec(BONDAGE_OF), &(current_era() + bonding_duration())); - } -} - -pub mod privileged { - use super::*; - - /// Set the number of sessions in an era. - pub fn set_sessions_per_era(new: BlockNumber) { - storage::put(NEXT_SESSIONS_PER_ERA, &new); - } - - /// The length of the bonding duration in eras. - pub fn set_bonding_duration(new: BlockNumber) { - storage::put(BONDING_DURATION, &new); - } - - /// The length of a staking era in sessions. - pub fn set_validator_count(new: u32) { - storage::put(VALIDATOR_COUNT, &new); - } - - /// Force there to be a new era. This also forces a new session immediately after. - pub fn force_new_era() { - new_era(); - session::privileged::force_new_session(); - } } pub mod internal { @@ -540,6 +592,8 @@ pub mod testing { use codec::{Joiner, KeyedVec}; use keyring::Keyring::*; use runtime::session; + use super::public::{Call, Dispatch}; + use super::privileged::{Dispatch as PrivDispatch, Call as PrivCall}; pub fn externalities(session_length: u64, sessions_per_era: u64, current_era: u64) -> TestExternalities { let extras: TestExternalities = map![ @@ -560,7 +614,6 @@ pub mod testing { mod tests { use super::*; use super::internal::*; - use super::public::*; use super::privileged::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; @@ -569,6 +622,9 @@ mod tests { use environment::with_env; use demo_primitives::AccountId; use runtime::{staking, session}; + use runtime::system::PrivPass; + use runtime::staking::public::{Call, Dispatch}; + use runtime::staking::privileged::{Call as PCall, Dispatch as PDispatch}; #[test] fn staking_should_work() { @@ -595,9 +651,9 @@ mod tests { // Block 1: Add three validators. No obvious change. with_env(|e| e.block_number = 1); - stake(&Alice); - stake(&Bob); - stake(&Dave); + public::Call::stake().dispatch(PublicPass::new(&Alice)); + PublicPass::new(&Bob).stake(); + PublicPass::new(&Dave).stake(); check_new_era(); assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); @@ -608,8 +664,8 @@ mod tests { // Block 3: Unstake highest, introduce another staker. No change yet. with_env(|e| e.block_number = 3); - stake(&Charlie); - unstake(&Dave); + PublicPass::new(&Charlie).stake(); + PublicPass::new(&Dave).unstake(); check_new_era(); // Block 4: New era - validators change. @@ -619,7 +675,7 @@ mod tests { // Block 5: Transfer stake from highest to lowest. No change yet. with_env(|e| e.block_number = 5); - transfer(&Dave, &Alice, 40); + PublicPass::new(&Dave).transfer(Alice.to_raw_public(), 40); check_new_era(); // Block 6: Lowest now validator. @@ -629,7 +685,7 @@ mod tests { // Block 7: Unstake three. No change yet. with_env(|e| e.block_number = 7); - unstake(&Charlie); + PublicPass::new(&Charlie).unstake(); check_new_era(); assert_eq!(session::validators(), vec![Alice.to_raw_public(), Charlie.into()]); @@ -668,7 +724,7 @@ mod tests { // Block 3: Schedule an era length change; no visible changes. with_env(|e| e.block_number = 3); - set_sessions_per_era(3); + PrivPass.set_sessions_per_era(3); check_new_era(); assert_eq!(sessions_per_era(), 2u64); assert_eq!(last_era_length_change(), 0u64); @@ -721,7 +777,7 @@ mod tests { fn staking_balance_transfer_works() { with_externalities(&mut TestExternalities::default(), || { set_free_balance(&Alice, 111); - transfer(&Alice, &Bob, 69); + PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); assert_eq!(balance(&Alice), 42); assert_eq!(balance(&Bob), 69); }); @@ -732,8 +788,8 @@ mod tests { fn staking_balance_transfer_when_bonded_panics() { with_externalities(&mut TestExternalities::default(), || { set_free_balance(&Alice, 111); - stake(&Alice); - transfer(&Alice, &Bob, 69); + PublicPass::new(&Alice).stake(); + PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); }); } @@ -760,7 +816,7 @@ mod tests { with_externalities(&mut TestExternalities::default(), || { set_free_balance(&Alice, 111); reserve_balance(&Alice, 69); - transfer(&Alice, &Bob, 69); + PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); }); } diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 4add4dd146403..149a0a89807ee 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -23,8 +23,9 @@ use runtime_io::{print, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; use runtime_support::{Hashable, storage}; use environment::with_env; -use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Block, Header, - UncheckedTransaction, Function, Log}; +use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Header, Log}; +use block::Block; +use transaction::UncheckedTransaction; use runtime::{staking, session}; use dispatch; @@ -32,6 +33,7 @@ pub const NONCE_OF: &[u8] = b"sys:non:"; pub const BLOCK_HASH_AT: &[u8] = b"sys:old:"; pub const CODE: &[u8] = b"sys:cod"; + /// The current block number being processed. Set by `execute_block`. pub fn block_number() -> BlockNumber { with_env(|e| e.block_number) @@ -42,6 +44,8 @@ pub fn block_hash(number: BlockNumber) -> Hash { storage::get_or_default(&number.to_keyed_vec(BLOCK_HASH_AT)) } +pub struct PrivPass; + pub mod privileged { use super::*; @@ -137,16 +141,19 @@ fn execute_transaction(utx: UncheckedTransaction) { Err(_) => panic!("All transactions should be properly signed"), }; - // check nonce - let nonce_key = tx.signed.to_keyed_vec(NONCE_OF); - let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0); - assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); + { + // check nonce + let nonce_key = tx.signed.to_keyed_vec(NONCE_OF); + let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0); + assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); - // increment nonce in storage - storage::put(&nonce_key, &(expected_nonce + 1)); + // increment nonce in storage + storage::put(&nonce_key, &(expected_nonce + 1)); + } // decode parameters and dispatch - dispatch::function(&tx.function, &tx.signed); + let tx = tx.drain().transaction; + tx.function.dispatch(staking::PublicPass::new(&tx.signed)); } fn initial_checks(block: &Block) { @@ -226,8 +233,11 @@ mod tests { use keyring::Keyring::*; use environment::with_env; use primitives::hexdisplay::HexDisplay; - use demo_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function}; + use demo_primitives::{Header, Digest}; + use transaction::{UncheckedTransaction, Transaction}; use runtime::staking; + use dispatch::public::Call as PubCall; + use runtime::staking::public::Call as StakingCall; #[test] fn staking_balance_transfer_dispatch_works() { @@ -239,7 +249,7 @@ mod tests { transaction: Transaction { signed: One.into(), nonce: 0, - function: Function::StakingTransfer(Two.into(), 69), + function: PubCall::Staking(StakingCall::transfer(Two.into(), 69)), }, signature: hex!("5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05").into(), }; diff --git a/demo/runtime/src/runtime/timestamp.rs b/demo/runtime/src/runtime/timestamp.rs index 52b6cbe2d7d18..ff2c18b9bd4ba 100644 --- a/demo/runtime/src/runtime/timestamp.rs +++ b/demo/runtime/src/runtime/timestamp.rs @@ -17,6 +17,7 @@ //! Timestamp manager: just handles the current timestamp. use runtime_support::storage; +use runtime::staking::PublicPass; pub type Timestamp = u64; @@ -27,11 +28,14 @@ pub fn get() -> Timestamp { storage::get_or_default(CURRENT_TIMESTAMP) } -pub mod public { - use super::*; +impl_dispatch! { + pub mod public; + fn set(now: Timestamp) = 0; +} +impl<'a> public::Dispatch for PublicPass<'a> { /// Set the current time. - pub fn set(now: Timestamp) { + fn set(self, now: Timestamp) { storage::put(CURRENT_TIMESTAMP, &now); } } @@ -44,6 +48,8 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use runtime::timestamp; use codec::{Joiner, KeyedVec}; + use demo_primitives::AccountId; + use runtime::staking::PublicPass; #[test] fn timestamp_works() { @@ -53,7 +59,7 @@ mod tests { with_externalities(&mut t, || { assert_eq!(get(), 42); - set(69); + PublicPass::nobody().set(69); assert_eq!(get(), 69); }); } diff --git a/demo/runtime/src/transaction.rs b/demo/runtime/src/transaction.rs new file mode 100644 index 0000000000000..06b95148c805c --- /dev/null +++ b/demo/runtime/src/transaction.rs @@ -0,0 +1,190 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate Demo. + +// Substrate Demo 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. + +// Substrate Demo 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 Substrate Demo. If not, see . + +//! Transaction type. + +use rstd::vec::Vec; +use rstd::ops; +use codec::{Input, Slicable, NonTrivialSlicable}; +use demo_primitives::{AccountId, TxOrder, SessionKey, Signature}; +use dispatch::PubCall; + +#[cfg(feature = "std")] +use std::fmt; + +use block::Number as BlockNumber; + +/// A vetted and verified transaction from the external world. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +pub struct Transaction { + /// Who signed it (note this is not a signature). + pub signed: AccountId, + /// The number of transactions have come before from the same signer. + pub nonce: TxOrder, + /// The function that should be called. + pub function: PubCall, +} + +impl Slicable for Transaction { + fn decode(input: &mut I) -> Option { + Some(Transaction { + signed: try_opt!(Slicable::decode(input)), + nonce: try_opt!(Slicable::decode(input)), + function: try_opt!(Slicable::decode(input)), + }) + } + + fn encode(&self) -> Vec { + let mut v = Vec::new(); + + self.signed.using_encoded(|s| v.extend(s)); + self.nonce.using_encoded(|s| v.extend(s)); + self.function.using_encoded(|s| v.extend(s)); + + v + } +} + +impl ::codec::NonTrivialSlicable for Transaction {} + +/// A transactions right from the external world. Unchecked. +#[derive(Eq, Clone)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct UncheckedTransaction { + /// The actual transaction information. + pub transaction: Transaction, + /// The signature; should be an Ed25519 signature applied to the serialised `transaction` field. + pub signature: Signature, +} + +impl Slicable for UncheckedTransaction { + fn decode(input: &mut I) -> Option { + // This is a little more complicated than usual since the binary format must be compatible + // with substrate's generic `Vec` type. Basically this just means accepting that there + // will be a prefix of u32, which has the total number of bytes following (we don't need + // to use this). + let _length_do_not_remove_me_see_above: u32 = try_opt!(Slicable::decode(input)); + + Some(UncheckedTransaction { + transaction: try_opt!(Slicable::decode(input)), + signature: try_opt!(Slicable::decode(input)), + }) + } + + fn encode(&self) -> Vec { + let mut v = Vec::new(); + + // need to prefix with the total length as u32 to ensure it's binary comptible with + // Vec. we'll make room for it here, then overwrite once we know the length. + v.extend(&[0u8; 4]); + + self.transaction.signed.using_encoded(|s| v.extend(s)); + self.transaction.nonce.using_encoded(|s| v.extend(s)); + self.transaction.function.using_encoded(|s| v.extend(s)); + self.signature.using_encoded(|s| v.extend(s)); + + let length = (v.len() - 4) as u32; + length.using_encoded(|s| v[0..4].copy_from_slice(s)); + + v + } +} + +impl ::codec::NonTrivialSlicable for UncheckedTransaction {} + +impl PartialEq for UncheckedTransaction { + fn eq(&self, other: &Self) -> bool { + self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction + } +} + +#[cfg(feature = "std")] +impl fmt::Debug for UncheckedTransaction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "UncheckedTransaction({:?})", self.transaction) + } +} + +/// A type-safe indicator that a transaction has been checked. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct CheckedTransaction(UncheckedTransaction); + +impl CheckedTransaction { + /// Get a reference to the checked signature. + pub fn signature(&self) -> &Signature { + &self.0.signature + } + + /// Get the inner object. + pub fn drain(self) -> UncheckedTransaction { + self.0 + } +} + +impl ops::Deref for CheckedTransaction { + type Target = Transaction; + + fn deref(&self) -> &Transaction { + &self.0.transaction + } +} + +/// Check the signature on a transaction. +/// +/// On failure, return the transaction back. +pub fn check(tx: UncheckedTransaction) -> Result { + let msg = ::codec::Slicable::encode(&tx.transaction); + if ::runtime_io::ed25519_verify(&tx.signature.0, &msg, &tx.transaction.signed) { + Ok(CheckedTransaction(tx)) + } else { + Err(tx) + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use primitives; + use codec::Slicable; + use primitives::hexdisplay::HexDisplay; + use dispatch::public::Call; + use runtime::timestamp::public::Call as TimestampCall; + + #[test] + fn serialize_unchecked() { + let tx = UncheckedTransaction { + transaction: Transaction { + signed: [1; 32], + nonce: 999u64, + function: Call::Timestamp(TimestampCall::set(135135)), + }, + signature: primitives::hash::H512([0; 64]), + }; + // 71000000 + // 0101010101010101010101010101010101010101010101010101010101010101 + // e703000000000000 + // 00 + // df0f0200 + // 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + let v = Slicable::encode(&tx); + println!("{}", HexDisplay::from(&v)); + assert_eq!(UncheckedTransaction::decode(&mut &v[..]).unwrap(), tx); + } +} diff --git a/substrate/codec/src/slicable.rs b/substrate/codec/src/slicable.rs index eb2b01db52fc8..e473c0bf5e18c 100644 --- a/substrate/codec/src/slicable.rs +++ b/substrate/codec/src/slicable.rs @@ -19,7 +19,6 @@ use rstd::{mem, slice}; use rstd::vec::Vec; use super::joiner::Joiner; -use super::endiansensitive::EndianSensitive; /// Trait that allows reading of data into a slice. pub trait Input { @@ -56,39 +55,6 @@ pub trait Slicable: Sized { // TODO: under specialization, remove this and simply specialize in place serializable types. pub trait NonTrivialSlicable: Slicable {} -impl Slicable for T { - fn decode(input: &mut I) -> Option { - let size = mem::size_of::(); - assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type."); - let mut val: T = unsafe { mem::zeroed() }; - - unsafe { - let raw: &mut [u8] = slice::from_raw_parts_mut( - &mut val as *mut T as *mut u8, - size - ); - if input.read(raw) != size { return None } - } - Some(val.from_le()) - } - - fn using_encoded R>(&self, f: F) -> R { - self.as_le_then(|le| { - let size = mem::size_of::(); - let value_slice = unsafe { - let ptr = le as *const _ as *const u8; - if size != 0 { - slice::from_raw_parts(ptr, size) - } else { - &[] - } - }; - - f(value_slice) - }) - } -} - impl Slicable for Option { fn decode(input: &mut I) -> Option { u8::decode(input).and_then(|v| match v { @@ -109,6 +75,16 @@ impl Slicable for Option { } impl NonTrivialSlicable for Option {} +impl Slicable for Box { + fn decode(input: &mut I) -> Option { + Some(Box::new(T::decode(input)?)) + } + + fn using_encoded R>(&self, f: F) -> R { + (*self).using_encoded(f) + } +} + impl Slicable for Vec { fn decode(input: &mut I) -> Option { u32::decode(input).and_then(move |len| { @@ -173,7 +149,7 @@ macro_rules! impl_vec_simple_array { ($($size:expr),*) => { $( impl Slicable for Vec<[T; $size]> - where [T; $size]: EndianSensitive + where [T; $size]: EndianSensitive + Slicable { fn decode(input: &mut I) -> Option { u32::decode(input).and_then(move |len| { @@ -325,6 +301,108 @@ mod inner_tuple_impl { tuple_impl!(A, B, C, D, E, F, G, H, I, J, K,); } +/// Trait to allow conversion to a know endian representation when sensitive. +/// Types implementing this trait must have a size > 0. +// note: the copy bound and static lifetimes are necessary for safety of `Slicable` blanket +// implementation. +trait EndianSensitive: Copy + 'static { + fn to_le(self) -> Self { self } + fn to_be(self) -> Self { self } + fn from_le(self) -> Self { self } + fn from_be(self) -> Self { self } + fn as_be_then T>(&self, f: F) -> T { f(&self) } + fn as_le_then T>(&self, f: F) -> T { f(&self) } +} + +macro_rules! impl_endians { + ( $( $t:ty ),* ) => { $( + impl EndianSensitive for $t { + fn to_le(self) -> Self { <$t>::to_le(self) } + fn to_be(self) -> Self { <$t>::to_be(self) } + fn from_le(self) -> Self { <$t>::from_le(self) } + fn from_be(self) -> Self { <$t>::from_be(self) } + fn as_be_then T>(&self, f: F) -> T { let d = self.to_be(); f(&d) } + fn as_le_then T>(&self, f: F) -> T { let d = self.to_le(); f(&d) } + } + + impl Slicable for $t { + fn decode(input: &mut I) -> Option { + let size = mem::size_of::<$t>(); + assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type."); + let mut val: $t = unsafe { mem::zeroed() }; + + unsafe { + let raw: &mut [u8] = slice::from_raw_parts_mut( + &mut val as *mut $t as *mut u8, + size + ); + if input.read(raw) != size { return None } + } + Some(val.from_le()) + } + + fn using_encoded R>(&self, f: F) -> R { + self.as_le_then(|le| { + let size = mem::size_of::<$t>(); + let value_slice = unsafe { + let ptr = le as *const _ as *const u8; + if size != 0 { + slice::from_raw_parts(ptr, size) + } else { + &[] + } + }; + + f(value_slice) + }) + } + } + )* } +} +macro_rules! impl_non_endians { + ( $( $t:ty ),* ) => { $( + impl EndianSensitive for $t {} + + impl Slicable for $t { + fn decode(input: &mut I) -> Option { + let size = mem::size_of::<$t>(); + assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type."); + let mut val: $t = unsafe { mem::zeroed() }; + + unsafe { + let raw: &mut [u8] = slice::from_raw_parts_mut( + &mut val as *mut $t as *mut u8, + size + ); + if input.read(raw) != size { return None } + } + Some(val.from_le()) + } + + fn using_encoded R>(&self, f: F) -> R { + self.as_le_then(|le| { + let size = mem::size_of::<$t>(); + let value_slice = unsafe { + let ptr = le as *const _ as *const u8; + if size != 0 { + slice::from_raw_parts(ptr, size) + } else { + &[] + } + }; + + f(value_slice) + }) + } + } + )* } +} + +impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); +impl_non_endians!(u8, i8, [u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], + [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], + [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128], bool); + #[cfg(test)] mod tests { From 82a178d4e1e8a0ee9ddfb4056b8b8f9f2bc58bfd Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 13 Mar 2018 12:46:06 +0100 Subject: [PATCH 02/29] Council vote tests. --- demo/runtime/src/runtime/council_vote.rs | 126 ++++++++++++----------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/demo/runtime/src/runtime/council_vote.rs b/demo/runtime/src/runtime/council_vote.rs index 19e3ddae20c70..4f96adbaa1157 100644 --- a/demo/runtime/src/runtime/council_vote.rs +++ b/demo/runtime/src/runtime/council_vote.rs @@ -255,6 +255,8 @@ mod tests { use demo_primitives::AccountId; use runtime::democracy::VoteThreshold; use runtime::{staking, council, democracy}; + use super::public::Dispatch; + use super::privileged::Dispatch as PrivDispatch; fn new_test_ext() -> TestExternalities { testing::externalities() @@ -280,27 +282,31 @@ mod tests { }); } - fn sessions_per_era_propsal(value: u64) -> Proposal { + fn sessions_per_era_proposal(value: u64) -> Proposal { Proposal::Staking(staking::privileged::Call::set_sessions_per_era(value)) } - fn bonding_duration_propsal(value: u64) -> Proposal { + fn bonding_duration_proposal(value: u64) -> Proposal { Proposal::Staking(staking::privileged::Call::set_bonding_duration(value)) } + fn cancel_referendum_proposal(id: u32) -> Proposal { + Proposal::Democracy(democracy::privileged::Call::cancel_referendum(id)) + } + #[test] fn referendum_cancellation_should_work_when_unanimous() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = bonding_duration_propsal(42); - democracy::privileged::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); + let proposal = bonding_duration_proposal(42); + democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); - let cancellation = Proposal::DemocracyCancelReferendum(0); + let cancellation = cancel_referendum_proposal(0); let hash = cancellation.blake2_256(); - public::propose(&Alice, &cancellation); - public::vote(&Bob, &hash, true); - public::vote(&Charlie, &hash, true); + PublicPass::new(&Alice).propose(Box::new(cancellation)); + PublicPass::new(&Bob).vote(hash, true); + PublicPass::new(&Charlie).vote(hash, true); assert_eq!(proposals(), vec![(2, hash)]); internal::end_block(1); @@ -315,14 +321,14 @@ mod tests { fn referendum_cancellation_should_fail_when_not_unanimous() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); - democracy::privileged::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); + let proposal = bonding_duration_proposal(42); + democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); - let cancellation = Proposal::DemocracyCancelReferendum(0); + let cancellation = cancel_referendum_proposal(0); let hash = cancellation.blake2_256(); - public::propose(&Alice, &cancellation); - public::vote(&Bob, &hash, true); - public::vote(&Charlie, &hash, false); + PublicPass::new(&Alice).propose(Box::new(cancellation)); + PublicPass::new(&Bob).vote(hash, true); + PublicPass::new(&Charlie).vote(hash, false); internal::end_block(1); with_env(|e| e.block_number = 2); @@ -335,13 +341,13 @@ mod tests { fn referendum_cancellation_should_fail_when_abstentions() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); - democracy::privileged::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); + let proposal = bonding_duration_proposal(42); + democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); - let cancellation = Proposal::DemocracyCancelReferendum(0); + let cancellation = cancel_referendum_proposal(0); let hash = cancellation.blake2_256(); - public::propose(&Alice, &cancellation); - public::vote(&Bob, &hash, true); + PublicPass::new(&Alice).propose(Box::new(cancellation)); + PublicPass::new(&Bob).vote(hash, true); internal::end_block(1); with_env(|e| e.block_number = 2); @@ -354,10 +360,10 @@ mod tests { fn veto_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); + let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); - public::propose(&Alice, &proposal); - public::veto(&Bob, &hash); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).veto(hash); assert_eq!(proposals().len(), 0); assert_eq!(democracy::active_referendums().len(), 0); }); @@ -368,14 +374,14 @@ mod tests { fn double_veto_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); + let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); - public::propose(&Alice, &proposal); - public::veto(&Bob, &hash); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).veto(hash); with_env(|e| e.block_number = 3); - public::propose(&Alice, &proposal); - public::veto(&Bob, &hash); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).veto(hash); }); } @@ -384,13 +390,13 @@ mod tests { fn retry_in_cooloff_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); + let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); - public::propose(&Alice, &proposal); - public::veto(&Bob, &hash); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).veto(hash); with_env(|e| e.block_number = 2); - public::propose(&Alice, &proposal); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); }); } @@ -398,21 +404,21 @@ mod tests { fn retry_after_cooloff_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); + let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); - public::propose(&Alice, &proposal); - public::veto(&Bob, &hash); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).veto(hash); with_env(|e| e.block_number = 3); - public::propose(&Alice, &proposal); - public::vote(&Bob, &hash, false); - public::vote(&Charlie, &hash, true); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).vote(hash, false); + PublicPass::new(&Charlie).vote(hash, true); internal::end_block(3); with_env(|e| e.block_number = 4); internal::end_block(4); assert_eq!(proposals().len(), 0); - assert_eq!(democracy::active_referendums(), vec![(0, 7, Proposal::StakingSetBondingDuration(42), VoteThreshold::SimpleMajority)]); + assert_eq!(democracy::active_referendums(), vec![(0, 7, bonding_duration_proposal(42), VoteThreshold::SimpleMajority)]); }); } @@ -420,14 +426,14 @@ mod tests { fn alternative_double_veto_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); + let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); - public::propose(&Alice, &proposal); - public::veto(&Bob, &hash); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).veto(hash); with_env(|e| e.block_number = 3); - public::propose(&Alice, &proposal); - public::veto(&Charlie, &hash); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Charlie).veto(hash); assert_eq!(proposals().len(), 0); assert_eq!(democracy::active_referendums().len(), 0); }); @@ -437,9 +443,9 @@ mod tests { fn simple_propose_should_work() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - let proposal = Proposal::StakingSetBondingDuration(42); + let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); - public::propose(&Alice, &proposal); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); assert_eq!(proposals().len(), 1); assert_eq!(proposal_voters(&hash), vec![Alice.to_raw_public()]); assert_eq!(vote_of(&Alice, &hash), Some(true)); @@ -451,8 +457,9 @@ mod tests { fn unvoted_proposal_should_expire_without_action() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetBondingDuration(42)); - assert_eq!(tally(&Proposal::StakingSetBondingDuration(42).blake2_256()), (1, 0, 2)); + let proposal = bonding_duration_proposal(42); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + assert_eq!(tally(&proposal.blake2_256()), (1, 0, 2)); internal::end_block(1); with_env(|e| e.block_number = 2); @@ -466,16 +473,17 @@ mod tests { fn unanimous_proposal_should_expire_with_biased_referendum() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetBondingDuration(42)); - public::vote(&Bob, &Proposal::StakingSetBondingDuration(42).blake2_256(), true); - public::vote(&Charlie, &Proposal::StakingSetBondingDuration(42).blake2_256(), true); - assert_eq!(tally(&Proposal::StakingSetBondingDuration(42).blake2_256()), (3, 0, 0)); + let proposal = bonding_duration_proposal(42); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).vote(proposal.blake2_256(), true); + PublicPass::new(&Charlie).vote(proposal.blake2_256(), true); + assert_eq!(tally(&proposal.blake2_256()), (3, 0, 0)); internal::end_block(1); with_env(|e| e.block_number = 2); internal::end_block(2); assert_eq!(proposals().len(), 0); - assert_eq!(democracy::active_referendums(), vec![(0, 5, Proposal::StakingSetBondingDuration(42), VoteThreshold::SuperMajorityAgainst)]); + assert_eq!(democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SuperMajorityAgainst)]); }); } @@ -483,16 +491,17 @@ mod tests { fn majority_proposal_should_expire_with_unbiased_referendum() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Alice, &Proposal::StakingSetBondingDuration(42)); - public::vote(&Bob, &Proposal::StakingSetBondingDuration(42).blake2_256(), true); - public::vote(&Charlie, &Proposal::StakingSetBondingDuration(42).blake2_256(), false); - assert_eq!(tally(&Proposal::StakingSetBondingDuration(42).blake2_256()), (2, 1, 0)); + let proposal = bonding_duration_proposal(42); + PublicPass::new(&Alice).propose(Box::new(proposal.clone())); + PublicPass::new(&Bob).vote(proposal.blake2_256(), true); + PublicPass::new(&Charlie).vote(proposal.blake2_256(), false); + assert_eq!(tally(&proposal.blake2_256()), (2, 1, 0)); internal::end_block(1); with_env(|e| e.block_number = 2); internal::end_block(2); assert_eq!(proposals().len(), 0); - assert_eq!(democracy::active_referendums(), vec![(0, 5, Proposal::StakingSetBondingDuration(42), VoteThreshold::SimpleMajority)]); + assert_eq!(democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SimpleMajority)]); }); } @@ -501,7 +510,8 @@ mod tests { fn propose_by_public_should_panic() { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); - public::propose(&Dave, &Proposal::StakingSetBondingDuration(42)); + let proposal = bonding_duration_proposal(42); + PublicPass::new(&Dave).propose(Box::new(proposal)); }); } } From 1d28d9a97af09661f9e5c09fbab3d2c2067c7a86 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 13 Mar 2018 13:05:46 +0100 Subject: [PATCH 03/29] Fix tests. --- demo/runtime/src/dispatch.rs | 9 ++-- demo/runtime/src/runtime/session.rs | 73 ++++++++++++++++------------- demo/runtime/src/runtime/staking.rs | 2 +- demo/runtime/src/runtime/system.rs | 11 +++-- 4 files changed, 55 insertions(+), 40 deletions(-) diff --git a/demo/runtime/src/dispatch.rs b/demo/runtime/src/dispatch.rs index 93be322e520f4..e5eecee1ca20d 100644 --- a/demo/runtime/src/dispatch.rs +++ b/demo/runtime/src/dispatch.rs @@ -224,8 +224,9 @@ impl_meta_dispatch! { pub mod public; path public; trait staking::PublicPass; - Staking(mod staking) = 0; - Timestamp(mod timestamp) = 1; + Session(mod session) = 1; + Staking(mod staking) = 2; + Timestamp(mod timestamp) = 3; Democracy(mod democracy) = 5; Council(mod council) = 6; CouncilVote(mod council) = 7; @@ -235,7 +236,9 @@ impl_meta_dispatch! { pub mod privileged; path privileged; trait system::PrivPass; - Staking(mod staking) = 0; + System(mod system) = 0; + Session(mod session) = 1; + Staking(mod staking) = 2; Democracy(mod democracy) = 5; Council(mod council) = 6; CouncilVote(mod council) = 7; diff --git a/demo/runtime/src/runtime/session.rs b/demo/runtime/src/runtime/session.rs index c5c5387dd9b57..705b08c5ae06a 100644 --- a/demo/runtime/src/runtime/session.rs +++ b/demo/runtime/src/runtime/session.rs @@ -22,6 +22,8 @@ use codec::KeyedVec; use runtime_support::{storage, StorageVec}; use demo_primitives::{AccountId, SessionKey, BlockNumber}; use runtime::{system, staking, consensus}; +use runtime::system::PrivPass; +use runtime::staking::PublicPass; pub const SESSION_LENGTH: &[u8] = b"ses:len"; pub const CURRENT_INDEX: &[u8] = b"ses:ind"; @@ -62,28 +64,35 @@ pub fn last_length_change() -> BlockNumber { storage::get_or(LAST_LENGTH_CHANGE, 0) } -pub mod public { - use super::*; +impl_dispatch! { + pub mod public; + fn set_key(key: SessionKey) = 0; +} +impl<'a> public::Dispatch for PublicPass<'a> { /// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next /// session. - pub fn set_key(validator: &AccountId, key: &SessionKey) { + fn set_key(self, key: SessionKey) { // set new value for next session - storage::put(&validator.to_keyed_vec(NEXT_KEY_FOR), key); + storage::put(&self.to_keyed_vec(NEXT_KEY_FOR), &key); } } -pub mod privileged { - use super::*; +impl_dispatch! { + pub mod privileged; + fn set_length(new: BlockNumber) = 0; + fn force_new_session() = 1; +} +impl privileged::Dispatch for PrivPass { /// Set a new era length. Won't kick in until the next era change (at current length). - pub fn set_length(new: BlockNumber) { + fn set_length(self, new: BlockNumber) { storage::put(NEXT_SESSION_LENGTH, &new); } /// Forces a new session. - pub fn force_new_session() { - rotate_session(); + fn force_new_session(self) { + internal::rotate_session(); } } @@ -110,27 +119,27 @@ pub mod internal { rotate_session(); } } -} -/// Move onto next session: register the new authority set. -fn rotate_session() { - // Increment current session index. - storage::put(CURRENT_INDEX, &(current_index() + 1)); + /// Move onto next session: register the new authority set. + pub fn rotate_session() { + // Increment current session index. + storage::put(CURRENT_INDEX, &(current_index() + 1)); - // Enact era length change. - if let Some(next_len) = storage::get::(NEXT_SESSION_LENGTH) { - storage::put(SESSION_LENGTH, &next_len); - storage::put(LAST_LENGTH_CHANGE, &system::block_number()); - storage::kill(NEXT_SESSION_LENGTH); - } - - // Update any changes in session keys. - validators().iter().enumerate().for_each(|(i, v)| { - let k = v.to_keyed_vec(NEXT_KEY_FOR); - if let Some(n) = storage::take(&k) { - consensus::internal::set_authority(i as u32, &n); + // Enact era length change. + if let Some(next_len) = storage::get::(NEXT_SESSION_LENGTH) { + storage::put(SESSION_LENGTH, &next_len); + storage::put(LAST_LENGTH_CHANGE, &system::block_number()); + storage::kill(NEXT_SESSION_LENGTH); } - }); + + // Update any changes in session keys. + validators().iter().enumerate().for_each(|(i, v)| { + let k = v.to_keyed_vec(NEXT_KEY_FOR); + if let Some(n) = storage::take(&k) { + consensus::internal::set_authority(i as u32, &n); + } + }); + } } #[cfg(any(feature = "std", test))] @@ -161,7 +170,7 @@ pub mod testing { mod tests { use super::*; use super::public::*; - use super::privileged::*; + use super::privileged::Dispatch as PrivDispatch; use super::internal::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; @@ -200,14 +209,14 @@ mod tests { with_externalities(&mut t, || { // Block 1: Change to length 3; no visible change. with_env(|e| e.block_number = 1); - set_length(3); + PrivPass.set_length(3); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 0); // Block 2: Length now changed to 3. Index incremented. with_env(|e| e.block_number = 2); - set_length(3); + PrivPass.set_length(3); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); @@ -220,7 +229,7 @@ mod tests { // Block 4: Change to length 2; no visible change. with_env(|e| e.block_number = 4); - set_length(2); + PrivPass.set_length(2); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); @@ -261,7 +270,7 @@ mod tests { // Block 3: Set new key for validator 2; no visible change. with_env(|e| e.block_number = 3); - set_key(&[20; 32], &[22; 32]); + PublicPass::test(&[20; 32]).set_key([22; 32]); assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); check_rotate_session(); diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index 8fa92dd76ec16..a3ff490e0e307 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -249,7 +249,7 @@ impl privileged::Dispatch for system::PrivPass { /// Force there to be a new era. This also forces a new session immediately after. fn force_new_era(self) { new_era(); - session::privileged::force_new_session(); + session::internal::rotate_session(); } } diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 149a0a89807ee..bbe321feaf704 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -46,12 +46,15 @@ pub fn block_hash(number: BlockNumber) -> Hash { pub struct PrivPass; -pub mod privileged { - use super::*; +impl_dispatch! { + pub mod privileged; + fn set_code(new: Vec) = 0; +} +impl privileged::Dispatch for PrivPass { /// Set the new code. - pub fn set_code(new: &[u8]) { - storage::unhashed::put_raw(b":code", new); + fn set_code(self, new: Vec) { + storage::unhashed::put_raw(b":code", &new); } } From 69c88c3ba97a4b1cd428ab0e48f59dcbbab98c2d Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 13 Mar 2018 13:06:16 +0100 Subject: [PATCH 04/29] whitespace. --- demo/runtime/src/runtime/council.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/demo/runtime/src/runtime/council.rs b/demo/runtime/src/runtime/council.rs index 777144676f426..67ef51d361be7 100644 --- a/demo/runtime/src/runtime/council.rs +++ b/demo/runtime/src/runtime/council.rs @@ -256,7 +256,6 @@ pub fn leaderboard() -> Option> { storage::get(LEADERBOARD) } - impl_dispatch! { pub mod public; fn set_approvals(votes: Vec, index: VoteIndex) = 0; From b12a708dcf525ffd55d27c456b3bc0496bfd74f9 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 14 Mar 2018 11:56:55 +0100 Subject: [PATCH 05/29] Fix demo runtime tests. --- demo/runtime/src/runtime/council_vote.rs | 2 +- demo/runtime/src/runtime/democracy.rs | 6 ++++++ demo/runtime/src/runtime/staking.rs | 6 ++++-- demo/runtime/src/runtime/system.rs | 11 +++++++---- substrate/codec/src/slicable.rs | 2 +- substrate/ed25519/src/lib.rs | 2 +- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/demo/runtime/src/runtime/council_vote.rs b/demo/runtime/src/runtime/council_vote.rs index 4f96adbaa1157..008214c5879ae 100644 --- a/demo/runtime/src/runtime/council_vote.rs +++ b/demo/runtime/src/runtime/council_vote.rs @@ -205,7 +205,7 @@ pub mod internal { println!("Executing proposal {:?} {:?}", proposal, tally); if let &Proposal::Democracy(democracy::privileged::Call::cancel_referendum(ref_index)) = &proposal { if let (_, 0, 0) = tally { - democracy::privileged::Call::cancel_referendum(ref_index).dispatch(PrivPass); + democracy::internal::cancel_referendum(ref_index); } } else { if tally.0 > tally.1 + tally.2 { diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index beb184651de53..f662e18121cbc 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -265,6 +265,11 @@ pub mod internal { inject_referendum(system::block_number() + voting_period(), proposal, vote_threshold); } + /// Remove a referendum. + pub fn cancel_referendum(ref_index: ReferendumIndex) { + clear_referendum(ref_index); + } + /// Current era is ending; we should finish up any proposals. pub fn end_block(now: BlockNumber) { // pick out another public referendum if it's time. @@ -355,6 +360,7 @@ pub mod testing { twox_128(staking::SESSIONS_PER_ERA).to_vec() => vec![].and(&1u64), twox_128(staking::VALIDATOR_COUNT).to_vec() => vec![].and(&3u64), twox_128(staking::CURRENT_ERA).to_vec() => vec![].and(&1u64), + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![].and(&1u64), twox_128(LAUNCH_PERIOD).to_vec() => vec![].and(&1u64), twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64), diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index a3ff490e0e307..1a3f5b0496ba8 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -603,6 +603,7 @@ pub mod testing { twox_128(&2u32.to_keyed_vec(INTENTION_AT)).to_vec() => Charlie.to_raw_public_vec(), twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&sessions_per_era), twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&3u64), + twox_128(TRANSACTION_FEE).to_vec() => vec![].and(&1u64), twox_128(CURRENT_ERA).to_vec() => vec![].and(¤t_era), twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ]; @@ -637,6 +638,7 @@ mod tests { twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&2u32), twox_128(BONDING_DURATION).to_vec() => vec![].and(&3u64), twox_128(TOTAL_STAKE).to_vec() => vec![].and(&100u64), + twox_128(TRANSACTION_FEE).to_vec() => vec![].and(&0u64), twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&10u64), twox_128(&Bob.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&20u64), twox_128(&Charlie.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&30u64), @@ -775,8 +777,8 @@ mod tests { #[test] fn staking_balance_transfer_works() { - with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + with_externalities(&mut testing::externalities(1, 3, 1), || { + set_free_balance(&Alice, 112); PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); assert_eq!(balance(&Alice), 42); assert_eq!(balance(&Bob), 69); diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index bbe321feaf704..33d48f72beca5 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -245,7 +245,8 @@ mod tests { #[test] fn staking_balance_transfer_dispatch_works() { let mut t: TestExternalities = map![ - twox_128(&One.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&One.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0] ]; let tx = UncheckedTransaction { @@ -254,12 +255,14 @@ mod tests { nonce: 0, function: PubCall::Staking(StakingCall::transfer(Two.into(), 69)), }, - signature: hex!("5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05").into(), + signature: hex!("3a682213cb10e8e375fe0817fe4d220a4622d910088809ed7fc8b4ea3871531dbadb22acfedd28a100a0b7bd2d274e0ff873655b13c88f4640b5569db3222706").into(), }; + println!("TX: {}", HexDisplay::from(&tx.transaction.encode())); + with_externalities(&mut t, || { internal::execute_transaction(tx, Header::from_block_number(1)); - assert_eq!(staking::balance(&One), 42); + assert_eq!(staking::balance(&One), 32); assert_eq!(staking::balance(&Two), 69); }); } @@ -275,7 +278,7 @@ mod tests { let h = Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("f4f6408fe3ce1d78d30bb7ed625b32f91e45b8b566023df309cfd93c6f4af9a4").into(), + state_root: hex!("584e0c1f4d4b96153591e3906d756762493dffeb5fa7159e7107014aec8d9c3d").into(), transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), digest: Digest { logs: vec![], }, }; diff --git a/substrate/codec/src/slicable.rs b/substrate/codec/src/slicable.rs index e473c0bf5e18c..490dca31a4882 100644 --- a/substrate/codec/src/slicable.rs +++ b/substrate/codec/src/slicable.rs @@ -81,7 +81,7 @@ impl Slicable for Box { } fn using_encoded R>(&self, f: F) -> R { - (*self).using_encoded(f) + self.as_ref().using_encoded(f) } } diff --git a/substrate/ed25519/src/lib.rs b/substrate/ed25519/src/lib.rs index f8a2ec0ce62a0..91f64b5f94262 100644 --- a/substrate/ed25519/src/lib.rs +++ b/substrate/ed25519/src/lib.rs @@ -221,7 +221,7 @@ mod test { let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); assert_eq!(public, Public::from_raw(hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee"))); - let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000002228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); let signature = pair.sign(&message[..]); println!("Correct signature: {}", HexDisplay::from(&signature.0)); assert!(verify_strong(&signature, &message[..], &public)); From 8e3cc5170a9ab9c00947cacd29cb2b943a44bfc0 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 14 Mar 2018 12:37:34 +0100 Subject: [PATCH 06/29] Fix up tests. --- demo/executor/src/lib.rs | 50 ++++++++++-------- .../release/polkadot_runtime.compact.wasm | Bin 92722 -> 134847 bytes .../release/polkadot_runtime.wasm | Bin 92771 -> 134896 bytes .../substrate_test_runtime.compact.wasm | Bin 32002 -> 32002 bytes .../release/substrate_test_runtime.wasm | Bin 32082 -> 32082 bytes 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/demo/executor/src/lib.rs b/demo/executor/src/lib.rs index 1740897add160..6e07f3c5fbf02 100644 --- a/demo/executor/src/lib.rs +++ b/demo/executor/src/lib.rs @@ -41,11 +41,13 @@ mod tests { use codec::{KeyedVec, Slicable, Joiner}; use keyring::Keyring::{self, Alice, Bob}; use runtime_support::Hashable; - use demo_runtime::runtime::staking::{self, balance, BALANCE_OF}; use state_machine::{CodeExecutor, TestExternalities}; use primitives::twox_128; - use demo_primitives::{Hash, Header, BlockNumber, Block, Digest, Transaction, - UncheckedTransaction, Function}; + use demo_primitives::{Hash, Header, BlockNumber, Digest}; + use demo_runtime::transaction::{Transaction, UncheckedTransaction}; + use demo_runtime::block::Block; + use demo_runtime::runtime::staking::{self, balance, BALANCE_OF}; + use demo_runtime::dispatch; use ed25519::{Public, Pair}; const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm"); @@ -62,7 +64,7 @@ mod tests { let transaction = Transaction { signed: Alice.into(), nonce: 0, - function: Function::StakingTransfer(Bob.into(), 69), + function: dispatch::PubCall::Staking(staking::public::Call::transfer(Bob.into(), 69)), }; let signature = Keyring::from_raw_public(transaction.signed).unwrap() .sign(&transaction.encode()); @@ -73,7 +75,8 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -83,7 +86,8 @@ mod tests { #[test] fn panic_execution_with_native_equivalent_code_gives_error() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -93,7 +97,8 @@ mod tests { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -108,7 +113,8 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -152,11 +158,11 @@ mod tests { construct_block( 1, [69u8; 32].into(), - hex!("970ae19447bef129c88ee80c72797fa9dfeda4ca1a26d10102b669d776eb0ccf").into(), + hex!("cfb76a83e40aa6a0d3f92255e6229e74808cae31d9f46053f31129b797540d03").into(), vec![Transaction { signed: Alice.into(), nonce: 0, - function: Function::StakingTransfer(Bob.into(), 69), + function: dispatch::PubCall::Staking(staking::public::Call::transfer(Bob.into(), 69)), }] ) } @@ -165,17 +171,17 @@ mod tests { construct_block( 2, block1().1, - hex!("347ece6ef0d193bd7c2bfbda17706b82eb24c0965f415784a44b138f0df034cd").into(), + hex!("c713bd003e303648e8d904bcfa44084865c9b70c398547e678028cc7cf60907f").into(), vec![ Transaction { signed: Bob.into(), nonce: 0, - function: Function::StakingTransfer(Alice.into(), 5), + function: dispatch::PubCall::Staking(staking::public::Call::transfer(Alice.into(), 5)), }, Transaction { signed: Alice.into(), nonce: 1, - function: Function::StakingTransfer(Bob.into(), 15), + function: dispatch::PubCall::Staking(staking::public::Call::transfer(Bob.into(), 15)), } ] ) @@ -188,15 +194,15 @@ mod tests { Executor::new().call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap(); runtime_io::with_externalities(&mut t, || { - assert_eq!(balance(&Alice), 42); + assert_eq!(balance(&Alice), 41); assert_eq!(balance(&Bob), 69); }); Executor::new().call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap(); runtime_io::with_externalities(&mut t, || { - assert_eq!(balance(&Alice), 32); - assert_eq!(balance(&Bob), 79); + assert_eq!(balance(&Alice), 30); + assert_eq!(balance(&Bob), 78); }); } @@ -207,22 +213,23 @@ mod tests { WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap(); runtime_io::with_externalities(&mut t, || { - assert_eq!(balance(&Alice), 42); + assert_eq!(balance(&Alice), 41); assert_eq!(balance(&Bob), 69); }); WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap(); runtime_io::with_externalities(&mut t, || { - assert_eq!(balance(&Alice), 32); - assert_eq!(balance(&Bob), 79); + assert_eq!(balance(&Alice), 30); + assert_eq!(balance(&Bob), 78); }); } #[test] fn panic_execution_gives_error() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm"); @@ -233,7 +240,8 @@ mod tests { #[test] fn successful_execution_gives_ok() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm"); diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 1a7785d62623f53de0c64cb75a2aff30a273585f..51ece299b15ec748063864dc451c20c50d4cf996 100644 GIT binary patch literal 134847 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 z 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 diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 7528a02d42f7c13ae4826476215bacb482f7c9c3..3e5dfa7600fae96f03b20b50aaa683e48cc12b51 100644 GIT binary patch literal 134896 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%0DF5bXGn{tm&%! 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 HsLB5ewi~hB diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index fc34a3fd55082e7011646e99b1fc54c7d4fda632..9271aa6501f18138d17de1c52306644ac3ebd646 100644 GIT binary patch delta 2117 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 L;MiYJcKQDWpAz}+ diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index c27b24b0c21ae7094dd821cf5309d28a5a547c52..ac8ce9ca407f3841cf11d0ab3c698409487b6a17 100644 GIT binary patch delta 2187 zcmaJ?T}&KB9G}_UyW6|taL*ne-a(mL4!ENr*AlK@z%eaNW7`;8><5t8P5w!p!T7uwLupXO>At8NinI7tq=C0iNui97;8#mBI%3%XZCgvit!$1 zXMXeh|NbBIpSgQa@VzH^{xe*K;OB8+j1k7Ff>lX%sjAi!!cZ^N~xq z#(c4&SW;_v2p$OG^yaVRXbe_=$XuR2kcpQ_8b=D#F}4ybVO@F;h+Nm-0g)Zm2@H!z zv0io~)+A;#0H3ev!$FWCMZ~AY;p-!cR%iZR`>hn*Mzpx3>N5Xmx~es?8;L9J0xj1) z93{Gk1Is@vz7d# zLD>n4ONbAOR>}U{oyJ?)-QE!EXw}$}*6p!Sm^@2YB?HDemqC}2CJ>ba01JS9+FB0> zaKH6^oMdO(HrEIW(1A0n7<3j}M!#WOh9k^uYm5IU^BID{CcBPY-u_ZfkU?;b>o6(a z7m%&s^4{zaHwJC_x1;8XSuq0cBxcF4O?65(h&Kf_Vh`IJamXx5ce>yRdpetVPtNS8 zfZg67lVGv(!ZujM4tylxdh^zyw_Le8D7ltz5~0oyVcU-w9IPGYx@?1BUJbfuf2cnY2K7%(n+?R*tF4M!{R zdj#dv!RxNoA6dpS(JK6z_b>e7*KPD5$_U5)q9mE}% zCgptrMBMZ-#ON0HaaCMUH@yOt7C5yLNM67Wz%Pg!YT^Ks0^s+4wV?_Hx5jxGCnvWD&nGA2c6;#lz-bl}K5b zl+qkrF0JVfd!?#DN+Ljk`;IXfxrdsAWIekfjd@~ z&Kd+XpVHy66nw>mdqIK?M`#HWE;wTgJJXp^m>&l}3K18if(6~NnX_!xs90$M?r<#U zfESQ;zS)Ug3sAqn?(fS(;UerOXb;*h!*jyDF1d`9q_91`uR(DadMkLP@4j*Y7Kcv8 zdG*hpN^$I3<_8!r40Pf$_RT;QZ2U4%EQjE~0N#xC4-@-G?Zz#v+gkw^=e&nuzUaNB k@aKnN<4pi_MhpD=eql^H^X$;uFz0{Z>)tq1&nAQa0v6y4Q2+n{ delta 2193 zcmZuyT})g>6rQ>F?%m~YxeF{^cNaRl{Ou1bKTWswr_w19ZAny&p{?2|(rw_vLIpHN zW0nV^V2qMX8=snBLsHTj(t0te#s^}WSRaZFYT`p5s3FD&P1|-G{j| z-+bqMXU;h@yKx_H+{c%%V63q#IG}sV;pbsD@nbo^p3P*3vZqn48z$L_w=!rKho&;q zD4=Ht$Hpdx&?DNZ$xH?XD>83qhTfdcy!twzqv+9Udp$ilI6gHvG(9pgj@rDZM#cxn zMy709dx;k#ipo4`65ibqs%tI1_#*U-vYZaf@r%XhCI&WrvT~R}-D+F(nXn5!Fm9 z0pj9I!z2n(4L{o&?#If!_C&$L9gOz=0Uq5=$qlM)cPh^{h{)J=q;6$ z5XIn#J!KcjBv=O{^I*LciDOu-M?Vzf%WSow4dAVYLF@y2Qcg;ZIDAWqX2h(4rf(Hr z4KZShC#v#~5%m}yEFN2aN}z$Lo1-ME866QHL2(rk-#~>z3>q^DqU|P~tD_!6kYkV^ zAh$no-Xl9A3hHYw5^EsEqa8v*o-%uk;^* z#fAP~wNM~PYU!qC5|yqYq7jXD^+jEwr~+wU8c5~*e18%4fu)+jF(jgL1n>f)2&9O! zDG{ZJBmER1;PXFzcq|32MjKO4cN38Mgw86H z`x+r*RdgG&QAHPBCfyP_tfC$c04xAzCKKTKZ1Pi_VyV{pCSe40;4DBq3z#RqivA9# zkZw4_PPZPY{vRe=YpnrqKes;53n)CmXln(Dx3@x-ZsevD)5B3p!Gfs}2P?oGD+o|} zbC6j`TS*$akS(QB&}$p19v57aU3=Pi|2>_ifX$~H6UJ8{6`;D%p9XMq%Ul+_8yJ*@|0H za|)ZMk3$8o(Jr1mjV`)P7_XPu=hf&O)KcL2^V%GbX{4YFwYa+IK7?O@UexGSD6>YF z-F69uCyD2as?i1AR*+@Z=r5%l$$^j~0RaF6RLAUd=ng@3I8uybUf5tm{yK|lV<%lUWDt|q6dIw_E z#bwzRH&v(0kZ6HZ8-cS6*a7&((IF)cFe3ndZ)_Xs7jOqbX=M%*>#yFp!f&xo=OD=i zzpU+njWDgFoWM(&P t^kuwi4g4uUYwx^244dx(H)rm}E$mBk#+i?eegJd+&%WcnS<$g}-@l(%4k!Qs From 5eca74a3b39ccb0d9cccf78fef2b23e457b3eb62 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 14 Mar 2018 13:02:48 +0100 Subject: [PATCH 07/29] Remove dead code. --- substrate/codec/src/endiansensitive.rs | 81 -------------------------- substrate/codec/src/lib.rs | 2 - 2 files changed, 83 deletions(-) delete mode 100644 substrate/codec/src/endiansensitive.rs diff --git a/substrate/codec/src/endiansensitive.rs b/substrate/codec/src/endiansensitive.rs deleted file mode 100644 index 00ff9a775fe71..0000000000000 --- a/substrate/codec/src/endiansensitive.rs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Endian manager. - -/// Trait to allow conversion to a know endian representation when sensitive. -/// Types implementing this trait must have a size > 0. -// note: the copy bound and static lifetimes are necessary for safety of `Slicable` blanket -// implementation. -pub trait EndianSensitive: Copy + 'static { - fn to_le(self) -> Self { self } - fn to_be(self) -> Self { self } - fn from_le(self) -> Self { self } - fn from_be(self) -> Self { self } - fn as_be_then T>(&self, f: F) -> T { f(&self) } - fn as_le_then T>(&self, f: F) -> T { f(&self) } -} - -macro_rules! impl_endians { - ( $( $t:ty ),* ) => { $( - impl EndianSensitive for $t { - fn to_le(self) -> Self { <$t>::to_le(self) } - fn to_be(self) -> Self { <$t>::to_be(self) } - fn from_le(self) -> Self { <$t>::from_le(self) } - fn from_be(self) -> Self { <$t>::from_be(self) } - fn as_be_then T>(&self, f: F) -> T { let d = self.to_be(); f(&d) } - fn as_le_then T>(&self, f: F) -> T { let d = self.to_le(); f(&d) } - } - )* } -} -macro_rules! impl_non_endians { - ( $( $t:ty ),* ) => { $( - impl EndianSensitive for $t {} - )* } -} - -// NOTE: See test to ensure correctness. -impl EndianSensitive for bool {} - -impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize); -impl_non_endians!(u8, i8, [u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], - [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); - -#[cfg(test)] -mod tests { - use super::EndianSensitive; - - #[test] - fn endian_sensitive_is_copy() { - fn _takes_copy() { } - fn _takes_endian_sensitive() { _takes_copy::() } - } - - #[test] - fn endian_sensitive_outlives_static() { - fn _takes_static() { } - fn _takes_endian_sensitive() { _takes_static::() } - } - - #[test] - fn bool_is_not_endian_sensitive() { - let b = true; - assert_eq!(b.to_be(), b.to_le()); - let b = false; - assert_eq!(b.to_be(), b.to_le()); - } -} diff --git a/substrate/codec/src/lib.rs b/substrate/codec/src/lib.rs index 92df92d44927e..15ff92b4f6694 100644 --- a/substrate/codec/src/lib.rs +++ b/substrate/codec/src/lib.rs @@ -23,12 +23,10 @@ #[cfg_attr(not(feature = "std"), macro_use)] extern crate substrate_runtime_std as rstd; -mod endiansensitive; mod slicable; mod joiner; mod keyedvec; -pub use self::endiansensitive::EndianSensitive; pub use self::slicable::{Input, Slicable, NonTrivialSlicable}; pub use self::joiner::Joiner; pub use self::keyedvec::KeyedVec; From 5d5f194c14f6c371dcf4bc77210b117764e5676a Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 14 Mar 2018 15:37:44 +0100 Subject: [PATCH 08/29] Initial util code for random beacon --- demo/runtime/src/lib.rs | 1 + demo/runtime/src/safe_mix.rs | 116 +++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 demo/runtime/src/safe_mix.rs diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index b9d0b32912691..edd563ba47854 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -38,6 +38,7 @@ extern crate integer_sqrt; #[macro_use] pub mod dispatch; +pub mod safe_mix; pub mod block; pub mod transaction; pub mod environment; diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs new file mode 100644 index 0000000000000..fb31f54221999 --- /dev/null +++ b/demo/runtime/src/safe_mix.rs @@ -0,0 +1,116 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate Demo. + +// Substrate Demo 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. + +// Substrate Demo 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 Substrate Demo. If not, see . + +//! Means of mixing a series of hashes to create a single secure hash. + +fn sub_mix(seeds: &[u64]) -> u64 { + (seeds[0] & seeds[1]) | (seeds[1] & seeds[2]) | (seeds[0] & seeds[2]) +} + +/// 3x3 mixing. +pub fn mix33(seeds: &[u64]) -> u64 { + let mut working = [0u64; 3]; + for i in 0..3 { + working[i] = sub_mix(&seeds[i * 3..i * 3 + 3]); + } + sub_mix(&working) +} + +/// 3x3 mixing. +pub fn mix(seeds: &[u64]) -> Result { + let max_depth = (0..12) + .scan(1, |a, _| { *a *= 3; Some(*a) }) + .position(|v| seeds.len() == v) + .ok_or(())?; + assert!(max_depth <= 11); + + let mut accum = [[0u64; 3]; 12]; + for i in 0..seeds.len() / 3 { + // first level: + accum[0][i % 3] = sub_mix(&seeds[i * 3..i * 3 + 3]); + + let mut index_at_depth = i; + for depth in 0..12 { + if index_at_depth % 3 != 2 { + break; + } + index_at_depth /= 3; + + // end of the threesome at depth. + accum[depth + 1][index_at_depth] = sub_mix(&accum[depth]); + } + } + Ok(accum[max_depth][0]) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sub_mix_works() { + assert_eq!(sub_mix(&[0, 0, 0][..]), 0); + assert_eq!(sub_mix(&[0, 0, 1][..]), 0); + assert_eq!(sub_mix(&[0, 1, 0][..]), 0); + assert_eq!(sub_mix(&[0, 1, 1][..]), 1); + assert_eq!(sub_mix(&[1, 0, 0][..]), 0); + assert_eq!(sub_mix(&[1, 0, 1][..]), 1); + assert_eq!(sub_mix(&[1, 1, 0][..]), 1); + assert_eq!(sub_mix(&[1, 1, 1][..]), 1); + + assert_eq!(sub_mix(&[0, 0, 0][..]), 0); + assert_eq!(sub_mix(&[0, 0, 2][..]), 0); + assert_eq!(sub_mix(&[0, 2, 0][..]), 0); + assert_eq!(sub_mix(&[0, 2, 2][..]), 2); + assert_eq!(sub_mix(&[2, 0, 0][..]), 0); + assert_eq!(sub_mix(&[2, 0, 2][..]), 2); + assert_eq!(sub_mix(&[2, 2, 0][..]), 2); + assert_eq!(sub_mix(&[2, 2, 2][..]), 2); + } + + #[test] + fn mix_works_on_first_level() { + assert_eq!(mix(&[0, 0, 0][..]).unwrap(), 0); + assert_eq!(mix(&[0, 0, 1][..]).unwrap(), 0); + assert_eq!(mix(&[0, 1, 0][..]).unwrap(), 0); + assert_eq!(mix(&[0, 1, 1][..]).unwrap(), 1); + assert_eq!(mix(&[1, 0, 0][..]).unwrap(), 0); + assert_eq!(mix(&[1, 0, 1][..]).unwrap(), 1); + assert_eq!(mix(&[1, 1, 0][..]).unwrap(), 1); + assert_eq!(mix(&[1, 1, 1][..]).unwrap(), 1); + + assert_eq!(mix(&[0, 0, 0][..]).unwrap(), 0); + assert_eq!(mix(&[0, 0, 2][..]).unwrap(), 0); + assert_eq!(mix(&[0, 2, 0][..]).unwrap(), 0); + assert_eq!(mix(&[0, 2, 2][..]).unwrap(), 2); + assert_eq!(mix(&[2, 0, 0][..]).unwrap(), 0); + assert_eq!(mix(&[2, 0, 2][..]).unwrap(), 2); + assert_eq!(mix(&[2, 2, 0][..]).unwrap(), 2); + assert_eq!(mix(&[2, 2, 2][..]).unwrap(), 2); + } + + #[test] + fn mix_works_on_second_level() { + assert_eq!(mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0][..]).unwrap(), 0); + assert_eq!(mix(&[0, 1, 1, 1, 0, 0, 1, 0, 1][..]).unwrap(), 1); + assert_eq!(mix(&[1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1); + } + + #[test] + fn mix_works_on_third_level() { + assert_eq!(mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1); + } +} From 8c2396dd6c5a440b4013767a64dba4b769ecaf09 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 14 Mar 2018 16:36:49 +0100 Subject: [PATCH 09/29] Timestamp uses new storage API. --- demo/runtime/src/lib.rs | 2 +- demo/runtime/src/runtime/timestamp.rs | 17 +- .../runtime-support/src/storage/generator.rs | 206 +++++------------- substrate/runtime-support/src/storage/mod.rs | 57 +++-- 4 files changed, 111 insertions(+), 171 deletions(-) diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index b9d0b32912691..2de76f6ea601e 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -20,7 +20,7 @@ #[allow(unused_imports)] #[macro_use] extern crate substrate_runtime_std as rstd; #[macro_use] extern crate substrate_runtime_io as runtime_io; -extern crate substrate_runtime_support as runtime_support; +#[macro_use] extern crate substrate_runtime_support as runtime_support; #[cfg(any(feature = "std", test))] extern crate substrate_keyring as keyring; #[cfg(feature = "std")] #[macro_use] extern crate serde_derive; diff --git a/demo/runtime/src/runtime/timestamp.rs b/demo/runtime/src/runtime/timestamp.rs index ff2c18b9bd4ba..038a8695e294d 100644 --- a/demo/runtime/src/runtime/timestamp.rs +++ b/demo/runtime/src/runtime/timestamp.rs @@ -16,27 +16,29 @@ //! Timestamp manager: just handles the current timestamp. -use runtime_support::storage; +use runtime_support::storage::StorageValue; use runtime::staking::PublicPass; pub type Timestamp = u64; -pub const CURRENT_TIMESTAMP: &[u8] = b"tim:val"; +storage_items! { + pub now: b"tim:val" => Timestamp; +} /// Get the current time. pub fn get() -> Timestamp { - storage::get_or_default(CURRENT_TIMESTAMP) + now::get_or_default() } impl_dispatch! { pub mod public; - fn set(now: Timestamp) = 0; + fn set(new_now: Timestamp) = 0; } impl<'a> public::Dispatch for PublicPass<'a> { /// Set the current time. - fn set(self, now: Timestamp) { - storage::put(CURRENT_TIMESTAMP, &now); + fn set(self, new_now: Timestamp) { + now::put(&new_now); } } @@ -46,6 +48,7 @@ mod tests { use super::public::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; + use runtime_support::storage::StorageValue; use runtime::timestamp; use codec::{Joiner, KeyedVec}; use demo_primitives::AccountId; @@ -54,7 +57,7 @@ mod tests { #[test] fn timestamp_works() { let mut t: TestExternalities = map![ - twox_128(CURRENT_TIMESTAMP).to_vec() => vec![].and(&42u64) + twox_128(now::key()).to_vec() => vec![].and(&42u64) ]; with_externalities(&mut t, || { diff --git a/substrate/runtime-support/src/storage/generator.rs b/substrate/runtime-support/src/storage/generator.rs index ce02a4e099264..c161b51d83808 100644 --- a/substrate/runtime-support/src/storage/generator.rs +++ b/substrate/runtime-support/src/storage/generator.rs @@ -36,7 +36,7 @@ //! //! storage_items! { //! // public value -//! pub Value: b"stored_key" => SessionKey; +//! pub Value: b"putd_key" => SessionKey; //! // private map. //! Balances: b"private_map:" => map [AuthorityId => Balance]; //! // private list. @@ -52,17 +52,17 @@ use rstd::vec::Vec; /// Abstraction around storage. pub trait Storage { /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn load(&self, key: &[u8]) -> Option; + fn get(&self, key: &[u8]) -> Option; /// Put a value in under a key. - fn store(&self, key: &[u8], val: &T); + fn put(&self, key: &[u8], val: &T); /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]); /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - let value = self.load(key); + let value = self.get(key); self.kill(key); value } @@ -73,9 +73,9 @@ pub trait StorageValue { /// Get the storage key. fn key() -> &'static [u8]; /// Load the value from the provided storage instance. - fn load(storage: &S) -> Option; + fn get(storage: &S) -> Option; /// Store a value under this key into the provded storage instance. - fn store(val: &T, storage: &S); + fn put(val: &T, storage: &S); /// Clear the storage value. fn kill(storage: &S); /// Take a value from storage, removing it afterwards. @@ -87,7 +87,7 @@ pub trait StorageList { /// Get the prefix key in storage. fn prefix() -> &'static [u8]; - /// Get the key used to store the length field. + /// Get the key used to put the length field. fn len_key() -> Vec; /// Get the storage key used to fetch a value at a given index. @@ -140,53 +140,30 @@ macro_rules! __storage_items_internal { (($($vis:tt)*) $name: ident: $key: expr => $ty:ty) => { $($vis)* struct $name; - #[allow(unused)] - impl $name { + impl $crate::storage::generator::StorageValue<$ty> for $name { /// Get the storage key. - $($vis)* fn key() -> &'static [u8] { + fn key() -> &'static [u8] { $key } /// Load the value from the provided storage instance. - $($vis)* fn load(storage: &S) -> Option<$ty> { - storage.load($key) + fn get(storage: &S) -> Option<$ty> { + storage.get($key) } /// Store a value under this key into the provded storage instance. - $($vis)* fn store(val: &$ty, storage: &S) { - storage.store($key, val) + fn put(val: &$ty, storage: &S) { + storage.put($key, val) } /// Kill the value. - $($vis)* fn kill(storage: &S) { + fn kill(storage: &S) { storage.kill($key) } /// Take and remove the value from the provided storage instance. - $($vis)* fn take(storage: &S) -> Option<$ty> { - storage.take($key) - } - } - - impl $crate::storage::generator::StorageValue<$ty> for $name { - fn key() -> &'static [u8] { - $key - } - - fn load(storage: &S) -> Option<$ty> { - $name::load(storage) - } - - fn store(val: &$ty, storage: &S) { - $name::store(val, storage) - } - - fn kill(storage: &S) { - $name::kill(storage) - } - fn take(storage: &S) -> Option<$ty> { - $name::take(storage) + storage.take($key) } } }; @@ -194,191 +171,120 @@ macro_rules! __storage_items_internal { (($($vis:tt)*) $name: ident: $prefix: expr => map [$kty: ty => $ty:ty]) => { $($vis)* struct $name; - #[allow(unused)] - impl $name { + impl $crate::storage::generator::StorageMap<$kty, $ty> for $name { /// Get the prefix key in storage. - $($vis)* fn prefix() -> &'static [u8] { + fn prefix() -> &'static [u8] { $prefix } /// Get the storage key used to fetch a value corresponding to a specific key. - $($vis)* fn key_for(x: &$kty) -> Vec { + fn key_for(x: &$kty) -> Vec { let mut key = $prefix.to_vec(); key.extend($crate::codec::Slicable::encode(x)); key } /// Load the value associated with the given key from the map. - $($vis)* fn get(key: &$kty, storage: &S) -> Option<$ty> { + fn get(key: &$kty, storage: &S) -> Option<$ty> { let key = $name::key_for(key); - storage.load(&key[..]) + storage.get(&key[..]) } /// Store a value to be associated with the given key from the map. - $($vis)* fn insert(key: &$kty, val: &$ty, storage: &S) { + fn insert(key: &$kty, val: &$ty, storage: &S) { let key = $name::key_for(key); - storage.store(&key[..], val); + storage.put(&key[..], val); } /// Remove the value from storage. - $($vis)* fn remove(key: &$kty, storage: &S) { + fn remove(key: &$kty, storage: &S) { storage.kill(&$name::key_for(key)[..]); } /// Take the value, reading and removing it. - $($vis)* fn take(key: &$kty, storage: &S) -> Option<$ty> { + fn take(key: &$kty, storage: &S) -> Option<$ty> { let key = $name::key_for(key); storage.take(&key[..]) } } - - impl $crate::storage::generator::StorageMap<$kty, $ty> for $name { - fn prefix() -> &'static [u8] { - $prefix - } - - fn key_for(x: &$kty) -> Vec { - $name::key_for(x) - } - - fn get(key: &$kty, storage: &S) -> Option<$ty> { - $name::get(key, storage) - } - - fn insert(key: &$kty, val: &$ty, storage: &S) { - $name::insert(key, val, storage) - } - - fn remove(key: &$kty, storage: &S) { - $name::remove(key, storage) - } - - fn take(key: &$kty, storage: &S) -> Option<$ty> { - $name::take(key, storage) - } - } }; // generator for lists. (($($vis:tt)*) $name: ident: $prefix: expr => list [$ty:ty]) => { $($vis)* struct $name; - #[allow(unused)] impl $name { + fn clear_item(index: u32, storage: &S) { + if index < $name::len(storage) { + storage.kill(&$name::key_for(index)); + } + } + + fn set_len(count: u32, storage: &S) { + (count..$name::len(storage)).for_each(|i| $name::clear_item(i, storage)); + storage.put(&$name::len_key(), &count); + } + } + + impl $crate::storage::generator::StorageList<$ty> for $name { /// Get the prefix key in storage. - $($vis)* fn prefix() -> &'static [u8] { + fn prefix() -> &'static [u8] { $prefix } - /// Get the key used to store the length field. + /// Get the key used to put the length field. // TODO: concat macro should accept byte literals. - $($vis)* fn len_key() -> Vec { + fn len_key() -> Vec { let mut key = $prefix.to_vec(); key.extend(b"len"); key } /// Get the storage key used to fetch a value at a given index. - $($vis)* fn key_for(index: u32) -> Vec { + fn key_for(index: u32) -> Vec { let mut key = $prefix.to_vec(); key.extend($crate::codec::Slicable::encode(&index)); key } /// Read out all the items. - $($vis)* fn items(storage: &S) -> Vec<$ty> { + fn items(storage: &S) -> Vec<$ty> { (0..$name::len(storage)) .map(|i| $name::get(i, storage).expect("all items within length are set; qed")) .collect() } /// Set the current set of items. - $($vis)* fn set_items(items: &[$ty], storage: &S) { + fn set_items(items: &[$ty], storage: &S) { $name::set_len(items.len() as u32, storage); items.iter() .enumerate() .for_each(|(i, item)| $name::set_item(i as u32, item, storage)); } - $($vis)* fn set_item(index: u32, item: &$ty, storage: &S) { + fn set_item(index: u32, item: &$ty, storage: &S) { if index < $name::len(storage) { - storage.store(&$name::key_for(index)[..], item); + storage.put(&$name::key_for(index)[..], item); } } /// Load the value at given index. Returns `None` if the index is out-of-bounds. - $($vis)* fn get(index: u32, storage: &S) -> Option<$ty> { - storage.load(&$name::key_for(index)[..]) + fn get(index: u32, storage: &S) -> Option<$ty> { + storage.get(&$name::key_for(index)[..]) } /// Load the length of the list. - $($vis)* fn len(storage: &S) -> u32 { - storage.load(&$name::len_key()).unwrap_or_default() + fn len(storage: &S) -> u32 { + storage.get(&$name::len_key()).unwrap_or_default() } /// Clear the list. - $($vis)* fn clear(storage: &S) { + fn clear(storage: &S) { for i in 0..$name::len(storage) { $name::clear_item(i, storage); } storage.kill(&$name::len_key()[..]) } - - fn clear_item(index: u32, storage: &S) { - if index < $name::len(storage) { - storage.kill(&$name::key_for(index)); - } - } - - fn set_len(count: u32, storage: &S) { - (count..$name::len(storage)).for_each(|i| $name::clear_item(i, storage)); - storage.store(&$name::len_key(), &count); - } - } - - impl $crate::storage::generator::StorageList<$ty> for $name { - /// Get the prefix key in storage. - fn prefix() -> &'static [u8] { - $prefix - } - - /// Get the key used to store the length field. - // TODO: concat macro should accept byte literals. - fn len_key() -> Vec { - $name::len_key() - } - - /// Get the storage key used to fetch a value at a given index. - fn key_for(index: u32) -> Vec { - $name::key_for(index) - } - - /// Read out all the items. - fn items(storage: &S) -> Vec<$ty> { - $name::items(storage) - } - - /// Set the current set of items. - fn set_items(items: &[$ty], storage: &S) { - $name::set_items(items, storage) - } - - fn set_item(index: u32, item: &$ty, storage: &S) { - $name::set_item(index, item, storage) - } - - /// Load the value at given index. Returns `None` if the index is out-of-bounds. - fn get(index: u32, storage: &S) -> Option<$ty> { - $name::get(index, storage) - } - - fn len(storage: &S) -> u32 { - $name::len(storage) - } - - fn clear(storage: &S) { - $name::clear(storage) - } } }; } @@ -424,11 +330,11 @@ mod tests { use super::*; impl Storage for RefCell, Vec>> { - fn load(&self, key: &[u8]) -> Option { + fn get(&self, key: &[u8]) -> Option { self.borrow_mut().get(key).map(|v| T::decode(&mut &v[..]).unwrap()) } - fn store(&self, key: &[u8], val: &T) { + fn put(&self, key: &[u8], val: &T) { self.borrow_mut().insert(key.to_owned(), val.encode()); } @@ -446,11 +352,11 @@ mod tests { #[test] fn value() { let storage = RefCell::new(HashMap::new()); - assert!(Value::load(&storage).is_none()); - Value::store(&100_000, &storage); - assert_eq!(Value::load(&storage), Some(100_000)); + assert!(Value::get(&storage).is_none()); + Value::put(&100_000, &storage); + assert_eq!(Value::get(&storage), Some(100_000)); Value::kill(&storage); - assert!(Value::load(&storage).is_none()); + assert!(Value::get(&storage).is_none()); } #[test] diff --git a/substrate/runtime-support/src/storage/mod.rs b/substrate/runtime-support/src/storage/mod.rs index fb4aa17487360..f8e4ce0e007c3 100644 --- a/substrate/runtime-support/src/storage/mod.rs +++ b/substrate/runtime-support/src/storage/mod.rs @@ -47,7 +47,7 @@ pub fn get(key: &[u8]) -> Option { key: &key[..], pos: 0, }; - Slicable::decode(&mut input).expect("stroage is not null, therefore must be a valid type") + Slicable::decode(&mut input).expect("storage is not null, therefore must be a valid type") }) } @@ -126,23 +126,23 @@ struct RuntimeStorage; impl ::GenericStorage for RuntimeStorage { /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn load(&self, key: &[u8]) -> Option { - get(key) + fn get(&self, key: &[u8]) -> Option { + super::storage::get(key) } /// Put a value in under a key. - fn store(&self, key: &[u8], val: &T) { - put(key, val) + fn put(&self, key: &[u8], val: &T) { + super::storage::put(key, val) } /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]) { - kill(key) + super::storage::kill(key) } /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - take(key) + super::storage::take(key) } } @@ -150,25 +150,47 @@ impl ::GenericStorage for RuntimeStorage { pub trait StorageValue { /// Get the storage key. fn key() -> &'static [u8]; + + /// Load the value from the provided storage instance. + fn get() -> Option; + /// Load the value from the provided storage instance. - fn load() -> Option; + fn get_or(alt: T) -> T { Self::get().unwrap_or(alt) } + + /// Load the value from the provided storage instance. + fn get_or_else T>(alt: F) -> T { Self::get().unwrap_or_else(alt) } + + /// Load the value from the provided storage instance. + fn get_or_default() -> T where T: Default { Self::get().unwrap_or_else(Default::default) } + /// Store a value under this key into the provded storage instance. - fn store(val: &T); + fn put(val: &T); + /// Clear the storage value. fn kill(); + /// Take a value from storage, removing it afterwards. fn take() -> Option; + + /// Load the value from the provided storage instance. + fn take_or(alt: T) -> T { Self::take().unwrap_or(alt) } + + /// Load the value from the provided storage instance. + fn take_or_else T>(alt: F) -> T { Self::take().unwrap_or_else(alt) } + + /// Load the value from the provided storage instance. + fn take_or_default() -> T where T: Default { Self::take().unwrap_or_else(Default::default) } } impl StorageValue for U where U: generator::StorageValue { fn key() -> &'static [u8] { >::key() } - fn load() -> Option { - U::load(&RuntimeStorage) + fn get() -> Option { + U::get(&RuntimeStorage) } - fn store(val: &T) { - U::store(val, &RuntimeStorage) + fn put(val: &T) { + U::put(val, &RuntimeStorage) } fn kill() { U::kill(&RuntimeStorage) @@ -257,6 +279,15 @@ pub trait StorageMap { /// Load the value associated with the given key from the map. fn get(key: &K) -> Option; + /// Load the value from the provided storage instance. + fn get_or(key: &K, alt: V) -> V { Self::get(key).unwrap_or(alt) } + + /// Load the value from the provided storage instance. + fn get_or_else V>(key: &K, alt: F) -> V { Self::get(key).unwrap_or_else(alt) } + + /// Load the value from the provided storage instance. + fn get_or_default(key: &K) -> V where V: Default { Self::get(key).unwrap_or_else(Default::default) } + /// Store a value to be associated with the given key from the map. fn insert(key: &K, val: &V); From 6b6c240d6d6fb906f6c574e2785b90da5a9b7b21 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 14 Mar 2018 20:48:59 +0100 Subject: [PATCH 10/29] Move over system module to new API. --- demo/runtime/src/genesismap.rs | 6 ++-- demo/runtime/src/runtime/system.rs | 27 +++++++-------- demo/runtime/src/runtime/timestamp.rs | 14 ++++---- substrate/runtime-support/src/lib.rs | 2 +- .../runtime-support/src/storage/generator.rs | 34 +++++++++---------- substrate/runtime-support/src/storage/mod.rs | 6 ++++ 6 files changed, 46 insertions(+), 43 deletions(-) diff --git a/demo/runtime/src/genesismap.rs b/demo/runtime/src/genesismap.rs index c3b7da1b7d8c2..ce93deb8e0f82 100644 --- a/demo/runtime/src/genesismap.rs +++ b/demo/runtime/src/genesismap.rs @@ -19,7 +19,7 @@ use codec::{KeyedVec, Joiner}; use std::collections::HashMap; use runtime_io::twox_128; -use runtime_support::Hashable; +use runtime_support::{Hashable, StorageMap}; use primitives::Block; use demo_primitives::{BlockNumber, AccountId}; use runtime::staking::Balance; @@ -113,7 +113,7 @@ impl GenesisConfig { ) .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ - (system::CODE[..].into(), wasm_runtime), + (b":code".to_vec(), wasm_runtime), (consensus::AUTHORITY_COUNT[..].into(), vec![].and(&(self.authorities.len() as u32))), ].into_iter()) .chain(self.authorities.iter() @@ -127,6 +127,6 @@ impl GenesisConfig { pub fn additional_storage_with_genesis(genesis_block: &Block) -> HashMap, Vec> { use codec::Slicable; map![ - twox_128(&0u64.to_keyed_vec(system::BLOCK_HASH_AT)).to_vec() => genesis_block.header.blake2_256().encode() + system::BlockHash::key_for(&0) => genesis_block.header.blake2_256().encode() ] } diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 33d48f72beca5..775642eb854e8 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -21,7 +21,7 @@ use rstd::prelude::*; use rstd::mem; use runtime_io::{print, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; -use runtime_support::{Hashable, storage}; +use runtime_support::{Hashable, storage, StorageValue, StorageMap}; use environment::with_env; use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Header, Log}; use block::Block; @@ -29,10 +29,10 @@ use transaction::UncheckedTransaction; use runtime::{staking, session}; use dispatch; -pub const NONCE_OF: &[u8] = b"sys:non:"; -pub const BLOCK_HASH_AT: &[u8] = b"sys:old:"; -pub const CODE: &[u8] = b"sys:cod"; - +storage_items! { + pub Nonce: b"sys:non" => map [ AccountId => TxOrder ]; + pub BlockHash: b"sys:old" => map [ BlockNumber => [u8; 32] ]; +} /// The current block number being processed. Set by `execute_block`. pub fn block_number() -> BlockNumber { @@ -40,8 +40,8 @@ pub fn block_number() -> BlockNumber { } /// Get the block hash of a given block (uses storage). -pub fn block_hash(number: BlockNumber) -> Hash { - storage::get_or_default(&number.to_keyed_vec(BLOCK_HASH_AT)) +pub fn block_hash(number: BlockNumber) -> Option { + BlockHash::get(&number).map(Into::into) } pub struct PrivPass; @@ -146,12 +146,11 @@ fn execute_transaction(utx: UncheckedTransaction) { { // check nonce - let nonce_key = tx.signed.to_keyed_vec(NONCE_OF); - let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0); + let expected_nonce: TxOrder = Nonce::get_or(&tx.signed, 0); assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); // increment nonce in storage - storage::put(&nonce_key, &(expected_nonce + 1)); + Nonce::insert(&tx.signed, &(expected_nonce + 1)); } // decode parameters and dispatch @@ -164,7 +163,7 @@ fn initial_checks(block: &Block) { // check parent_hash is correct. assert!( - header.number > 0 && block_hash(header.number - 1) == header.parent_hash, + header.number > 0 && block_hash(header.number - 1).map(|h| h == header.parent_hash).unwrap_or(false), "Parent hash should be valid." ); @@ -193,7 +192,7 @@ fn final_checks(block: &Block) { fn post_finalise(header: &Header) { // store the header hash in storage; we can't do it before otherwise there would be a // cyclic dependency. - storage::put(&header.number.to_keyed_vec(BLOCK_HASH_AT), &header.blake2_256()); + BlockHash::insert(&header.number, &header.blake2_256()); } #[cfg(feature = "std")] @@ -221,7 +220,7 @@ pub mod testing { pub fn externalities() -> TestExternalities { map![ - twox_128(&0u64.to_keyed_vec(BLOCK_HASH_AT)).to_vec() => [69u8; 32].encode() + twox_128(&BlockHash::key_for(&0)).to_vec() => [69u8; 32].encode() ] } } @@ -278,7 +277,7 @@ mod tests { let h = Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("584e0c1f4d4b96153591e3906d756762493dffeb5fa7159e7107014aec8d9c3d").into(), + state_root: hex!("c3cd675eefaa269502ee6dc1af7b9941c0be462eb31a5273c00cec40a8ace837").into(), transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), digest: Digest { logs: vec![], }, }; diff --git a/demo/runtime/src/runtime/timestamp.rs b/demo/runtime/src/runtime/timestamp.rs index 038a8695e294d..13f8e2502bf73 100644 --- a/demo/runtime/src/runtime/timestamp.rs +++ b/demo/runtime/src/runtime/timestamp.rs @@ -22,23 +22,21 @@ use runtime::staking::PublicPass; pub type Timestamp = u64; storage_items! { - pub now: b"tim:val" => Timestamp; + pub Now: b"tim:val" => Timestamp; } /// Get the current time. -pub fn get() -> Timestamp { - now::get_or_default() -} +pub fn get() -> Timestamp { Now::require() } impl_dispatch! { pub mod public; - fn set(new_now: Timestamp) = 0; + fn set(now: Timestamp) = 0; } impl<'a> public::Dispatch for PublicPass<'a> { /// Set the current time. - fn set(self, new_now: Timestamp) { - now::put(&new_now); + fn set(self, now: Timestamp) { + Now::put(&now); } } @@ -57,7 +55,7 @@ mod tests { #[test] fn timestamp_works() { let mut t: TestExternalities = map![ - twox_128(now::key()).to_vec() => vec![].and(&42u64) + twox_128(Now::key()).to_vec() => vec![].and(&42u64) ]; with_externalities(&mut t, || { diff --git a/substrate/runtime-support/src/lib.rs b/substrate/runtime-support/src/lib.rs index 6e946ce6c7988..86c3b589b82d3 100644 --- a/substrate/runtime-support/src/lib.rs +++ b/substrate/runtime-support/src/lib.rs @@ -29,5 +29,5 @@ pub use self::storage::generator::Storage as GenericStorage; pub mod storage; mod hashable; -pub use self::storage::StorageVec; +pub use self::storage::{StorageVec, StorageValue, StorageMap}; pub use self::hashable::Hashable; diff --git a/substrate/runtime-support/src/storage/generator.rs b/substrate/runtime-support/src/storage/generator.rs index c161b51d83808..207c27b84bc89 100644 --- a/substrate/runtime-support/src/storage/generator.rs +++ b/substrate/runtime-support/src/storage/generator.rs @@ -186,24 +186,24 @@ macro_rules! __storage_items_internal { /// Load the value associated with the given key from the map. fn get(key: &$kty, storage: &S) -> Option<$ty> { - let key = $name::key_for(key); + let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); storage.get(&key[..]) } /// Store a value to be associated with the given key from the map. fn insert(key: &$kty, val: &$ty, storage: &S) { - let key = $name::key_for(key); + let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); storage.put(&key[..], val); } /// Remove the value from storage. fn remove(key: &$kty, storage: &S) { - storage.kill(&$name::key_for(key)[..]); + storage.kill(&<$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key)[..]); } /// Take the value, reading and removing it. fn take(key: &$kty, storage: &S) -> Option<$ty> { - let key = $name::key_for(key); + let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); storage.take(&key[..]) } } @@ -214,14 +214,14 @@ macro_rules! __storage_items_internal { impl $name { fn clear_item(index: u32, storage: &S) { - if index < $name::len(storage) { - storage.kill(&$name::key_for(index)); + if index < <$name as $crate::storage::generator::StorageList<$ty>>::len(storage) { + storage.kill(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)); } } fn set_len(count: u32, storage: &S) { - (count..$name::len(storage)).for_each(|i| $name::clear_item(i, storage)); - storage.put(&$name::len_key(), &count); + (count..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage)); + storage.put(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key(), &count); } } @@ -248,8 +248,8 @@ macro_rules! __storage_items_internal { /// Read out all the items. fn items(storage: &S) -> Vec<$ty> { - (0..$name::len(storage)) - .map(|i| $name::get(i, storage).expect("all items within length are set; qed")) + (0..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage)) + .map(|i| <$name as $crate::storage::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed")) .collect() } @@ -258,32 +258,32 @@ macro_rules! __storage_items_internal { $name::set_len(items.len() as u32, storage); items.iter() .enumerate() - .for_each(|(i, item)| $name::set_item(i as u32, item, storage)); + .for_each(|(i, item)| <$name as $crate::storage::generator::StorageList<$ty>>::set_item(i as u32, item, storage)); } fn set_item(index: u32, item: &$ty, storage: &S) { - if index < $name::len(storage) { - storage.put(&$name::key_for(index)[..], item); + if index < <$name as $crate::storage::generator::StorageList<$ty>>::len(storage) { + storage.put(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)[..], item); } } /// Load the value at given index. Returns `None` if the index is out-of-bounds. fn get(index: u32, storage: &S) -> Option<$ty> { - storage.get(&$name::key_for(index)[..]) + storage.get(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)[..]) } /// Load the length of the list. fn len(storage: &S) -> u32 { - storage.get(&$name::len_key()).unwrap_or_default() + storage.get(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key()).unwrap_or_default() } /// Clear the list. fn clear(storage: &S) { - for i in 0..$name::len(storage) { + for i in 0..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage) { $name::clear_item(i, storage); } - storage.kill(&$name::len_key()[..]) + storage.kill(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key()[..]) } } }; diff --git a/substrate/runtime-support/src/storage/mod.rs b/substrate/runtime-support/src/storage/mod.rs index f8e4ce0e007c3..759541a1581de 100644 --- a/substrate/runtime-support/src/storage/mod.rs +++ b/substrate/runtime-support/src/storage/mod.rs @@ -154,6 +154,9 @@ pub trait StorageValue { /// Load the value from the provided storage instance. fn get() -> Option; + /// Load the value from the provided storage instance. + fn require() -> T { Self::get().expect("Required values must be present") } + /// Load the value from the provided storage instance. fn get_or(alt: T) -> T { Self::get().unwrap_or(alt) } @@ -279,6 +282,9 @@ pub trait StorageMap { /// Load the value associated with the given key from the map. fn get(key: &K) -> Option; + /// Load the value from the provided storage instance. + fn require(key: &K) -> V { Self::get(key).expect("Required values must be present") } + /// Load the value from the provided storage instance. fn get_or(key: &K, alt: V) -> V { Self::get(key).unwrap_or(alt) } From a79dab27fd191e16e34d3841f442a8d6cf1266a4 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 15 Mar 2018 11:52:33 +0100 Subject: [PATCH 11/29] Much nicer storage API, moved over staking module. --- demo/runtime/src/genesismap.rs | 10 +- demo/runtime/src/runtime/democracy.rs | 48 ++- demo/runtime/src/runtime/staking.rs | 408 ++++++++---------- demo/runtime/src/runtime/system.rs | 26 +- demo/runtime/src/runtime/timestamp.rs | 9 +- substrate/runtime-support/src/lib.rs | 2 +- .../runtime-support/src/storage/generator.rs | 209 +++++++-- substrate/runtime-support/src/storage/mod.rs | 82 ++-- 8 files changed, 425 insertions(+), 369 deletions(-) diff --git a/demo/runtime/src/genesismap.rs b/demo/runtime/src/genesismap.rs index ce93deb8e0f82..024688e2c3e46 100644 --- a/demo/runtime/src/genesismap.rs +++ b/demo/runtime/src/genesismap.rs @@ -19,7 +19,7 @@ use codec::{KeyedVec, Joiner}; use std::collections::HashMap; use runtime_io::twox_128; -use runtime_support::{Hashable, StorageMap}; +use runtime_support::{Hashable, StorageMap, StorageList, StorageValue}; use primitives::Block; use demo_primitives::{BlockNumber, AccountId}; use runtime::staking::Balance; @@ -83,9 +83,9 @@ impl GenesisConfig { (&session::SESSION_LENGTH[..], vec![].and(&self.session_length)), (&session::VALIDATOR_COUNT[..], vec![].and(&(self.validators.len() as u32))), - (&staking::INTENTION_COUNT[..], vec![].and(&0u32)), - (&staking::SESSIONS_PER_ERA[..], vec![].and(&self.sessions_per_era)), - (&staking::CURRENT_ERA[..], vec![].and(&0u64)), + (&staking::Intention::len_key()[..], vec![].and(&0u32)), + (&staking::SessionsPerEra::key()[..], vec![].and(&self.sessions_per_era)), + (&staking::CurrentEra::key()[..], vec![].and(&0u64)), (&democracy::LAUNCH_PERIOD[..], vec![].and(&self.launch_period)), (&democracy::VOTING_PERIOD[..], vec![].and(&self.voting_period)), @@ -113,7 +113,7 @@ impl GenesisConfig { ) .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ - (b":code".to_vec(), wasm_runtime), + (system::CODE.to_vec(), wasm_runtime), (consensus::AUTHORITY_COUNT[..].into(), vec![].and(&(self.authorities.len() as u32))), ].into_iter()) .chain(self.authorities.iter() diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index f662e18121cbc..a86b1139b60ca 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -295,7 +295,7 @@ pub mod internal { // tally up votes for any expiring referenda. for (index, _, proposal, vote_threshold) in maturing_referendums_at(now) { let (approve, against) = tally(index); - let total_stake = staking::total_stake(); + let total_stake = staking::TotalStake::get(); clear_referendum(index); if vote_threshold.approved(approve, against, total_stake) { proposal.dispatch(PrivPass); @@ -334,6 +334,7 @@ fn clear_referendum(ref_index: ReferendumIndex) { pub mod testing { use super::*; use runtime_io::{twox_128, TestExternalities}; + use runtime_support::{StorageList, StorageValue, StorageMap}; use codec::Joiner; use keyring::Keyring::*; use runtime::{session, staking}; @@ -345,22 +346,22 @@ pub mod testing { twox_128(&0u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Alice.to_raw_public_vec(), twox_128(&1u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Bob.to_raw_public_vec(), twox_128(&2u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Charlie.to_raw_public_vec(), - twox_128(staking::INTENTION_COUNT).to_vec() => vec![].and(&3u32), - twox_128(&0u32.to_keyed_vec(staking::INTENTION_AT)).to_vec() => Alice.to_raw_public_vec(), - twox_128(&1u32.to_keyed_vec(staking::INTENTION_AT)).to_vec() => Bob.to_raw_public_vec(), - twox_128(&2u32.to_keyed_vec(staking::INTENTION_AT)).to_vec() => Charlie.to_raw_public_vec(), - twox_128(&Alice.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&10u64), - twox_128(&Bob.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&20u64), - twox_128(&Charlie.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&30u64), - twox_128(&Dave.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&40u64), - twox_128(&Eve.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&50u64), - twox_128(&Ferdie.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&60u64), - twox_128(&One.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&1u64), - twox_128(staking::TOTAL_STAKE).to_vec() => vec![].and(&210u64), - twox_128(staking::SESSIONS_PER_ERA).to_vec() => vec![].and(&1u64), - twox_128(staking::VALIDATOR_COUNT).to_vec() => vec![].and(&3u64), - twox_128(staking::CURRENT_ERA).to_vec() => vec![].and(&1u64), - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![].and(&1u64), + twox_128(&staking::Intention::len_key()).to_vec() => vec![].and(&3u32), + twox_128(&staking::Intention::key_for(0)).to_vec() => Alice.to_raw_public_vec(), + twox_128(&staking::Intention::key_for(1)).to_vec() => Bob.to_raw_public_vec(), + twox_128(&staking::Intention::key_for(2)).to_vec() => Charlie.to_raw_public_vec(), + twox_128(&staking::FreeBalanceOf::key_for(&Alice)).to_vec() => vec![].and(&10u64), + twox_128(&staking::FreeBalanceOf::key_for(&Bob)).to_vec() => vec![].and(&20u64), + twox_128(&staking::FreeBalanceOf::key_for(&Charlie)).to_vec() => vec![].and(&30u64), + twox_128(&staking::FreeBalanceOf::key_for(&Dave)).to_vec() => vec![].and(&40u64), + twox_128(&staking::FreeBalanceOf::key_for(&Eve)).to_vec() => vec![].and(&50u64), + twox_128(&staking::FreeBalanceOf::key_for(&Ferdie)).to_vec() => vec![].and(&60u64), + twox_128(&staking::FreeBalanceOf::key_for(&One)).to_vec() => vec![].and(&1u64), + twox_128(staking::TotalStake::key()).to_vec() => vec![].and(&210u64), + twox_128(staking::SessionsPerEra::key()).to_vec() => vec![].and(&1u64), + twox_128(staking::ValidatorCount::key()).to_vec() => vec![].and(&3u64), + twox_128(staking::CurrentEra::key()).to_vec() => vec![].and(&1u64), + twox_128(staking::TransactionFee::key()).to_vec() => vec![].and(&1u64), twox_128(LAUNCH_PERIOD).to_vec() => vec![].and(&1u64), twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64), @@ -373,6 +374,7 @@ pub mod testing { mod tests { use super::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; + use runtime_support::{StorageValue, StorageMap}; use codec::{KeyedVec, Joiner}; use keyring::Keyring::*; use environment::with_env; @@ -394,8 +396,8 @@ mod tests { assert_eq!(voting_period(), 1u64); assert_eq!(minimum_deposit(), 1u64); assert_eq!(next_free_ref_index(), 0u32); - assert_eq!(staking::sessions_per_era(), 1u64); - assert_eq!(staking::total_stake(), 210u64); + assert_eq!(staking::SessionsPerEra::get(), 1u64); + assert_eq!(staking::TotalStake::get(), 210u64); }); } @@ -519,19 +521,19 @@ mod tests { PublicPass::test(&Alice).vote(0, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); - assert_eq!(staking::bonding_duration(), 4u64); + assert_eq!(staking::BondingDuration::get(), 4u64); with_env(|e| e.block_number = 2); PublicPass::test(&Alice).vote(1, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); - assert_eq!(staking::bonding_duration(), 3u64); + assert_eq!(staking::BondingDuration::get(), 3u64); with_env(|e| e.block_number = 3); PublicPass::test(&Alice).vote(2, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); - assert_eq!(staking::bonding_duration(), 2u64); + assert_eq!(staking::BondingDuration::get(), 2u64); }); } @@ -632,7 +634,7 @@ mod tests { fn passing_low_turnout_voting_should_work() { with_externalities(&mut new_test_ext(), || { assert_eq!(staking::era_length(), 1u64); - assert_eq!(staking::total_stake(), 210u64); + assert_eq!(staking::TotalStake::get(), 210u64); with_env(|e| e.block_number = 1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index 1a3f5b0496ba8..4da7654068004 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -22,7 +22,7 @@ use rstd::cell::RefCell; use rstd::collections::btree_map::{BTreeMap, Entry}; use runtime_io::{print, blake2_256}; use codec::{Slicable, Input, KeyedVec}; -use runtime_support::{storage, StorageVec}; +use runtime_support::{storage, StorageValue, StorageList, StorageMap}; use demo_primitives::{BlockNumber, AccountId}; use runtime::{system, session}; @@ -32,78 +32,52 @@ pub type Balance = u64; /// The amount of bonding period left in an account. Measured in eras. pub type Bondage = u64; -pub const BONDING_DURATION: &[u8] = b"sta:loc"; -pub const VALIDATOR_COUNT: &[u8] = b"sta:vac"; -pub const SESSIONS_PER_ERA: &[u8] = b"sta:spe"; -pub const NEXT_SESSIONS_PER_ERA: &[u8] = b"sta:nse"; -pub const CURRENT_ERA: &[u8] = b"sta:era"; -pub const LAST_ERA_LENGTH_CHANGE: &[u8] = b"sta:lec"; -pub const TOTAL_STAKE: &[u8] = b"sta:tot"; -pub const INTENTION_AT: &[u8] = b"sta:wil:"; -pub const INTENTION_COUNT: &[u8] = b"sta:wil:len"; -pub const TRANSACTION_FEE: &[u8] = b"sta:fee"; - -pub const BALANCE_OF: &[u8] = b"sta:bal:"; -pub const RESERVED_BALANCE_OF: &[u8] = b"sta:lbo:"; -pub const BONDAGE_OF: &[u8] = b"sta:bon:"; -pub const CODE_OF: &[u8] = b"sta:cod:"; -pub const STORAGE_OF: &[u8] = b"sta:sto:"; - -pub struct IntentionStorageVec {} -impl StorageVec for IntentionStorageVec { - type Item = AccountId; - const PREFIX: &'static[u8] = INTENTION_AT; -} - -/// The fee to be paid for making a transaction. -pub fn transaction_fee() -> Balance { - storage::get(TRANSACTION_FEE).expect("All basic parameters should be defined") -} - -/// The length of the bonding duration in eras. -pub fn bonding_duration() -> BlockNumber { - storage::get_or_default(BONDING_DURATION) -} - -/// The length of a staking era in sessions. -pub fn validator_count() -> usize { - storage::get_or_default::(VALIDATOR_COUNT) as usize +storage_items! { + // The length of the bonding duration in eras. + pub BondingDuration get(bonding_duration): b"sta:loc" => required BlockNumber; + // The length of a staking era in sessions. + pub ValidatorCount get(validator_count): b"sta:vac" => required u32; + // The length of a staking era in sessions. + pub SessionsPerEra get(sessions_per_era): b"sta:spe" => required BlockNumber; + // The total amount of stake on the system. + pub TotalStake get(total_stake): b"sta:tot" => required Balance; + // The fee to be paid for making a transaction. + pub TransactionFee get(transaction_fee): b"sta:fee" => required Balance; + + // The current era index. + pub CurrentEra get(current_era): b"sta:era" => required BlockNumber; + // All the accounts with a desire to stake. + pub Intention: b"sta:wil:" => list [ AccountId ]; + // The next value of sessions per era. + pub NextSessionsPerEra get(next_sessions_per_era): b"sta:nse" => BlockNumber; + // The block number at which the era length last changed. + pub LastEraLengthChange get(last_era_length_change): b"sta:lec" => default BlockNumber; + + // The balance of a given account. + pub FreeBalanceOf get(free_balance_of): b"sta:bal:" => default map [ AccountId => Balance ]; + + // The amount of the balance of a given account that is exterally reserved; this can still get + // slashed, but gets slashed last of all. + pub ReservedBalanceOf get(reserved_balance_of): b"sta:lbo:" => default map [ AccountId => Balance ]; + + // The block at which the `who`'s funds become entirely liquid. + pub BondageOf get(bondage_of): b"sta:bon:" => default map [ AccountId => Bondage ]; + + // The code associated with an account. + pub CodeOf: b"sta:cod:" => default map [ AccountId => Vec ]; // TODO Vec values should be optimised to not do a length prefix. + + // The storage items associated with an account/key. + pub StorageOf: b"sta:sto:" => map [ (AccountId, Vec) => Vec ]; // TODO: keys should also be able to take AsRef to ensure Vecs can be passed as &[u8] } /// The length of a staking era in blocks. pub fn era_length() -> BlockNumber { - sessions_per_era() * session::length() + SessionsPerEra::get() * session::length() } -/// The length of a staking era in sessions. -pub fn sessions_per_era() -> BlockNumber { - storage::get_or_default(SESSIONS_PER_ERA) -} - -/// The current era index. -pub fn current_era() -> BlockNumber { - storage::get_or_default(CURRENT_ERA) -} - -/// The block number at which the era length last changed. -pub fn last_era_length_change() -> BlockNumber { - storage::get_or_default(LAST_ERA_LENGTH_CHANGE) -} - -/// The balance of a given account. +/// The combined balance of `who`. pub fn balance(who: &AccountId) -> Balance { - free_balance(who) + reserved_balance(who) -} - -/// The balance of a given account. -pub fn free_balance(who: &AccountId) -> Balance { - storage::get_or_default(&who.to_keyed_vec(BALANCE_OF)) -} - -/// The amount of the balance of a given account that is exterally reserved; this can still get -/// slashed, but gets slashed last of all. -pub fn reserved_balance(who: &AccountId) -> Balance { - storage::get_or_default(&who.to_keyed_vec(RESERVED_BALANCE_OF)) + FreeBalanceOf::get(who) + ReservedBalanceOf::get(who) } /// Some result as `slash(who, value)` (but without the side-effects) asuming there are no @@ -112,11 +86,6 @@ pub fn can_slash(who: &AccountId, value: Balance) -> bool { balance(who) >= value } -/// The block at which the `who`'s funds become entirely liquid. -pub fn bondage(who: &AccountId) -> Bondage { - storage::get_or_default(&who.to_keyed_vec(BONDAGE_OF)) -} - #[derive(PartialEq, Copy, Clone)] #[cfg_attr(test, derive(Debug))] pub enum LockStatus { @@ -127,28 +96,23 @@ pub enum LockStatus { /// The block at which the `who`'s funds become entirely liquid. pub fn unlock_block(who: &AccountId) -> LockStatus { - match bondage(who) { + match BondageOf::get(who) { i if i == Bondage::max_value() => LockStatus::Staked, i if i <= system::block_number() => LockStatus::Liquid, i => LockStatus::LockedUntil(i), } } -/// The total amount of stake on the system. -pub fn total_stake() -> Balance { - storage::get_or(TOTAL_STAKE, 0) -} - pub struct PublicPass<'a> (&'a AccountId); const NOBODY: AccountId = [0u8; 32]; impl<'a> PublicPass<'a> { pub fn new(transactor: &AccountId) -> PublicPass { - let b = free_balance(&transactor); - let transaction_fee = transaction_fee(); + let b = FreeBalanceOf::get(&transactor); + let transaction_fee = TransactionFee::get(); assert!(b >= transaction_fee, "attempt to transact without enough funds to pay fee"); - internal::set_free_balance(&transactor, b - transaction_fee); + FreeBalanceOf::insert(transactor, b - transaction_fee); PublicPass(transactor) } @@ -199,26 +163,26 @@ impl<'a> public::Dispatch for PublicPass<'a> { /// /// Effects will be felt at the beginning of the next era. fn stake(self) { - let mut intentions = IntentionStorageVec::items(); + let mut intentions = Intention::items(); // can't be in the list twice. assert!(intentions.iter().find(|&t| *t == *self).is_none(), "Cannot stake if already staked."); intentions.push(self.clone()); - IntentionStorageVec::set_items(&intentions); - storage::put(&self.to_keyed_vec(BONDAGE_OF), &u64::max_value()); + Intention::set_items(&intentions); + BondageOf::insert(*self, u64::max_value()); } /// Retract the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. fn unstake(self) { - let mut intentions = IntentionStorageVec::items(); + let mut intentions = Intention::items(); if let Some(position) = intentions.iter().position(|&t| t == *self) { intentions.swap_remove(position); } else { panic!("Cannot unstake if not already staked."); } - IntentionStorageVec::set_items(&intentions); - storage::put(&self.to_keyed_vec(BONDAGE_OF), &(current_era() + bonding_duration())); + Intention::set_items(&intentions); + BondageOf::insert(*self, CurrentEra::get() + BondingDuration::get()); } } @@ -233,17 +197,17 @@ impl_dispatch! { impl privileged::Dispatch for system::PrivPass { /// Set the number of sessions in an era. fn set_sessions_per_era(self, new: BlockNumber) { - storage::put(NEXT_SESSIONS_PER_ERA, &new); + NextSessionsPerEra::put(&new); } /// The length of the bonding duration in eras. fn set_bonding_duration(self, new: BlockNumber) { - storage::put(BONDING_DURATION, &new); + BondingDuration::put(&new); } /// The length of a staking era in sessions. fn set_validator_count(self, new: u32) { - storage::put(VALIDATOR_COUNT, &new); + ValidatorCount::put(&new); } /// Force there to be a new era. This also forces a new session immediately after. @@ -254,9 +218,9 @@ impl privileged::Dispatch for system::PrivPass { } // Each identity's stake may be in one of three bondage states, given by an integer: -// - n | n <= current_era(): inactive: free to be transferred. +// - n | n <= CurrentEra::get(): inactive: free to be transferred. // - ~0: active: currently representing a validator. -// - n | n > current_era(): deactivating: recently representing a validator and not yet +// - n | n > CurrentEra::get(): deactivating: recently representing a validator and not yet // ready for transfer. mod private { @@ -296,15 +260,13 @@ mod private { pub struct DirectExt; impl Externalities for DirectExt { fn get_storage(&self, account: &AccountId, location: &[u8]) -> Option> { - let mut v = account.to_keyed_vec(STORAGE_OF); - v.extend(location); - storage::get_raw(&v) + StorageOf::get(&(*account, location.to_vec())) } fn get_code(&self, account: &AccountId) -> Vec { - storage::get_raw(&account.to_keyed_vec(CODE_OF)).unwrap_or_default() + CodeOf::get(account) } fn get_balance(&self, account: &AccountId) -> Balance { - storage::get_or_default::(&account.to_keyed_vec(BALANCE_OF)) + FreeBalanceOf::get(account) } } @@ -327,19 +289,16 @@ mod private { pub fn commit_state(s: State) { for (address, changed) in s.into_iter() { if let Some(balance) = changed.balance { - storage::put(&address.to_keyed_vec(BALANCE_OF), &balance); + FreeBalanceOf::insert(address, balance); } if let Some(code) = changed.code { - storage::put(&address.to_keyed_vec(CODE_OF), &code); + CodeOf::insert(&address, &code); } - let storage_key = address.to_keyed_vec(STORAGE_OF); for (k, v) in changed.storage.into_iter() { - let mut key = storage_key.clone(); - key.extend(k); if let Some(value) = v { - storage::put_raw(&key, &value); + StorageOf::insert(&(address, k), &value); } else { - storage::kill(&key); + StorageOf::remove(&(address, k)); } } } @@ -404,7 +363,7 @@ mod private { assert!(from_balance >= value); let to_balance = ext.get_balance(dest); - assert!(bondage(transactor) <= bondage(dest)); + assert!(BondageOf::get(transactor) <= BondageOf::get(dest)); assert!(to_balance + value > to_balance); // no overflow // TODO: a fee, based upon gaslimit/gasprice. @@ -470,17 +429,10 @@ mod private { pub mod internal { use super::*; - /// Set the balance of an account. - /// Needless to say, this is super low-level and accordingly dangerous. Ensure any modules that - /// use it are auditted to the hilt. - pub fn set_free_balance(who: &AccountId, value: Balance) { - storage::put(&who.to_keyed_vec(BALANCE_OF), &value); - } - /// Hook to be called after to transaction processing. pub fn check_new_era() { // check block number and call new_era if necessary. - if (system::block_number() - last_era_length_change()) % era_length() == 0 { + if (system::block_number() - LastEraLengthChange::get()) % era_length() == 0 { new_era(); } } @@ -488,9 +440,9 @@ pub mod internal { /// Deduct from an unbonded balance. true if it happened. pub fn deduct_unbonded(who: &AccountId, value: Balance) -> bool { if let LockStatus::Liquid = unlock_block(who) { - let b = free_balance(who); + let b = FreeBalanceOf::get(who); if b >= value { - set_free_balance(who, b - value); + FreeBalanceOf::insert(who, &(b - value)); return true; } } @@ -499,14 +451,14 @@ pub mod internal { /// Refund some balance. pub fn refund(who: &AccountId, value: Balance) { - set_free_balance(who, free_balance(who) + value) + FreeBalanceOf::insert(who, &(FreeBalanceOf::get(who) + value)) } /// Will slash any balance, but prefer free over reserved. pub fn slash(who: &AccountId, value: Balance) -> bool { - let free_balance = free_balance(who); + let free_balance = FreeBalanceOf::get(who); let free_slash = cmp::min(free_balance, value); - set_free_balance(who, free_balance - free_slash); + FreeBalanceOf::insert(who, &(free_balance - free_slash)); if free_slash < value { slash_reserved(who, value - free_slash) } else { @@ -516,63 +468,59 @@ pub mod internal { /// Moves `value` from balance to reserved balance. pub fn reserve_balance(who: &AccountId, value: Balance) { - let b = free_balance(who); + let b = FreeBalanceOf::get(who); assert!(b >= value); - set_free_balance(who, b - value); - set_reserved_balance(who, reserved_balance(who) + value); + FreeBalanceOf::insert(who, &(b - value)); + ReservedBalanceOf::insert(who, &(ReservedBalanceOf::get(who) + value)); } /// Moves `value` from reserved balance to balance. pub fn unreserve_balance(who: &AccountId, value: Balance) { - let b = reserved_balance(who); + let b = ReservedBalanceOf::get(who); let value = cmp::min(b, value); - set_reserved_balance(who, b - value); - set_free_balance(who, free_balance(who) + value); + ReservedBalanceOf::insert(who, &(b - value)); + FreeBalanceOf::insert(who, &(FreeBalanceOf::get(who) + value)); } /// Moves `value` from reserved balance to balance. pub fn slash_reserved(who: &AccountId, value: Balance) -> bool { - let b = reserved_balance(who); + let b = ReservedBalanceOf::get(who); let slash = cmp::min(b, value); - set_reserved_balance(who, b - slash); + ReservedBalanceOf::insert(who, &(b - slash)); value == slash } /// Moves `value` from reserved balance to balance. pub fn transfer_reserved_balance(slashed: &AccountId, beneficiary: &AccountId, value: Balance) -> bool { - let b = reserved_balance(slashed); + let b = ReservedBalanceOf::get(slashed); let slash = cmp::min(b, value); - set_reserved_balance(slashed, b - slash); - set_free_balance(beneficiary, free_balance(beneficiary) + slash); + ReservedBalanceOf::insert(slashed, &(b - slash)); + FreeBalanceOf::insert(beneficiary, &(FreeBalanceOf::get(beneficiary) + slash)); slash == value } } -/// Set the reserved portion of `who`'s balance. -fn set_reserved_balance(who: &AccountId, value: Balance) { - storage::put(&who.to_keyed_vec(RESERVED_BALANCE_OF), &value); -} - /// The era has changed - enact new staking set. /// /// NOTE: This always happens immediately before a session change to ensure that new validators /// get a chance to set their session keys. fn new_era() { // Increment current era. - storage::put(CURRENT_ERA, &(current_era() + 1)); + CurrentEra::put(&(CurrentEra::get() + 1)); // Enact era length change. - let next_spe: u64 = storage::get_or_default(NEXT_SESSIONS_PER_ERA); - if next_spe > 0 && next_spe != sessions_per_era() { - storage::put(SESSIONS_PER_ERA, &next_spe); - storage::put(LAST_ERA_LENGTH_CHANGE, &system::block_number()); + if let Some(next_spe) = NextSessionsPerEra::get() { + if next_spe != SessionsPerEra::get() { + SessionsPerEra::put(&next_spe); + LastEraLengthChange::put(&system::block_number()); + } } // evaluate desired staking amounts and nominations and optimise to find the best // combination of validators, then use session::internal::set_validators(). // for now, this just orders would-be stakers by their balances and chooses the top-most - // validator_count() of them. - let mut intentions = IntentionStorageVec::items() + // ValidatorCount::get() of them. + let mut intentions = Intention::items() .into_iter() .map(|v| (balance(&v), v)) .collect::>(); @@ -580,7 +528,7 @@ fn new_era() { session::internal::set_validators( &intentions.into_iter() .map(|(_, v)| v) - .take(validator_count()) + .take(ValidatorCount::get() as usize) .collect::>() ); } @@ -597,15 +545,15 @@ pub mod testing { pub fn externalities(session_length: u64, sessions_per_era: u64, current_era: u64) -> TestExternalities { let extras: TestExternalities = map![ - twox_128(INTENTION_COUNT).to_vec() => vec![].and(&3u32), - twox_128(&0u32.to_keyed_vec(INTENTION_AT)).to_vec() => Alice.to_raw_public_vec(), - twox_128(&1u32.to_keyed_vec(INTENTION_AT)).to_vec() => Bob.to_raw_public_vec(), - twox_128(&2u32.to_keyed_vec(INTENTION_AT)).to_vec() => Charlie.to_raw_public_vec(), - twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&sessions_per_era), - twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&3u64), - twox_128(TRANSACTION_FEE).to_vec() => vec![].and(&1u64), - twox_128(CURRENT_ERA).to_vec() => vec![].and(¤t_era), - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&Intention::len_key()).to_vec() => vec![].and(&3u32), + twox_128(&Intention::key_for(0)).to_vec() => Alice.to_raw_public_vec(), + twox_128(&Intention::key_for(1)).to_vec() => Bob.to_raw_public_vec(), + twox_128(&Intention::key_for(2)).to_vec() => Charlie.to_raw_public_vec(), + twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&sessions_per_era), + twox_128(&ValidatorCount::key()).to_vec() => vec![].and(&3u64), + twox_128(&TransactionFee::key()).to_vec() => vec![].and(&1u64), + twox_128(&CurrentEra::key()).to_vec() => vec![].and(¤t_era), + twox_128(&FreeBalanceOf::key_for(&Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ]; session::testing::externalities(session_length).into_iter().chain(extras.into_iter()).collect() } @@ -634,21 +582,21 @@ mod tests { twox_128(session::VALIDATOR_COUNT).to_vec() => vec![].and(&2u32), twox_128(&0u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => vec![10; 32], twox_128(&1u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => vec![20; 32], - twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64), - twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&2u32), - twox_128(BONDING_DURATION).to_vec() => vec![].and(&3u64), - twox_128(TOTAL_STAKE).to_vec() => vec![].and(&100u64), - twox_128(TRANSACTION_FEE).to_vec() => vec![].and(&0u64), - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&10u64), - twox_128(&Bob.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&20u64), - twox_128(&Charlie.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&30u64), - twox_128(&Dave.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&40u64) + twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&2u64), + twox_128(&ValidatorCount::key()).to_vec() => vec![].and(&2u32), + twox_128(&BondingDuration::key()).to_vec() => vec![].and(&3u64), + twox_128(&TotalStake::key()).to_vec() => vec![].and(&100u64), + twox_128(&TransactionFee::key()).to_vec() => vec![].and(&0u64), + twox_128(&FreeBalanceOf::key_for(&Alice)).to_vec() => vec![].and(&10u64), + twox_128(&FreeBalanceOf::key_for(&Bob)).to_vec() => vec![].and(&20u64), + twox_128(&FreeBalanceOf::key_for(&Charlie)).to_vec() => vec![].and(&30u64), + twox_128(&FreeBalanceOf::key_for(&Dave)).to_vec() => vec![].and(&40u64) ]; with_externalities(&mut t, || { assert_eq!(era_length(), 2u64); - assert_eq!(validator_count(), 2usize); - assert_eq!(bonding_duration(), 3u64); + assert_eq!(ValidatorCount::get(), 2); + assert_eq!(BondingDuration::get(), 3); assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); // Block 1: Add three validators. No obvious change. @@ -702,75 +650,75 @@ mod tests { fn staking_eras_work() { let mut t: TestExternalities = map![ twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64), - twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64) + twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&2u64) ]; with_externalities(&mut t, || { assert_eq!(era_length(), 2u64); - assert_eq!(sessions_per_era(), 2u64); - assert_eq!(last_era_length_change(), 0u64); - assert_eq!(current_era(), 0u64); + assert_eq!(SessionsPerEra::get(), 2u64); + assert_eq!(LastEraLengthChange::get(), 0u64); + assert_eq!(CurrentEra::get(), 0u64); // Block 1: No change. with_env(|e| e.block_number = 1); check_new_era(); - assert_eq!(sessions_per_era(), 2u64); - assert_eq!(last_era_length_change(), 0u64); - assert_eq!(current_era(), 0u64); + assert_eq!(SessionsPerEra::get(), 2u64); + assert_eq!(LastEraLengthChange::get(), 0u64); + assert_eq!(CurrentEra::get(), 0u64); // Block 2: Simple era change. with_env(|e| e.block_number = 2); check_new_era(); - assert_eq!(sessions_per_era(), 2u64); - assert_eq!(last_era_length_change(), 0u64); - assert_eq!(current_era(), 1u64); + assert_eq!(SessionsPerEra::get(), 2u64); + assert_eq!(LastEraLengthChange::get(), 0u64); + assert_eq!(CurrentEra::get(), 1u64); // Block 3: Schedule an era length change; no visible changes. with_env(|e| e.block_number = 3); PrivPass.set_sessions_per_era(3); check_new_era(); - assert_eq!(sessions_per_era(), 2u64); - assert_eq!(last_era_length_change(), 0u64); - assert_eq!(current_era(), 1u64); + assert_eq!(SessionsPerEra::get(), 2u64); + assert_eq!(LastEraLengthChange::get(), 0u64); + assert_eq!(CurrentEra::get(), 1u64); // Block 4: Era change kicks in. with_env(|e| e.block_number = 4); check_new_era(); - assert_eq!(sessions_per_era(), 3u64); - assert_eq!(last_era_length_change(), 4u64); - assert_eq!(current_era(), 2u64); + assert_eq!(SessionsPerEra::get(), 3u64); + assert_eq!(LastEraLengthChange::get(), 4u64); + assert_eq!(CurrentEra::get(), 2u64); // Block 5: No change. with_env(|e| e.block_number = 5); check_new_era(); - assert_eq!(sessions_per_era(), 3u64); - assert_eq!(last_era_length_change(), 4u64); - assert_eq!(current_era(), 2u64); + assert_eq!(SessionsPerEra::get(), 3u64); + assert_eq!(LastEraLengthChange::get(), 4u64); + assert_eq!(CurrentEra::get(), 2u64); // Block 6: No change. with_env(|e| e.block_number = 6); check_new_era(); - assert_eq!(sessions_per_era(), 3u64); - assert_eq!(last_era_length_change(), 4u64); - assert_eq!(current_era(), 2u64); + assert_eq!(SessionsPerEra::get(), 3u64); + assert_eq!(LastEraLengthChange::get(), 4u64); + assert_eq!(CurrentEra::get(), 2u64); // Block 7: Era increment. with_env(|e| e.block_number = 7); check_new_era(); - assert_eq!(sessions_per_era(), 3u64); - assert_eq!(last_era_length_change(), 4u64); - assert_eq!(current_era(), 3u64); + assert_eq!(SessionsPerEra::get(), 3u64); + assert_eq!(LastEraLengthChange::get(), 4u64); + assert_eq!(CurrentEra::get(), 3u64); }); } #[test] fn staking_balance_works() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 42); - assert_eq!(free_balance(&Alice), 42); - assert_eq!(reserved_balance(&Alice), 0); + FreeBalanceOf::insert(*Alice, 42); + assert_eq!(FreeBalanceOf::get(&Alice), 42); + assert_eq!(ReservedBalanceOf::get(&Alice), 0); assert_eq!(balance(&Alice), 42); - assert_eq!(free_balance(&Bob), 0); - assert_eq!(reserved_balance(&Bob), 0); + assert_eq!(FreeBalanceOf::get(&Bob), 0); + assert_eq!(ReservedBalanceOf::get(&Bob), 0); assert_eq!(balance(&Bob), 0); }); } @@ -778,7 +726,7 @@ mod tests { #[test] fn staking_balance_transfer_works() { with_externalities(&mut testing::externalities(1, 3, 1), || { - set_free_balance(&Alice, 112); + FreeBalanceOf::insert(*Alice, 112); PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); assert_eq!(balance(&Alice), 42); assert_eq!(balance(&Bob), 69); @@ -789,7 +737,7 @@ mod tests { #[should_panic] fn staking_balance_transfer_when_bonded_panics() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); PublicPass::new(&Alice).stake(); PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); }); @@ -798,17 +746,17 @@ mod tests { #[test] fn reserving_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); assert_eq!(balance(&Alice), 111); - assert_eq!(free_balance(&Alice), 111); - assert_eq!(reserved_balance(&Alice), 0); + assert_eq!(FreeBalanceOf::get(&Alice), 111); + assert_eq!(ReservedBalanceOf::get(&Alice), 0); reserve_balance(&Alice, 69); assert_eq!(balance(&Alice), 111); - assert_eq!(free_balance(&Alice), 42); - assert_eq!(reserved_balance(&Alice), 69); + assert_eq!(FreeBalanceOf::get(&Alice), 42); + assert_eq!(ReservedBalanceOf::get(&Alice), 69); }); } @@ -816,7 +764,7 @@ mod tests { #[should_panic] fn staking_balance_transfer_when_reserved_panics() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 69); PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); }); @@ -825,17 +773,17 @@ mod tests { #[test] fn deducting_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); assert!(deduct_unbonded(&Alice, 69)); - assert_eq!(free_balance(&Alice), 42); + assert_eq!(FreeBalanceOf::get(&Alice), 42); }); } #[test] fn deducting_balance_should_fail_when_bonded() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64), - twox_128(&Alice.to_raw_public().to_keyed_vec(BONDAGE_OF)).to_vec() => vec![].and(&2u64) + twox_128(&FreeBalanceOf::key_for(&Alice)).to_vec() => vec![].and(&111u64), + twox_128(&BondageOf::key_for(&Alice)).to_vec() => vec![].and(&2u64) ]; with_externalities(&mut t, || { with_env(|e| e.block_number = 1); @@ -847,90 +795,90 @@ mod tests { #[test] fn refunding_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 42); + FreeBalanceOf::insert(*Alice, 42); refund(&Alice, 69); - assert_eq!(free_balance(&Alice), 111); + assert_eq!(FreeBalanceOf::get(&Alice), 111); }); } #[test] fn slashing_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 69); assert!(slash(&Alice, 69)); - assert_eq!(free_balance(&Alice), 0); - assert_eq!(reserved_balance(&Alice), 42); + assert_eq!(FreeBalanceOf::get(&Alice), 0); + assert_eq!(ReservedBalanceOf::get(&Alice), 42); }); } #[test] fn slashing_incomplete_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 42); + FreeBalanceOf::insert(*Alice, 42); reserve_balance(&Alice, 21); assert!(!slash(&Alice, 69)); - assert_eq!(free_balance(&Alice), 0); - assert_eq!(reserved_balance(&Alice), 0); + assert_eq!(FreeBalanceOf::get(&Alice), 0); + assert_eq!(ReservedBalanceOf::get(&Alice), 0); }); } #[test] fn unreserving_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); unreserve_balance(&Alice, 42); - assert_eq!(reserved_balance(&Alice), 69); - assert_eq!(free_balance(&Alice), 42); + assert_eq!(ReservedBalanceOf::get(&Alice), 69); + assert_eq!(FreeBalanceOf::get(&Alice), 42); }); } #[test] fn slashing_reserved_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); assert!(slash_reserved(&Alice, 42)); - assert_eq!(reserved_balance(&Alice), 69); - assert_eq!(free_balance(&Alice), 0); + assert_eq!(ReservedBalanceOf::get(&Alice), 69); + assert_eq!(FreeBalanceOf::get(&Alice), 0); }); } #[test] fn slashing_incomplete_reserved_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 42); assert!(!slash_reserved(&Alice, 69)); - assert_eq!(free_balance(&Alice), 69); - assert_eq!(reserved_balance(&Alice), 0); + assert_eq!(FreeBalanceOf::get(&Alice), 69); + assert_eq!(ReservedBalanceOf::get(&Alice), 0); }); } #[test] fn transferring_reserved_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); assert!(transfer_reserved_balance(&Alice, &Bob, 42)); - assert_eq!(reserved_balance(&Alice), 69); - assert_eq!(free_balance(&Alice), 0); - assert_eq!(reserved_balance(&Bob), 0); - assert_eq!(free_balance(&Bob), 42); + assert_eq!(ReservedBalanceOf::get(&Alice), 69); + assert_eq!(FreeBalanceOf::get(&Alice), 0); + assert_eq!(ReservedBalanceOf::get(&Bob), 0); + assert_eq!(FreeBalanceOf::get(&Bob), 42); }); } #[test] fn transferring_incomplete_reserved_balance_should_work() { with_externalities(&mut TestExternalities::default(), || { - set_free_balance(&Alice, 111); + FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 42); assert!(!transfer_reserved_balance(&Alice, &Bob, 69)); - assert_eq!(reserved_balance(&Alice), 0); - assert_eq!(free_balance(&Alice), 69); - assert_eq!(reserved_balance(&Bob), 0); - assert_eq!(free_balance(&Bob), 42); + assert_eq!(ReservedBalanceOf::get(&Alice), 0); + assert_eq!(FreeBalanceOf::get(&Alice), 69); + assert_eq!(ReservedBalanceOf::get(&Bob), 0); + assert_eq!(FreeBalanceOf::get(&Bob), 42); }); } } diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 775642eb854e8..1e61a8324b576 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -30,20 +30,17 @@ use runtime::{staking, session}; use dispatch; storage_items! { - pub Nonce: b"sys:non" => map [ AccountId => TxOrder ]; - pub BlockHash: b"sys:old" => map [ BlockNumber => [u8; 32] ]; + pub Nonce: b"sys:non" => default map [ AccountId => TxOrder ]; + pub BlockHashAt: b"sys:old" => required map [ BlockNumber => Hash ]; } +pub const CODE: &'static[u8] = b":code"; + /// The current block number being processed. Set by `execute_block`. pub fn block_number() -> BlockNumber { with_env(|e| e.block_number) } -/// Get the block hash of a given block (uses storage). -pub fn block_hash(number: BlockNumber) -> Option { - BlockHash::get(&number).map(Into::into) -} - pub struct PrivPass; impl_dispatch! { @@ -54,7 +51,7 @@ impl_dispatch! { impl privileged::Dispatch for PrivPass { /// Set the new code. fn set_code(self, new: Vec) { - storage::unhashed::put_raw(b":code", &new); + storage::unhashed::put_raw(CODE, &new); } } @@ -146,7 +143,7 @@ fn execute_transaction(utx: UncheckedTransaction) { { // check nonce - let expected_nonce: TxOrder = Nonce::get_or(&tx.signed, 0); + let expected_nonce: TxOrder = Nonce::get(&tx.signed); assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); // increment nonce in storage @@ -163,7 +160,7 @@ fn initial_checks(block: &Block) { // check parent_hash is correct. assert!( - header.number > 0 && block_hash(header.number - 1).map(|h| h == header.parent_hash).unwrap_or(false), + header.number > 0 && BlockHashAt::get(&(header.number - 1)) == header.parent_hash, "Parent hash should be valid." ); @@ -192,7 +189,7 @@ fn final_checks(block: &Block) { fn post_finalise(header: &Header) { // store the header hash in storage; we can't do it before otherwise there would be a // cyclic dependency. - BlockHash::insert(&header.number, &header.blake2_256()); + BlockHashAt::insert(&header.number, &header.blake2_256().into()); } #[cfg(feature = "std")] @@ -220,7 +217,7 @@ pub mod testing { pub fn externalities() -> TestExternalities { map![ - twox_128(&BlockHash::key_for(&0)).to_vec() => [69u8; 32].encode() + twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode() ] } } @@ -231,6 +228,7 @@ mod tests { use super::internal::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; + use runtime_support::StorageValue; use codec::{Joiner, KeyedVec, Slicable}; use keyring::Keyring::*; use environment::with_env; @@ -244,8 +242,8 @@ mod tests { #[test] fn staking_balance_transfer_dispatch_works() { let mut t: TestExternalities = map![ - twox_128(&One.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&staking::FreeBalanceOf::key_for(&One)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TransactionFee::key()).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0] ]; let tx = UncheckedTransaction { diff --git a/demo/runtime/src/runtime/timestamp.rs b/demo/runtime/src/runtime/timestamp.rs index 13f8e2502bf73..ed51ebabc7279 100644 --- a/demo/runtime/src/runtime/timestamp.rs +++ b/demo/runtime/src/runtime/timestamp.rs @@ -22,12 +22,9 @@ use runtime::staking::PublicPass; pub type Timestamp = u64; storage_items! { - pub Now: b"tim:val" => Timestamp; + pub Now: b"tim:val" => required Timestamp; } -/// Get the current time. -pub fn get() -> Timestamp { Now::require() } - impl_dispatch! { pub mod public; fn set(now: Timestamp) = 0; @@ -59,9 +56,9 @@ mod tests { ]; with_externalities(&mut t, || { - assert_eq!(get(), 42); + assert_eq!(Now::get(), 42); PublicPass::nobody().set(69); - assert_eq!(get(), 69); + assert_eq!(Now::get(), 69); }); } } diff --git a/substrate/runtime-support/src/lib.rs b/substrate/runtime-support/src/lib.rs index 86c3b589b82d3..b3aea78cbc6e6 100644 --- a/substrate/runtime-support/src/lib.rs +++ b/substrate/runtime-support/src/lib.rs @@ -29,5 +29,5 @@ pub use self::storage::generator::Storage as GenericStorage; pub mod storage; mod hashable; -pub use self::storage::{StorageVec, StorageValue, StorageMap}; +pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap}; pub use self::hashable::Hashable; diff --git a/substrate/runtime-support/src/storage/generator.rs b/substrate/runtime-support/src/storage/generator.rs index 207c27b84bc89..e11596433dc31 100644 --- a/substrate/runtime-support/src/storage/generator.rs +++ b/substrate/runtime-support/src/storage/generator.rs @@ -49,11 +49,35 @@ use codec; use rstd::vec::Vec; +/// Trait to allow passing by either value or reference +pub trait ArgType { + /// Dispatch `f` with argument derived from self. + fn dispatch_with_ref R, R>(self, f: F) -> R; +} + +impl ArgType for V { + fn dispatch_with_ref R, R>(self, f: F) -> R { f(&self) } +} + +impl<'a, V> ArgType for &'a V { + fn dispatch_with_ref R, R>(self, f: F) -> R { f(self) } +} +/* +impl ArgType for AsRef where AsRef: Sized { + fn dispatch_with_ref R, R>(self, f: F) -> R { f(self.as_ref()) } +} +*/ /// Abstraction around storage. pub trait Storage { /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option; + /// Load the bytes of a key from storage. Can panic if the type is incorrect. + fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. + fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } + /// Put a value in under a key. fn put(&self, key: &[u8], val: &T); @@ -66,20 +90,33 @@ pub trait Storage { self.kill(key); value } + + /// Take a value from storage, deleting it after reading. + fn seize(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } + + /// Take a value from storage, deleting it after reading. + fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } } /// A strongly-typed value kept in storage. pub trait StorageValue { + /// The type that get/take returns. + type Query; + /// Get the storage key. fn key() -> &'static [u8]; + /// Load the value from the provided storage instance. - fn get(storage: &S) -> Option; + fn get(storage: &S) -> Self::Query; + + /// Take a value from storage, removing it afterwards. + fn take(storage: &S) -> Self::Query; + /// Store a value under this key into the provded storage instance. - fn put(val: &T, storage: &S); + fn put(val: &T, storage: &S) { storage.put(Self::key(), val) } + /// Clear the storage value. - fn kill(storage: &S); - /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Option; + fn kill(storage: &S) { storage.kill(Self::key()) } } /// A strongly-typed list in storage. @@ -114,6 +151,9 @@ pub trait StorageList { /// A strongly-typed map in storage. pub trait StorageMap { + /// The type that get/take returns. + type Query; + /// Get the prefix key in storage. fn prefix() -> &'static [u8]; @@ -121,7 +161,7 @@ pub trait StorageMap { fn key_for(x: &K) -> Vec; /// Load the value associated with the given key from the map. - fn get(key: &K, storage: &S) -> Option; + fn get(key: &K, storage: &S) -> Self::Query; /// Store a value to be associated with the given key from the map. fn insert(key: &K, val: &V, storage: &S); @@ -130,48 +170,52 @@ pub trait StorageMap { fn remove(key: &K, storage: &S); /// Take the value under a key. - fn take(key: &K, storage: &S) -> Option; + fn take(key: &K, storage: &S) -> Self::Query; } #[macro_export] #[doc(hidden)] macro_rules! __storage_items_internal { // generator for values. - (($($vis:tt)*) $name: ident: $key: expr => $ty:ty) => { + (($($vis:tt)*) ($get_fn:ident) ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { + __storage_items_internal!{ ($($vis)*) () ($gettype) ($getter) ($taker) $name : $key => $ty } + pub fn $get_fn() -> $gettype { $name :: get() } + }; + (($($vis:tt)*) () ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { $($vis)* struct $name; impl $crate::storage::generator::StorageValue<$ty> for $name { + type Query = $gettype; + /// Get the storage key. fn key() -> &'static [u8] { $key } /// Load the value from the provided storage instance. - fn get(storage: &S) -> Option<$ty> { - storage.get($key) - } - - /// Store a value under this key into the provded storage instance. - fn put(val: &$ty, storage: &S) { - storage.put($key, val) - } - - /// Kill the value. - fn kill(storage: &S) { - storage.kill($key) + fn get(storage: &S) -> Self::Query { + storage.$getter($key) } - /// Take and remove the value from the provided storage instance. - fn take(storage: &S) -> Option<$ty> { - storage.take($key) + /// Take a value from storage, removing it afterwards. + fn take(storage: &S) -> Self::Query { + storage.$taker($key) } } }; // generator for maps. - (($($vis:tt)*) $name: ident: $prefix: expr => map [$kty: ty => $ty:ty]) => { + (($($vis:tt)*) ($get_fn:ident) ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { + __storage_items_internal!{ ($($vis)*) () ($gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } + pub fn $get_fn>(key: K) -> $gettype { + key.dispatch_with_ref($name :: get) + } + }; + (($($vis:tt)*) () ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $($vis)* struct $name; impl $crate::storage::generator::StorageMap<$kty, $ty> for $name { + type Query = $gettype; + /// Get the prefix key in storage. fn prefix() -> &'static [u8] { $prefix @@ -185,9 +229,9 @@ macro_rules! __storage_items_internal { } /// Load the value associated with the given key from the map. - fn get(key: &$kty, storage: &S) -> Option<$ty> { + fn get(key: &$kty, storage: &S) -> Self::Query { let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); - storage.get(&key[..]) + storage.$getter(&key[..]) } /// Store a value to be associated with the given key from the map. @@ -202,14 +246,14 @@ macro_rules! __storage_items_internal { } /// Take the value, reading and removing it. - fn take(key: &$kty, storage: &S) -> Option<$ty> { + fn take(key: &$kty, storage: &S) -> Self::Query { let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); - storage.take(&key[..]) + storage.$taker(&key[..]) } } }; // generator for lists. - (($($vis:tt)*) $name: ident: $prefix: expr => list [$ty:ty]) => { + (($($vis:tt)*) $name:ident : $prefix:expr => list [$ty:ty]) => { $($vis)* struct $name; impl $name { @@ -293,29 +337,114 @@ macro_rules! __storage_items_internal { #[macro_export] macro_rules! storage_items { // simple values - ($name: ident: $key: expr => $ty:ty; $($t:tt)*) => { - __storage_items_internal!(() $name: $key => $ty); + ($name:ident : $key:expr => $ty:ty; $($t:tt)*) => { + __storage_items_internal!(() () (Option<$ty>) (get) (take) $name: $key => $ty); + storage_items!($($t)*); + }; + (pub $name:ident : $key:expr => $ty:ty; $($t:tt)*) => { + __storage_items_internal!((pub) () (Option<$ty>) (get) (take) $name: $key => $ty); + storage_items!($($t)*); + }; + ($name:ident : $key:expr => default $ty:ty; $($t:tt)*) => { + __storage_items_internal!(() () ($ty) (get_or_default) (take_or_default) $name: $key => $ty); + storage_items!($($t)*); + }; + (pub $name:ident : $key:expr => default $ty:ty; $($t:tt)*) => { + __storage_items_internal!((pub) () ($ty) (get_or_default) (take_or_default) $name: $key => $ty); + storage_items!($($t)*); + }; + ($name:ident : $key:expr => required $ty:ty; $($t:tt)*) => { + __storage_items_internal!(() () ($ty) (require) (seize) $name: $key => $ty); storage_items!($($t)*); }; - (pub $name: ident: $key: expr => $ty:ty; $($t:tt)*) => { - __storage_items_internal!((pub) $name: $key => $ty); + (pub $name:ident : $key:expr => required $ty:ty; $($t:tt)*) => { + __storage_items_internal!((pub) () ($ty) (require) (seize) $name: $key => $ty); storage_items!($($t)*); }; + + ($name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => { + __storage_items_internal!(() ($getfn) (Option<$ty>) (get) (take) $name: $key => $ty); + storage_items!($($t)*); + }; + (pub $name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => { + __storage_items_internal!((pub) ($getfn) (Option<$ty>) (get) (take) $name: $key => $ty); + storage_items!($($t)*); + }; + ($name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => { + __storage_items_internal!(() ($getfn) ($ty) (get_or_default) (take_or_default) $name: $key => $ty); + storage_items!($($t)*); + }; + (pub $name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => { + __storage_items_internal!((pub) ($getfn) ($ty) (get_or_default) (take_or_default) $name: $key => $ty); + storage_items!($($t)*); + }; + ($name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => { + __storage_items_internal!(() ($getfn) ($ty) (require) (seize) $name: $key => $ty); + storage_items!($($t)*); + }; + (pub $name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => { + __storage_items_internal!((pub) ($getfn) ($ty) (require) (seize) $name: $key => $ty); + storage_items!($($t)*); + }; + // maps - ($name: ident: $prefix: expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => { - __storage_items_internal!(() $name: $prefix => map [$kty => $ty]); + ($name:ident : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!(() () (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + (pub $name:ident : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!((pub) () (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + ($name:ident : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!(() () ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + (pub $name:ident : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!((pub) () ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + ($name:ident : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!(() () ($ty) (require) (seize) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + (pub $name:ident : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!((pub) () ($ty) (require) (seize) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + + ($name:ident get($getfn:ident) : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!(() ($getfn) (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + (pub $name:ident get($getfn:ident) : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!((pub) ($getfn) (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; - (pub $name: ident: $prefix: expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => { - __storage_items_internal!((pub) $name: $prefix => map [$kty => $ty]); + ($name:ident get($getfn:ident) : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!(() ($getfn) ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); storage_items!($($t)*); }; + (pub $name:ident get($getfn:ident) : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!((pub) ($getfn) ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + ($name:ident get($getfn:ident) : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!(() ($getfn) ($ty) (require) (seize) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + (pub $name:ident get($getfn:ident) : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => { + __storage_items_internal!((pub) ($getfn) ($ty) (require) (seize) $name: $prefix => map [$kty => $ty]); + storage_items!($($t)*); + }; + + // lists - ($name: ident: $prefix: expr => list [$ty:ty]; $($t:tt)*) => { + ($name:ident : $prefix:expr => list [$ty:ty]; $($t:tt)*) => { __storage_items_internal!(() $name: $prefix => list [$ty]); storage_items!($($t)*); }; - (pub $name: ident: $prefix: expr => list [$ty:ty]; $($t:tt)*) => { + (pub $name:ident : $prefix:expr => list [$ty:ty]; $($t:tt)*) => { __storage_items_internal!((pub) $name: $prefix => list [$ty]); storage_items!($($t)*); }; @@ -349,7 +478,7 @@ mod tests { Map: b"c:" => map [u32 => [u8; 32]]; } - #[test] + #[test] fn value() { let storage = RefCell::new(HashMap::new()); assert!(Value::get(&storage).is_none()); diff --git a/substrate/runtime-support/src/storage/mod.rs b/substrate/runtime-support/src/storage/mod.rs index 759541a1581de..b0446f576aa53 100644 --- a/substrate/runtime-support/src/storage/mod.rs +++ b/substrate/runtime-support/src/storage/mod.rs @@ -22,6 +22,7 @@ use runtime_io::{self, twox_128}; use codec::{Slicable, KeyedVec, Input}; pub mod generator; +use self::generator::ArgType; // TODO: consider using blake256 to avoid possible preimage attack. @@ -148,57 +149,41 @@ impl ::GenericStorage for RuntimeStorage { /// A trait for working with macro-generated storage values under the substrate storage API. pub trait StorageValue { + /// The type that get/take return. + type Query; + /// Get the storage key. fn key() -> &'static [u8]; /// Load the value from the provided storage instance. - fn get() -> Option; - - /// Load the value from the provided storage instance. - fn require() -> T { Self::get().expect("Required values must be present") } - - /// Load the value from the provided storage instance. - fn get_or(alt: T) -> T { Self::get().unwrap_or(alt) } - - /// Load the value from the provided storage instance. - fn get_or_else T>(alt: F) -> T { Self::get().unwrap_or_else(alt) } - - /// Load the value from the provided storage instance. - fn get_or_default() -> T where T: Default { Self::get().unwrap_or_else(Default::default) } + fn get() -> Self::Query; /// Store a value under this key into the provded storage instance. - fn put(val: &T); + fn put>(val: Arg); /// Clear the storage value. fn kill(); /// Take a value from storage, removing it afterwards. - fn take() -> Option; - - /// Load the value from the provided storage instance. - fn take_or(alt: T) -> T { Self::take().unwrap_or(alt) } - - /// Load the value from the provided storage instance. - fn take_or_else T>(alt: F) -> T { Self::take().unwrap_or_else(alt) } - - /// Load the value from the provided storage instance. - fn take_or_default() -> T where T: Default { Self::take().unwrap_or_else(Default::default) } + fn take() -> Self::Query; } impl StorageValue for U where U: generator::StorageValue { + type Query = U::Query; + fn key() -> &'static [u8] { >::key() } - fn get() -> Option { + fn get() -> Self::Query { U::get(&RuntimeStorage) } - fn put(val: &T) { - U::put(val, &RuntimeStorage) + fn put>(val: Arg) { + val.dispatch_with_ref(|val| U::put(val, &RuntimeStorage)) } fn kill() { U::kill(&RuntimeStorage) } - fn take() -> Option { + fn take() -> Self::Query { U::take(&RuntimeStorage) } } @@ -221,7 +206,7 @@ pub trait StorageList { fn set_items(items: &[T]); /// Set the item at the given index. - fn set_item(index: u32, item: &T); + fn set_item>(index: u32, val: Arg); /// Load the value at given index. Returns `None` if the index is out-of-bounds. fn get(index: u32) -> Option; @@ -254,8 +239,8 @@ impl StorageList for U where U: generator::StorageList { U::set_items(items, &RuntimeStorage) } - fn set_item(index: u32, item: &T) { - U::set_item(index, item, &RuntimeStorage) + fn set_item>(index: u32, val: Arg) { + val.dispatch_with_ref(|val| U::set_item(index, val, &RuntimeStorage)) } fn get(index: u32) -> Option { @@ -273,6 +258,9 @@ impl StorageList for U where U: generator::StorageList { /// A strongly-typed map in storage. pub trait StorageMap { + /// The type that get/take return. + type Query; + /// Get the prefix key in storage. fn prefix() -> &'static [u8]; @@ -280,31 +268,21 @@ pub trait StorageMap { fn key_for(x: &K) -> Vec; /// Load the value associated with the given key from the map. - fn get(key: &K) -> Option; - - /// Load the value from the provided storage instance. - fn require(key: &K) -> V { Self::get(key).expect("Required values must be present") } - - /// Load the value from the provided storage instance. - fn get_or(key: &K, alt: V) -> V { Self::get(key).unwrap_or(alt) } - - /// Load the value from the provided storage instance. - fn get_or_else V>(key: &K, alt: F) -> V { Self::get(key).unwrap_or_else(alt) } - - /// Load the value from the provided storage instance. - fn get_or_default(key: &K) -> V where V: Default { Self::get(key).unwrap_or_else(Default::default) } + fn get(key: &K) -> Self::Query; /// Store a value to be associated with the given key from the map. - fn insert(key: &K, val: &V); + fn insert, ValArg: ArgType>(key: KeyArg, val: ValArg); /// Remove the value under a key. fn remove(key: &K); /// Take the value under a key. - fn take(key: &K) -> Option; + fn take(key: &K) -> Self::Query; } impl StorageMap for U where U: generator::StorageMap { + type Query = U::Query; + fn prefix() -> &'static [u8] { >::prefix() } @@ -313,19 +291,23 @@ impl StorageMap for U where U: generator::Sto >::key_for(item) } - fn get(key: &K) -> Option { + fn get(key: &K) -> Self::Query { U::get(key, &RuntimeStorage) } - fn insert(key: &K, val: &V) { - U::insert(key, val, &RuntimeStorage) + fn insert, ValArg: ArgType>(key: KeyArg, val: ValArg) { + val.dispatch_with_ref(|val| + key.dispatch_with_ref(|key| + U::insert(key, val, &RuntimeStorage) + ) + ) } fn remove(key: &K) { U::remove(key, &RuntimeStorage) } - fn take(key: &K) -> Option { + fn take(key: &K) -> Self::Query { U::take(key, &RuntimeStorage) } } From 1fd6b3e5d27ae4dfbbb64bc880853661aa1cfe27 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 15 Mar 2018 13:11:27 +0100 Subject: [PATCH 12/29] More refactoring. --- demo/runtime/src/genesismap.rs | 13 ++-- demo/runtime/src/runtime/democracy.rs | 22 +++---- demo/runtime/src/runtime/session.rs | 89 ++++++++++----------------- demo/runtime/src/runtime/staking.rs | 8 +-- 4 files changed, 48 insertions(+), 84 deletions(-) diff --git a/demo/runtime/src/genesismap.rs b/demo/runtime/src/genesismap.rs index 024688e2c3e46..936821090080d 100644 --- a/demo/runtime/src/genesismap.rs +++ b/demo/runtime/src/genesismap.rs @@ -80,8 +80,8 @@ impl GenesisConfig { pub fn genesis_map(&self) -> HashMap, Vec> { let wasm_runtime = include_bytes!("../wasm/genesis.wasm").to_vec(); vec![ - (&session::SESSION_LENGTH[..], vec![].and(&self.session_length)), - (&session::VALIDATOR_COUNT[..], vec![].and(&(self.validators.len() as u32))), + (session::SessionLength::key(), vec![].and(&self.session_length)), + (session::Validators::key(), vec![].and(&self.validators)), (&staking::Intention::len_key()[..], vec![].and(&0u32)), (&staking::SessionsPerEra::key()[..], vec![].and(&self.sessions_per_era)), @@ -105,11 +105,8 @@ impl GenesisConfig { (&council_vote::VOTING_PERIOD[..], vec![].and(&self.council_proposal_voting_period)) ].into_iter() .map(|(k, v)| (k.into(), v)) - .chain(self.validators.iter() - .enumerate() - .map(|(i, account)| ((i as u32).to_keyed_vec(session::VALIDATOR_AT), vec![].and(account))) - ).chain(self.balances.iter() - .map(|&(account, balance)| (account.to_keyed_vec(staking::BALANCE_OF), vec![].and(&balance))) + .chain(self.balances.iter() + .map(|&(account, balance)| (staking::FreeBalanceOf::key_for(&account), vec![].and(&balance))) ) .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ @@ -127,6 +124,6 @@ impl GenesisConfig { pub fn additional_storage_with_genesis(genesis_block: &Block) -> HashMap, Vec> { use codec::Slicable; map![ - system::BlockHash::key_for(&0) => genesis_block.header.blake2_256().encode() + system::BlockHashAt::key_for(&0) => genesis_block.header.blake2_256().encode() ] } diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index a86b1139b60ca..20e09f427bb78 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -295,7 +295,7 @@ pub mod internal { // tally up votes for any expiring referenda. for (index, _, proposal, vote_threshold) in maturing_referendums_at(now) { let (approve, against) = tally(index); - let total_stake = staking::TotalStake::get(); + let total_stake = staking::total_stake(); clear_referendum(index); if vote_threshold.approved(approve, against, total_stake) { proposal.dispatch(PrivPass); @@ -341,11 +341,8 @@ pub mod testing { pub fn externalities() -> TestExternalities { map![ - twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64), - twox_128(session::VALIDATOR_COUNT).to_vec() => vec![].and(&3u32), - twox_128(&0u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Alice.to_raw_public_vec(), - twox_128(&1u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Bob.to_raw_public_vec(), - twox_128(&2u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Charlie.to_raw_public_vec(), + twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64), + twox_128(session::Validators::key()).to_vec() => vec![].and(&vec![Alice.to_raw_public(), Bob.into(), Charlie.into()]), twox_128(&staking::Intention::len_key()).to_vec() => vec![].and(&3u32), twox_128(&staking::Intention::key_for(0)).to_vec() => Alice.to_raw_public_vec(), twox_128(&staking::Intention::key_for(1)).to_vec() => Bob.to_raw_public_vec(), @@ -374,7 +371,6 @@ pub mod testing { mod tests { use super::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; - use runtime_support::{StorageValue, StorageMap}; use codec::{KeyedVec, Joiner}; use keyring::Keyring::*; use environment::with_env; @@ -396,8 +392,8 @@ mod tests { assert_eq!(voting_period(), 1u64); assert_eq!(minimum_deposit(), 1u64); assert_eq!(next_free_ref_index(), 0u32); - assert_eq!(staking::SessionsPerEra::get(), 1u64); - assert_eq!(staking::TotalStake::get(), 210u64); + assert_eq!(staking::sessions_per_era(), 1u64); + assert_eq!(staking::total_stake(), 210u64); }); } @@ -521,19 +517,19 @@ mod tests { PublicPass::test(&Alice).vote(0, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); - assert_eq!(staking::BondingDuration::get(), 4u64); + assert_eq!(staking::bonding_duration(), 4u64); with_env(|e| e.block_number = 2); PublicPass::test(&Alice).vote(1, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); - assert_eq!(staking::BondingDuration::get(), 3u64); + assert_eq!(staking::bonding_duration(), 3u64); with_env(|e| e.block_number = 3); PublicPass::test(&Alice).vote(2, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); - assert_eq!(staking::BondingDuration::get(), 2u64); + assert_eq!(staking::bonding_duration(), 2u64); }); } @@ -634,7 +630,7 @@ mod tests { fn passing_low_turnout_voting_should_work() { with_externalities(&mut new_test_ext(), || { assert_eq!(staking::era_length(), 1u64); - assert_eq!(staking::TotalStake::get(), 210u64); + assert_eq!(staking::total_stake(), 210u64); with_env(|e| e.block_number = 1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); diff --git a/demo/runtime/src/runtime/session.rs b/demo/runtime/src/runtime/session.rs index 705b08c5ae06a..81bfac5b1d37c 100644 --- a/demo/runtime/src/runtime/session.rs +++ b/demo/runtime/src/runtime/session.rs @@ -19,49 +19,31 @@ use rstd::prelude::*; use codec::KeyedVec; -use runtime_support::{storage, StorageVec}; +use runtime_support::{storage, StorageValue, StorageMap}; use demo_primitives::{AccountId, SessionKey, BlockNumber}; use runtime::{system, staking, consensus}; use runtime::system::PrivPass; use runtime::staking::PublicPass; -pub const SESSION_LENGTH: &[u8] = b"ses:len"; -pub const CURRENT_INDEX: &[u8] = b"ses:ind"; -pub const LAST_LENGTH_CHANGE: &[u8] = b"ses:llc"; -pub const NEXT_KEY_FOR: &[u8] = b"ses:nxt:"; -pub const NEXT_SESSION_LENGTH: &[u8] = b"ses:nln"; -pub const VALIDATOR_AT: &[u8] = b"ses:val:"; -pub const VALIDATOR_COUNT: &[u8] = b"ses:val:len"; - -struct ValidatorStorageVec {} -impl StorageVec for ValidatorStorageVec { - type Item = AccountId; - const PREFIX: &'static[u8] = VALIDATOR_AT; -} - -/// Get the current set of validators. -pub fn validators() -> Vec { - ValidatorStorageVec::items() -} - -/// The number of blocks in each session. -pub fn length() -> BlockNumber { - storage::get_or(SESSION_LENGTH, 0) +storage_items!{ + // The current set of validators. + pub Validators get(validators): b"ses:val" => required Vec; + // Current length of the session. + pub SessionLength get(length): b"ses:len" => required BlockNumber; + // Current index of the session. + pub CurrentIndex get(current_index): b"ses:ind" => required BlockNumber; + + // Block at which the session length last changed. + LastLengthChange: b"ses:llc" => default BlockNumber; + // The next key for a given validator. + NextKeyFor: b"ses:nxt:" => map [ AccountId => SessionKey ]; + // The next session length. + NextSessionLength: b"ses:nln" => BlockNumber; } /// The number of validators currently. pub fn validator_count() -> u32 { - ValidatorStorageVec::count() as u32 -} - -/// The current era index. -pub fn current_index() -> BlockNumber { - storage::get_or(CURRENT_INDEX, 0) -} - -/// The block number at which the era length last changed. -pub fn last_length_change() -> BlockNumber { - storage::get_or(LAST_LENGTH_CHANGE, 0) + Validators::get().len() as u32 // TODO: can probably optimised } impl_dispatch! { @@ -74,7 +56,7 @@ impl<'a> public::Dispatch for PublicPass<'a> { /// session. fn set_key(self, key: SessionKey) { // set new value for next session - storage::put(&self.to_keyed_vec(NEXT_KEY_FOR), &key); + NextKeyFor::insert(*self, key) } } @@ -87,7 +69,7 @@ impl_dispatch! { impl privileged::Dispatch for PrivPass { /// Set a new era length. Won't kick in until the next era change (at current length). fn set_length(self, new: BlockNumber) { - storage::put(NEXT_SESSION_LENGTH, &new); + NextSessionLength::put(new); } /// Forces a new session. @@ -103,10 +85,10 @@ pub mod internal { /// Set the current set of validators. /// - /// Called by staking::next_era() only. `next_session` should be called after this in order to + /// Called by `staking::next_era()` only. `next_session` should be called after this in order to /// update the session keys to the next validator set. pub fn set_validators(new: &[AccountId]) { - ValidatorStorageVec::set_items(new); + Validators::put(&new.to_vec()); // TODO: optimise. consensus::internal::set_authorities(new); } @@ -115,7 +97,7 @@ pub mod internal { // do this last, after the staking system has had chance to switch out the authorities for the // new set. // check block number and call next_session if necessary. - if (system::block_number() - last_length_change()) % length() == 0 { + if (system::block_number() - LastLengthChange::get()) % length() == 0 { rotate_session(); } } @@ -123,19 +105,17 @@ pub mod internal { /// Move onto next session: register the new authority set. pub fn rotate_session() { // Increment current session index. - storage::put(CURRENT_INDEX, &(current_index() + 1)); + CurrentIndex::put(CurrentIndex::get() + 1); // Enact era length change. - if let Some(next_len) = storage::get::(NEXT_SESSION_LENGTH) { - storage::put(SESSION_LENGTH, &next_len); - storage::put(LAST_LENGTH_CHANGE, &system::block_number()); - storage::kill(NEXT_SESSION_LENGTH); + if let Some(next_len) = NextSessionLength::take() { + SessionLength::put(next_len); + LastLengthChange::put(system::block_number()); } // Update any changes in session keys. validators().iter().enumerate().for_each(|(i, v)| { - let k = v.to_keyed_vec(NEXT_KEY_FOR); - if let Some(n) = storage::take(&k) { + if let Some(n) = NextKeyFor::take(v) { consensus::internal::set_authority(i as u32, &n); } }); @@ -147,20 +127,15 @@ pub mod testing { use super::*; use runtime_io::{twox_128, TestExternalities}; use codec::{Joiner, KeyedVec}; - use keyring::Keyring; + use keyring::Keyring::*; use runtime::system; pub fn externalities(session_length: u64) -> TestExternalities { - let one = Keyring::One.to_raw_public(); - let two = Keyring::Two.to_raw_public(); let three = [3u8; 32]; let extras: TestExternalities = map![ - twox_128(SESSION_LENGTH).to_vec() => vec![].and(&session_length), - twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&3u32), - twox_128(&0u32.to_keyed_vec(VALIDATOR_AT)).to_vec() => one.to_vec(), - twox_128(&1u32.to_keyed_vec(VALIDATOR_AT)).to_vec() => two.to_vec(), - twox_128(&2u32.to_keyed_vec(VALIDATOR_AT)).to_vec() => three.to_vec() + twox_128(SessionLength::key()).to_vec() => vec![].and(&session_length), + twox_128(Validators::key()).to_vec() => vec![].and(&vec![One.into(), Two.into(), three]) ]; system::testing::externalities().into_iter().chain(extras.into_iter()).collect() } @@ -181,11 +156,9 @@ mod tests { fn simple_setup() -> TestExternalities { map![ - twox_128(SESSION_LENGTH).to_vec() => vec![].and(&2u64), + twox_128(SessionLength::key()).to_vec() => vec![].and(&2u64), // the validators (10, 20, ...) - twox_128(b"ses:val:len").to_vec() => vec![].and(&2u32), - twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32], - twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32], + twox_128(Validators::key()).to_vec() => vec![].and(&vec![[10u8; 32], [20; 32]]), // initial session keys (11, 21, ...) b":auth:len".to_vec() => vec![].and(&2u32), 0u32.to_keyed_vec(b":auth:") => vec![11; 32], diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index 4da7654068004..880b899f86f73 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -578,10 +578,8 @@ mod tests { #[test] fn staking_should_work() { let mut t: TestExternalities = map![ - twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64), - twox_128(session::VALIDATOR_COUNT).to_vec() => vec![].and(&2u32), - twox_128(&0u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => vec![10; 32], - twox_128(&1u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => vec![20; 32], + twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64), + twox_128(session::Validators::key()).to_vec() => vec![].and(&vec![[10u8; 32], [20; 32]]), twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&2u64), twox_128(&ValidatorCount::key()).to_vec() => vec![].and(&2u32), twox_128(&BondingDuration::key()).to_vec() => vec![].and(&3u64), @@ -649,7 +647,7 @@ mod tests { #[test] fn staking_eras_work() { let mut t: TestExternalities = map![ - twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64), + twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64), twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&2u64) ]; with_externalities(&mut t, || { From 51b4a8c4d8ac57fd8c1720799b74c036d1af2fa7 Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 15 Mar 2018 14:34:17 +0100 Subject: [PATCH 13/29] Democracy uses new storage API. --- demo/runtime/src/genesismap.rs | 6 +- demo/runtime/src/runtime/democracy.rs | 166 +++++++----------- demo/runtime/src/runtime/staking.rs | 72 ++++---- demo/runtime/src/runtime/system.rs | 2 +- .../runtime-support/src/storage/generator.rs | 54 +++--- substrate/runtime-support/src/storage/mod.rs | 53 ++++-- 6 files changed, 179 insertions(+), 174 deletions(-) diff --git a/demo/runtime/src/genesismap.rs b/demo/runtime/src/genesismap.rs index 936821090080d..1633c271b029d 100644 --- a/demo/runtime/src/genesismap.rs +++ b/demo/runtime/src/genesismap.rs @@ -87,9 +87,9 @@ impl GenesisConfig { (&staking::SessionsPerEra::key()[..], vec![].and(&self.sessions_per_era)), (&staking::CurrentEra::key()[..], vec![].and(&0u64)), - (&democracy::LAUNCH_PERIOD[..], vec![].and(&self.launch_period)), - (&democracy::VOTING_PERIOD[..], vec![].and(&self.voting_period)), - (&democracy::MINIMUM_DEPOSIT[..], vec![].and(&self.minimum_deposit)), + (democracy::LaunchPeriod::key(), vec![].and(&self.launch_period)), + (democracy::VotingPeriod::key(), vec![].and(&self.voting_period)), + (democracy::MinimumDeposit::key(), vec![].and(&self.minimum_deposit)), (&council::CANDIDACY_BOND[..], vec![].and(&self.candidacy_bond)), (&council::VOTING_BOND[..], vec![].and(&self.voter_bond)), diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index 20e09f427bb78..34025bf8f54c0 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -19,7 +19,7 @@ use rstd::prelude::*; use integer_sqrt::IntegerSquareRoot; use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable}; -use runtime_support::storage; +use runtime_support::{StorageValue, StorageMap}; use demo_primitives::{AccountId, Hash, BlockNumber}; use dispatch::PrivCall as Proposal; use runtime::{staking, system, session}; @@ -83,48 +83,36 @@ impl Approved for VoteThreshold { } } -// public proposals -pub const PUBLIC_PROP_COUNT: &[u8] = b"dem:ppc"; // PropIndex -pub const PUBLIC_PROPS: &[u8] = b"dem:pub"; // Vec<(PropIndex, Proposal)> -pub const DEPOSIT_OF: &[u8] = b"dem:dep:"; // PropIndex -> (Balance, Vec) -pub const LAUNCH_PERIOD: &[u8] = b"dem:lau"; // BlockNumber -pub const MINIMUM_DEPOSIT: &[u8] = b"dem:min"; // Balance - -// referenda -pub const VOTING_PERIOD: &[u8] = b"dem:per"; // BlockNumber -pub const REFERENDUM_COUNT: &[u8] = b"dem:rco"; // ReferendumIndex -pub const NEXT_TALLY: &[u8] = b"dem:nxt"; // ReferendumIndex -pub const REFERENDUM_INFO_OF: &[u8] = b"dem:pro:"; // ReferendumIndex -> (BlockNumber, Proposal, VoteThreshold) -pub const VOTERS_FOR: &[u8] = b"dem:vtr:"; // ReferendumIndex -> Vec -pub const VOTE_OF: &[u8] = b"dem:vot:"; // (ReferendumIndex, AccountId) -> bool - -/// The minimum amount to be used as a deposit for a public referendum proposal. -pub fn minimum_deposit() -> Balance { - storage::get(MINIMUM_DEPOSIT) - .expect("all core parameters of council module must be in place") -} - -/// How often (in blocks) to check for new votes. -pub fn voting_period() -> BlockNumber { - storage::get(VOTING_PERIOD) - .expect("all core parameters of council module must be in place") -} - -/// How often (in blocks) new public referenda are launched. -pub fn launch_period() -> BlockNumber { - storage::get(LAUNCH_PERIOD) - .expect("all core parameters of council module must be in place") +storage_items! { + // The number of (public) proposals that have been made so far. + pub PublicPropCount get(public_prop_count): b"dem:ppc" => default PropIndex; + // The public proposals. Unsorted. + pub PublicProps get(public_props): b"dem:pub" => default Vec<(PropIndex, Proposal, AccountId)>; + // Those who have locked a deposit. + pub DepositOf get(deposit_lockers): b"dem:dep:" => map [ PropIndex => (Balance, Vec) ]; + // How often (in blocks) new public referenda are launched. + pub LaunchPeriod get(launch_period): b"dem:lau" => required BlockNumber; + // The minimum amount to be used as a deposit for a public referendum proposal. + pub MinimumDeposit get(minimum_deposit): b"dem:min" => required Balance; + + // How often (in blocks) to check for new votes. + pub VotingPeriod get(voting_period): b"dem:per" => required BlockNumber; + + // The next free referendum index, aka the number of referendums started so far. + pub ReferendumCount get(next_free_ref_index): b"dem:rco" => default ReferendumIndex; + // The next referendum index that should be tallied. + pub NextTally get(next_tally): b"dem:nxt" => default ReferendumIndex; + // Information concerning any given referendum. + pub ReferendumInfoOf get(referendum_info): b"dem:pro:" => map [ ReferendumIndex => (BlockNumber, Proposal, VoteThreshold) ]; + + // Get the voters for the current proposal. + pub VotersFor get(voters_for): b"dem:vtr:" => default map [ ReferendumIndex => Vec ]; + + // Get the vote, if Some, of `who`. + pub VoteOf get(vote_of): b"dem:vot:" => map [ (ReferendumIndex, AccountId) => bool ]; } -/// The public proposals. Unsorted. -pub fn public_props() -> Vec<(PropIndex, Proposal, AccountId)> { - storage::get_or_default(PUBLIC_PROPS) -} - -/// Those who have locked a deposit. -pub fn deposit_lockers(proposal: PropIndex) -> Option<(Balance, Vec)> { - storage::get(&proposal.to_keyed_vec(DEPOSIT_OF)) -} +// public proposals /// Get the amount locked in support of `proposal`; false if proposal isn't a valid proposal /// index. @@ -134,28 +122,13 @@ pub fn locked_for(proposal: PropIndex) -> Option { /// Return true if `ref_index` is an on-going referendum. pub fn is_active_referendum(ref_index: ReferendumIndex) -> bool { - storage::exists(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF)) -} - -/// Get the voters for the current proposal. -pub fn voters_for(ref_index: ReferendumIndex) -> Vec { - storage::get_or_default(&ref_index.to_keyed_vec(VOTERS_FOR)) -} - -/// Get the vote, if Some, of `who`. -pub fn vote_of(who: &AccountId, ref_index: ReferendumIndex) -> Option { - storage::get(&(*who, ref_index).to_keyed_vec(VOTE_OF)) -} - -/// Get the info concerning the next referendum. -pub fn referendum_info(ref_index: ReferendumIndex) -> Option<(BlockNumber, Proposal, VoteThreshold)> { - storage::get(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF)) + ReferendumInfoOf::exists(ref_index) } /// Get all referendums currently active. pub fn active_referendums() -> Vec<(ReferendumIndex, BlockNumber, Proposal, VoteThreshold)> { - let next: ReferendumIndex = storage::get_or_default(NEXT_TALLY); - let last: ReferendumIndex = storage::get_or_default(REFERENDUM_COUNT); + let next = NextTally::get(); + let last = ReferendumCount::get(); (next..last).into_iter() .filter_map(|i| referendum_info(i).map(|(n, p, t)| (i, n, p, t))) .collect() @@ -163,8 +136,8 @@ pub fn active_referendums() -> Vec<(ReferendumIndex, BlockNumber, Proposal, Vote /// Get all referendums ready for tally at block `n`. pub fn maturing_referendums_at(n: BlockNumber) -> Vec<(ReferendumIndex, BlockNumber, Proposal, VoteThreshold)> { - let next: ReferendumIndex = storage::get_or_default(NEXT_TALLY); - let last: ReferendumIndex = storage::get_or_default(REFERENDUM_COUNT); + let next = NextTally::get(); + let last = ReferendumCount::get(); (next..last).into_iter() .filter_map(|i| referendum_info(i).map(|(n, p, t)| (i, n, p, t))) .take_while(|&(_, block_number, _, _)| block_number == n) @@ -174,16 +147,11 @@ pub fn maturing_referendums_at(n: BlockNumber) -> Vec<(ReferendumIndex, BlockNum /// Get the voters for the current proposal. pub fn tally(ref_index: ReferendumIndex) -> (staking::Balance, staking::Balance) { voters_for(ref_index).iter() - .map(|a| (staking::balance(a), vote_of(a, ref_index).expect("all items come from `voters`; for an item to be in `voters` there must be a vote registered; qed"))) + .map(|a| (staking::balance(a), vote_of((ref_index, *a)).expect("all items come from `voters`; for an item to be in `voters` there must be a vote registered; qed"))) .map(|(bal, vote)| if vote { (bal, 0) } else { (0, bal) }) .fold((0, 0), |(a, b), (c, d)| (a + c, b + d)) } -/// Get the next free referendum index, aka the number of referendums started so far. -pub fn next_free_ref_index() -> ReferendumIndex { - storage::get_or_default(REFERENDUM_COUNT) -} - pub type BoxedProposal = Box; impl_dispatch! { @@ -199,24 +167,22 @@ impl<'a> public::Dispatch for PublicPass<'a> { assert!(value >= minimum_deposit()); assert!(staking::internal::deduct_unbonded(&self, value)); - let index: PropIndex = storage::get_or_default(PUBLIC_PROP_COUNT); - storage::put(PUBLIC_PROP_COUNT, &(index + 1)); - storage::put(&index.to_keyed_vec(DEPOSIT_OF), &(value, vec![*self])); + let index = PublicPropCount::get(); + PublicPropCount::put(index + 1); + DepositOf::insert(index, (value, vec![*self])); let mut props = public_props(); props.push((index, (*proposal).clone(), *self)); - storage::put(PUBLIC_PROPS, &props); + PublicProps::put(props); } /// Propose a sensitive action to be taken. fn second(self, proposal: PropIndex) { - let key = proposal.to_keyed_vec(DEPOSIT_OF); - let mut deposit: (Balance, Vec) = - storage::get(&key).expect("can only second an existing proposal"); + let mut deposit = DepositOf::get(proposal).expect("can only second an existing proposal"); assert!(staking::internal::deduct_unbonded(&self, deposit.0)); deposit.1.push(*self); - storage::put(&key, &deposit); + DepositOf::insert(proposal, deposit); } /// Vote in a referendum. If `approve_proposal` is true, the vote is to enact the proposal; @@ -228,13 +194,12 @@ impl<'a> public::Dispatch for PublicPass<'a> { if staking::balance(&self) == 0 { panic!("transactor must have balance to signal approval."); } - let key = (*self, ref_index).to_keyed_vec(VOTE_OF); - if !storage::exists(&key) { + if !VoteOf::exists(&(ref_index, *self)) { let mut voters = voters_for(ref_index); voters.push(self.clone()); - storage::put(&ref_index.to_keyed_vec(VOTERS_FOR), &voters); + VotersFor::insert(ref_index, voters); } - storage::put(&key, &approve_proposal); + VoteOf::insert(&(ref_index, *self), approve_proposal); } } @@ -281,13 +246,12 @@ pub mod internal { { let (prop_index, proposal, _) = public_props.swap_remove(winner_index); let (deposit, depositors): (Balance, Vec) = - storage::take(&prop_index.to_keyed_vec(DEPOSIT_OF)) - .expect("depositors always exist for current proposals"); + DepositOf::take(prop_index).expect("depositors always exist for current proposals"); // refund depositors for d in &depositors { staking::internal::refund(d, deposit); } - storage::put(PUBLIC_PROPS, &public_props); + PublicProps::put(public_props); inject_referendum(now + voting_period(), proposal, VoteThreshold::SuperMajorityApprove); } } @@ -300,7 +264,7 @@ pub mod internal { if vote_threshold.approved(approve, against, total_stake) { proposal.dispatch(PrivPass); } - storage::put(NEXT_TALLY, &(index + 1)); + NextTally::put(index + 1); } } } @@ -316,17 +280,17 @@ fn inject_referendum( panic!("Cannot inject a referendum that ends earlier than preceeding referendum"); } - storage::put(REFERENDUM_COUNT, &(ref_index + 1)); - storage::put(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF), &(end, proposal, vote_threshold)); + ReferendumCount::put(ref_index + 1); + ReferendumInfoOf::insert(ref_index, (end, proposal, vote_threshold)); ref_index } /// Remove all info on a referendum. fn clear_referendum(ref_index: ReferendumIndex) { - storage::kill(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF)); - storage::kill(&ref_index.to_keyed_vec(VOTERS_FOR)); + ReferendumInfoOf::remove(ref_index); + VotersFor::remove(ref_index); for v in voters_for(ref_index) { - storage::kill(&(v, ref_index).to_keyed_vec(VOTE_OF)); + VoteOf::remove((ref_index, v)); } } @@ -347,22 +311,22 @@ pub mod testing { twox_128(&staking::Intention::key_for(0)).to_vec() => Alice.to_raw_public_vec(), twox_128(&staking::Intention::key_for(1)).to_vec() => Bob.to_raw_public_vec(), twox_128(&staking::Intention::key_for(2)).to_vec() => Charlie.to_raw_public_vec(), - twox_128(&staking::FreeBalanceOf::key_for(&Alice)).to_vec() => vec![].and(&10u64), - twox_128(&staking::FreeBalanceOf::key_for(&Bob)).to_vec() => vec![].and(&20u64), - twox_128(&staking::FreeBalanceOf::key_for(&Charlie)).to_vec() => vec![].and(&30u64), - twox_128(&staking::FreeBalanceOf::key_for(&Dave)).to_vec() => vec![].and(&40u64), - twox_128(&staking::FreeBalanceOf::key_for(&Eve)).to_vec() => vec![].and(&50u64), - twox_128(&staking::FreeBalanceOf::key_for(&Ferdie)).to_vec() => vec![].and(&60u64), - twox_128(&staking::FreeBalanceOf::key_for(&One)).to_vec() => vec![].and(&1u64), + twox_128(&staking::FreeBalanceOf::key_for(*Alice)).to_vec() => vec![].and(&10u64), + twox_128(&staking::FreeBalanceOf::key_for(*Bob)).to_vec() => vec![].and(&20u64), + twox_128(&staking::FreeBalanceOf::key_for(*Charlie)).to_vec() => vec![].and(&30u64), + twox_128(&staking::FreeBalanceOf::key_for(*Dave)).to_vec() => vec![].and(&40u64), + twox_128(&staking::FreeBalanceOf::key_for(*Eve)).to_vec() => vec![].and(&50u64), + twox_128(&staking::FreeBalanceOf::key_for(*Ferdie)).to_vec() => vec![].and(&60u64), + twox_128(&staking::FreeBalanceOf::key_for(*One)).to_vec() => vec![].and(&1u64), twox_128(staking::TotalStake::key()).to_vec() => vec![].and(&210u64), twox_128(staking::SessionsPerEra::key()).to_vec() => vec![].and(&1u64), twox_128(staking::ValidatorCount::key()).to_vec() => vec![].and(&3u64), twox_128(staking::CurrentEra::key()).to_vec() => vec![].and(&1u64), twox_128(staking::TransactionFee::key()).to_vec() => vec![].and(&1u64), - twox_128(LAUNCH_PERIOD).to_vec() => vec![].and(&1u64), - twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64), - twox_128(MINIMUM_DEPOSIT).to_vec() => vec![].and(&1u64) + twox_128(LaunchPeriod::key()).to_vec() => vec![].and(&1u64), + twox_128(VotingPeriod::key()).to_vec() => vec![].and(&1u64), + twox_128(MinimumDeposit::key()).to_vec() => vec![].and(&1u64) ] } } @@ -430,7 +394,7 @@ mod tests { assert_eq!(next_free_ref_index(), 1); assert_eq!(voters_for(r), vec![Alice.to_raw_public()]); - assert_eq!(vote_of(&Alice, r), Some(true)); + assert_eq!(vote_of((r, *Alice)), Some(true)); assert_eq!(tally(r), (10, 0)); democracy::internal::end_block(system::block_number()); @@ -545,7 +509,7 @@ mod tests { PublicPass::test(&Alice).vote(r, true); assert_eq!(voters_for(r), vec![Alice.to_raw_public()]); - assert_eq!(vote_of(&Alice, r), Some(true)); + assert_eq!(vote_of((r, *Alice)), Some(true)); assert_eq!(tally(r), (10, 0)); democracy::internal::end_block(system::block_number()); @@ -578,7 +542,7 @@ mod tests { PublicPass::test(&Alice).vote(r, false); assert_eq!(voters_for(r), vec![Alice.to_raw_public()]); - assert_eq!(vote_of(&Alice, r), Some(false)); + assert_eq!(vote_of((r, *Alice)), Some(false)); assert_eq!(tally(r), (0, 10)); democracy::internal::end_block(system::block_number()); diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index 880b899f86f73..ea5114385afe9 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -109,7 +109,7 @@ const NOBODY: AccountId = [0u8; 32]; impl<'a> PublicPass<'a> { pub fn new(transactor: &AccountId) -> PublicPass { - let b = FreeBalanceOf::get(&transactor); + let b = FreeBalanceOf::get(transactor); let transaction_fee = TransactionFee::get(); assert!(b >= transaction_fee, "attempt to transact without enough funds to pay fee"); FreeBalanceOf::insert(transactor, b - transaction_fee); @@ -553,7 +553,7 @@ pub mod testing { twox_128(&ValidatorCount::key()).to_vec() => vec![].and(&3u64), twox_128(&TransactionFee::key()).to_vec() => vec![].and(&1u64), twox_128(&CurrentEra::key()).to_vec() => vec![].and(¤t_era), - twox_128(&FreeBalanceOf::key_for(&Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ]; session::testing::externalities(session_length).into_iter().chain(extras.into_iter()).collect() } @@ -585,10 +585,10 @@ mod tests { twox_128(&BondingDuration::key()).to_vec() => vec![].and(&3u64), twox_128(&TotalStake::key()).to_vec() => vec![].and(&100u64), twox_128(&TransactionFee::key()).to_vec() => vec![].and(&0u64), - twox_128(&FreeBalanceOf::key_for(&Alice)).to_vec() => vec![].and(&10u64), - twox_128(&FreeBalanceOf::key_for(&Bob)).to_vec() => vec![].and(&20u64), - twox_128(&FreeBalanceOf::key_for(&Charlie)).to_vec() => vec![].and(&30u64), - twox_128(&FreeBalanceOf::key_for(&Dave)).to_vec() => vec![].and(&40u64) + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![].and(&10u64), + twox_128(&FreeBalanceOf::key_for(*Bob)).to_vec() => vec![].and(&20u64), + twox_128(&FreeBalanceOf::key_for(*Charlie)).to_vec() => vec![].and(&30u64), + twox_128(&FreeBalanceOf::key_for(*Dave)).to_vec() => vec![].and(&40u64) ]; with_externalities(&mut t, || { @@ -712,11 +712,11 @@ mod tests { fn staking_balance_works() { with_externalities(&mut TestExternalities::default(), || { FreeBalanceOf::insert(*Alice, 42); - assert_eq!(FreeBalanceOf::get(&Alice), 42); - assert_eq!(ReservedBalanceOf::get(&Alice), 0); + assert_eq!(FreeBalanceOf::get(*Alice), 42); + assert_eq!(ReservedBalanceOf::get(*Alice), 0); assert_eq!(balance(&Alice), 42); - assert_eq!(FreeBalanceOf::get(&Bob), 0); - assert_eq!(ReservedBalanceOf::get(&Bob), 0); + assert_eq!(FreeBalanceOf::get(*Bob), 0); + assert_eq!(ReservedBalanceOf::get(*Bob), 0); assert_eq!(balance(&Bob), 0); }); } @@ -747,14 +747,14 @@ mod tests { FreeBalanceOf::insert(*Alice, 111); assert_eq!(balance(&Alice), 111); - assert_eq!(FreeBalanceOf::get(&Alice), 111); - assert_eq!(ReservedBalanceOf::get(&Alice), 0); + assert_eq!(FreeBalanceOf::get(*Alice), 111); + assert_eq!(ReservedBalanceOf::get(*Alice), 0); reserve_balance(&Alice, 69); assert_eq!(balance(&Alice), 111); - assert_eq!(FreeBalanceOf::get(&Alice), 42); - assert_eq!(ReservedBalanceOf::get(&Alice), 69); + assert_eq!(FreeBalanceOf::get(*Alice), 42); + assert_eq!(ReservedBalanceOf::get(*Alice), 69); }); } @@ -773,15 +773,15 @@ mod tests { with_externalities(&mut TestExternalities::default(), || { FreeBalanceOf::insert(*Alice, 111); assert!(deduct_unbonded(&Alice, 69)); - assert_eq!(FreeBalanceOf::get(&Alice), 42); + assert_eq!(FreeBalanceOf::get(*Alice), 42); }); } #[test] fn deducting_balance_should_fail_when_bonded() { let mut t: TestExternalities = map![ - twox_128(&FreeBalanceOf::key_for(&Alice)).to_vec() => vec![].and(&111u64), - twox_128(&BondageOf::key_for(&Alice)).to_vec() => vec![].and(&2u64) + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![].and(&111u64), + twox_128(&BondageOf::key_for(*Alice)).to_vec() => vec![].and(&2u64) ]; with_externalities(&mut t, || { with_env(|e| e.block_number = 1); @@ -795,7 +795,7 @@ mod tests { with_externalities(&mut TestExternalities::default(), || { FreeBalanceOf::insert(*Alice, 42); refund(&Alice, 69); - assert_eq!(FreeBalanceOf::get(&Alice), 111); + assert_eq!(FreeBalanceOf::get(*Alice), 111); }); } @@ -805,8 +805,8 @@ mod tests { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 69); assert!(slash(&Alice, 69)); - assert_eq!(FreeBalanceOf::get(&Alice), 0); - assert_eq!(ReservedBalanceOf::get(&Alice), 42); + assert_eq!(FreeBalanceOf::get(*Alice), 0); + assert_eq!(ReservedBalanceOf::get(*Alice), 42); }); } @@ -816,8 +816,8 @@ mod tests { FreeBalanceOf::insert(*Alice, 42); reserve_balance(&Alice, 21); assert!(!slash(&Alice, 69)); - assert_eq!(FreeBalanceOf::get(&Alice), 0); - assert_eq!(ReservedBalanceOf::get(&Alice), 0); + assert_eq!(FreeBalanceOf::get(*Alice), 0); + assert_eq!(ReservedBalanceOf::get(*Alice), 0); }); } @@ -827,8 +827,8 @@ mod tests { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); unreserve_balance(&Alice, 42); - assert_eq!(ReservedBalanceOf::get(&Alice), 69); - assert_eq!(FreeBalanceOf::get(&Alice), 42); + assert_eq!(ReservedBalanceOf::get(*Alice), 69); + assert_eq!(FreeBalanceOf::get(*Alice), 42); }); } @@ -838,8 +838,8 @@ mod tests { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); assert!(slash_reserved(&Alice, 42)); - assert_eq!(ReservedBalanceOf::get(&Alice), 69); - assert_eq!(FreeBalanceOf::get(&Alice), 0); + assert_eq!(ReservedBalanceOf::get(*Alice), 69); + assert_eq!(FreeBalanceOf::get(*Alice), 0); }); } @@ -849,8 +849,8 @@ mod tests { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 42); assert!(!slash_reserved(&Alice, 69)); - assert_eq!(FreeBalanceOf::get(&Alice), 69); - assert_eq!(ReservedBalanceOf::get(&Alice), 0); + assert_eq!(FreeBalanceOf::get(*Alice), 69); + assert_eq!(ReservedBalanceOf::get(*Alice), 0); }); } @@ -860,10 +860,10 @@ mod tests { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); assert!(transfer_reserved_balance(&Alice, &Bob, 42)); - assert_eq!(ReservedBalanceOf::get(&Alice), 69); - assert_eq!(FreeBalanceOf::get(&Alice), 0); - assert_eq!(ReservedBalanceOf::get(&Bob), 0); - assert_eq!(FreeBalanceOf::get(&Bob), 42); + assert_eq!(ReservedBalanceOf::get(*Alice), 69); + assert_eq!(FreeBalanceOf::get(*Alice), 0); + assert_eq!(ReservedBalanceOf::get(*Bob), 0); + assert_eq!(FreeBalanceOf::get(*Bob), 42); }); } @@ -873,10 +873,10 @@ mod tests { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 42); assert!(!transfer_reserved_balance(&Alice, &Bob, 69)); - assert_eq!(ReservedBalanceOf::get(&Alice), 0); - assert_eq!(FreeBalanceOf::get(&Alice), 69); - assert_eq!(ReservedBalanceOf::get(&Bob), 0); - assert_eq!(FreeBalanceOf::get(&Bob), 42); + assert_eq!(ReservedBalanceOf::get(*Alice), 0); + assert_eq!(FreeBalanceOf::get(*Alice), 69); + assert_eq!(ReservedBalanceOf::get(*Bob), 0); + assert_eq!(FreeBalanceOf::get(*Bob), 42); }); } } diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 1e61a8324b576..7ab4108417c0b 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -242,7 +242,7 @@ mod tests { #[test] fn staking_balance_transfer_dispatch_works() { let mut t: TestExternalities = map![ - twox_128(&staking::FreeBalanceOf::key_for(&One)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(&staking::FreeBalanceOf::key_for(*One)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], twox_128(staking::TransactionFee::key()).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0] ]; diff --git a/substrate/runtime-support/src/storage/generator.rs b/substrate/runtime-support/src/storage/generator.rs index e11596433dc31..f569bb9473b13 100644 --- a/substrate/runtime-support/src/storage/generator.rs +++ b/substrate/runtime-support/src/storage/generator.rs @@ -69,6 +69,9 @@ impl ArgType for AsRef where AsRef: Sized { */ /// Abstraction around storage. pub trait Storage { + /// true if the key exists in storage. + fn exists(&self, key: &[u8]) -> bool; + /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option; @@ -106,6 +109,11 @@ pub trait StorageValue { /// Get the storage key. fn key() -> &'static [u8]; + /// true if the value is defined in storage. + fn exists(storage: &S) -> bool { + storage.exists(Self::key()) + } + /// Load the value from the provided storage instance. fn get(storage: &S) -> Self::Query; @@ -113,10 +121,14 @@ pub trait StorageValue { fn take(storage: &S) -> Self::Query; /// Store a value under this key into the provded storage instance. - fn put(val: &T, storage: &S) { storage.put(Self::key(), val) } + fn put(val: &T, storage: &S) { + storage.put(Self::key(), val) + } /// Clear the storage value. - fn kill(storage: &S) { storage.kill(Self::key()) } + fn kill(storage: &S) { + storage.kill(Self::key()) + } } /// A strongly-typed list in storage. @@ -160,17 +172,26 @@ pub trait StorageMap { /// Get the storage key used to fetch a value corresponding to a specific key. fn key_for(x: &K) -> Vec; + /// true if the value is defined in storage. + fn exists(key: &K, storage: &S) -> bool { + storage.exists(&Self::key_for(key)[..]) + } + /// Load the value associated with the given key from the map. fn get(key: &K, storage: &S) -> Self::Query; + /// Take the value under a key. + fn take(key: &K, storage: &S) -> Self::Query; + /// Store a value to be associated with the given key from the map. - fn insert(key: &K, val: &V, storage: &S); + fn insert(key: &K, val: &V, storage: &S) { + storage.put(&Self::key_for(key)[..], val); + } /// Remove the value under a key. - fn remove(key: &K, storage: &S); - - /// Take the value under a key. - fn take(key: &K, storage: &S) -> Self::Query; + fn remove(key: &K, storage: &S) { + storage.kill(&Self::key_for(key)[..]); + } } #[macro_export] @@ -179,7 +200,7 @@ macro_rules! __storage_items_internal { // generator for values. (($($vis:tt)*) ($get_fn:ident) ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { __storage_items_internal!{ ($($vis)*) () ($gettype) ($getter) ($taker) $name : $key => $ty } - pub fn $get_fn() -> $gettype { $name :: get() } + pub fn $get_fn() -> $gettype { <$name as $crate::storage::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) } }; (($($vis:tt)*) () ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { $($vis)* struct $name; @@ -207,7 +228,7 @@ macro_rules! __storage_items_internal { (($($vis:tt)*) ($get_fn:ident) ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { __storage_items_internal!{ ($($vis)*) () ($gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } pub fn $get_fn>(key: K) -> $gettype { - key.dispatch_with_ref($name :: get) + key.dispatch_with_ref(|k| <$name as $crate::storage::generator::StorageMap<$kty, $ty>> :: get(k, &$crate::storage::RuntimeStorage)) } }; (($($vis:tt)*) () ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { @@ -234,17 +255,6 @@ macro_rules! __storage_items_internal { storage.$getter(&key[..]) } - /// Store a value to be associated with the given key from the map. - fn insert(key: &$kty, val: &$ty, storage: &S) { - let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); - storage.put(&key[..], val); - } - - /// Remove the value from storage. - fn remove(key: &$kty, storage: &S) { - storage.kill(&<$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key)[..]); - } - /// Take the value, reading and removing it. fn take(key: &$kty, storage: &S) -> Self::Query { let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); @@ -459,6 +469,10 @@ mod tests { use super::*; impl Storage for RefCell, Vec>> { + fn exists(&self, key: &[u8]) -> bool { + self.borrow_mut().get(key).is_some() + } + fn get(&self, key: &[u8]) -> Option { self.borrow_mut().get(key).map(|v| T::decode(&mut &v[..]).unwrap()) } diff --git a/substrate/runtime-support/src/storage/mod.rs b/substrate/runtime-support/src/storage/mod.rs index b0446f576aa53..71bd3580fc94b 100644 --- a/substrate/runtime-support/src/storage/mod.rs +++ b/substrate/runtime-support/src/storage/mod.rs @@ -123,9 +123,13 @@ pub fn put_raw(key: &[u8], value: &[u8]) { runtime_io::set_storage(&twox_128(key)[..], value) } -struct RuntimeStorage; +pub struct RuntimeStorage; impl ::GenericStorage for RuntimeStorage { + fn exists(&self, key: &[u8]) -> bool { + super::storage::exists(key) + } + /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option { super::storage::get(key) @@ -155,6 +159,9 @@ pub trait StorageValue { /// Get the storage key. fn key() -> &'static [u8]; + /// Does the value (explicitly) exist in storage? + fn exists() -> bool; + /// Load the value from the provided storage instance. fn get() -> Self::Query; @@ -174,6 +181,9 @@ impl StorageValue for U where U: generator::StorageValue { fn key() -> &'static [u8] { >::key() } + fn exists() -> bool { + U::exists(&RuntimeStorage) + } fn get() -> Self::Query { U::get(&RuntimeStorage) } @@ -265,19 +275,22 @@ pub trait StorageMap { fn prefix() -> &'static [u8]; /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &K) -> Vec; + fn key_for>(key: KeyArg) -> Vec; + + /// Does the value (explicitly) exist in storage? + fn exists>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. - fn get(key: &K) -> Self::Query; + fn get>(key: KeyArg) -> Self::Query; /// Store a value to be associated with the given key from the map. fn insert, ValArg: ArgType>(key: KeyArg, val: ValArg); /// Remove the value under a key. - fn remove(key: &K); + fn remove>(key: KeyArg); /// Take the value under a key. - fn take(key: &K) -> Self::Query; + fn take>(key: KeyArg) -> Self::Query; } impl StorageMap for U where U: generator::StorageMap { @@ -287,12 +300,22 @@ impl StorageMap for U where U: generator::Sto >::prefix() } - fn key_for(item: &K) -> Vec { - >::key_for(item) + fn key_for>(key: KeyArg) -> Vec { + key.dispatch_with_ref(|item| + >::key_for(item) + ) + } + + fn exists>(key: KeyArg) -> bool { + key.dispatch_with_ref(|item| + U::exists(item, &RuntimeStorage) + ) } - fn get(key: &K) -> Self::Query { - U::get(key, &RuntimeStorage) + fn get>(key: KeyArg) -> Self::Query { + key.dispatch_with_ref(|item| + U::get(item, &RuntimeStorage) + ) } fn insert, ValArg: ArgType>(key: KeyArg, val: ValArg) { @@ -303,12 +326,16 @@ impl StorageMap for U where U: generator::Sto ) } - fn remove(key: &K) { - U::remove(key, &RuntimeStorage) + fn remove>(key: KeyArg) { + key.dispatch_with_ref(|key| + U::remove(key, &RuntimeStorage) + ) } - fn take(key: &K) -> Self::Query { - U::take(key, &RuntimeStorage) + fn take>(key: KeyArg) -> Self::Query { + key.dispatch_with_ref(|key| + U::take(key, &RuntimeStorage) + ) } } From 8ada9f726d0dc1a164a0805b0093181d5eab99d2 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 16 Mar 2018 14:42:34 +0100 Subject: [PATCH 14/29] Council uses new RPC. --- demo/runtime/src/genesismap.rs | 22 +- demo/runtime/src/runtime/council.rs | 392 +++++++----------- demo/runtime/src/runtime/council_vote.rs | 96 ++--- .../runtime-support/src/storage/generator.rs | 23 +- substrate/runtime-support/src/storage/mod.rs | 63 ++- 5 files changed, 232 insertions(+), 364 deletions(-) diff --git a/demo/runtime/src/genesismap.rs b/demo/runtime/src/genesismap.rs index 1633c271b029d..5fa83499b335a 100644 --- a/demo/runtime/src/genesismap.rs +++ b/demo/runtime/src/genesismap.rs @@ -91,18 +91,18 @@ impl GenesisConfig { (democracy::VotingPeriod::key(), vec![].and(&self.voting_period)), (democracy::MinimumDeposit::key(), vec![].and(&self.minimum_deposit)), - (&council::CANDIDACY_BOND[..], vec![].and(&self.candidacy_bond)), - (&council::VOTING_BOND[..], vec![].and(&self.voter_bond)), - (&council::PRESENT_SLASH_PER_VOTER[..], vec![].and(&self.present_slash_per_voter)), - (&council::CARRY_COUNT[..], vec![].and(&self.carry_count)), - (&council::PRESENTATION_DURATION[..], vec![].and(&self.presentation_duration)), - (&council::VOTING_PERIOD[..], vec![].and(&self.council_election_voting_period)), - (&council::TERM_DURATION[..], vec![].and(&self.council_term_duration)), - (&council::DESIRED_SEATS[..], vec![].and(&self.desired_seats)), - (&council::INACTIVE_GRACE_PERIOD[..], vec![].and(&self.inactive_grace_period)), + (council::CandidacyBond::key(), vec![].and(&self.candidacy_bond)), + (council::VotingBond::key(), vec![].and(&self.voter_bond)), + (council::PresentSlashPerVoter::key(), vec![].and(&self.present_slash_per_voter)), + (council::CarryCount::key(), vec![].and(&self.carry_count)), + (council::PresentationDuration::key(), vec![].and(&self.presentation_duration)), + (council::VotingPeriod::key(), vec![].and(&self.council_election_voting_period)), + (council::TermDuration::key(), vec![].and(&self.council_term_duration)), + (council::DesiredSeats::key(), vec![].and(&self.desired_seats)), + (council::InactiveGracePeriod::key(), vec![].and(&self.inactive_grace_period)), - (&council_vote::COOLOFF_PERIOD[..], vec![].and(&self.cooloff_period)), - (&council_vote::VOTING_PERIOD[..], vec![].and(&self.council_proposal_voting_period)) + (council_vote::CooloffPeriod::key(), vec![].and(&self.cooloff_period)), + (council_vote::VotingPeriod::key(), vec![].and(&self.council_proposal_voting_period)) ].into_iter() .map(|(k, v)| (k.into(), v)) .chain(self.balances.iter() diff --git a/demo/runtime/src/runtime/council.rs b/demo/runtime/src/runtime/council.rs index ecdc3ea8dba27..6363764f1a2e3 100644 --- a/demo/runtime/src/runtime/council.rs +++ b/demo/runtime/src/runtime/council.rs @@ -18,7 +18,7 @@ use rstd::prelude::*; use codec::KeyedVec; -use runtime_support::storage; +use runtime_support::{StorageMap, StorageValue}; use demo_primitives::{AccountId, Hash, BlockNumber}; use runtime::{staking, system, session}; use runtime::system::PrivPass; @@ -80,103 +80,66 @@ use runtime::staking::{PublicPass, Balance}; pub type VoteIndex = u32; -// parameters -pub const CANDIDACY_BOND: &[u8] = b"cou:cbo"; -pub const VOTING_BOND: &[u8] = b"cou:vbo"; -pub const PRESENT_SLASH_PER_VOTER: &[u8] = b"cou:pss"; -pub const CARRY_COUNT: &[u8] = b"cou:cco"; -pub const PRESENTATION_DURATION: &[u8] = b"cou:pdu"; -pub const INACTIVE_GRACE_PERIOD: &[u8] = b"cou:vgp"; -pub const VOTING_PERIOD: &[u8] = b"cou:per"; -pub const TERM_DURATION: &[u8] = b"cou:trm"; -pub const DESIRED_SEATS: &[u8] = b"cou:sts"; - -// permanent state (always relevant, changes only at the finalisation of voting) -pub const ACTIVE_COUNCIL: &[u8] = b"cou:act"; // Vec<(AccountId, expiry: BlockNumber)> -pub const VOTE_COUNT: &[u8] = b"cou:vco"; // VoteIndex - -// persistent state (always relevant, changes constantly) -pub const APPROVALS_OF: &[u8] = b"cou:apr:"; // Vec -pub const REGISTER_INFO_OF: &[u8] = b"cou:reg:"; // Candidate -> (VoteIndex, u32) -pub const LAST_ACTIVE_OF: &[u8] = b"cou:lac:"; // Voter -> VoteIndex -pub const VOTERS: &[u8] = b"cou:vrs"; // Vec -pub const CANDIDATES: &[u8] = b"cou:can"; // Vec, has holes -pub const CANDIDATE_COUNT: &[u8] = b"cou:cnc"; // u32 - -// temporary state (only relevant during finalisation/presentation) -pub const NEXT_FINALISE: &[u8] = b"cou:nxt"; -pub const SNAPSHOTED_STAKES: &[u8] = b"cou:sss"; // Vec -pub const LEADERBOARD: &[u8] = b"cou:win"; // Vec<(Balance, AccountId)> ORDERED low -> high - -/// How much should be locked up in order to submit one's candidacy. -pub fn candidacy_bond() -> Balance { - storage::get(CANDIDACY_BOND) - .expect("all core parameters of council module must be in place") -} - -/// How much should be locked up in order to be able to submit votes. -pub fn voting_bond() -> Balance { - storage::get(VOTING_BOND) - .expect("all core parameters of council module must be in place") -} - -/// How long to give each top candidate to present themselves after the vote ends. -pub fn presentation_duration() -> BlockNumber { - storage::get(PRESENTATION_DURATION) - .expect("all core parameters of council module must be in place") -} - -/// How often (in blocks) to check for new votes. -pub fn voting_period() -> BlockNumber { - storage::get(VOTING_PERIOD) - .expect("all core parameters of council module must be in place") -} - -/// How many votes need to go by after a voter's last vote before they can be reaped if their -/// approvals are moot. -pub fn inactivity_grace_period() -> VoteIndex { - storage::get(INACTIVE_GRACE_PERIOD) - .expect("all core parameters of council module must be in place") -} - -/// How long each position is active for. -pub fn term_duration() -> BlockNumber { - storage::get(TERM_DURATION) - .expect("all core parameters of council module must be in place") -} - -/// The punishment, per voter, if you provide an invalid presentation. -pub fn present_slash_per_voter() -> Balance { - storage::get(PRESENT_SLASH_PER_VOTER) - .expect("all core parameters of council module must be in place") -} - -/// Number of accounts that should be sitting on the council. -pub fn desired_seats() -> u32 { - storage::get(DESIRED_SEATS) - .expect("all core parameters of council module must be in place") -} - -/// How many runners-up should have their approvals persist until the next vote. -pub fn carry_count() -> u32 { - storage::get(CARRY_COUNT) - .expect("all core parameters of council module must be in place") +storage_items! { + // parameters + // How much should be locked up in order to submit one's candidacy. + pub CandidacyBond get(candidacy_bond): b"cou:cbo" => required Balance; + // How much should be locked up in order to be able to submit votes. + pub VotingBond get(voting_bond): b"cou:vbo" => required Balance; + // The punishment, per voter, if you provide an invalid presentation. + pub PresentSlashPerVoter get(present_slash_per_voter): b"cou:pss" => required Balance; + // How many runners-up should have their approvals persist until the next vote. + pub CarryCount get(carry_count): b"cou:cco" => required u32; + // How long to give each top candidate to present themselves after the vote ends. + pub PresentationDuration get(presentation_duration): b"cou:pdu" => required BlockNumber; + // How many votes need to go by after a voter's last vote before they can be reaped if their + // approvals are moot. + pub InactiveGracePeriod get(inactivity_grace_period): b"cou:vgp" => required VoteIndex; + // How often (in blocks) to check for new votes. + pub VotingPeriod get(voting_period): b"cou:per" => required BlockNumber; + // How long each position is active for. + pub TermDuration get(term_duration): b"cou:trm" => required BlockNumber; + // Number of accounts that should be sitting on the council. + pub DesiredSeats get(desired_seats): b"cou:sts" => required u32; + + // permanent state (always relevant, changes only at the finalisation of voting) + // The current council. When there's a vote going on, this should still be used for executive + // matters. + pub ActiveCouncil get(active_council): b"cou:act" => default Vec<(AccountId, BlockNumber)>; + // The total number of votes that have happened or are in progress. + pub VoteCount get(vote_index): b"cou:vco" => default VoteIndex; + + // persistent state (always relevant, changes constantly) + // The last cleared vote index that this voter was last active at. + pub ApprovalsOf get(approvals_of): b"cou:apr" => default map [ AccountId => Vec ]; + // The vote index and list slot that the candidate `who` was registered or `None` if they are not + // currently registered. + pub RegisterInfoOf get(candidate_reg_info): b"cou:reg" => map [ AccountId => (VoteIndex, u32) ]; + // The last cleared vote index that this voter was last active at. + pub LastActiveOf get(voter_last_active): b"cou:lac" => map [ AccountId => VoteIndex ]; + // The present voter list. + pub Voters get(voters): b"cou:vrs" => default Vec; + // The present candidate list. + pub Candidates get(candidates): b"cou:can" => default Vec; // has holes + pub CandidateCount get(candidate_count): b"cou:cnc" => default u32; + + // temporary state (only relevant during finalisation/presentation) + // The accounts holding the seats that will become free on the next tally. + pub NextFinalise get(next_finalise): b"cou:nxt" => (BlockNumber, u32, Vec); + // The stakes as they were at the point that the vote ended. + pub SnapshotedStakes get(snapshoted_stakes): b"cou:sss" => required Vec; + // Get the leaderboard if we;re in the presentation phase. + pub Leaderboard get(leaderboard): b"cou:win" => Vec<(Balance, AccountId)>; // ORDERED low -> high } /// True if we're currently in a presentation period. pub fn presentation_active() -> bool { - storage::exists(NEXT_FINALISE) -} - -/// The current council. When there's a vote going on, this should still be used for executive -/// matters. -pub fn active_council() -> Vec<(AccountId, BlockNumber)> { - storage::get_or_default(ACTIVE_COUNCIL) + NextFinalise::exists() } /// If `who` a candidate at the moment? pub fn is_a_candidate(who: &AccountId) -> bool { - storage::exists(&who.to_keyed_vec(REGISTER_INFO_OF)) + RegisterInfoOf::exists(who) } /// Determine the block that a vote can happen on which is no less than `n`. @@ -215,47 +178,6 @@ pub fn next_tally() -> Option { } } -/// The accounts holding the seats that will become free on the next tally. -pub fn next_finalise() -> Option<(BlockNumber, u32, Vec)> { - storage::get(NEXT_FINALISE) -} - -/// The total number of votes that have happened or are in progress. -pub fn vote_index() -> VoteIndex { - storage::get_or_default(VOTE_COUNT) -} - -/// The present candidate list. -pub fn candidates() -> Vec { - storage::get_or_default(CANDIDATES) -} - -/// The present voter list. -pub fn voters() -> Vec { - storage::get_or_default(VOTERS) -} - -/// The vote index and list slot that the candidate `who` was registered or `None` if they are not -/// currently registered. -pub fn candidate_reg_info(who: &AccountId) -> Option<(VoteIndex, u32)> { - storage::get(&who.to_keyed_vec(REGISTER_INFO_OF)) -} - -/// The last cleared vote index that this voter was last active at. -pub fn voter_last_active(voter: &AccountId) -> Option { - storage::get(&voter.to_keyed_vec(LAST_ACTIVE_OF)) -} - -/// The last cleared vote index that this voter was last active at. -pub fn approvals_of(voter: &AccountId) -> Vec { - storage::get_or_default(&voter.to_keyed_vec(APPROVALS_OF)) -} - -/// Get the leaderboard if we;re in the presentation phase. -pub fn leaderboard() -> Option> { - storage::get(LEADERBOARD) -} - impl_dispatch! { pub mod public; fn set_approvals(votes: Vec, index: VoteIndex) = 0; @@ -271,17 +193,17 @@ impl<'a> public::Dispatch for PublicPass<'a> { fn set_approvals(self, votes: Vec, index: VoteIndex) { assert!(!presentation_active()); assert_eq!(index, vote_index()); - if !storage::exists(&self.to_keyed_vec(LAST_ACTIVE_OF)) { + if !LastActiveOf::exists(*self) { // not yet a voter - deduct bond. staking::internal::reserve_balance(&self, voting_bond()); - storage::put(VOTERS, &{ - let mut v: Vec = storage::get_or_default(VOTERS); + Voters::put({ + let mut v = Voters::get(); v.push(self.clone()); v }); } - storage::put(&self.to_keyed_vec(APPROVALS_OF), &votes); - storage::put(&self.to_keyed_vec(LAST_ACTIVE_OF), &index); + ApprovalsOf::insert(*self, votes); + LastActiveOf::insert(*self, index); } /// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices @@ -291,7 +213,7 @@ impl<'a> public::Dispatch for PublicPass<'a> { /// May be called by anyone. Returns the voter deposit to `signed`. fn reap_inactive_voter(self, signed_index: u32, who: AccountId, who_index: u32, assumed_vote_index: VoteIndex) { assert!(!presentation_active(), "cannot reap during presentation period"); - assert!(voter_last_active(&self).is_some(), "reaper must be a voter"); + assert!(voter_last_active(*self).is_some(), "reaper must be a voter"); let last_active = voter_last_active(&who).expect("target for inactivity cleanup must be active"); assert!(assumed_vote_index == vote_index(), "vote index not current"); assert!(last_active < assumed_vote_index - inactivity_grace_period(), "cannot reap during grace perid"); @@ -326,7 +248,7 @@ impl<'a> public::Dispatch for PublicPass<'a> { /// Remove a voter. All votes are cancelled and the voter deposit is returned. fn retract_voter(self, index: u32) { assert!(!presentation_active(), "cannot retract when presenting"); - assert!(storage::exists(&self.to_keyed_vec(LAST_ACTIVE_OF)), "cannot retract non-voter"); + assert!(LastActiveOf::exists(*self), "cannot retract non-voter"); let voters = voters(); let index = index as usize; assert!(index < voters.len(), "retraction index invalid"); @@ -343,8 +265,8 @@ impl<'a> public::Dispatch for PublicPass<'a> { assert!(staking::internal::deduct_unbonded(&self, candidacy_bond()), "candidate has not enough funds"); let slot = slot as usize; - let count = storage::get_or_default::(CANDIDATE_COUNT) as usize; - let candidates: Vec = storage::get_or_default(CANDIDATES); + let count = CandidateCount::get() as usize; + let candidates = Candidates::get(); assert!( (slot == count && count == candidates.len()) || (slot < candidates.len() && candidates[slot] == AccountId::default()), @@ -357,20 +279,20 @@ impl<'a> public::Dispatch for PublicPass<'a> { } else { candidates[slot] = self.clone(); } - storage::put(CANDIDATES, &candidates); - storage::put(CANDIDATE_COUNT, &(count as u32 + 1)); - storage::put(&self.to_keyed_vec(REGISTER_INFO_OF), &(vote_index(), slot)); + Candidates::put(candidates); + CandidateCount::put(count as u32 + 1); + RegisterInfoOf::insert(*self, (vote_index(), slot as u32)); } /// Claim that `signed` is one of the top carry_count() + current_vote().1 candidates. - /// Only works if the block number >= current_vote().0 and < current_vote().0 + presentation_duration() + /// Only works if the `block_number >= current_vote().0` and `< current_vote().0 + presentation_duration()`` /// `signed` should have at least fn present_winner(self, candidate: AccountId, total: Balance, index: VoteIndex) { assert_eq!(index, vote_index(), "index not current"); - let (_, _, expiring): (BlockNumber, u32, Vec) = storage::get(NEXT_FINALISE) + let (_, _, expiring) = NextFinalise::get() .expect("cannot present outside of presentation period"); - let stakes: Vec = storage::get_or_default(SNAPSHOTED_STAKES); - let voters: Vec = storage::get_or_default(VOTERS); + let stakes = SnapshotedStakes::get(); + let voters = Voters::get(); let bad_presentation_punishment = present_slash_per_voter() * voters.len() as Balance; assert!(staking::can_slash(&self, bad_presentation_punishment), "presenter must have sufficient slashable funds"); @@ -382,14 +304,14 @@ impl<'a> public::Dispatch for PublicPass<'a> { } let (registered_since, candidate_index): (VoteIndex, u32) = - storage::get(&candidate.to_keyed_vec(REGISTER_INFO_OF)).expect("presented candidate must be current"); + RegisterInfoOf::get(candidate).expect("presented candidate must be current"); let actual_total = voters.iter() .zip(stakes.iter()) .filter_map(|(voter, stake)| match voter_last_active(voter) { Some(b) if b >= registered_since => approvals_of(voter).get(candidate_index as usize) - .and_then(|approved| if *approved { Some(stake) } else { None }), + .and_then(|approved| if *approved { Some(*stake) } else { None }), _ => None, }) .sum(); @@ -398,7 +320,7 @@ impl<'a> public::Dispatch for PublicPass<'a> { // insert into leaderboard leaderboard[0] = (total, candidate.clone()); leaderboard.sort_by_key(|&(t, _)| t); - storage::put(LEADERBOARD, &leaderboard); + Leaderboard::put(leaderboard); } else { staking::internal::slash(&self, bad_presentation_punishment); } @@ -418,7 +340,7 @@ impl privileged::Dispatch for PrivPass { /// election when they expire. If more, then a new vote will be started if one is not already /// in progress. fn set_desired_seats(self, count: u32) { - storage::put(DESIRED_SEATS, &count); + DesiredSeats::put(count); } /// Remove a particular member. A tally will happen instantly (if not already in a presentation @@ -429,19 +351,19 @@ impl privileged::Dispatch for PrivPass { .into_iter() .filter(|i| i.0 != who) .collect(); - storage::put(ACTIVE_COUNCIL, &new_council); + ActiveCouncil::put(new_council); } /// Set the presentation duration. If there is current a vote being presented for, will /// invoke `finalise_vote`. fn set_presentation_duration(self, count: BlockNumber) { - storage::put(PRESENTATION_DURATION, &count); + PresentationDuration::put(count); } /// Set the presentation duration. If there is current a vote being presented for, will /// invoke `finalise_vote`. fn set_term_duration(self, count: BlockNumber) { - storage::put(TERM_DURATION, &count); + TermDuration::put(count); } } @@ -468,9 +390,9 @@ pub mod internal { /// Remove a voter from the system. Trusts that voters()[index] != voter. fn remove_voter(voter: &AccountId, index: usize, mut voters: Vec) { - storage::put(VOTERS, &{ voters.swap_remove(index); voters }); - storage::kill(&voter.to_keyed_vec(APPROVALS_OF)); - storage::kill(&voter.to_keyed_vec(LAST_ACTIVE_OF)); + Voters::put({ voters.swap_remove(index); voters }); + ApprovalsOf::remove(voter); + LastActiveOf::remove(voter); } /// Close the voting, snapshot the staking and the number of seats that are actually up for grabs. @@ -478,18 +400,18 @@ fn start_tally() { let active_council = active_council(); let desired_seats = desired_seats() as usize; let number = system::block_number(); - let expiring = active_council.iter().take_while(|i| i.1 == number).cloned().collect::>(); + let expiring = active_council.iter().take_while(|i| i.1 == number).map(|i| i.0).collect::>(); if active_council.len() - expiring.len() < desired_seats { let empty_seats = desired_seats - (active_council.len() - expiring.len()); - storage::put(NEXT_FINALISE, &(number + presentation_duration(), empty_seats as u32, expiring)); + NextFinalise::put((number + presentation_duration(), empty_seats as u32, expiring)); - let voters: Vec = storage::get_or_default(VOTERS); - let votes: Vec = voters.iter().map(staking::balance).collect(); - storage::put(SNAPSHOTED_STAKES, &votes); + let voters = Voters::get(); + let votes = voters.iter().map(staking::balance).collect::>(); + SnapshotedStakes::put(votes); // initialise leaderboard. let leaderboard_size = empty_seats + carry_count() as usize; - storage::put(LEADERBOARD, &vec![(0 as Balance, AccountId::default()); leaderboard_size]); + Leaderboard::put(vec![(0 as Balance, AccountId::default()); leaderboard_size]); } } @@ -498,10 +420,10 @@ fn start_tally() { /// a new vote is started. /// Clears all presented candidates, returning the bond of the elected ones. fn finalise_tally() { - storage::kill(SNAPSHOTED_STAKES); - let (_, coming, expiring): (BlockNumber, u32, Vec) = storage::take(NEXT_FINALISE) + SnapshotedStakes::kill(); + let (_, coming, expiring): (BlockNumber, u32, Vec) = NextFinalise::take() .expect("finalise can only be called after a tally is started."); - let leaderboard: Vec<(Balance, AccountId)> = storage::take(LEADERBOARD).unwrap_or_default(); + let leaderboard: Vec<(Balance, AccountId)> = Leaderboard::take().unwrap_or_default(); let new_expiry = system::block_number() + term_duration(); // return bond to winners. @@ -526,10 +448,10 @@ fn finalise_tally() { .map(|(_, a)| (a, new_expiry))) .collect(); new_council.sort_by_key(|&(_, expiry)| expiry); - storage::put(ACTIVE_COUNCIL, &new_council); + ActiveCouncil::put(new_council); // clear all except runners-up from candidate list. - let candidates: Vec = storage::get_or_default(CANDIDATES); + let candidates = Candidates::get(); let mut new_candidates = vec![AccountId::default(); candidates.len()]; // shrink later. let runners_up = leaderboard.into_iter() .rev() @@ -544,16 +466,16 @@ fn finalise_tally() { for (old, new) in candidates.iter().zip(new_candidates.iter()) { if old != new { // removed - kill it - storage::kill(&old.to_keyed_vec(REGISTER_INFO_OF)); + RegisterInfoOf::remove(old); } } // discard any superfluous slots. if let Some(last_index) = new_candidates.iter().rposition(|c| *c != AccountId::default()) { new_candidates.truncate(last_index + 1); } - storage::put(CANDIDATES, &(new_candidates)); - storage::put(CANDIDATE_COUNT, &count); - storage::put(VOTE_COUNT, &(vote_index() + 1)); + Candidates::put(new_candidates); + CandidateCount::put(count); + VoteCount::put(vote_index() + 1); } #[cfg(test)] @@ -565,15 +487,15 @@ pub mod testing { pub fn externalities() -> TestExternalities { let extras: TestExternalities = map![ - twox_128(CANDIDACY_BOND).to_vec() => vec![].and(&9u64), - twox_128(VOTING_BOND).to_vec() => vec![].and(&3u64), - twox_128(PRESENT_SLASH_PER_VOTER).to_vec() => vec![].and(&1u64), - twox_128(CARRY_COUNT).to_vec() => vec![].and(&2u32), - twox_128(PRESENTATION_DURATION).to_vec() => vec![].and(&2u64), - twox_128(VOTING_PERIOD).to_vec() => vec![].and(&4u64), - twox_128(TERM_DURATION).to_vec() => vec![].and(&5u64), - twox_128(DESIRED_SEATS).to_vec() => vec![].and(&2u32), - twox_128(INACTIVE_GRACE_PERIOD).to_vec() => vec![].and(&1u32) + twox_128(CandidacyBond::key()).to_vec() => vec![].and(&9u64), + twox_128(VotingBond::key()).to_vec() => vec![].and(&3u64), + twox_128(PresentSlashPerVoter::key()).to_vec() => vec![].and(&1u64), + twox_128(CarryCount::key()).to_vec() => vec![].and(&2u32), + twox_128(PresentationDuration::key()).to_vec() => vec![].and(&2u64), + twox_128(VotingPeriod::key()).to_vec() => vec![].and(&4u64), + twox_128(TermDuration::key()).to_vec() => vec![].and(&5u64), + twox_128(DesiredSeats::key()).to_vec() => vec![].and(&2u32), + twox_128(InactiveGracePeriod::key()).to_vec() => vec![].and(&1u32) ]; democracy::testing::externalities() .into_iter().chain(extras.into_iter()).collect() @@ -621,11 +543,11 @@ mod tests { assert_eq!(candidates(), Vec::::new()); assert_eq!(is_a_candidate(&Alice), false); - assert_eq!(candidate_reg_info(&Alice), None); + assert_eq!(candidate_reg_info(*Alice), None); assert_eq!(voters(), Vec::::new()); - assert_eq!(voter_last_active(&Alice), None); - assert_eq!(approvals_of(&Alice), vec![]); + assert_eq!(voter_last_active(*Alice), None); + assert_eq!(approvals_of(*Alice), vec![]); }); } @@ -634,22 +556,22 @@ mod tests { with_externalities(&mut new_test_ext(), || { with_env(|e| e.block_number = 1); assert_eq!(candidates(), Vec::::new()); - assert_eq!(candidate_reg_info(&Alice), None); - assert_eq!(candidate_reg_info(&Bob), None); + assert_eq!(candidate_reg_info(*Alice), None); + assert_eq!(candidate_reg_info(*Bob), None); assert_eq!(is_a_candidate(&Alice), false); assert_eq!(is_a_candidate(&Bob), false); PublicPass::test(&Alice).submit_candidacy(0); assert_eq!(candidates(), vec![Alice.to_raw_public()]); - assert_eq!(candidate_reg_info(&Alice), Some((0 as VoteIndex, 0u32))); - assert_eq!(candidate_reg_info(&Bob), None); + assert_eq!(candidate_reg_info(*Alice), Some((0 as VoteIndex, 0u32))); + assert_eq!(candidate_reg_info(*Bob), None); assert_eq!(is_a_candidate(&Alice), true); assert_eq!(is_a_candidate(&Bob), false); PublicPass::test(&Bob).submit_candidacy(1); assert_eq!(candidates(), vec![Alice.to_raw_public(), Bob.into()]); - assert_eq!(candidate_reg_info(&Alice), Some((0 as VoteIndex, 0u32))); - assert_eq!(candidate_reg_info(&Bob), Some((0 as VoteIndex, 1u32))); + assert_eq!(candidate_reg_info(*Alice), Some((0 as VoteIndex, 0u32))); + assert_eq!(candidate_reg_info(*Bob), Some((0 as VoteIndex, 1u32))); assert_eq!(is_a_candidate(&Alice), true); assert_eq!(is_a_candidate(&Bob), true); }); @@ -657,9 +579,9 @@ mod tests { fn new_test_ext_with_candidate_holes() -> TestExternalities { let mut t = new_test_ext(); - t.insert(twox_128(CANDIDATES).to_vec(), vec![].and(&vec![AccountId::default(), AccountId::default(), Alice.to_raw_public()])); - t.insert(twox_128(CANDIDATE_COUNT).to_vec(), vec![].and(&1u32)); - t.insert(twox_128(&Alice.to_raw_public().to_keyed_vec(REGISTER_INFO_OF)).to_vec(), vec![].and(&(0 as VoteIndex, 2u32))); + t.insert(twox_128(Candidates::key()).to_vec(), vec![].and(&vec![AccountId::default(), AccountId::default(), Alice.to_raw_public()])); + t.insert(twox_128(CandidateCount::key()).to_vec(), vec![].and(&1u32)); + t.insert(twox_128(&RegisterInfoOf::key_for(*Alice)).to_vec(), vec![].and(&(0 as VoteIndex, 2u32))); t } @@ -758,8 +680,8 @@ mod tests { PublicPass::test(&Alice).set_approvals(vec![true], 0); PublicPass::test(&Dave).set_approvals(vec![true], 0); - assert_eq!(approvals_of(&Alice), vec![true]); - assert_eq!(approvals_of(&Dave), vec![true]); + assert_eq!(approvals_of(*Alice), vec![true]); + assert_eq!(approvals_of(*Dave), vec![true]); assert_eq!(voters(), vec![Alice.to_raw_public(), Dave.into()]); PublicPass::test(&Bob).submit_candidacy(1); @@ -768,10 +690,10 @@ mod tests { PublicPass::test(&Bob).set_approvals(vec![false, true, true], 0); PublicPass::test(&Charlie).set_approvals(vec![false, true, true], 0); - assert_eq!(approvals_of(&Alice), vec![true]); - assert_eq!(approvals_of(&Dave), vec![true]); - assert_eq!(approvals_of(&Bob), vec![false, true, true]); - assert_eq!(approvals_of(&Charlie), vec![false, true, true]); + assert_eq!(approvals_of(*Alice), vec![true]); + assert_eq!(approvals_of(*Dave), vec![true]); + assert_eq!(approvals_of(*Bob), vec![false, true, true]); + assert_eq!(approvals_of(*Charlie), vec![false, true, true]); assert_eq!(voters(), vec![Alice.to_raw_public(), Dave.into(), Bob.into(), Charlie.into()]); }); @@ -785,13 +707,13 @@ mod tests { PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Dave).set_approvals(vec![true], 0); - assert_eq!(approvals_of(&Dave), vec![true]); + assert_eq!(approvals_of(*Dave), vec![true]); PublicPass::test(&Bob).submit_candidacy(1); PublicPass::test(&Charlie).submit_candidacy(2); PublicPass::test(&Dave).set_approvals(vec![true, false, true], 0); - assert_eq!(approvals_of(&Dave), vec![true, false, true]); + assert_eq!(approvals_of(*Dave), vec![true, false, true]); }); } @@ -810,34 +732,34 @@ mod tests { PublicPass::test(&Dave).set_approvals(vec![true, false, true], 0); assert_eq!(voters(), vec![Alice.to_raw_public(), Bob.into(), Charlie.into(), Dave.into()]); - assert_eq!(approvals_of(&Alice), vec![true]); - assert_eq!(approvals_of(&Bob), vec![false, true, true]); - assert_eq!(approvals_of(&Charlie), vec![false, true, true]); - assert_eq!(approvals_of(&Dave), vec![true, false, true]); + assert_eq!(approvals_of(*Alice), vec![true]); + assert_eq!(approvals_of(*Bob), vec![false, true, true]); + assert_eq!(approvals_of(*Charlie), vec![false, true, true]); + assert_eq!(approvals_of(*Dave), vec![true, false, true]); PublicPass::test(&Alice).retract_voter(0); assert_eq!(voters(), vec![Dave.to_raw_public(), Bob.into(), Charlie.into()]); - assert_eq!(approvals_of(&Alice), Vec::::new()); - assert_eq!(approvals_of(&Bob), vec![false, true, true]); - assert_eq!(approvals_of(&Charlie), vec![false, true, true]); - assert_eq!(approvals_of(&Dave), vec![true, false, true]); + assert_eq!(approvals_of(*Alice), Vec::::new()); + assert_eq!(approvals_of(*Bob), vec![false, true, true]); + assert_eq!(approvals_of(*Charlie), vec![false, true, true]); + assert_eq!(approvals_of(*Dave), vec![true, false, true]); PublicPass::test(&Bob).retract_voter(1); assert_eq!(voters(), vec![Dave.to_raw_public(), Charlie.into()]); - assert_eq!(approvals_of(&Alice), Vec::::new()); - assert_eq!(approvals_of(&Bob), Vec::::new()); - assert_eq!(approvals_of(&Charlie), vec![false, true, true]); - assert_eq!(approvals_of(&Dave), vec![true, false, true]); + assert_eq!(approvals_of(*Alice), Vec::::new()); + assert_eq!(approvals_of(*Bob), Vec::::new()); + assert_eq!(approvals_of(*Charlie), vec![false, true, true]); + assert_eq!(approvals_of(*Dave), vec![true, false, true]); PublicPass::test(&Charlie).retract_voter(1); assert_eq!(voters(), vec![Dave.to_raw_public()]); - assert_eq!(approvals_of(&Alice), Vec::::new()); - assert_eq!(approvals_of(&Bob), Vec::::new()); - assert_eq!(approvals_of(&Charlie), Vec::::new()); - assert_eq!(approvals_of(&Dave), vec![true, false, true]); + assert_eq!(approvals_of(*Alice), Vec::::new()); + assert_eq!(approvals_of(*Bob), Vec::::new()); + assert_eq!(approvals_of(*Charlie), Vec::::new()); + assert_eq!(approvals_of(*Dave), vec![true, false, true]); }); } @@ -901,8 +823,8 @@ mod tests { assert!(!is_a_candidate(&Bob)); assert!(!is_a_candidate(&Eve)); assert_eq!(vote_index(), 1); - assert_eq!(voter_last_active(&Bob), Some(0)); - assert_eq!(voter_last_active(&Eve), Some(0)); + assert_eq!(voter_last_active(*Bob), Some(0)); + assert_eq!(voter_last_active(*Eve), Some(0)); }); } @@ -957,7 +879,7 @@ mod tests { ); assert_eq!(voters(), vec![Eve.to_raw_public()]); - assert_eq!(approvals_of(&Bob).len(), 0); + assert_eq!(approvals_of(*Bob).len(), 0); assert_eq!(staking::balance(&Bob), 17); assert_eq!(staking::balance(&Eve), 53); }); @@ -1017,7 +939,7 @@ mod tests { ); assert_eq!(voters(), vec![Eve.to_raw_public()]); - assert_eq!(approvals_of(&Bob).len(), 0); + assert_eq!(approvals_of(*Bob).len(), 0); assert_eq!(staking::balance(&Bob), 17); assert_eq!(staking::balance(&Eve), 53); }); @@ -1120,7 +1042,7 @@ mod tests { ); assert_eq!(voters(), vec![Bob.to_raw_public(), Charlie.into(), Eve.into()]); - assert_eq!(approvals_of(&Dave).len(), 0); + assert_eq!(approvals_of(*Dave).len(), 0); assert_eq!(staking::balance(&Dave), 37); }); } @@ -1327,13 +1249,13 @@ mod tests { assert!(is_a_candidate(&Charlie)); assert!(is_a_candidate(&Dave)); assert_eq!(vote_index(), 1); - assert_eq!(voter_last_active(&Bob), Some(0)); - assert_eq!(voter_last_active(&Charlie), Some(0)); - assert_eq!(voter_last_active(&Dave), Some(0)); - assert_eq!(voter_last_active(&Eve), Some(0)); - assert_eq!(voter_last_active(&Ferdie), Some(0)); - assert_eq!(candidate_reg_info(&Charlie), Some((0, 2))); - assert_eq!(candidate_reg_info(&Dave), Some((0, 3))); + assert_eq!(voter_last_active(*Bob), Some(0)); + assert_eq!(voter_last_active(*Charlie), Some(0)); + assert_eq!(voter_last_active(*Dave), Some(0)); + assert_eq!(voter_last_active(*Eve), Some(0)); + assert_eq!(voter_last_active(*Ferdie), Some(0)); + assert_eq!(candidate_reg_info(*Charlie), Some((0, 2))); + assert_eq!(candidate_reg_info(*Dave), Some((0, 3))); }); } @@ -1379,13 +1301,13 @@ mod tests { assert!(!is_a_candidate(&Eve)); assert!(is_a_candidate(&Dave)); assert_eq!(vote_index(), 2); - assert_eq!(voter_last_active(&Bob), Some(0)); - assert_eq!(voter_last_active(&Charlie), Some(0)); - assert_eq!(voter_last_active(&Dave), Some(0)); - assert_eq!(voter_last_active(&Eve), Some(0)); - assert_eq!(voter_last_active(&Ferdie), Some(1)); + assert_eq!(voter_last_active(*Bob), Some(0)); + assert_eq!(voter_last_active(*Charlie), Some(0)); + assert_eq!(voter_last_active(*Dave), Some(0)); + assert_eq!(voter_last_active(*Eve), Some(0)); + assert_eq!(voter_last_active(*Ferdie), Some(1)); - assert_eq!(candidate_reg_info(&Dave), Some((0, 3))); + assert_eq!(candidate_reg_info(*Dave), Some((0, 3))); }); } } diff --git a/demo/runtime/src/runtime/council_vote.rs b/demo/runtime/src/runtime/council_vote.rs index fbcf2d59c1558..7c701edd28adc 100644 --- a/demo/runtime/src/runtime/council_vote.rs +++ b/demo/runtime/src/runtime/council_vote.rs @@ -17,9 +17,10 @@ //! Council voting system. use rstd::prelude::*; +use rstd::borrow::Borrow; use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable}; use runtime_support::Hashable; -use runtime_support::storage; +use runtime_support::{StorageValue, StorageMap}; use demo_primitives::{AccountId, Hash, BlockNumber}; use runtime::{system, democracy, council}; use runtime::staking::{PublicPass, Balance}; @@ -28,43 +29,28 @@ use dispatch::PrivCall as Proposal; type ProposalHash = [u8; 32]; -pub const COOLOFF_PERIOD: &[u8] = b"cov:cooloff"; // BlockNumber -pub const VOTING_PERIOD: &[u8] = b"cov:period"; // BlockNumber - -pub const PROPOSALS: &[u8] = b"cov:prs"; // Vec<(expiry: BlockNumber, ProposalHash)> ordered by expiry. -pub const PROPOSAL_OF: &[u8] = b"cov:pro"; // ProposalHash -> Proposal -pub const PROPOSAL_VOTERS: &[u8] = b"cov:voters:"; // ProposalHash -> Vec -pub const COUNCIL_VOTE_OF: &[u8] = b"cov:vote:"; // (ProposalHash, AccountId) -> bool -pub const VETOED_PROPOSAL: &[u8] = b"cov:veto:"; // ProposalHash -> (BlockNumber, sorted_vetoers: Vec) - -pub fn cooloff_period() -> BlockNumber { - storage::get(COOLOFF_PERIOD).expect("all parameters must be defined") -} - -pub fn voting_period() -> BlockNumber { - storage::get(VOTING_PERIOD).expect("all parameters must be defined") -} - -pub fn proposals() -> Vec<(BlockNumber, ProposalHash)> { - storage::get_or_default(PROPOSALS) +storage_items! { + pub CooloffPeriod get(cooloff_period): b"cov:cooloff" => required BlockNumber; + pub VotingPeriod get(voting_period): b"cov:period" => required BlockNumber; + pub Proposals get(proposals): b"cov:prs" => default Vec<(BlockNumber, ProposalHash)>; // ordered by expiry. + pub ProposalOf get(proposal_of): b"cov:pro" => map [ ProposalHash => Proposal ]; + pub ProposalVoters get(proposal_voters): b"cov:voters:" => default map [ ProposalHash => Vec ]; + pub CouncilVoteOf get(vote_of): b"cov:vote:" => map [ (ProposalHash, AccountId) => bool ]; + pub VetoedProposal get(veto_of): b"cov:veto:" => map [ ProposalHash => (BlockNumber, Vec) ]; } -pub fn is_vetoed(proposal: &ProposalHash) -> bool { - storage::get(&proposal.to_keyed_vec(VETOED_PROPOSAL)) +pub fn is_vetoed>(proposal: B) -> bool { + VetoedProposal::get(proposal.borrow()) .map(|(expiry, _): (BlockNumber, Vec)| system::block_number() < expiry) .unwrap_or(false) } -pub fn veto_of(proposal: &ProposalHash) -> Option<(BlockNumber, Vec)> { - storage::get(&proposal.to_keyed_vec(VETOED_PROPOSAL)) -} - fn set_veto_of(proposal: &ProposalHash, expiry: BlockNumber, vetoers: Vec) { - storage::put(&proposal.to_keyed_vec(VETOED_PROPOSAL), &(expiry, vetoers)) + VetoedProposal::insert(proposal, (expiry, vetoers)); } fn kill_veto_of(proposal: &ProposalHash) { - storage::kill(&proposal.to_keyed_vec(VETOED_PROPOSAL)) + VetoedProposal::remove(proposal); } pub fn will_still_be_councillor_at(who: &AccountId, n: BlockNumber) -> bool { @@ -79,20 +65,12 @@ pub fn is_councillor(who: &AccountId) -> bool { .any(|&(ref a, _)| a == who) } -pub fn vote_of(who: &AccountId, proposal: &ProposalHash) -> Option { - storage::get(&(*proposal, *who).to_keyed_vec(COUNCIL_VOTE_OF)) -} - -pub fn proposal_voters(proposal: &ProposalHash) -> Vec { - storage::get_or_default(&proposal.to_keyed_vec(PROPOSAL_VOTERS)) -} - pub fn tally(proposal_hash: &ProposalHash) -> (u32, u32, u32) { - generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| storage::get(&(*p, *w).to_keyed_vec(COUNCIL_VOTE_OF))) + generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| CouncilVoteOf::get((*p, *w))) } fn take_tally(proposal_hash: &ProposalHash) -> (u32, u32, u32) { - generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| storage::get(&(*p, *w).to_keyed_vec(COUNCIL_VOTE_OF))) + generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| CouncilVoteOf::take((*p, *w))) } fn generic_tally Option>(proposal_hash: &ProposalHash, vote_of: F) -> (u32, u32, u32) { @@ -105,7 +83,7 @@ fn generic_tally Option>(proposal_hash } fn set_proposals(p: &Vec<(BlockNumber, ProposalHash)>) { - storage::put(PROPOSALS, p) + Proposals::put(p); } fn take_proposal_if_expiring_at(n: BlockNumber) -> Option<(Proposal, ProposalHash)> { @@ -114,7 +92,7 @@ fn take_proposal_if_expiring_at(n: BlockNumber) -> Option<(Proposal, ProposalHas Some(&(expiry, hash)) if expiry == n => { // yes this is horrible, but fixing it will need substantial work in storage. set_proposals(&proposals[1..].to_vec()); - let proposal = storage::take(&hash.to_keyed_vec(PROPOSAL_OF)).expect("all queued proposal hashes must have associated proposals"); + let proposal = ProposalOf::take(hash).expect("all queued proposal hashes must have associated proposals"); Some((proposal, hash)) } _ => None, @@ -142,23 +120,23 @@ impl<'a> public::Dispatch for PublicPass<'a> { proposals.sort_by_key(|&(expiry, _)| expiry); set_proposals(&proposals); - storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_OF), &proposal); - storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS), &vec![*self]); - storage::put(&(proposal_hash, *self).to_keyed_vec(COUNCIL_VOTE_OF), &true); + ProposalOf::insert(proposal_hash, *proposal); + ProposalVoters::insert(proposal_hash, vec![*self]); + CouncilVoteOf::insert((proposal_hash, *self), true); } fn vote(self, proposal: ProposalHash, approve: bool) { - if vote_of(&self, &proposal).is_none() { + if vote_of((*self, proposal)).is_none() { let mut voters = proposal_voters(&proposal); voters.push(*self); - storage::put(&proposal.to_keyed_vec(PROPOSAL_VOTERS), &voters); + ProposalVoters::insert(proposal, voters); } - storage::put(&(proposal, *self).to_keyed_vec(COUNCIL_VOTE_OF), &approve); + CouncilVoteOf::insert((proposal, *self), approve); } fn veto(self, proposal_hash: ProposalHash) { assert!(is_councillor(&self), "only councillors may veto council proposals"); - assert!(storage::exists(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS)), "proposal must exist to be vetoed"); + assert!(ProposalVoters::exists(&proposal_hash), "proposal must exist to be vetoed"); let mut existing_vetoers = veto_of(&proposal_hash) .map(|pair| pair.1) @@ -169,10 +147,10 @@ impl<'a> public::Dispatch for PublicPass<'a> { set_veto_of(&proposal_hash, system::block_number() + cooloff_period(), existing_vetoers); set_proposals(&proposals().into_iter().filter(|&(_, h)| h != proposal_hash).collect::>()); - storage::kill(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS)); - storage::kill(&proposal_hash.to_keyed_vec(PROPOSAL_OF)); + ProposalVoters::remove(proposal_hash); + ProposalOf::remove(proposal_hash); for (c, _) in council::active_council() { - storage::kill(&(proposal_hash, c).to_keyed_vec(COUNCIL_VOTE_OF)); + CouncilVoteOf::remove((proposal_hash, c)); } } } @@ -185,11 +163,11 @@ impl_dispatch! { impl privileged::Dispatch for PrivPass { fn set_cooloff_period(self, blocks: BlockNumber) { - storage::put(COOLOFF_PERIOD, &blocks); + CooloffPeriod::put(blocks); } fn set_voting_period(self, blocks: BlockNumber) { - storage::put(VOTING_PERIOD, &blocks); + VotingPeriod::put(blocks); } } @@ -230,14 +208,14 @@ pub mod testing { pub fn externalities() -> TestExternalities { let expiry: BlockNumber = 10; let extras: TestExternalities = map![ - twox_128(council::ACTIVE_COUNCIL).to_vec() => vec![].and(&vec![ + twox_128(council::ActiveCouncil::key()).to_vec() => vec![].and(&vec![ (Alice.to_raw_public(), expiry), (Bob.into(), expiry), (Charlie.into(), expiry) ]), - twox_128(COOLOFF_PERIOD).to_vec() => vec![].and(&2u64), - twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64), - twox_128(democracy::VOTING_PERIOD).to_vec() => vec![].and(&3u64) + twox_128(CooloffPeriod::key()).to_vec() => vec![].and(&2u64), + twox_128(VotingPeriod::key()).to_vec() => vec![].and(&1u64), + twox_128(democracy::VotingPeriod::key()).to_vec() => vec![].and(&3u64) ]; council::testing::externalities() .into_iter().chain(extras.into_iter()).collect() @@ -274,9 +252,9 @@ mod tests { assert_eq!(is_councillor(&Alice), true); assert_eq!(is_councillor(&Dave), false); assert_eq!(proposals(), Vec::<(BlockNumber, ProposalHash)>::new()); - assert_eq!(proposal_voters(&ProposalHash::default()), Vec::::new()); + assert_eq!(proposal_voters(ProposalHash::default()), Vec::::new()); assert_eq!(is_vetoed(&ProposalHash::default()), false); - assert_eq!(vote_of(&Alice, &ProposalHash::default()), None); + assert_eq!(vote_of((*Alice, ProposalHash::default())), None); assert_eq!(tally(&ProposalHash::default()), (0, 0, 3)); }); } @@ -447,7 +425,7 @@ mod tests { PublicPass::new(&Alice).propose(Box::new(proposal.clone())); assert_eq!(proposals().len(), 1); assert_eq!(proposal_voters(&hash), vec![Alice.to_raw_public()]); - assert_eq!(vote_of(&Alice, &hash), Some(true)); + assert_eq!(vote_of((*Alice, hash)), Some(true)); assert_eq!(tally(&hash), (1, 0, 2)); }); } diff --git a/substrate/runtime-support/src/storage/generator.rs b/substrate/runtime-support/src/storage/generator.rs index f569bb9473b13..28f7163c4e2c3 100644 --- a/substrate/runtime-support/src/storage/generator.rs +++ b/substrate/runtime-support/src/storage/generator.rs @@ -48,25 +48,8 @@ use codec; use rstd::vec::Vec; +pub use rstd::borrow::Borrow; -/// Trait to allow passing by either value or reference -pub trait ArgType { - /// Dispatch `f` with argument derived from self. - fn dispatch_with_ref R, R>(self, f: F) -> R; -} - -impl ArgType for V { - fn dispatch_with_ref R, R>(self, f: F) -> R { f(&self) } -} - -impl<'a, V> ArgType for &'a V { - fn dispatch_with_ref R, R>(self, f: F) -> R { f(self) } -} -/* -impl ArgType for AsRef where AsRef: Sized { - fn dispatch_with_ref R, R>(self, f: F) -> R { f(self.as_ref()) } -} -*/ /// Abstraction around storage. pub trait Storage { /// true if the key exists in storage. @@ -227,8 +210,8 @@ macro_rules! __storage_items_internal { // generator for maps. (($($vis:tt)*) ($get_fn:ident) ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { __storage_items_internal!{ ($($vis)*) () ($gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } - pub fn $get_fn>(key: K) -> $gettype { - key.dispatch_with_ref(|k| <$name as $crate::storage::generator::StorageMap<$kty, $ty>> :: get(k, &$crate::storage::RuntimeStorage)) + pub fn $get_fn>(key: K) -> $gettype { + <$name as $crate::storage::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) } }; (($($vis:tt)*) () ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { diff --git a/substrate/runtime-support/src/storage/mod.rs b/substrate/runtime-support/src/storage/mod.rs index 71bd3580fc94b..a16339f3dbe5a 100644 --- a/substrate/runtime-support/src/storage/mod.rs +++ b/substrate/runtime-support/src/storage/mod.rs @@ -22,7 +22,6 @@ use runtime_io::{self, twox_128}; use codec::{Slicable, KeyedVec, Input}; pub mod generator; -use self::generator::ArgType; // TODO: consider using blake256 to avoid possible preimage attack. @@ -166,7 +165,7 @@ pub trait StorageValue { fn get() -> Self::Query; /// Store a value under this key into the provded storage instance. - fn put>(val: Arg); + fn put>(val: Arg); /// Clear the storage value. fn kill(); @@ -187,8 +186,8 @@ impl StorageValue for U where U: generator::StorageValue { fn get() -> Self::Query { U::get(&RuntimeStorage) } - fn put>(val: Arg) { - val.dispatch_with_ref(|val| U::put(val, &RuntimeStorage)) + fn put>(val: Arg) { + U::put(val.borrow(), &RuntimeStorage) } fn kill() { U::kill(&RuntimeStorage) @@ -216,7 +215,7 @@ pub trait StorageList { fn set_items(items: &[T]); /// Set the item at the given index. - fn set_item>(index: u32, val: Arg); + fn set_item>(index: u32, val: Arg); /// Load the value at given index. Returns `None` if the index is out-of-bounds. fn get(index: u32) -> Option; @@ -249,8 +248,8 @@ impl StorageList for U where U: generator::StorageList { U::set_items(items, &RuntimeStorage) } - fn set_item>(index: u32, val: Arg) { - val.dispatch_with_ref(|val| U::set_item(index, val, &RuntimeStorage)) + fn set_item>(index: u32, val: Arg) { + U::set_item(index, val.borrow(), &RuntimeStorage) } fn get(index: u32) -> Option { @@ -275,22 +274,22 @@ pub trait StorageMap { fn prefix() -> &'static [u8]; /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for>(key: KeyArg) -> Vec; + fn key_for>(key: KeyArg) -> Vec; /// Does the value (explicitly) exist in storage? - fn exists>(key: KeyArg) -> bool; + fn exists>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. - fn get>(key: KeyArg) -> Self::Query; + fn get>(key: KeyArg) -> Self::Query; /// Store a value to be associated with the given key from the map. - fn insert, ValArg: ArgType>(key: KeyArg, val: ValArg); + fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg); /// Remove the value under a key. - fn remove>(key: KeyArg); + fn remove>(key: KeyArg); /// Take the value under a key. - fn take>(key: KeyArg) -> Self::Query; + fn take>(key: KeyArg) -> Self::Query; } impl StorageMap for U where U: generator::StorageMap { @@ -300,42 +299,28 @@ impl StorageMap for U where U: generator::Sto >::prefix() } - fn key_for>(key: KeyArg) -> Vec { - key.dispatch_with_ref(|item| - >::key_for(item) - ) + fn key_for>(key: KeyArg) -> Vec { + >::key_for(key.borrow()) } - fn exists>(key: KeyArg) -> bool { - key.dispatch_with_ref(|item| - U::exists(item, &RuntimeStorage) - ) + fn exists>(key: KeyArg) -> bool { + U::exists(key.borrow(), &RuntimeStorage) } - fn get>(key: KeyArg) -> Self::Query { - key.dispatch_with_ref(|item| - U::get(item, &RuntimeStorage) - ) + fn get>(key: KeyArg) -> Self::Query { + U::get(key.borrow(), &RuntimeStorage) } - fn insert, ValArg: ArgType>(key: KeyArg, val: ValArg) { - val.dispatch_with_ref(|val| - key.dispatch_with_ref(|key| - U::insert(key, val, &RuntimeStorage) - ) - ) + fn insert, ValArg: Borrow>(key: KeyArg, val: ValArg) { + U::insert(key.borrow(), val.borrow(), &RuntimeStorage) } - fn remove>(key: KeyArg) { - key.dispatch_with_ref(|key| - U::remove(key, &RuntimeStorage) - ) + fn remove>(key: KeyArg) { + U::remove(key.borrow(), &RuntimeStorage) } - fn take>(key: KeyArg) -> Self::Query { - key.dispatch_with_ref(|key| - U::take(key, &RuntimeStorage) - ) + fn take>(key: KeyArg) -> Self::Query { + U::take(key.borrow(), &RuntimeStorage) } } From c4f5f42ace03a60d366f120bb360c7673446a4c2 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 16 Mar 2018 15:23:01 +0100 Subject: [PATCH 15/29] Fix more tests. --- demo/executor/src/lib.rs | 34 +++++++++--------- demo/runtime/src/runtime/council_vote.rs | 2 +- demo/runtime/src/runtime/democracy.rs | 1 + demo/runtime/src/runtime/session.rs | 2 ++ demo/runtime/src/runtime/staking.rs | 24 +++++++------ demo/runtime/src/runtime/system.rs | 2 +- .../release/demo_runtime.compact.wasm | Bin 160453 -> 162042 bytes .../release/demo_runtime.wasm | Bin 160504 -> 162096 bytes .../release/polkadot_runtime.compact.wasm | Bin 134847 -> 134847 bytes .../release/polkadot_runtime.wasm | Bin 134896 -> 134896 bytes .../substrate_test_runtime.compact.wasm | Bin 32002 -> 32002 bytes .../release/substrate_test_runtime.wasm | Bin 32082 -> 32082 bytes 12 files changed, 36 insertions(+), 29 deletions(-) diff --git a/demo/executor/src/lib.rs b/demo/executor/src/lib.rs index 6e07f3c5fbf02..5c6b2748d7a76 100644 --- a/demo/executor/src/lib.rs +++ b/demo/executor/src/lib.rs @@ -38,15 +38,15 @@ mod tests { use runtime_io; use super::Executor; use substrate_executor::WasmExecutor; - use codec::{KeyedVec, Slicable, Joiner}; + use codec::{Slicable, Joiner}; use keyring::Keyring::{self, Alice, Bob}; - use runtime_support::Hashable; + use runtime_support::{Hashable, StorageValue, StorageMap}; use state_machine::{CodeExecutor, TestExternalities}; use primitives::twox_128; use demo_primitives::{Hash, Header, BlockNumber, Digest}; use demo_runtime::transaction::{Transaction, UncheckedTransaction}; use demo_runtime::block::Block; - use demo_runtime::runtime::staking::{self, balance, BALANCE_OF}; + use demo_runtime::runtime::staking::{self, FreeBalanceOf, balance}; use demo_runtime::dispatch; use ed25519::{Public, Pair}; @@ -75,8 +75,8 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -86,8 +86,8 @@ mod tests { #[test] fn panic_execution_with_native_equivalent_code_gives_error() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -97,8 +97,8 @@ mod tests { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -113,8 +113,8 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] ]; let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -158,7 +158,7 @@ mod tests { construct_block( 1, [69u8; 32].into(), - hex!("cfb76a83e40aa6a0d3f92255e6229e74808cae31d9f46053f31129b797540d03").into(), + hex!("7a388ce5b4eeadbb9268ae96e8822b223f4fd1841327d99f4e1c21fad81f97f2").into(), vec![Transaction { signed: Alice.into(), nonce: 0, @@ -171,7 +171,7 @@ mod tests { construct_block( 2, block1().1, - hex!("c713bd003e303648e8d904bcfa44084865c9b70c398547e678028cc7cf60907f").into(), + hex!("e4eb71be8b816f2061f32f284e9b429562cdc1b82f11725e5f965ff23439f5e9").into(), vec![ Transaction { signed: Bob.into(), @@ -228,8 +228,8 @@ mod tests { #[test] fn panic_execution_gives_error() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm"); @@ -240,8 +240,8 @@ mod tests { #[test] fn successful_execution_gives_ok() { let mut t: TestExternalities = map![ - twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8] + twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm"); diff --git a/demo/runtime/src/runtime/council_vote.rs b/demo/runtime/src/runtime/council_vote.rs index 7c701edd28adc..cf35f58c31e58 100644 --- a/demo/runtime/src/runtime/council_vote.rs +++ b/demo/runtime/src/runtime/council_vote.rs @@ -425,7 +425,7 @@ mod tests { PublicPass::new(&Alice).propose(Box::new(proposal.clone())); assert_eq!(proposals().len(), 1); assert_eq!(proposal_voters(&hash), vec![Alice.to_raw_public()]); - assert_eq!(vote_of((*Alice, hash)), Some(true)); + assert_eq!(vote_of((hash, *Alice)), Some(true)); assert_eq!(tally(&hash), (1, 0, 2)); }); } diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index 34025bf8f54c0..d5e893d9f3445 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -323,6 +323,7 @@ pub mod testing { twox_128(staking::ValidatorCount::key()).to_vec() => vec![].and(&3u64), twox_128(staking::CurrentEra::key()).to_vec() => vec![].and(&1u64), twox_128(staking::TransactionFee::key()).to_vec() => vec![].and(&1u64), + twox_128(staking::BondingDuration::key()).to_vec() => vec![].and(&0u64), twox_128(LaunchPeriod::key()).to_vec() => vec![].and(&1u64), twox_128(VotingPeriod::key()).to_vec() => vec![].and(&1u64), diff --git a/demo/runtime/src/runtime/session.rs b/demo/runtime/src/runtime/session.rs index 81bfac5b1d37c..72180db2e4555 100644 --- a/demo/runtime/src/runtime/session.rs +++ b/demo/runtime/src/runtime/session.rs @@ -135,6 +135,7 @@ pub mod testing { let extras: TestExternalities = map![ twox_128(SessionLength::key()).to_vec() => vec![].and(&session_length), + twox_128(CurrentIndex::key()).to_vec() => vec![].and(&0u64), twox_128(Validators::key()).to_vec() => vec![].and(&vec![One.into(), Two.into(), three]) ]; system::testing::externalities().into_iter().chain(extras.into_iter()).collect() @@ -157,6 +158,7 @@ mod tests { fn simple_setup() -> TestExternalities { map![ twox_128(SessionLength::key()).to_vec() => vec![].and(&2u64), + twox_128(CurrentIndex::key()).to_vec() => vec![].and(&0u64), // the validators (10, 20, ...) twox_128(Validators::key()).to_vec() => vec![].and(&vec![[10u8; 32], [20; 32]]), // initial session keys (11, 21, ...) diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index ea5114385afe9..eb0521812f98e 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -549,10 +549,11 @@ pub mod testing { twox_128(&Intention::key_for(0)).to_vec() => Alice.to_raw_public_vec(), twox_128(&Intention::key_for(1)).to_vec() => Bob.to_raw_public_vec(), twox_128(&Intention::key_for(2)).to_vec() => Charlie.to_raw_public_vec(), - twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&sessions_per_era), - twox_128(&ValidatorCount::key()).to_vec() => vec![].and(&3u64), - twox_128(&TransactionFee::key()).to_vec() => vec![].and(&1u64), - twox_128(&CurrentEra::key()).to_vec() => vec![].and(¤t_era), + twox_128(SessionsPerEra::key()).to_vec() => vec![].and(&sessions_per_era), + twox_128(ValidatorCount::key()).to_vec() => vec![].and(&3u64), + twox_128(BondingDuration::key()).to_vec() => vec![].and(&0u64), + twox_128(TransactionFee::key()).to_vec() => vec![].and(&1u64), + twox_128(CurrentEra::key()).to_vec() => vec![].and(¤t_era), twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ]; session::testing::externalities(session_length).into_iter().chain(extras.into_iter()).collect() @@ -580,11 +581,12 @@ mod tests { let mut t: TestExternalities = map![ twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64), twox_128(session::Validators::key()).to_vec() => vec![].and(&vec![[10u8; 32], [20; 32]]), - twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&2u64), - twox_128(&ValidatorCount::key()).to_vec() => vec![].and(&2u32), - twox_128(&BondingDuration::key()).to_vec() => vec![].and(&3u64), - twox_128(&TotalStake::key()).to_vec() => vec![].and(&100u64), - twox_128(&TransactionFee::key()).to_vec() => vec![].and(&0u64), + twox_128(CurrentEra::key()).to_vec() => vec![].and(&0u64), + twox_128(SessionsPerEra::key()).to_vec() => vec![].and(&2u64), + twox_128(ValidatorCount::key()).to_vec() => vec![].and(&2u32), + twox_128(BondingDuration::key()).to_vec() => vec![].and(&3u64), + twox_128(TotalStake::key()).to_vec() => vec![].and(&100u64), + twox_128(TransactionFee::key()).to_vec() => vec![].and(&0u64), twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![].and(&10u64), twox_128(&FreeBalanceOf::key_for(*Bob)).to_vec() => vec![].and(&20u64), twox_128(&FreeBalanceOf::key_for(*Charlie)).to_vec() => vec![].and(&30u64), @@ -648,7 +650,9 @@ mod tests { fn staking_eras_work() { let mut t: TestExternalities = map![ twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64), - twox_128(&SessionsPerEra::key()).to_vec() => vec![].and(&2u64) + twox_128(SessionsPerEra::key()).to_vec() => vec![].and(&2u64), + twox_128(ValidatorCount::key()).to_vec() => vec![].and(&2u32), + twox_128(CurrentEra::key()).to_vec() => vec![].and(&0u64) ]; with_externalities(&mut t, || { assert_eq!(era_length(), 2u64); diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 7ab4108417c0b..1c6c74ae0d125 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -275,7 +275,7 @@ mod tests { let h = Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("c3cd675eefaa269502ee6dc1af7b9941c0be462eb31a5273c00cec40a8ace837").into(), + state_root: hex!("cc3f1f5db826013193e502c76992b5e933b12367e37a269a9822b89218323e9f").into(), transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), digest: Digest { logs: vec![], }, }; diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index 8d4177558c879383d18ca9954e22d0c54b394113..ce845090eb5805afcc14c9453de6756cbb1c7ac3 100644 GIT binary patch literal 162042 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≪*59m-zCmsY z_t`hg`HcqIPhgtQD*%ApTGXz96WVfH(TE2C?G19vSLeqhx2Z;&mE$S*08n4+Aid-D zAA%`kLBjgHD0$H2tfKrXr#L+AA|6Nyg9a1vSP6UN)_HlngVgLG8Jc5u3i2;V3O-rK zFViA7BqfrKC@2ypt+|PUe+>!g|JnX~=^dRoOQf7Yb@`;F$I8#e=f4!wrz|~L{FRvg z)tEjV)1Qy&UyJGIWBP@d{`HvtLQMZgOt)hCH)Hy@V)~0QeI};=WlaC8m_DnN6IlB5 z#3rHPmYo66)z7ExC)8N4&e=~630kLv#u|KN76R|l7(~>wEXdA$c4k18g3VY_k+M_? zWUS7L&K_45@I+K)QiO*XMO|2Gu=kndnp>QWA+(BI%6XxE}FbS2n2zKZxR6s9TH*7 zKPe`a?yQJ}=(8vx2*&q;SU8sYf82W;ahBAbj{O&EsjA-Z^Td#pLk+G9D}Mjt&FNn&fQ*&*IPR3hp=X}7ZiFP zHa6!MisIV7Dpf1z7ao@L`yD--^Q#PVe#PBJew<%rez~cEen#i_!xa&$yxgWA_eym7 zAJg97p7oU{#n!qzW69Dck-sFR=lVWJJWw|zB=8i@gfs;_v+2PHTM3AlJq<8 zwEblF;>(`lkvW9^iEu9?o^lwJo-h0NS&#VrjKxKQ`g5#zk~7mkiT2_TjlRo{toeX zn7=jt*7>`QzuWn{gTFiZyNkag{2k@*hxq$p{y52ga5sPV@OO;Asi!$OIRJrqUzOfYsw1uu2)Rv zZ3>H^Pj!riVR~y>)G^+wR;8$8qN!GOXjhey;)?g~)@%Xpt(8S3hosSCpOr-=hkY<0 zG^i4(`-j3XLw8F!6u(#vhtszz_>e)|0NTKJEwBXj3acQAunmT>uQzk%ik@$Y&m4<8 zrRUZ7yv&&)dcHM2A7o>lo)5+618l3)^Wpfs#Ew!uuh|sGU_EB<=j?uE-xiM0dxyEKe&qw0(t~0~EdOm8g)WHwMZ0=;) zr|ch&&+H7}ujjYLXO8z+)bri(nSBULdcG$B<=|aP|5iD8x6-Y0P%HhLENfnz2Z&$J$ zPAEATjw?A3jwx9R_b6EmcPrT+-lk+<_+cgE;fIv$4M&wMgd+B9)c z?+X4!)6!r4V(dUq^$QQ1zUmjQgP|xe1?X4`%#}N$0`uaIi-6oYIs!*yI7ULvpv{mH zG*4!D2^#JhY68p29Xp|(JL3onHD}Elj)Dw~p((Ho-7yvF-DezGq26=G@fEak-B1=d zvcs_!>V0P%aiQLS#&H)=L5{vqFP(7=hWfx6M`EZCo^d<|tuHlHhWe&6j?GYWqP!tA zAnb-y@WQ>X0rOB1r=Jd|!{E%|wCoV-Cxp{-!kp1SOOV12p0#OeF8Gt^VQ-Abc<2rX zZi51;?4b%KB}#>Sjm^FH9@B|9G^JVH_f$q%Ki-^LHtjfD0dUc#;KO_7r)4hQrpr-& zr7XuEuZtSbkCjwu%qkn1{v&8%q3z@sEq;VaFRnpi78q~`iZjSr8ZyDmd?!aoR?{|( z&v=`)Rs&lrS}~)87a>1Ge;+v5Um39KgDC+8@)asCKQYj3pO5#|qOGd0kq&o40NJlb zfr0t|jf36 F{<60YRt;T#y!T!<>WBYQk6S}zpt_?R)p|=?D?^ArgaKre%Q0|29 zm!Lu$;a7~I-%19*amX)LJ3-DQ;RxiLV{bL9{OS$ke0(R-92*r)l-OI$;@`Kj`QMhd zM8WlS*4CX+J`$=QWh_wIs<2S%`byLtma(Xf+6+RP4ot!W1B83C}gFG03MKh4rmBtl5H-PUMjPdddc+89BYP0RmU z#{D(kVhgQ-p*;!+2g2fk7;H0oTuKU12U){yvdaSb% zCKwRg`B@GS5p_R-2`~*HmVkbM#S;XL^~cBB1&UieMz7g+)uVO}jb`PgR*DEs{Xdzo zC9lce1p$XJoxzD>%`I1j3UwVXFFYcvMD0XkIK>=GAwXX-cT_@tCb?FR6EK0#C}rq7 zs@RHF+{H^f^o2rDX_0h&<#0Xp`}Iceocq?;$N_%v2X%IZC)=ptlOI}7y8y7v&}fbT zvMrj21~n&Gm`XH_Y#lepLR2WYRy}DKbaY29+ydK7tsN=P*##X$W^FmGDspbJ3TzHY z6C*CJ#J#9nyJ!N<^Ls(jr&WHF2z@Hgx>ICdQ8%jcxBh_uUGw@?$N&xKG3r^&p6&9`E&mO!gfl|q=UMiXY3x$f$` zFyIX6v8xMlM$~Ab4x9~YVDOqmnod%oUouB1OWL$2+fk+sZ&JAg>P!Zt0213@>2Bw4 zW){1Vw@o9nYD&D#35nuu;-BJe+W_pmO)#Bo@wS9gyzQ6IbRuv2_0*e)m@HRgRSvT>vWP(h1TgJ|Jh4rcp57XL)1Bx-0G_t_kP)EEiA{G1miBFxk zNyOWhte}KZp3d8u1mbPmy{&ECY+!+%fJ?m1Z;>FrR6B-MEYSdFcYC2=30yYjTtwK8gLv%^a15}FSbJ=hhk#k=avq2|sabku z$in-WM=csEld#9w^O#8TU%H1~D-^7*88Qcbawyu-?_K<+s#*QsjquK>F1dy%r>Wm5LyhqY)08gySdg(8~ zgohH)**cxhR5#ZZvo+msXVa&4RVSyg*miBwqu{%88)W|9yyP@~eH2u}UOG?jsMudN zNT1lbcaqaea_X0-RZ&j;@-#sr8|0U#0fWh@DuN}b;)Ly^;L%MIkSgw`y5kG|zFQsU zWEk~e)%z1LFL=n($$aZ?{bK>DGe`FJn~Q^iS7-l61V@h(r^P25r^zCryyiAbVwfFsg2^cm3G$Z-c*2?daTU@IrZgH)ixW%>l54goyS=<6+ zz&_3`((2G(j+Jo>9!u$3eIBLiT3y^SBk36B7EW`7H$?1X{E~5*uTSPYWINrCH_tiN zVjLBSEcWi0feew^Vj<}SmW~nB|E?HGtCUdm^YumB4`52Ze&!H;n$fk-|NV5ew>5dW zSv@k`D|z25xGt7TPZcj(daU@L;`7&H`gKcB7XKiozg5;x9A;d#S20>-U~hfJBg1>w zi%aEjp9EpAIp|!hDtreA$fz7jsd%-m=9IuR|SG*EdujNXV zCAi#7S|!S&5)S!KrBum9DiOKrEw6-2anozdq7szxNEVg!^SP1+$rYagg+B_LM&(9~ z{DrcpWVahEyNghOEf9*wyNr zvJ9-IZ^|;T(wUjLZyRARB<*bDQdU+#R{l78n2E~?=(`XWjAa)z5ZBH-2H#!sdirBL z4ri@X&0rsf%KF*S-Kk`%M2o zv;;gW;9&1K4rZDOMvk&x09LM40n?fta~yHvcduxZrie( zK({Ts3Hn~boP5xILZILVV5*VtCZDSt10VFvpl1XmJr5Hvc;G{0DXD3chuvC8=tEeL zi7`(-4FI=CA^-33k>i;z=i`|w_ceQ}VM@NH4rpQ@dEf~}mk(%?uQ`Ra(?4rNCZySt zlzh$Jh_9(L%Nt*F3O?3ZBHNB`(#c7*KPsSu6ddhB-r^Vr^2l(-)^_8vnb-_c}%eCEt@OOfbr(?ym5UsIgRqL<+a(U# zAzQ8ZOD_~ar%VgOM89cDhfKn&?l&bd{M&Cyl+k_m6lHXuJw+MaXa7Nz(WUPDJIZ+F z2BM4v0@2P=mN9sEqank8SZ$v$K`2X!f+vpD3ctWhDxsS+aucm;6MF z^|8j23ZB`fNw)4v=7CX>GkyzR&ti1J#7uJrMAQhAC@(NL{c9yFRGX`U6e%N!q!~Xg zA!R)y0|-BGfyog;8U*WW%Yg{~OA*e#a)Zzn`>rpy^_*%YGQ9BmV23=LP~z?| z|XFM1Rx&-QcCM@;s)ltTTuK1vmc#{|s_0694DN)}nVUv~j&61V+ESK7oWu2>H z=PGrsqt01G&VRAcpU&|+h!axh_;Oq4$PrnoUSwt3QDjxk-pVfDn*v$OK>Z_RrO#C+ z;#EEVSC*O@1h%M&Z|&6NbhQ$e=!5~t$keQMqUN)wt6LxM<%RHD`yLstiJWWo`P~}l zftPq{ND=dhq>5^ai$fq}N4FD?9Vx$} ziT%L@Q4A)G2ZtrGl!7fdgrM38hvkVK_BPPn?8XZH3HRkiSH^3-dgV{okFjWjE%Vc1 zEgWL=>uyrS?SiF1#Wn!_Jj~I7N--MG?MB@nwo#ZM9jqJl!^8T0oAu5n6b85RTaysV zzXLJnFqMuL154}Z*IoSblSMfFR2fHsT@ywcAQl?19Z_;P+@+)nM=e30@?{n7JYEDO z930YNPi~0_RWh}C6vnrwzjvSoi3u2pmfD*|ckVE;oa4?lu83s~b zJByWP(hD{HN_DCPR^j3II6?Vl{p5g4yperFdu2nJa zc@G&(*xy1jeyo5!aXO0INqWbMBh-cK!t(a{pe5PfHF8+6zU)^LISJOQnd8OVD9ve< z>X_Zf5Q{5|o>9XZbA%>j%A!X?_VE^?b#qDiFiq1dmM#CJeytU6J63&&f}AA}Gp@<2 zDJ6&+*T`_KY2%Gw3BzYU=^&m%xB!D&AT!j;G6WN+j$kMYFa%kqk=?z(<~lW9edt(q zPV|NC90F@UT4EFU;c`8#B}{AeWru>*J+VnHYL34S=G&WWP9?F!k@6`{Lb@E=I){Qc z)__O7N$>1h{e^w8e`W5>lVs69tm8=5HU?5D>)#0LT&B@4?DGzaVV-0*6;acKWL00G zr4*uuFPQ>0b>KhV9z z60~@P5}Jaj>aX&`maSCvuk#a0Q0{N=6KT-T-{L0{p`ZT;Ka(_6^*`dtx@Pab!4qTd}=5Z4dYc zG=VsrD#eJ;8y4f|RXUeyt$u-gs>K_OSW^b7xj~~cwxO|jZR}L}d<%^)NFH8cmp}u6 zyhzhh{3``}#byf)+F0rZ4MtGpK0^n?3wZujf9#!q$-mO1{=M2!7xi9qx~DL&ARpLY zPzsCsM^>CUDcEOkl#{XgXY8ypw-4MRyh$fs-ixjIi*`Q!fVrvqzwn>4{QUF&Qw4t3 zf9|I`0SD_HB=>JL)mb*|w@miut*|TivHCBMxyN9veAZ=lsUHY*@Q zplN+IkKF7_mzC~4R(wh6?6KnS zE1f@9{2Hl!%!UT-*Ky4$0Y-cI*sN@X+tW52GH^mE$itFy{I%c!XZ$Ny&eWH<0$#{=j=^j0 zb+mJx79x}diubor5$)VkxC#f!&It$CuyY64p>?<MXJsC)6Lz;4Fvzv2XjD#)a+I zGiIHZY)LGPZyF7tEPB&&6HVzs*b%|MrZG#X0{!2;F-u(L#>}iJ9k1#UV`gNM-MNMt zt7OJ>VA~Ctv83aj4}$3jGh;F-S23aassC8qgn9nIqR?gz!%qJb{ssp&@w82r$+DZSJ69bq{vUm`jY~1HU+E0Q_R$?9zO$W8nP4Bug0PeDO!9go zo2uRackhVX`!aexvMP-mtHP9W$?A)bp`H1S+T3eCT8E8=d$01#;Qh?6iE|0+WqwVZ zYl`mm_!YUzeTe+J)UsILJ->FO;S#4o+r+LN`CU4}9ilSal)oj~Lq<-L&}O>?Pe*ns zF((zcm$gUE50u$~Gb_-hsma6jIgog`e&sXT7t9Rg_4`?IwC;+^{4B=!;?S=!bahTb zppA`9VQ19I7lHitJ#U=HZ0w^qsB6LND!i>PpTTK;!VG-030C1}qsc#y7LzuOmQ1GF zBnRcnVUK-YMBc>PytDZ1KDQiEhZ1ne&_x{zf>PskWKQstvP7aM@FS8Aec2gv2lM3~ zCtXU{;3a31>BsThsJolGq9(OqE-AQZ!I9Kyayd0NFqiY!Wgks9HZCoN3x@v1|0n{u zPb#m;ablhTBNlp;L6Gf-UTr{?1)%^mL!~UBY5^*!o`*E%Qi1IkWHHBRR1T3fof?%t zK%?|1HyWj=4M&tB;K+?C3$34_P?HxXPvMkEFF{}eJ&Fa@&%jRLA`?>u<+(f~(<-A4 zNKNC)z-?#|)x@UK2sg4(3uQ2*XIpoCoQqe$I?oq6eti*x-Y@H%VCi52PjzWw6?qs6 zMv+>aiV*bkyX(T|3sa2B!V;}wd|E4fDM6z5gD7hz$)J&Nn7J%AbOJ`jaYSUMK+Jg% z5VA$=Hnl2*`8{U_aVVmnQxuT2@pCf%BvLnwKUooROZ+)~X0RH6((bLq?A&H(aO43C zw;&3w%S;fKQ&>PKcuG)4{+DDrb!>mUOP^djv-ycQwl}_c2k*(KIGq|N&cxr`JH4?L zwB9zy1$;VRwC`V7C#J|!gVt;ey#w{W_C5LV(hrbB7ggG;Gh88}^<|;8b+GSN^ zgd*G;W|T~dos!m`6f2nrsyEWW&tNUVNaQ3*coaSmMmE@wFZ=y>h7#v_9LM?)PIYH6 zWBkF~b8<{Yz-tU0DFdbXSG<}Aj2@I}28>AsNRp0fym>i}H)HtME6JbJ969nrM;nF3 z>~nk>>z5BenQ^fp38@W04{slUGJIF0(rkgC1OnD3<+w?Y$-wrYbleA}SG08_4obCe zBMwUU@G}ldS-PDDrMsw3Rl`o4YqRs9bbMq`%G&b3%p_MkxWX}!+ci_~YWsdu6B09> zYn-UI(Tg`Hoh7E(!7*K{T`-1_=krC`;oBL!)XyWBg>BFR|@_@l6s$S+FRGQh*@4+p-DDqM@4_t6=&7 z(n7J+wumb~(Yz5iHpvZ#t@j~bsP@e*soqD=~!54SH7cb(MY+2FID>m zSsU>CG!%da?7fjjV{TCjkYCk>gr2Q=Xs+X*J zHznxRpeRfiPPKL6R9hELy}m9qG*NG)54un$3(#Rnho0`WpjTWR#bmFH@ELUV=QrdL zxaR(vIS1~Wn4pMD8sPPmfS+yyKivi%4g7kF+<>R126(A#@eqE_MD{}tW(Hf%e8rBO zHpRtGDHxDrzG!QzYZ!J7I-4u26U!k|<5KFBVSs7I&VKB0OH(NWO*NvRG_-mW&a?;w zAu~=Qwg8TI$E9QshG{p3X%~iR9Qi#oV96;43h$(&St*x3^Cj2pB=yDxHOP^#o;qOw zW_ebh5Hoynd(#>M=nc{)v38K#Sb7pQnVmj(yya&q(i6p6TuQTtS~^r&rau~|QduBm zgbMN%HE9*;<#So?U&8L4LqW$Q1>_!Eu(#5bDqB$H8t`$HNPq$lE-Pf2I5dSd7Q0bc$_K% z<+)vT7KoT7AISogvDkTekt&5;9BSq$#Dbb-#ZR)vW#`)7OndH0ejjbLn^hKV&}{Cf zvJeT!cx3V&oES!H7Hwe)nkkbAG$WK0wKyzI+`*5)q~Q9=TuhT-C+1-cq84dR?69I1 zHmWN$b)KUZ)?4~4T@Ym&&>|9|IhA)}I0k0R!V@vqLi6H*q1t1C+I?CHGpRF|rnPKhQfec&8S^N}l99@$ z3npC+M+m$ptdfQ?xS}932IW<{bCmBd`h+zVHyqJBG?T_vr4-tAC7o)$G7tF}s$ zr!Z~3SDZ;0fuo_We&KygnRh^a@U*HYW)9qXO$+NC4qE1XYYr-jnJAz3Yi;w1uq=D; zfQo~%fr-mGns}krg)lyhFf!lj7_>EFE}($aP134nbx&b)MgzZ$tTYYV+9nPNhGzP?wZd_*7q0OD!xX6g)PIbjIKo@KRKJw{TY ztVrN?lIad((l`Du%+i%kQFX^Ar>4gzdh{qZIX#SRy_ZYc)XFXc7bK~}c88~&q}WS6 zLwux8)T5(9npnY+HYP!wn~~HFbmiNu?qTbJx^ZWv24M+Tj!aPjrVUY?rs^)A&I!hd zF5$^KKTCaXDuJLUmXtM!hBos$ps!WS2q_7hm`o&FDjvv9Bw_Pb7wu46WAz!P5>>T7 zsFJNxJ7%K9JX1cjm2$<53jwMB^wWGO9&>t3?J3)?$war>UL`=4R?wG3$0M zVbgZXttTi1U%~~EoFXqYY!j~DbY*7S%A&UE87((O%X9wLP9kb_(I(0UjhVTF7Gk#~ zkX%NscBs*r8Wf)^bDw#7iu-fvpa+0!&5$gmb^XT5X3w3GU4d=%f9 zF5|90Q{FSq1nE^0GjY$`pTzzxnKV$B-l3;X*l`>}vs~+)Fxi$BeYb zhM{Go3C|=WO}(j(iuPRAnA+>GS3S&hyeq!ku2)MOsA}?B|Y0ElWOhTNM)nDkXzU; z<1*GaAmbVw>}2bo8Bb%>8F?D0zGS7Np*Iq{rH8kc4*f#Y9ug%nNnKzW% zoQkI2+H_k_na?09mFp8YMq~!dws^<1MD)**(kcPCy0((qDRndo3YpBeMxum z+D*OVN#2LM6cKMQ9tWN9V14H4>)d9KrV$26Kj8}J(e0)_L1Vh-QJH!N24m3UCq^J& zIOZ>4Hk6rLhsZP8IY>Mtp1FqFb@Z_e)jOZ`C>&^(M+2$o7iIlCs*AVEYb)XrA0VD) za3emzKVPd3Jl@GWp3Ze187|>S^glRQ4om3J;!!21ick2{C;jQCJ^8eflf`46JYK)N zUQh5FINtdIDgiGtir-lcG=cVYa1%J|;NA-rwc332Kyt;qqkx=|@`wq9I)7Ub7 zYPIGDTid=WTA;+>AYRYuVsMb*Wc}^+{>SUhoBJPsY7yOnJ@9Q;f;@H3~2AH!}e z)i2%N|M=|57~?b9clDm#vrGvZ5E04@)abS?hi^=faVN;|ppoH&!Z$s8t1$iTo!Ifs!t_%Ag97}95k4X#*N5$MCxU?AmphBg1ybwa$>5WH&FMr|$*WXyMY`ppSJIrkp?%MyVzm{ssF+HRS6hNkI?<40 z-7!#1O`6x00ag~3wE7_Ewt((_>M%zjwP02F_)wjp&6Hy(N@p{vdxQ@21H&1!#Z!9;fu{1#Q%pRxbEse@9|G3!RMv~LItDAU zpj0LO*o$guXHkU|RLqJjf?Ax+CxK1nO7=A0svv5@fTgo-NNGg&Dm6j_%|T@eMwmR; z%FJFYywH56`T_h=LduC0QHDVk2eGB<+lY_qDk5IIZ@LM16uqFjoCQqGai=WRA&p@A zDyo$x`kd8DqiVBSiBS;~GuKzHR-!Rb8z?<%R#`yOt~VNkR=q$XwIXAX4P~nhvz=7Z zu2<%i?zHMvCDBf>+aUtLi# z7%)s|otb=0;B2mBuK5=9x3x}lZsC$-OI}s1QEbDm{Pd{r?w94;lN;TedpX^FrgElr zZUFI7>qNw76$3mG@j0tOyt35RcCFJK(wVhR%T+Z0CUz_`I+e&vlGfpj<;ecbIL2R7 zbgfk~tClNn<_NT=*U96JM{*m?DrGQ_IEPX#S6ce14YQO{Bt(+LsGmfP79{d`@nbvk z5IV>V_*g@lbigEjGvR1P9H=DMMsq}_xN~rk6Dt?dMsw0ei^$^K0|&W!lMgRegT?8< z@y@Xcaj-Wg&TTa-We1n_@|mTRet;+4o$>=bBW275mR<;4eyI7|tQ<52oRx#7inDT< z5i!6{5&NKbra3Lbybp!SiJ|-D4DF{w1$~{Krt7wr$&M^G6xec@s7UiG=2<6MWYyBV z9cf;>oun)OsJWel)AKYwD|H^{QlM!fGFtiZD0ScgD%|}ki7M_gW{bS-QTjOTiF%`MMN zx99+V1lIuWTpQrgS~)Zoznx0Q+m$XjuvE1`_IN0~?j2xMlkM(f=~W+?PaU^=co*n3 z7Sg!x4LiG4;;e@km6)q&z+Guhml>uU6c74Wy~@u zZmG;U%n}ydZke8Wm`o2^@CJmeIWIV*3%fR01*{8m8sLPLs1-c}jg}07XCUcm)+2;q zWiQNy*}C&lddo3W?6IiJ`)0?f@LbnIOo8e2F3^>au;8Vt13%8N%)Mfjqy1ds=N13C zKU9I@Pj`olibzeJ8O$Q;E1eCFPG;{4Sa^gWRgE-FF$!5Z!#r5b*9foAvgv8=2=M$K z;@spe<=l%5Qgh+`F?&Vf^T7(!%vaLu*@E>DMz2c~Hu4jVmQtuG)XI%?*)^IQX)&2| zi7*scwM!F@6cK#3g=g@jnrJZz0^Twmh)n{!<%2?h|y`=qzZp^A2`IlbS=umI5#2a?8F|>#3JP(es5p+8brqL3K z^_ZvA_3-1j=BeiVlvUGoT^ZDoJ8mVYAoo=;Y;YLb6ya)uj_;in^D>3=%{dqnPx~^d zY}rdnFT>QZJBJa&S9-HXK6iAS{)4am<~M%lFZ{yaJ1L{gcYqf^VI2eysiaI;s5j}X zI$=*FNmd|!CJ0~P11-A%LLHY(MHiTi zQu;zUgxh&dc-A%$>2fFv3+WyVDv%iAKM_I!9?L^_c%BD^EDwAp;^cB@5YO}Akd;Gc zc%Co5Cyx%nTk0La+Ag7h(_V%K1M(MVT9eu0Fra z?8uu49#b?kC*-Uc+3**mGUtFIQ^Do?I5-(id>@)vDqnhj(IjQ%y|Xt136k;@Iz)_W zx&%IanrCV2I!lV)m>ym^bNc14{mM6f_8)xfOHoo*z()K;=yFLxW7~|Xt3}s4Sys^g zycF_O=~LYy!{g`lMEZ4*qe*Pjjno(R_fM+Sb5ocI((|lK12~ke?cGz>g{fhb=SvfW zleDF8$Zg8Ap(p-Y!6}jEq;=S9UcSd{WUsGJpy6+nfY=%Fq}-_QnY|pvy4R@(Y|w-F zmSAHQ{QG8ag5f@cAujumoi4)aXFfQ)OuJG%<{ymcS>>AT8PT+^q)^v8=-N%`r2S5X z`bF^EnE5aB)TrO*c^Xl*o17W++*IPAW55J%jcjm`kqr*IEFPCd%p9aQXxs_(m~qhW z{Ql>Yu5}KwPu$MMlA;;axc-&p${Yltc@R^o=+`I2LB_#Nn zH6n6BWI_q;AaTa3_!?%?JA|-K)zcH)l`ksH!DEog5$CssigO!=% zH~3YhulVcbFE!DNG@yq~rzZEB-5&eZN|+z4fB{_dpW=F)+2XXu1DrF~*#I#4fG8l` zLj3y{I+X7oCrL(JBK9++0+iWDY`nuDa+2M zO*CeNQWU$2O5|NdBl2F4LhB^@ZCtkQWc*dYP^Aks@Gte9hmO zz4A8z(|!ZP$bZ!M6OiH?dHEOS81Iz4ax2)fS#AJZX3K3~GiuQ1>_EW>msuU&5>`Jn zyWeZV$_~kVJU%`C6SMom5cV4m!tlehdj$!zoNmtiV2+ku@xwd(AW00kEP=chE8*|_ zOa7G|^Y3FRdyf?PIUc08jdn$=75$@FJk&4E!G(HX@ZwtPhK1d5xrY{@a7 zznQmH(bhVP0$EWg4@b6DXp+kb2nAVNxMIp``zk!Nd=<8cn3*MgCXNhkN-hI#RS|x9n{2khqU3#el$A1YpzeO7u-csj&k-~uen4PY zXC=krw&RxH)-F2eJ{uFP$iP^%1czga{Wgd)>g^WtsJihI6^$d0F2By0vF9HDSD*X& z7ow-AeLOpj8FAm~f(;x%Q%?gzb;*4d9$I5Y_C6ZOq(&Lunn;4;)|hcg-!f(t?jVqD zno<^H###6F8A{Ci=1YW(l?)m)_L$F@g-o=Lyny;RF5^SSjNe5_Vjk4L8Dqwg)sZ&( zQ7|J8+}V9E!X#px&H)PYD8+(K*SQ!HZmwIwX6v#=%)U(j0|$*BE4s(-fD|Q2gVP(u z-QVS?6dR}j*vD-4X2)i@2wqz;jmPU(Zs~tKtp3C-Hxu+99}Z7H{=wOUVc7rRPmsv) zVpu=K&maqnGKZkjuafmm{kXwk%G0{yVmo4`_Z96Kwxc~TlRxX-qk5(BdRp$(^B7Abx@URsV{=B)x8G3 z_Kwb{XRY={18B8x#)ww?E?Qna(rHOwGdQ#^Uc0B1Z8Ji*KZko@f(>!a9^SUD1FOcJpEGf*icsC z+1a^(%|L;_f0kgE420D5p4llT!I-38dBkQ)kXKx*(9^0Cw$#ZXB>1tybf(R3Fvp3W z)x2i?+HKKs#~kJulU>*Cl0-I~pusH(Hy|^FQBTN*4OkkdWPi$zG5vrlMLr1f0l@Oi zI>9Ylz&Ecr7oZ6pU%>81;iShhB%(DQlT^qpQXvcB7O4={;w9gGfkN&NZdV}}kvpJQ z)T_nD%FVzh7|pi=XkDdz6$@{Kq3zv9oSuE(?17nEWe`POd^Rqb?GVi;lFCkOvSrt0 zmidYAIary7FdQIF#2~s~VtG`Mn!!A~m5XsLsFJdLK!cA;J?^Ez6td^h49a~S@jU6J zg*#nRuEX~PzsY!y_@2=*;Sx@VO^ylu^LCS0Vh)KdAuyBJbi1>GeT#jwNGrrKHw3rC z9N*-Ic=PxkVZ}~@to$;S*hB2FH^^NzHY2d3PlDHjPr?rQrhR@|uExaj>>4aH;i~8C z2|7BXuWoEC;`Cw{W+LrH;v&&-a|rt#y1z<4tcJs?Pd`BK(koFRsj*G|c-c zA$(wA7G6s5qa-AJlD@3b5pS==aHPObw^A6leHmVmyLnM5tzVhNi57o|dzjh*qeXl| z-GcA*#Pm?aCX3E4>kD~C_Fex|)rRW2G-YlznVU9XVt+p!V3M`trIGAmm0Z_vkuMM8 zB~n?7%cQ$wIS%X4Fj-8*F%&Q$$FWPvn5_lFNAV#Plv-ge2Vx#;ii<@B zizp5Nwz?Oui8?KdcFVlrR7?KTm%`nIals5C+sfUDLktZ-sgNBw>8(vXQenFdl>)3X zuhO%wFeTfuDa%)#mGBOTh<;}9C%l|>sYzEHDd&7gq%mwkJg_=ydH zL~l54e}YaZd=<{xR1jhHbg6AibACB7wan+$lCycWl*T&-oDs~i<+BArF@tyBfm9-YV#g?fX0MH`?I)NUl8NP zEOy#f+6se8>;fHN)s;!j9D>Yi^cDf&_zQa+e;GtuK(xUxgf^HP&6X^TN34L_);k+0 z3=>F_Xj}`$xEDe( z$rGiwxJlZI1~KU1{4yv>vN5peEg?t25hs0}!8c1#XV4u$#lgrhc*%`X$fcTwC}J9d z1aXl;iQmR*ZJJ^bU<_`-C9P1SY-C8eZTd>57wJP5u^~mq^$w$Saj!+gi^<_kE6rD~ zCgKKgHAJ*IS0kby{Kl{*I)nx2fI=doenCVG4H9KUR8K`JBVtHIL`LP2H(FIhgqHk! z6%joeQ!qLJvDY9XpB8+YiRjPvfjqtq>NPn*6N-o=MnqoiOhl+BB1)}LXN!n&5*8u? zKV6fS(!j=u$oWxV*@50;+@-erMqYu*gf>U|Zs9NtBTiTfWrjgP0&HltX z0iY2NaCxWyg1Z?j+~AyRzXTn&$kBDE*^Jfg3}k#oE9kiXpAj<7Pub#9&-o-(Okg}e z2Fuyq+9=rQ@$wD6U;k6gZFB(bbcL~IQEIBs-tjg3()f3B3>crNfAa6tJNa{rWa>+# zOC8D!68=TSrin-SCzu|)SKWEc*H1wM1?yWnK6}`{=E^t{A0}$tSg9~z(ZV>iAsT5t zaEHqSw;K2rf&Z=J1A%u7vnz8;i-Q<17LM5!M~94uId)>$rTValw{I2^MdVHO3JVxZ9!~1RtN5gfl4%viq#znH|im5s4k_f!KjF(z+yjTr3fD ztsq$zetc*EwdHSL!QU3u-QiurYs-eSl|MHEIg)Bfm{)TrT;GF;&6>? zsw%Ob_(I3zdn2BmGC;Furwq6EvqU*jOnW`C&S5#L_^3nyh(+lUV%us|0U7j#j5k$a zMn__yJlElYgWe5(uV^iG_O(~oSyNeqo<&pb6_d`w?G=+!)u?3ixy6duh^W&|n<|Ss zP;a?fXILTc@4-0(L~=wO z?P{ZFwW?Je8%)5$cWG+3)q-VF$4Ird_O4y6>d>0g)-3J_e+elLu zIN%EN1VNm|X2a1{KwX#%a}t13_%z)sg==uFWZLvRPzsgU@suhR0yGz%_{uBDaQU=5 z0l-w=f&~Uw!)OSU(8`H*sg!CJqowduySL3&_Q?!TvzsRvKu!_!1iSaK=rHsjq6*W? z+)@Spi@_ekW#U0w*jm;do2WJfybxz!L59>P`p!P+g(VK*W`D{}{dc3HR0mlWLF8DC z;v))S+H6?a*G64Vufw>l)aMmHax8~<8d%5`Z3f*TBu0{La;KGSLOEA`iTnu>O9#r9XH!{Aox7kQU% zmt)NUPw7bMmHHiVAPC!N=?pN7+^r~>QQ%m0w-E@~*d}Fe`9fIMQCADv^Ri%iQx;qL zQlT+vPdlA5k^)P#M}9Dj)75N|%#maTgRMo+7No}J5DPsZ`y%Y^@BduncgYST1d<$% zjcQ17($@NvsEOR=NM#w`DE@59$jyp0XS5zt#MBNaB;K}Y2@=p+{vM;HZ4IuDNIM}{ zi{Ze1w)O+{V|?stNDOEJZI&iur$ER&Oucuy*`4y#t+tJ2^VWJ-|A*LJmA9>2xQkIN zIofjd(j8XlwSgs9Jh|k_A{I3_{-+y%A(eGLs5A(>KmS8e=;f&<+TTA1z8(%yM;>_RRa?foJV0S z37CsRK1883IZILa(&WsGc?+&&YxUc~aIygtTP!oESxZrg+U^Cd5xB)1SmNILu(!R#KvPzyakbP~p+0!Kp z(?vMu@%DUbB7V#k1Uf>L+*o3bomD_(bC$*qIfLMwaYW9rl~O3*oMA&G^l#1()?tSH z44@@iI6d=lcY3hNyN-Lya^7v71&3XXE4IcoQWa6Hp}Wt9I0X$yD*iBjfgy^?6FMZi zSOpt zEv2tC4oh}-((EqB;B$bZRFjr_yZN{@F<7z;mQR#W_{~`?UBB6rxdee$Y{Q}jfHZoi zpT<_EQA`?EqBLB?;oyS9@ zNG-IY1=xfXP;fQDgt38`;xPisTb><>ZMy32>)m{i3wjKXy}}dkKMgBkMvt> zMApNq4&A4eY5%N}D%mhXCSXf*a4|D=coOHyO<2@?I7ju^=@ z`i%^n7=S{*%;n77=MQ8yjIr5UAK4;Wl1UGXZzC;c#aLN1_0buuD9}rbwWvEp(Y~W zxP*na#W1!Zu7%d58{5@J#EG|C$d3V;q+$(miBSx34HoHO#$ua=8qYYgkh`1|Pt!8S zI5@RT_@@P!I8mbuFnPuqd!5CXX}i_GHrsSCP;?sC+m40skg!FA6*sT|sG+1!AAqwbd9#&8$?x{5J?+**)u03yg6>5yizLj zi5o^%49XCqH0KH>Z*cyGPbHgWf6njQk*l1XvQW)dW{t1kt^0BF>f{n**5ghr{ix(z z>R<@G!-#6#XLf>{%Iza6pZ@Lnk*k!BKBB{zInZ1>k0TZ}0L@5C z$V+J`L6;oXZaQ?M+Z?(<4G{QYYQjEr{VEQ>1gQwr4}Q4nQ44UbsWopZ7~IrKm7S0J z;TC+P!!1}kqJghhxhBWJ(5@g`T*EZ7O`jZas6Bod$!@P zpDSX|=J5KdBKB;9Uq4mEo{_vV9xP(dHufD$!(Cm1%QzgR2Yf86V8t1;oM0PY_hC*t z($C>|a3uKQJQ{u4CL4RvT>7jC_=WqLu1|{WNy+H&TwASP956L3}d-N zi_VWsQ@gY~KeFwM)9Pz>`imdA&@J&J7O=%%a@8Y~Q^uG)&hUyFa?ps`G}N#Fj%^t+ z2I6&BoMQ#K8>wB;IZrbc(6$e+8!I3$0Dcw6UxRAn-bs+IzV+X4yvtg?h*e`@H3|>A z)arop*d&p?h+6R$11H1oc2T=V!xL{}!`yiWpRzBaEv(WID4W;O45Edi0XuxPGySA< zGT4=gdM>E7o0-r&fUve)THwpi95OjIxgR7s?P^V08BZLt_a^r(y(m@0hR@nHlf_*?%#;H*)bB+=zhrk3@P zvdUbA+X+Ps``Y2nx+^k2BXYV$GCw17x?eIsLqhYzJT%?WQXF%}(lb2}ZgY7=&ipNZ zKZY7d>>WNABN9 z#8@cB))}ucZNwrj3bEEZLDw-_RP=PApEgz8aYuE`*)ELFPs3OU-Cte zKj6Y2aN!>r7yjb6KmP+RL~Hy&7hb0>{GYoc7WpFgZsWXQlFcA91j7fBL0-ib!J7y? znT64?4htxQ%xwZ>`>515XJmuSCuWe>`0A(yX}p+uHnQm02Xj%ztrEE_M`?#btMb+E z<~ND16y{CeY;uGMo2<9~fgn2JO}I^_f};$7NlxG-;0Y(2Y{TD{P3|gQ-LlE%2DfZ- zSN>VcCU>{lWOa}C*(MWt&@o*7JI_~+l1KRmC|NF*%WZBdWF3D3ejTM zTgz*_4gC8GSHAgB;t&4rU-O{^-@@hb6P@DDU}|41YlFMx`l5xMheWuf&X)D^id_-B zS^3k;rB3vCLQkYG3LuJJ6cBu?K^a#&qXQW3$~oU(OI4|^{i^FCb+JjPE{>E>)jBp{ zKP$s)!pDE5Rs?_&FO~yJO6JuK3B5Y4=iiObzZcVQTY9qi{h0ofQo56}AOlT6$JPsw zaFdk4M6iVZtW&S@tUsg|OC;X=z1>SU^s1a;rB5oHwGU0;9c$+*yA{g!n~iHQX&?5& zvITbaM5OE|Rg_EXMOFRhL3#2R^=j6VsMT`)1k2?4uKq0PBJOc8ICW8(X0-K3lgE@Sh3PZI);ug%ak>|*_;Lb$9s;; zXB_C?um}$=7UAe~V-Zqg5#C-DnLuFZa1g4gO)}iI{6rY{Lo-e?pxrbH;;B#!^5G z8pU~gsnx(U&Y943i*rmoQlZ5^o0VRvJIZ{t68kV~bJZYkx!wX(L@f_8+B16SnF;N= z_A}_6kIzcBge9wuRON#mbHX9|4-gjJuM;)Lcyq;T-X9Le>0HmE@`Zfuz<6G(Ew-m- zyT!nn7^t+Oq>6xvulbfE>thxaPcQZD6)lQRg21;2@=Am#8)t^xvlqYEmoHwic6C{U z)81j;l~-N^iX&uqzMa6cz{#GluMNOO0l-qDe0jk_zPw;O?^g5Xyqit$-l$VeU*4z- z2Q%bz8Q}S=;oK@~bl5a}VY`O+iaFWk)oI8keiv=?F<6;;d*hpY5Y~9iU@kWjYbRRn z%Y<|CLd*SmlgG7a$r4g==VH?XttxdsXjns8(Br_>M12s@@PDbI-(m-HXnibmgO#Cz z26;xN2jzh+WHj#0x7dz1EUlg%HKuL)_r~4An=_Cy{{WAJ)O3m*11a4Qlo?fKqaQKN zofYxd#3)RC6NZJ1x4l`Ca4Fkl66;?nsWOSx8$sXD0v#7?+7a{S;@d(mbeH+_X{Cla z?`eq(Hf6nfP%}KtpvlB^G_TePC9||TV!p$!EZG&1G2y2!IRD`PoAt)kh>=hKMRmkO zT`{8kI-3=?4PK7dt129IaoyL4=eSfmM)kieRJ&T9j>cuX+n$aI%x)i%3W zw+z}ENl0GKZjH|PXN~d2sL|pxy5q&+MS9lpg4P4-wmfEH)V1Au#c)6)H2b}(apK+l zCYd4OO^3z<=XgG;zNMzk20S7N_db_cqY$H^J9{)-c2xX4I(^V*}y z{Va{Q(t)nrkffJT2%~M(NQ4LL!V)jtTZt%dycJPxJKcTY$F!>`%_d1LPLYVg_ zw)a@CHH=j(xo~Pvyvfuyemy$aC2Cu6Tti)c?+UukB}GVxs&AtT*x89H9t_b`><(0E zQ{&oH*yS=u(xSpq_Y|r0ZhT^6P;pFDP41CuhKDyjUlmXc2}11hnH>&MVamtYfUemB z&|Nabl%6rplL)|HB8JJsI1i$eJ+K6`d6RZq+Z$HYn7?S0lSEMu>p(4!=`72DezLiV zer;(zDw5J0ku)N+-!F9=WSsn(j4ImCpw&A1t92rcd=L6iC?GTv1?~;BA=5+Bh9siQ zwY6bK@?k?p)3&A!k?|xSovY=8a+;c2w$2p7Bp9bHQQ??Bo%G}#N=_E<^5osZEkBRi zbc{6M2^W*7Oj^RS6SDbo8OmFn$3jr9>U=a-G7uvYWi@?wS`M|=(sI?mB3h2ffv8B* zlCLO8?ZG-bo#P=eCU89#(+8I=pL+l3$+~QCdsCmmNW6+ zQOmKmLb4>Ww{Wo8fGC(Fw&!1lmIE&avVd_1Y@3$*|JpnA=(w&j!Pj1;x+SS(E!JYo zPZh_OSM95pxJ>NC1Y$$N7DBADRJLVHRZ3OKiD#yhvN2771eEDalfyQmCrunWY0L}_ znRFV&Ob7{wPRyLp$pAxi=9n}5!O-G#x+g=^@%+Af-+NVBoQ0<6^qDjADZlsb`rU88 z-@WfX_VI{qyONgEhc*0@Yq`j8r{xGB%O^;*rqlZ;c|OtRewWNA-zD?OyRJzg##|}r zTJArVJC)_>7X#kl-8c&#R(PrVyNLEXOHThkEc;Itmi?WE`kD2YLjC5!g!;LcP(PQq z6zYGeV$qgO;VGBsF!w#qTj(917;qAZ;B>s$YIY{+vr(eSp6 zj{1_qrdMJ!d>24kk-b5BE`&xAD2UhUPq4PrzfO=%8hQW*Mx&9o>IYFn?O-ETR{~2E z6C3IFS5}lDin4qHG)e&D9bGeoZ60<6%6?!O47J)qY{|XC=whX|_!OHnIyvXk9MmhX z2=lgdD8a0yMyPC>l$W!y<@zH*UNOmnYkU|Rx7ttfP~x)p_GF}B`ExRsYQfV^wi3$H zn)v%>#~+CCb$GlxygN;=9@$Q*w>)vjd|%K>z(Y19x4Ttr90y6{1KsBBt}qYwOX9Mt zb-nat1>8=;9p0Tgyz32BUWzyBCEK^0ZC^}7&5)Tu z+e6m7NU7Z6UBAOq0XCFub=u$ntZ8k~BFxDCCaKphW$0bw+9a`|(PkUHRwt!cYc!nW zku9w*L}s70`I?j0JlHhT&~FP1sU$Lp|KbGr zbQ0i1-AJD)1w_gXfUlNF+&uPU)(2p7rjgS3$W0QB$QR&!I-YKlXe7pwn0AshqCZ9~ zjYzm1NGjcEp-G~VD))UklSCt>^GP%$bHo%0#e*W#NZfs+%OufAjk^S3l4wLeJzWNg z4ovFdn3#NRDd?G;Gcox(H`LB>NTQK?H|B0|Vgmc6)8e9ToKv~MX9Kgr9`EYfKvcQ7 zs$PyFMi+JmRpE}Mbo7jFQ-&}nGj1p18gx+?a*vpCF{YV{c+wL3lLEeE$DKntJ0P{3 z`W8Sr;8(aT6f0E~3R@Z`rvG+(H7-o6R)9$efcA9b&7yj1Tu3mutDFbTf()4T(!Fev zn78SVnc^F~_-El860w#l=LtTE?}}oL>G!oa(Ew|2TFL|?G1`=- zwX}kdHzl261haw_He}M*lJHB{0TK{>CQ=wz(8Xj@8(o4-0>0VHV&14t6eW(5U20#7+3C{cR}kw;!f1eb#)+%TuXDicFVSR{&)u#!0Lv24+? zC1yo4=0{NEh&cqMqFhGfq#~o*9q@|0B6uP>%;NneX$f&_8_|+#5J>`SQcUu=bv1>S zGSC;X^SG^bBt>hHWroaI=q)p3ey4_(Et-hAs!wawS)+ShK|;Z}HN>`QiaM{ryM|0H zSAj)akr`{~(3Vk|MoMgIl7M81y;y3<>RiKNtQL^eyB5SXWDSd1dEOYZkZZpDuK9|% zi+tsVjLmBHc%vM@ZA^z8tZf?+!Ly)<(XGU=OS}RZ0)kZI;&7E~G-{V)ObgPivD%yv z?sTb_lQm0}ae}ehCHt(0pgkGU&dw0f*>)>SsSK+CSjkH%IVUUlB=cIaYQV~9P}J;M zMgd7clooj-g8!m;eat&`GmxLS952YQZ0RqF4H11L##k2?@L1&2(t?PvdBv9qKDIY@ zSE5OOQi9Xf9%gq7pOmPu*c?MWCW(Q{AVDJ>SNe&V@4e_dCK+}b3k3F^UnK)=vT!e} zkPk67Ssa@6F?R_YK+m(2M=$V`R3UDse-9aRK<dgTjFyc8#Pde(O$eyh3Cw9KJ(_N-4J zW~|8=N3?~lrU9Jeutl?WB?^llO$Av7)*b<`?y(lk{0zj<15Gd(L77K4L&FtqUO&Ur zjs-O(M_#Fs#T1!vwn-p?Ll?plyE8zFx#vV%ne>?^1uCh>a2{efKrRA~=OOrUH$k{! zFBo<=K)8|*Hh|w@cxel-MY9V?*KQ02j4pQy2{}X=$;KI@)EDJ|4N;Ng@f0c*|%>lajW6ow~xi6=+zd6GZj$x-5-q@PwdA;oy6=KEbl>H)%7MT3zj#Zh$d@JSy8zL3vz8r-c8=! zCyt#;)ZR`iQo&I`-UBTsac8M18+XooPe9~`WIN)>|7Q1^hb0q9;Qu%$3d#09%9&ga ze>{lBYLY&iR_N1ugRbh{LRU#|&Kcts`g^0^-on8AU`k?AtT0Wqfh?`lyvgnZi5B!i z6qJDRT99RM(~x|>yl9zd#r$$vcXOhtg^fy4)E37sMXjb5t5r^pZ;=wjsq8|{Eh1Bb z0}{w@wVGRQW@f~Gg*py{)I^n2AqD-lZWpz7?b;TcPL7Ps$(AT8)S6C6ZY^t8fN7L| zRCzy*^i$u$Mn-*@uN^g?2*H0caQNf(vnT`0O( z-9qq@Ewf2B6}14QY5^Z7EGCil94p1qHi$ImU^5I_wjq#SWdM5EB@hIS5z3YKZ=>HX zR3{+RmV;0S2$7by)mnq9!9IBEc;>{EkRF+nC$n|d20Yuj2&N9K);hL7DOjvj)Z+NQe}w{r;hkxtWE36QnL>Jp>>_h0a1Jp)2*DEcV$|a_hx8a-kG8G3Voqh zwP8Rt*#vLWN7LXA3$0mJifVed>cJR#zaMqx&>QLsvk1MdCanR;6XhkURg+xA&mE13 zojV{AH+M|vvJ%NluC~@3vPT#W(0i~}i&_$$y;@7X=0o|ez|F9t?MN8dw5Ez%+N8N^ z5;uafoPuvskP(5NH&(^A84Y2JwrtoSyLnMMG#4I*8(N%nX%ODgLf)>WPIj?6jgdlO zPSz|>(VXLPQXHy_rV*Z?Q@GQ~)k!pg5m}T(8)f=P+JO5OF^2^{aa0NdQzX65M&KK?BCF%}V*2Y$$?)O#3Wkv|4Y_AP7qZNec zY@2W-$jjShHjFpl=w&f+LP8ulTwn=tLV~BjqIBStbySeWd*P(wG(mwfo5 z=Y~Y3fSxSgjk&N|tmpxz1CaxX+FU~6N-{vDC(ZCuElwAgdbz2WQrDT|Q^l*r#lj`3 zS0-7$SEk=Y0wCeRc4Qrws!@L&1q(Rr!3$w%LY-U0*=o`lm3BmFtOivk7@(_0IPskJ zfDIpun|c9AoOAPW4Wn)n_}7dQic8}T-fk8Y8l6cWG~Q&%^v!7;b(DyzK@U53M=w^CtrF_`cEC?tqD;Nj9zA%dg4m1;8msuAX8rO@W=0=fi_Vg z^#?2K*{=f&)LFb?AsJ0=kcW+>L@*9k)^X0hlG=~V4E+?Xnv69!L&CtaF@SvwY39*L8%>)aQ zCTP<3Z+Tq8{#-(XkPO&?o0-aL1=NPa3{(c;Wj0X*sC_UC6qnmX(U;l-llTjaVh^=R zhRPYR`s)pHA&N;oksEucG-KbEhN_DL`9Y>`c78$>91pKM)H43G83CEFhYHdUGTm!r z?sxBQL5n`mSl@c}?dNvGC+7B1DPV4YvkP!dS$*pkaLT^0TRaHe0@dtPdS!c&n zg5gNW_nXw>zRfW5_15eOp$zg9LCN$3U*By;+N(`rbLVzZ}T zd@6yyL^m|ME;*XlPK%c73mi9BUuZz;4pbuM^uwe~43=mj{65hJT3jO<01yrh^vHr5 zy`1B#f!E=HwOF-ekTyWQkBf(By8JU@g2ah-6|aR^pRtvq>Lo&A%P=Cs&_p1$&#`!_ zkI`9a`nSSVUocfR{lfvqODvn}H}f9b5|^{ZMV+B8-sY02GY+_(1-MSUsOw%<~O{O4vvE0VhfLQBV3J<&!=+klqDPPN8?vfMqF7`e0r8Y>t=?@j6As#qz;E z2-K{OgRA?!Uhks)%LMGv+VaKq7?%rt^n^wt_8Di%jcs~MtS(5|geN)koQL5_2F4-CS$*;vjxTxF3Hl*#D&c3*U<#$5 zyyQF4;nlC%_>%vMMFr9`i_-(7V}3o!%in&n;|2_sSYNcB?~_*FF3N|_LSPv>E$pZ+a{Z>0UIsP$@nIem-McW zgtI)#&r+j$jGTLPizyFy_$t~F8Ef2cDyW~^Pcsn~gyE?l&dpdhN`#SqO z2Ra8khq^kuy1Kf%db)bM`nvkN2D%2jhPpeuySlr(d%AnO`?~wP2f7Elhk81Dx_Y{M zdU|?$`g;0%26_g2hI%`DyL!8OdwP3&`+EC(2YLs4hx$7Ey862Ndir|%`uh6&2Kom3 zhWb1EyZXEPd-{9(`}+I)2l@y5hXy(ax(2!jdIow2`Ud(31_lNPh6Xzay9T=ldj@+4 z`v&_52L=ZRhlT)gi0+4IdWdR6BzcmL22^|s46gz?*8~ibJjo{ms&R(YEu_wI71SLB zb@g0Xa4W0RL!EY=x)4ySp!H}rm+m+^S?HL|j%l`<392ola9VoI8aX&6EIB+pow*~I znrh!PV!@y(YvjgkCOu-EN=;0s;lrS+aT?0%3c8*7pbCC)`}XZ0@+236s?j5B>~y@q zwSnshS0DtudqOHc4_Gp!$081gKFIl^bCjtf^&(dac;>mrxt8ia9#S)2-3-YVKlwuj z^k4Z^%E-^sIae+N^4_qFwEKGPc=$L`X-HpXNWd*38Ac?z6)MegT}-8guxgirf}}Xt z4P5tdrMl-3*AUkct}+Tw^1+Du+CRI23urd5Ir+SZ5YsHoatjpwaQwqT{K(c`I{btF5T8B66(@36)Tk~N;mkB_A-STm|3 zR=ZTs^K>z)LYu7YQESA*cVd;7%R=-mGW)Drk=f^zsydQBHlDF|?y}OEF{_>KlnTfr zohcRHWZiK*ow4#0o@6nuF8Ch1^Yka~`=ieHy?^AMPux4RX6=8gs=nbJ+dHng z^+SjM?7yG8@00ic>qox&#GilX>1V(9(@Q@K)U4Xn)jKe}W7mPVf9TvN$@Z@P>#<#xx^mkvZX;}TiTmSBVy>_`+IeGg}U#_ZNm&vYK zd-(V6`qQucx?y$ey8YMPc<}wV+_(H%b(fv=?6PHKeg`iS6;jP+~pe&-txh4q&mK_+e!q1I;1jFFs1vy5u_o+x&&dPJgw3=RhQ~Idt}NO=F~^W}DxNw^bMK z4V?XSldAvdE&hh4K)m=$up_u5?5k?5D1N!W5G(#wb1YcA94vl4xIXsTr=$O6OZ~a~ z`~wwdZmlam9w|P4Osmpz`fmw*prZKU#x>D~iv7{z$3uVeP;7Oe>x+Ri zKiUwE1%t&ut~oOqzq5UF=pBLLeSzXP{Vo1#9P?tm+Up5fs;d(!s<-wUxHR{WLkMcsN{L~k|@NYxmivC@@-}^Tge-Nl^eDC}IqVKuq=U097W1sxOVlKV$;8^;WTfhE| zb07J9#lXz{=flw*yR(OX`Pa7``OIfGw!i1|vtRso4?TSTu_vBuKv!`0qd%(H?;Q*4qyNFcO1IuJ?|BM8yQU>J(<7r_wN4qLtp;Ng}I9z z*PwD6)X#mlCH`g54?WTWZ^!oH*|q+z>NSD&6|KQ7!D|Cmn~Pr#tq-gZv`2cCw>WcV zprRofDLy#lAB|LWHU!)JEkW;|!N3i{_JBW75vd68u{QE`tA77*usIxvg%2GV=&9@p zht7 zs;nK1MEjflsFE`yH^sbXJl98VT03+myg$0uf8Bure^n%U_DdiB%+YC8eCp#*p6mG3 z56)iq#s7GAD7-n~8`%)uA8ilTet2r1>WJ6u@wI;Xf7YJ;n?J5Rv+iAI?)_NcWU$g- z5sv@CNb&EY`ABB<{^Aqwt5{Y1n!3hz zZ}sZmZ^GeeQjH5SWwI*-1D#T!yb`4-=elGp9UVMwRCR#*!Zz@ zzF_UbyRh%EP-|4Z3@kUDDU461JMyRVh4iF`Tm`Vqz3E)oOC|toR=LL636Ae#lHPUw)8>vGnBd)D(4Qormco zp5*yfrmRerH#7Dbu0n(R_(2wsF-PtQsoQyQa{qvPL!p>lND8tTXMj6-4x+_xb!aBA2O3i_vsa$p{otrpq z<;Ra@gsXnC&cKqL;Nj9bz-DH&rVQ*q;@-H1MN3s(pUNNC1W4aLEj%$}G0CRJ`m!32 zx-~9XYW>ZnaWTemcp(e@9C~SL;f&5(YR#ckE}bbbXu7Zw0K`s--_X-6J++th^n}~f zY@2GosgTVHiK$O<2^^9NtS@u;UlKVy1oN# z6&1-(O^xgEURMMkdo?4+=SsdzW6&}q_59jkl%`VvwnL7)fm#eNvg zpfi5sJfy(lxeca)I|QZo+7G$(F=DIs!$gWYpR*rQQ_R*L+5pY~UnV|7$l+C7q2vaY zSY}3a2xjrb=aSvj=n+)xFYJd?^6-lNFeQWejgxb13Me-kDA7egX+NAArOxa|(Zfc_ z-jW`k->4GrMq`ZUpdkW1%{SXcH!NVqvDZid_B&xWusCh4z1xg;{97 zvW(rc3FShEqWGMSUvh4~FTjYOcI=eMcG zavuoKBRiT)jh@zevAA7rUEYh9CgDW%^!ViTy^GvfTgd<}P%oPKVd=9kmA0E|OzhVRi9qQWI8cN^C}I0;ZhpREbkr z9MNOrrwBJmv}Zh{y$amYqd1V6vFS<5J=F;Zu;QQ{3?PKup8v$p;NU0ZULbXwK*p8n zh-ZPTv0<-t;_TaX1YT2TrfadZVLURU;}gcG?NZy8<8-8bB7Ic5=ehA?#|xWAq84i8 zXkpkIfjzoZY-DTH(pfrXp-V>}i`}Yyd0TB$xpW?fDkU!EVeu?arG+cbcQbovHi2OW z<`-R<=g6HSS4QvTzU1c4cdM<$w(vM?JnCj;@n>`*oyts4xoX|?hXLt9vo2}xM{au$ zky|8Jrc6$6KX!AU>>>I{?&2BQ_o=goRLr_t=ViCfC2~8-#Zz>1=iS_5FLNVTPotv| zkFjxl3=Gl)Qela*#v*eIW1y}t^s4v~oDqA_I*5q*?NzHJHHWO_C~3leP^k9}CyT{C z)k>$LotWTFS!2^V5yfMOIo^3XH%_OseX2ootch7l+0khx02vJO9C=caP8|!%oCo&C zSD5cp8&+t$oDXytS^BuAUo~FDfh))SuU$ONl6!$%SlY$n-@CbwlRL8{_cb^7BDquK z%Ho|v)5~t|LceOtrIBJi)3M{FljC{qs^b9+sK#a4wzxtKa@_&yHe^P$%^v>6fil#Z zTpcU7#}AsZDYP(yl`kK5#5MHy3Pd5vgu7E&$@YIqI*$+X8ztjcUR_!v^HW7AVavt=q>*244=kR~%^urj0~^9)Fw zT@>ulaz%BKT%(dM4yg&PvM6dvdH!_HlB<-FpT$r9u2jZHo+SnNTd53dio+$@6o@8Hpw%IUk4C3x^eW(Yn02e$=)w+ll?@AyYYF>~ z>{8nuSj%l=e){N9){10iou6Q8ojL+Cv}Xu+?o$4dVGGT%OVzBPY+l)=Lc^))!tr4| z(p{{F;2R32#4#G?hkD;#O8rw3#Bei%A$6XzV&qGcmPgA{hhZFP3I5m(St%>7_Z(Ne zaL==#&ID3kC~NWC=-DZABGuQ&Z6vQ*GkcJ`W;JoiZgL`;%(>}T$pD=iw$U-RbN z&vR^`h|gF87(8S-(UJ#9zMgUDKT`Fde}$`*k)O3fo+RlyvTX)TQ%0oxtE8EwxCN5k YRdek9^n@As%(p$tCzO4F8$TocKl4(jZvX%Q literal 160453 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 literal 160504 zcmeFaYmi;nb?0}^xzE10Z{q@JG`i8#bb2vschP&Ey$*ARgEjf52`V1O65Tu zRz@FGDO5_6VkR0hzyDhMJo*8OfTWBQo8awz_CEWu_S);U*M6Mjp(h?mlO#zW-tl1L z?Af#F*#|TGt4N~f$_@R?0-v7Y+Z#|r3O5Co*Pd|L(q0M>%mbf4@s#(amImC(gz7eAc)l;5`Rr|; zahnQLRROJcX=tgA9Pg=hZBof+e(|xV9=Q4aw}H&lk2f0ahW(c{T3Lf}PP*+hO%sMZ zO&cwKnR4`7jWq2|wj1pM(RQ!hn6m#e`!DU1woMhaTEnc{-QJG>WsR(54OkM*WYm6!JFT6?7)W(_5SUDJ@NRz?_@J))2DOZE@#dBLV9w%`*79_ zyYu95b}kM4Th6-Ui9FFmGR_n<#|<)^OIPz|m>9Ok6Ja7hd*?j4i093_=U2zg!&x^w zUi~Azaql1ryO*hT+Xm)zZ|cKUz}61C^41xKoq=kkzZc}TL2<&#guu6v)R?9fUm@<}Sd|L78D$dBJAfkLfsrY0SX9Ofk%J)shn?)Q5 zmW0^Q1h&v}R3;W1cUBQTt>L~sp&2@%1u~NY3E8mOr<$+|Cc629tK;qfc}^Eq%{W!> zK&#Nl<03#v+0dYa=jQqYcNykj1g=MQUF1)H~RF}2EG{@>PJ(< z+EwE46o2Vp7gEXqz8m`sLU}1Pi6FtZ<)ID$Q`DbAQ|M?39S|P$3lf@O(2x)r;2S?V z@M$e$bbrDf_y<|qJ`25@`W~Jfcf>&*VQ>;8*&wulL_Aa}?+)aOu5O{-TA^jS8{Xw< z3*AksY3|N)HaRBmC(zhv+?3L=Ayv1A<1MvyO`Enu%Ty@;OpbKmZhCK8oDZo1t2tZ>8&H6O((&G?3YH~xM$p)9~-x& z&{gZCgb?qM5-pb(B3S3Z|%8_C$8?xHCU)i)JMY zNNb-|r-X@i#6iaxOFW=H!$y&s#T1hM5jpUkFwotAf!}Lo!x|%=!;;%hO&CDi!glAV z?ULe&Vj&$q9=5|+qoG(;4HHYkP?~Hs)i_Qj%!sfpf9>YHJA9BR#*OlPa@_QH5)hdL z#7~n8185r+@%~e)OCXZ#kQosTFD$dB87%;Ng*DNNuXt?NUr}`@zT&YkowiF$W8@s- zRkU#?LZd9FBr58KR!quDJIqQRl4XN-iErDbJ=G0aQHff>f;mMC2o@k_42yS4q5jEG zfoj4B%WNZrL)s}!vvz5QbxZ5Z;4upb`5o(r4&qa1Q+X{1LLW+&j55ur+bu`oB*4Y zhcryFU8H;OMq|imP0x(=klr^xPV?lhL8fw)M5VwnlpRS6nKjlNWy}YV*6ndNNGDtI z5%EIx`rSJ}+&4mq3`x0TfYin4aK@9>$x|Pr|8f$I{x=dC{g_=pn8^AyW$}7)ay%)u zGwF(A(iH_U?C3pVQmTPJ-7zy?vz(`Emh+*)vTaMIr1`-rZkF?M6*tRysfwHB9ICik z&NWNiEa%b^pET=jj4{v+DZ*qlU;^2O!|M>XnRXpPUfCO9gBWQFl%aB%MwpaBHBIkPy*i{<$0^D4Et-pdjAw#r0^VS(L|*BNS8SGL?1G8+ z@Th^=(o~I1u^d!@BMOs=B{qV*2nU&2?9*0^O@kl;FETGCR+CH`R1tWviX2j&OGq(G z1u4N20dIoM%SJuA9;i_aB&fy{!^O}=n=5792R2oRD@fB)Cel5;UuGg=W;c|&H0qgb z@F^N%poOPcE6QQc zKk8Xur$;H^X5N5abfJtcq|yasqL`XJYpAHa=YTmC0iii{idpZZ42!|~S??rLpm7`% zV^XFfq75-vO20i|NBz@OU^ocb%frdg;17cFue~h4kVRSkYgv@#ztYG$HCc`i$0k4O zA$|se?g&haRF-jnG6M+2+$rzJapkG+1Iyu-E! z&Hn$GrOk5Y%HV0rn_oY|g+f!Z2F6K#?tf0Ox|Pa!v~t)NMV#eNuL3sjPK_J+o5?8* zi~P-O^`FVX~I&=6U=I}s5WU#WP|C;ie3?xCB!YdfUT{wghuq_fAN0UPV zSI7{FI0(F+C2>J64AbrdiIPClk}L=b&BhsEmw2&P%e*?MRU`SfNRm@Us_izOktpaW z6@cLpbsv&cSpQEsx?@`dYtbrP+yXk>(OHr&JuFrqV3)(^1K0?IWRNefj{1@#p?N1x z^nsadp>ZdEJ>W5eNsS8(GavK^mm*QzU)z%e!vr4$8U(E%l`se`ATV^1Yz@i(G=pSPtzE}?Uz@=vtjBP26_v?&G!9q z0-ir*sHk9P(d%8o?giI_kF{0PPRV36HUU+Ul*(J0ih4y%Q1xxrc(l2E zdR(U`si3D+cT)ia4-C+&n!s#qjYK6~nH$ha=*CuUm5eE{h{#(qj&UNZ%sT*MK3R}1 zV99iD(QEvoEh+GU%w-X83k&hvMs>pv;9`EYDf24-Dg=Z(S}E1zBh2@)T%bRe6HbaR zwPa@P05=xbEHF2KS(bFdA363AA(jNS$<`>6LSj!$E$E&y43|ymHQ)%#& z!^6LgDgSn|Zdy>egRp&f^R@QDo6UL-S9LyQSl-97P^6umC zAxqaMM{uZ?fex|0JO!7|=Z(k5)O;t5KZTDWv`4~T8*hZPz2*%`?EHjUnZ+NmO;U0a zZ(;LjG6}|~Xlfg>ftq1glOkP}me{h_i4Rvpo~LA)>sQZq6!#vDoosG1J0Zf2d|t`s;C?v$quBvIJ+gzmZJ&l-UYjfe>E&u z6m;_B$O6XoNs}eK>I*Oy*-c%F_SEYp1oU=t52Ug!OdU-i#L)mIwAWMl+7LHco{a`1 zck+wrsF&{>b!+d}n##~1Lq>*lG?8CYri48n+eVX;VN{#%crw47o>uKmayH1Bk#kKs zQ*z!unj{|_7P_Zl>ZyG4$;U&F{E6qeT~lg%kA2h)X?i@Np+ts_5`aal-v{?Yz1md5Tq6rpBW6tnu*wWUFtn~U)oF&A*R~25ruuJB zq`gu|ArsA;$iOq>*C4;sKhZ~bOx4m?J=`1k2=GP#aT1LzyeKlICeiJ3Ye{ICtyFj` zLr)$el_AG8Gg~tnU;?5D)Ei|3ESSK&bI=LB{Ol8>9=(PvST4Flj+U+R0?uUD_F^E@ z40r2APj3?Ifw`bGgr>z~py26X0&?@SKSi~f`jmn!Ru^H9Oalcdvuc#C21Kd__YGvt z_f{#Ie*@1C{YQ`V2W^B~d~D(Lv3BUYw?m6JkpK3_sl8_#Tk^Nl$6*X+ibA(6P1P?= zUI1qkc}g@@!j&M3uPS_5g#+7~9*69jst=W5rfsC|ZNcANp}my^d& zV?$8O={N*9v?u9($^vLt!h(1|jGVSNxa zR%VAt|EM6eQ`7sSp7xMQHmMK#M~?nUNkXxJ#wGeauBJtX9|EA3)lmaxFqPQ@pr|r? zQke{^?NmXjLI%2;#85dY zz2Qws|I01+!m&{iYLX3zgXa3eEHqCQmMg7i%CPaDWMG1$`WMm3`Cjy7{(bCIDoUpI zO(YrnQn&c8t+e(;KmXs!i>RWp?`Y^h*)%`*gO9KBr!Uoz=70H*&aCGD z%YSk39-e>mC7yp{R*!%2mpl&i^jB}cojjiZ#^v6}iTn>=`{HW8tmJ?3k9q3d^SJ(l zEu>D`eGwb-^YrI(jMvT+FWa2^_2e0JcSE8HYGc=)_KJ?M9$y@Fggj^=9VK-%BIdAD zsYpUEb>2(0r%C2O3PE)qm$$N+H}4_oJJ=4Ow>i~Hnyq#N^FAR{mj8RKbemyF_L9~P zmJWq^vgEK87U+5>*C)P4E7Jh6G=xWSp2{#k&WyBE<*asP(;U99|ErC( zd)B1xXoB8CmD>6emrcf|erz{NL;Pf(TAA~?;fDMT*Jb7coR9>sj57M-cs7S1O36!8 z&kczwrEcihJS*TtX85F1v?0eT@nIuTs>Ku*C^2Da&>&o5eXUqo+bTm(;M_G`)OC5z zlu)&|RS}g-OPPQKcCXwO+B;X?qAsg=QpLSuriPkdp@~#0jc!zB7qCm|8q1NehO{^*0W5LbBt&n;R7Te8JN4bHIFs}i|#?|mP0f%A>Y)r z1gD%@6S=mEb>fjWw(2;8Ye->0Ep4zBRDK-c0;2{F z1WgiJHV~l;{LA!)wOh16Zj0j{!%&Pd(EbUs5Zpp3ZE`)FeUk9}4d%PxX_=I}2rpxI zYBP@Z`X0{iCuE6{YAMPH6Qvm~!dW^Ec)Bt@*B;)&q@e^Pz7bd(0U?w8UbM&4Bu~J? zlc1tSp49e(ge>nCU3h_U1hAa75BiY5LKLq{gpR~5q4RWQ`c}uFW5CA3qVSD$1EZ|q zq@jC~)rLFAt~*Wq291sHUVu1_t24>*OzRfr<4jjW!iF~&6S6?%*oo|n)sRXcz}8mO z+!bDpivxH7P$cQ0U=uX>|Fpi;j5TQbWlY~PrUyvHnEqiAP#B8D9qky*LT7#bim`bQAdbiHfS*hxD*)dLDh;Sn^DzB!}>NPBqs~fJZSes zAY5ZL0wW_Lme;DUVYD(!NH;u<3@j}I$=B1Gp3!m!^Z-(DFu8-W%cN1(08B{$!@!9E z#tt#rCZ)sD5^c$~=CbTWmt}y(Y?%VKWMzUH+~L_`#Z>F176+hq5obGQBOIY49X;Jv z;ajD2CKIO*^!2*CZ)f^)PJ^N%xsj5Kp-adPXt{Xv&_d#l%UZOZHOebB4oqH3#X6Q zY|IK~u<=nL@we!>7&FW8?ZHnLlqqArI{91~lqrF7*|t;Tq$@OkrQ*RL3(8W(Nxt@1 zjmPuulja4Rbct+BOPJrQ*iPvUNy^4I_lcQECIz*@Y@M0hG5`gS6FHIS!BkoOVRlV83&T-au%R5-flcj85x)( zdNCR_j$6lMXQIt!&*ZaT9OEC-nFTCM(`ccu#VB&ikjlu&lu?tLE_wl_0(^M8Y#SeI z3F#ATN^7YI=QymD$wUShd)2f?l0L3&D07mk6zmO;5Q2f>;iUhYt=b0mi`3aO+V|BG z2p$nTiL~rN&eF*Q2NGkmp178M9^%>}1(pRxjCYX|(&7mMq%+If^3c2~{R8Io)G1v= zy(~d$F#>M!Bohb4u4GR#VNe`z!`Wf^@4`U7*w7wFCO_J5#U^r-^*R=%=}~f$q~T}} z^|FgiO?AqB*q%gFn5bpz%4Nn!*}9s#OFOfB`3rtV4(p-JuOzCdc20XPs;JefD%d{$ zf+!f@pjFLqW|Z`*EP});c0WU52gt7NgpMn@o4^%+kqC}My1e|bHe)QS%Sg|Y#LKRF ze$Q$kk)Xa=SvemBc&x~p0Ds3A6%cy9?Fh}zuqg&)NE$Jtl+)gFLU%;f63PGxmmLp? zLJg_Lprz>n7T0S26=*+!vt(u$yHFt}+n{V!2)A(M^No zlDd<^!o@MpUU`hOA9fYpFqj>C)nSOK5?9+cqln&h%Ht5MkHnf-<*3)GE`UsSAH-CS z2*)RO2h?*4W0yo!Fec)qKK`W8Rs7sVe&wO3XoVt0@N4vC(iCSoaDd0xD2#f>U@#3! zn6{TN?bre)4FJNXeri@{Dk7`E*2PKL65X8Fghd)Qbc{dpN&2yockUTa&W~-gn%pGx zh^=hqK}Z534R3=xVJ4;WI1zd&8_kM@eDsTx&R4~q*nc)DfhV*1al@1b39vpB3bl&q zX8TeQ8=BFV{D;yn`*zaAT(9g61HMTmh4<{wLI8TjWHKPMs}sVCh9!Ou2%7=P5GIDh(~>vtyRa8TiO+y zR-z%Yjk1Y_L0~B1Y;bHA{xq-podGv_z}R*;m*QsVf`c@!{t@q-r^7 z?DctEtU6fCh8(6HoiKL<4@DcPX41QadVP1zhZ?1o}KoxXGC`+swDrOel zpnE}v1ts-Hej%N@(A5U!A7bj!(WJnEl)C50hbG-#rJzzdy7Lvf1LQ&q?5aU$wpy4x zN`;7pVfQl`;Eq7Vl5Vyr@~SRP7EFM9Ws_u(q^?zX(JO4lH?>Oj25d;Yx^%BseB21X zl);j-PT55!jesDPlywqc_lAlEm(zOjMi8&L{9yVeuS=q9I1&N|Y7!FUpcZ)~jYz~< zNfqk5c~v!r39e7Wy+@Xd47T0a)0X^rjz^fz@6NxMY1BM{+bpyr)*~EYE5%Eab6l-7 zWt03vaSCjW-eO=~j9}qOE@fV#WrkAjB`kholE(ff`L~JDA4$SQ?vli~O%q2@)41$->-$nG$JV_wZLzj%w*3x>LM0%0+SP1R6MYNKr5-U|@zOr1MGhS5TwJdmFH zC6N9?k2)wcm;Yszss*u_;eXSkwx^dE`8P2o|G`47%k)&8m(;-rIPV>f3e02PW1g+Y zgllPboKhweuGk-YOD;obtwX}BI<%+`!KLbSax9&;SUTe|8^>emf?`LLy&mk#zkRa- zKJ=lAK+YXtt4W00M=z9cb3V%8WuypS0&as`*|r=B6tqJusI2}P-Fa#~D_u7J+Q>^_NlBO0d*vuOVL0XZGKj(7R}DXhlYegEvE*wp{JMol zli!NrZ?gar41bKZ;jg5YR)gXtOVcP>;x(YI=cqGcFqn;9MA{MNG{T%lnA0s_ zj+|M*>~aSJ2jm6kOyrP1(Ht!(8Dv>nB<`yl@#(PWfd7myARx(pTALMw2Nz5T9lX1h z*kK1zC3x5d65k+t#uG&Z;WO@S7C&S3qP82a6F_q^Q6@o|OQG>Va>$9=Xo0uG+DMt~ zeMfp3{+vM`VUEy7I3tAXVT(|$(*&HKE#bJD<|WnCk!L=V+vOV%g}LSIK^7SZ?jHdY zOBvTF5rS3{Of0>FK&WBrU5NvU;C12ve7QJi-pi5=P$R3G5_LTOyzE=Mh|8oT3paC0 zhB`CWHz17g$Osl%&c3P*HeS~D&M?KfLV1cNrIp0&>?leIQx%5b!U5KTDRNr)O8Ns9>kSnRuagbcZta4tvl zjkpd@t4OxTv&}SSE`J@f6Z2eKs>;PAPsQlf_TO?r$x|Uj)~Z}l8Z+V`)q>OOg66VU zR!xvSiJEZRM{CiOsHVE?5BwdV0z{uxg6IRH>IT3l4eS1KPco(`?lQDWE~^qrzt_Ez z%0KQ&K*G-X5)$R2l5M3&$Sc8ge_h`0!VOb-rh8RkgIPJ*FXfO@bB^9#+1y;NB%7U7=v5M(V&hZ263s`>3B6ML0KmedUNb3) zx?TffevLATN}?Y?NrL1Y%jTw8z07kT8Gf4LX?U&t^%7R8~KbxZj#i&*uPO%z;? ziP@rmjr%dkR0XS0VmP~Rz(|dP!rS*3=U%qA+GhHV}7 z8^HzK4^gWb@LL(1@6eG$rtFvyx&0DmEG+fxoxF=y|^x}Jri?E0x z2p`f{pof3|GTjSa* zPZ$$p)lF>rj+z+z$TabGQ;JluU0kYvZCift*ksa%10vKugs@srici$EUZ(R=>rx@9 zE~zNGf~t}OjjoNgk0q5!nih1a;WdiZ&5|V@m>677naEtX9yPqi7P^|#ODKs-q$cV~ zz=BjLk|J-__(KbxMSkax9nO>m$54Tmcw?TDKV0hq!!+LDqJqn=Jlc4Y>q%6xgO#RQ z6;L~>c@nR=Cvx&PJ`Jm~Y713mz(Vk}RR>lxdubh$AO@`2^&ns)u-af(RL`lZ*pRNx zt3foh;i*Oin} zp{zG>l#5ELg{wk&x{!>vNtB4ztdfAFUT?HbDvQD@L0ZZ-aa#;XYHj4Ndw15=>yXsy zr8`t$W(%&{*bC0F#3#;$7d^9_W_sjj@h!8%1)gGG%Omj6cJ^jLO3g5R?>x3EE@sxf z0-IjPyX;bLw`_OFvSmB^Ck8unofPtIv$jX0i=oS|tQpM|#7}f3n)P}t*2(>y4N++( z73*LA&c>>+h|BdaLzOHZGwLJ0D=V$E1#8GPi;>zk*lp5m;M*=WGt49sHb{9R0E-~w z%v@6>VwcCcz-`W`Q@=rGPWuwO+3_%q#LAx@ZOg-m1KW0!3rj~jA*Q{9rMTKbq?A%S ziPVG>g2;taw`3jNwCyyno3^*2{wRT_E9Nj^4Qh8m1+hew-z=JyLMc*zO#(GaDPTIA z8d|KO6*VA}K;kTGX*DSBmxeAS&~BW{MfS^1vYd=umqZnTzV%MtK z8eE&~I2br+%8Xyzwz<3I4l>(48*}+rSx1yO{pW=8Bz=u=K=^e+%{YFGP%eVsCS*=F z%J}IBq*>0w9SQnjMGd&@+$ zS%?>GY(0T~*DORCy6db&+<7*gV|)p*x1;1|V5uYwr!qi}UKqP!xW`a455pD!cVn%a z3JbJow`S7G79~n7B6KBqckr_lwY?&5p^5NW873Z5D;HA7f!sgTR7@OyELLWj}*6-cVS$t$VVdhGpJzV=sky{HkF^ zNVNIoF!Xf$wnM=#P!Wp&V(Vz(QtG)&NvU|3D8A5uj&$CK=dJE)KzwY02BcSk0|Z#nWn@_Kh#1@0 zbtIZ6X+Ql0ebx#bR%X=Sos?uDa4fiy2|36b6Q0t&47hx65dfKOj%7Pbr=)IM$%{ackEh% zvIe=Gp)W|y=}QnX^{F7*R1q8d0f~A<>t#I#Nmh|-=G8HtfW59uY)@BtBM0w=xxRJe z5`+4RU8o68x}r@Gl1io%Oez(Ku2pH5mvQGmx(1}2E4B@+-I9O6zE!gM;o`jA&b0Z( zwWWODK86xM39<1TDS1&RzWIO0N2h9cZR*}+I;bs7kX@2LzlfKRZ&3^ph594~s6q-K zP7WzJmfYg8!yY^8!G{zaO+Mnm?Vw7#{}0K(!l?>aiJEb=-xfb)fwiHO_*DyD9MTI} zM+D_TT_q^zMlGQ|`jD`{E9$TLLTUOy5#!mJv0;#t!`g5d9maJE~YKw`@SQy@)=Ixl0# z*JXF%mCa;teVVyMJ+#99ziF&*3fgyq=rCk#hs&3cR7IN?v2ja&s}pB!0-B04qJRb^U`LHvT1!@UdCjG8<(F)Uk#0$4Fo^z8Icu83cY+ z7y}2w*fweG0%N8;nSi)uzVjNFF6&EN&DF|-3SHqZ24IeXJ5Sf(6y zK0Tst^5GL81%Gb-6}{Z%rU=SYw>fAB<0fJF=M!1GW(X8Vteqv^?O)sHDSv7s=M-$> z+{BGE4L&-FAW8gyxz;C;GNm8T_}vb7a#?Bm(=W5CFgYU`4kLT+$&|iCrp|~|baC1h zdN*0sr3?SmQR?FxHI6NM$2E0_+~K?(H$tp(c$}w}ZmMCY1>#qz))7hqx?%SgNUrNf ziSC)uIIXU5*-l54$h{;@gndJ$C35gW-IS!q(hqr~RLR{epk|pT-ERRlar5cy=5kpi zq8J+iE`cVci8@5$HjHJ8EvY5D?!p`C+?0OkSi0nc0zGJu?F|qMXmd}oxT0aomX9>- z29y#F@s1_GUCnMHQB|J$IL zOYr}_L6OCaer zGC^RT35f zhcoe30nO2<=wo}Z5g3~RzxP1)>)9wkd@X;?P`Ht?H~%a7lw@M=&A+T>WoGWppQ#?7 z)uSY4H5mUeCgrc+SP>+f_(Yrqss#mz9a9OrCTMEE-qCiQL_3&Ld^hwx zN4hO~9M8PG(s*{f-?k$zhW#&&8Iw;8AW^aPBAT-^$b3(tsbP8~0-iYx`Up8)~~r_)}kyH~_X!%q_Vfe6K^<42;I=dQq;S4}X$ zw23IDR+7>F8Y?P8fd!ETXwW$eI(GnG9gV`?TXA2F$?^&=!6Y}24j8{E`;zb#jxO-> znxv3~7-boEO!aakTn6o1C#^jer8NVV8-={E~eNbLE6912# zBgX97&}f~vGiJKFc)M*S2-(jLb|?#ilx^iBuxkYSV-ln<)R_WFI-q(DEUG+8j%${r zRIrInBpFPH*9DZMiYf6@SFMwsecQ_IvU6O@&i$3_92By1Qd1cE0HKAxE`!?}xE*TQ z+r%ZK`;Y5_a}RG`ptF3p!^Xt=Jz~~7!tG_gl5L`P6K7%tW{@7|FqS17FRT-`sxE{* zHNCrCU#}NG3au>C>-rG4+9QK$KUuM1qd-1;7>Zq6SS^SQHoD0|u%V}t#d1H2CkeE2 zV@fe_Qf755#pkRlBh)6Y3fN-GFNU-FhE{lE5iMSeBVgCY-DH9`EkeW z9`1}`^!J24rfT=Nsx^ny6lq=k(72GEDT4i|Ps0LKHsgCIcw(_v@QCu%1Ge{={=cn+ zzaSt|BKWnG2z^ZPhO|LQ`1Zs`x%+0GmTDQ<1q6jugi+DM7GwZSJACv3bf*tGPt_hG z8*4BJ>B4-Il41wlpjciVJ_-SQnv! z67EG1Sb~mytaG-G5cIExNTYzscBBysfT;$f#*Tt>hN3WP4EjN|X%0q{X17clzK1Yi zp?&$`@ght5mAQ#=wEPIhv>of)9|mT?VVvu})&_0jwitFWxs#8-jOM_+;MQQ$!5YkN zdE|;xp7|=zyz(^OZJv3rhrsGti1mzt8lKc)|NSd(^WU~#q4^oCMB1L$7Det7kTJKI zpO<|XW^^%}tywj~Kyi9d^m=u)(7+QE7Ij-&(JMjhb|V01qBvE(2z78fC>09;eH0_e zWWH}OCtJc6QU-2E!2Q5{{+kIafhO;w7B#!{d^Y?U#j%5Nam_@r>6ErhFMg1YW~tD$ zs#JoElQ{1*KMzxI7FP1`2wl;4r1I_~pd7P`jZZsOfRf!2r)p)$MRm*;4x7}7wKb!` zU2D@B_KEM!nah}pVFF|NWd@AQaa2Q}0bj&)o{{Nncrw!fY+Q_8lbC~{_1z%pew*Dw z64>g~ZWZtGS=5xr_~^JyW$ywpwaDz@ZyM1DI&Mi zlPccL582ZUPjBG8Byl&7YdB|kw$V59I!K?58%lBsqkC(p{{c>h(Ka$vQ}Riwxm%T32gK z$I%~M#>RCz4aBJ8H%hOeakZ2NnfPY=EWRXp{Q z#vj%%KzUuWBf~ta7mAoQIB=%ix*%=(h zgpXY@9JZ`5Gg@TGAiVnq@8yjKCD@?gae@Nw8yuwU{ZNUY-%&kAt*|kLU}KorNZ9m+ zc^?|0s$!dVLsV5@y#fA8d}EZmf@f`JMocgh77G1iV_%z>UyAecH_CarS!4)Xd1xep zf5XCK$v=%D7u}G4H2Lpi_@c0&c>svAc{xH-v#bNj`O=B{mJNj5fUuli;W{FMPf%%Z zMYkn&DC3o9=JwWG%2~NBy$|p44#S2>$nTUV)ne3ko~)auZ|#%_`}wy|zx(IM8QU+6 z(!hX;elYUxJY$ZM&dWm9)p9W$KVFD@KArU_uAuKgH#^Z?r4{Gkhrr=d+7GAaMATsC?f>I90B5neR%nE z>>eL*kJW;3&8!h)f-BWVdyrjwM(m;;?a8^b0|B<%R+?$0(EX(8QgM`%M4PTTG6NyM za8?PffCfPpgXExpP(reA)ByRKdyn^h3ehw#fab$KxOb+IQtOM!HNURd&u(1|V3C!a z61jWuK7!soh*)ALg*vmb=M0(xYE!93hDb>}LunI%;Yg_AF$x;qIE0fzz$CK+YvZIL zMc+H22NO&hyu}*=rk5#fcK;g|cWcJHI^J{l;3i=)?5Qd3J*KoV)s{`AZcy4xQnygr zXtOPpHm;Vs(x%D{N_)DT3`Qv{=S6Y&r{Ln+@x3jT_Rh-jlD{C~q(dpii5*aBGOb>( zGwXV#T^$j0Jx(R{dSCHMYW1p;7d9yEv=KUR1X`KVyr! z5IJkN<9SV9s74DzyYq+bl{jc}Rr3KL@E4!a3-DseT7Bn@zQLtB5CO4rFAoNDZONb- z*+Md@$S);ya?GJX2v4gHi(%)zgGoy61kCYvx+HM87=wmn)GsibnW^M(n+T<74J+8P5;*$%TkD?u%Gj zjYe^CJcO^+$djUgz40asfZA8FWZ<}5!C=4N1gGR5)bS}6Aq7c7)W245Qx{Pg1H;k^ zQ#?JPOd&&7FGXeQ;BI6OGd`_A0UhW9u*EuHthQBv(VI^I7=B9w3|pT{W+cnZSfx#1 zF=O>pNU%&8fR|hRt2X{s(&I`KxQQIRzrliLm5fFD2ljtqP2Y+i<}vS{}zHqlhPQOB%Ne@ z`R=bSG8a`NX>C;w`j#UHzZ-v{W$OKs2w3%N25r>5OHVR#eYqJCW2OgVl(PY0_?Y8c zf7uVP$eDgy)}<9KylaIzE*t`I%p>M1eceoUE$-C_F0<~)`h!$MY-^x|-;rg+TMPl8 zX6pn^*QO7pU~ULX>RxdmHJdo}HUPHF#Ehds|HU50Q7k*js+Fe^bykPtJtIdrpa)4ib?D`y!rZFw{^*uPx7mLT8 z{us1DKwq#x9_tGh`D=S{wtKFN$=2sHfLzL+FJ3tn0zcIhTj;36^nB<4;>5Ut$%a?D=Z?^dJ*CT@x z!`WAEvR4;x%Juf75xF3m?q4*Gp`S7ezH+D4z2*M0+)g?yL|P@RfgY z1fPtJ8y2?44Q5cL@g8)5mO0kF+;|u!a2GGRbc)EC&+KwYDW-6;pABXHc2>_iW0*^N zUDUWV`)|)>6K5Mw3pZ%({6hTF38ue3Ac|Y!6m-RYvMv`K_>ME%U53K&FK6(z7k3-* zAv(SX!FIW>D||u5#XUD9r`WI2TUq13p?xo8<;y(2o@imOxAH8{mw8^3r|vnnmb6tG z)!Fv?bwhXeWZq;Q0n3Ljb|pGEP^MjP_Dwy*~Xvn?8s6w?Ri^lcn%$kPT+ba`bSUF{Qf zK_(M<8^x@$VPdM2qD`f`Cdjp1URx_P+l`zTCe+gBKr zK{Y7$fwy&oVmt1uLAhdvVo88oBSZx8yDKq(yZjRxkgxR5C}SClD~p6)yto+rKmL4 zo<4+x^eoB~(^rk+1zW$4Y+cSysf+Oi#-mz#K|WB-JY z7*`rn|U(4lP~!hEp26F_feMe8tCxuGh`=lUyz8$n6{w07>n8_QD+W!qtkv8peL zVmA4Q%B0G;9}DLh$Tj??wT^K2sWq^}O|B4oN#a7$@*YXa0`s$&zN zAIAZkkExCFfXz$8tW!ISs7nc$^KuQ3NCxth%gGG(tqgu6TiNy18AOP*!70RM+R9)> zYROZ4DY{uhZadIHUiAgvlF|NZo@x`1HFuYh4gw$TZwZtO@r zCCCYF73EB!Jc+UAL{NU}JKuGt2$1r@S0Ke1z7?cuLbAoRq_$AeHoI}&B z#DQ7G?ivf->|AkNx2?RjMxiEx2t$!W{7vEmr9ZAc`c%Tk6VX1KIM zwayClo|WqW@X~V%PaoIyqk}>wG*u!wqP96)RM|uNa~of)H6tQfvd&SHw3m1UOC(9lQbqqFRFBVjmZ`yLhxWq_o-mqf3oM@VxYq&huB zjaiHj$JEsxE5AM66s|LmTMf=e2Fl98xvOBCNQL4xj`8B6K~3rMSB`;gWF~Ad3^M5- zO;-roA*>*sFJoG80Van@=u%Mmvgtm+YBb^oy(5c}adUc%Rw8oFHrI^GA zffX@zn^U<)NA^xUYr`O7GDd-0<%VJjillh-m(SF4L|VEZGei5t^jTtb7fR5YL2sMX zyRF2n-7L3(_k~*uEN8a}JW5JPiY}dp9XM!AL~g)UJdCSMU^exUsx5_M6geBD)bYrl z#erGmtk?@?t1TiBsf#HI)G)y+f`R(6YXMbuMw4Z#4WNqjt_Y`5bs;+>O&!iU`>YqI z2B(Qr%%ZEqiK(D#!ij8^t82?h^qShbcKo|1H3BM8>PDjTIs#Nvvnr|8K_;-fuV%;L9 zEZ<6tN(jG2-k@E4&_%c#VFr0fRV@|w`sz`cporq8S%1g$Uft6>9@#e$TYrfJ$gCCL z@wl&er?LMQR?AC*0D>|qD=v$+6l&@?A=QXZpZ|`vs|GIhh2#vGszG0agpYx+Xd$_VXi*+c8I!1s|Poj-bcj_j^lp@7s)JD7Ia@?V9b{R;Cs9#V120 zl%+a#MY_KiCHYhJ0eQ=5Bgguh_mS2)B@uH5?@`1GD6zY?_xPxgI`YBbX~D;!$f=8G z&vEs6Nd(Pu>|2|M{HowwVy_2dQX3KC7{S$W5SKbpA4Dd_SS(9wvC~A}pU7}4k&xiN zN<#|ZBKSNvJx?A=Q8d5+caI&IIz<=M?rx(ivMzk#@Una1Jqn-2h z$1;I2Zc8R>r04bS(Xrk16xurI){d_&LJ+Sqq{o%CH4AT z1INDin6Zw6!?0s@*`0!T%{b5K^FK!vv#^%Wy@>ysZO-gSM|(wcKv;(ac-J9MR&G1L zgy z#3s;7PqRo48EW~8Ty~IVFSU;_FHnK~)qJ;(a$rw9GTv+VDmeA+5cSz-o_1nHx5sQa zneK6(QQxGYVM-{~+9Ji+eJZGtOitg=_IU(6vW=;C}?cqZ$#Km%?7mEzJ; zlNO5$*qF`m(VfvqRSRec)9z!K0BGA**Umeq^KA|^C&_RPX3vft=s^iI*Gy{<&m99T zu2OQIe{D3{o%$Rs+Z$Pf79{M_n`R$Z-gpwH?V|U=Y%BxY;cY52VwQa4X-q8u#FwE? zpdf7Fi&+;NmUVT~e1(Q?!JaTw`y|~pH^6vWJNjr^ny-B~Zcd0NPtR~dmYaI-n;*|b zh8K?KLQBr{xgkQ9T8M_Zd)Z0^iuVj54+b{VWL?$a(MITzb<93aJWz8ZoI9v_q-2;j zx&l0n2{>OUaqe)l4kI%!dr4-BfBa5yef-YiUyC6hzawrR?6dHkH-^6# z!&hVY`!W237=9y$7i0L%82(`l|0ss9#qf_~_$M*^)07@^4i~5}!iLi3NOqLD_@i+V zStt2rlAm6aq^-Cy2}DdQ>4GQev9Pn;s_>6`NNAcIKv*>kg&qY%WrwLW7S=hjt@&RV z9$DD7yTcBFtTQjYfkJti;fc8cgt4V{Zva%LrOI&NAzQETY{b0J)t6F=E;HVOxYlE6 zrbwxGSi;`aZIRo}O2>c|R|3Mgtj{})Dxs71Jzb$();{Wwq!^I~WYUsfI-E}p`3MW~ zC>8Z2y0tROHn97t_iBnW@3>=Iz6mKbOgV(J@K=0fn?s=+4(g_QFT_oP+v6jbhwg}vx3Q;E zA`DfG&n~o}OsPaoCm}5P8c}~S<_$60*oe}3MKUoUvKX4%bliIi(Q@@6wRKl-NNoN& z7ccM&b2!d@LkzEndW{(JtN8RGC$6pOtYo9><@4doMS9P~u+7{S#fvOtT&j(HndR}a|UMC-Cb7b4s{6`DcDVAqqG0li{$-u4~S|G~kV*5c~*c2%E{BMa;&h?^DcJ4q1DHt~5o z>tz}Td4QP)+?1Sa97~yBUT1`|H(dAPXdl{nKYM>1?I3o+5Q_s%<1qYBY#10Cfo=`- z!*VRWtkR9q{=OE+tu-%$tQE~u*9b|7&Bvg+`M97OzM)P;?LH z1ob)j)~FVWJ(ij-M}JQto+Pi z>F{8i1>`6@*ORbFd$F%^OH}a&+k~4r)@88FKia_$!$Aw87(`M4+9?faH1)l*C-V>VOh}w_O_uB{7??C`<{!%ZE6Nss-=z zvGjfilKWryW*ihoRoGkUOgC zURw17Zr(1gAaf7!Q7&cK9(D`DX;2;d5z&~HH>LL+ zxMptUm(QAo@vh~$^{fMML%ux2oDx65xWz=T-yeQ>_;J=m_GnFnnWRWiDpxCRbboC zS@y*{($NJrn(>b?VHGfCrRba=-7=8O+r&jrl-#s9BIw-z5#hV~#gRQO0yQ<*1D0t; zE*fiZ{o;tGZXnga=3>O;Uvsg?@@p>4f3GlKF2C+lt{SlL<23p^FhP9$-Rkl8s>fHW z$KS6W|DbyOM)fF;f-@N;ul$?Ut3RwB|EPL=t$O_9>hVvi$3LweseHH%EI=x>5%)kA z6G?b|!(f)Hrx+E$ap=o0-)!~a5tSLoZ z8-32e({-P7UD+Z#DtIe6p+i*}b8ejLm($`n19yM zuQk{H5=0~zcG}`6Yw~6gdvTB!AuWrmu=_ci=D;jgIFtMbczcU(In1yt5^5>GtZh5G z_Wrfo?BEivMLXbiA&tk8zLP3lF7#Iq>uLD3|Efbsmn}X2&Jn9%{r7cVv(kB0$-39n z`sLYduD(po86o6MZ|h#KR+8$-Ngyk`+LhTll@Kf5{akjN%H zR#9h*Z+=d2-(2zvCvwF`v)cR42xA<0TrV%!%h#z$iRaR~pCFdlxS%?#l?|1!`pVX7 z_nl7DZcEOcBr{23;uJsMdStUOeRb#_{+!^CkVlv!wAHP4bqFJDQPwzY zlbnAjAh}8auD<0s(%07V5KZF5_DuOD%-LmDTnB-G^E?=_P|vkVD%R_%W`q3QinD8D zv|092!#Od;)_H2$(iAy`NWw+f8YSYAH zCjZ{e+y<#`>Fa7c{P#9&e9HJ?PYTfU8K@#fKneQrBhsu7jZ^6ME0U%m+IV@$NwX4Ne84Kg!`H*= zkOdoH4kpFK$#OV3XjRXsQG|@%Jz`zpAQ0n6I$_*%DHh^(+2H_i z>&_f2$8{a?lbT*^!iq&A)|WzKQ5|YWtgy+PRcNO7H7cLQK?1!OeK7JjTDKRh_&E7U z0@#=p88u#x6&DS7Lki@00)nX^`7Ln-6u@I!b5iw7*C4Upv|Fq7yZKn}gY4?E6Xs;| z36@VEV0%00QvYh!_iwgoz}lt@4z8T?<2WY6c^o$8#2H)vpS030H@5n{1L5SD14PJO z#5a2FXtJAt8$xUoJ%=oGqYx7J5R*OO~gI`STe8k&K>@v?zV-1qPf8QhVy zbp|GaI#-TfvH9#4?G$?%8d@K=!-s-fyHoru2Zh<`z7>S#98>3|r<&YI-f{>|Ay zw!)v#M+CITo{dqOypB+DLXZ%@k6>R!yguMn;2dulIG0BcH3`NI-@)eE;CCO(zkYho z+i}21yOXPx+8mUK`=jsBqaC8tofTStp-~<8n1HE5mg`0>&Q#npKknK<10gBh*e-k4 zZRdVNmtn)C^60T$Wdu7g)jpb}1WkHrWEQk5O6ygz=kRfS0vlZ_*7-19laXV2z)TQR z|CvdSZe`_d7;9ZWx`iE*+PQ=@zx@7@cI|6Nw=VGocAYZdY7^_>@MuMQ6r!hGbYvG7 zb1|TOumLo8_3;{EosQYni*{t7r5dz6@TRSWbn{Ev;F4c#RVfHyQb;fJ(EKGG!?3)v zl%PqqI;ry~pmE%qAA5C-S^^dYb0_HAMqP*0H+4|tQhVHbdF6ci^tfkx^f^>i)Bdh4gyifk1U`u}F&cg5uZo@b(^WNG6e(-$ZgX5%iU3r{zYnpiip$)c`ml#I zBV^m_%l09fq6O->Vhe0);N8RP8Y%1J9Wx(D07{e3*tdBJ1{tbWkdAOc$m%F<81nKT z?sG~@pOb{1d`@ZI=TyAbz;5MpD&Et+6&D=QWu;HM$>$^#YttNG62m8F*ph@`M;|^r zQ*_$XqIJLTXUr@L5|rLAh_XU^k-{*MQ>gS5s9hxfJ!C0@LMUQ1>b$S0{5g z3SpG{eWP-Xby1<{8(&!H$qqHbdIJxq5k<-iiG{9KX`DAaAscjc;t##YoXI@stRIxP zHPC_6V}ga>gUxThFsR{?^0XNPzym|8RCuGLHD0 z;zxAZYl^RZz`L8jMGp0sG^iV1Q7-yk)Sym(Rn1+UmSf6jUV?bjq?3b-{I{ab81RK~oeE z98|Bh79^BL5kYsJJ@$X5k=zVx#qdRcsyd65it>sSFQsuRQoLr;i_m~L z9G(K=UpK+16}BRagF_#REU%anBV(B*!dL6nnkhqamU$}pih8^cb(Fqor6}vAvg53h zYQ+WdjB4WlUqYf5faT&q$QqS@&C$kdC;@DXPN3wte2czzAwxC$RSVGn6)Ug(Q zuo+c@2^cM@>VR`*D^L8b=%3w*#IY)im6a?ifJ_P?!@+|BXrT?M)V7iERXGa84VC3m zsgRKwWXx+UwKeD9>!sMNdFQMXLFXN+@!1hr$`O4ThaTpf{C zx15tSzy;}wR+xI&j{I)^3c|_G_c9N05g?k91Q6GI1!YkuPT_?wTilwRo6uz?h>u&d z=O#uy;Ht)p@xB_R%{=*;(F8TveAkW?OO9WdlpGHe+iV@|R|k9Pff_C?= zH|a6>WFA9wGU+?{TL^P~PglZRA5dQN(+~M&c-G#suqaL2$zOukI!Z57kOh`pCU|9V zeo=-GXl|&*>m}Xu7{?Ywq$S$R9LO3{<~jGbF$J?GIq2yg2Y+K+>u)&lS$_l9wqhAh zea1K1_Vo;U`MDHQfoqG8YGie;&DaI%2e}d`B!_D$#i=i1-b<>+iZpO&zfk(X{8odR zYA62zC^Jgr01dK2m2k|az3fqB3A6)jVhGk1-(uEjHmvf(DlD{Pn!r3;FbISz)?g(0 z3%0`8_<<)ACRfEQVv)!%;;A3bDB65N@92}Dmy`Ib7IL~E#=jQBuUp9Jf*AgG3}1=i z@5JzTWB7Y9d^Lu@AHzS0;WuK4&1qigZ^rNsWB5lg#0ItZe;mUma6mS^J{l)z9nm5&wIm-X17#HAtl<5WKSp=DEK$GNnp?Q;`QPpET5b!@h4O9YpuvXwfKvgPNa z!uUs-yR3>(9`^+7cIlYdw958B7p?WlmOE;vA`R(Vo#P2=)uH$z-zh!<0_`R3k`}iH?cLTp0 z`Q60t5Wk!Gy`SF)_}#+qR(^;19pMLUjXuclD8FO;KE&_C{650(c7DhC<=(+V+_GXD zLZL;f(W0u>QWIc>Hl>61uh>GW$5B8!Urir9j_iL=j4Qynhadb^P+jA(7HAt`tV$ca zS#zsz%+dQS)}tiq-LI|qwIr%u3hybB!bcBe$L)G$A2|SPg>muL29rA4wQ4oK)WN35 zBA4n|LwBD~0pybR?meYy_arLe@J~^~a#6|kQjZRsDmhOj4~B6G-TrW0e9g5O^^6Z1 z#1)_wd{+WXQ19a)^bHB*0ho&KWtWTM`(vCd=6i}S#W>s7wQG6wo*3tPdu?wYT^Hkg zp>?46^)WujlD6W@p{3wJOy-V%?J^&|H^ygJr&auYF}{nXYsC-7I6LBZD1JkX@8q*8 zir*OHJ6NSw{H7S^(+#^6KV+`*(akY=8y7n$`Ta3I#Rd9`e;~#Oe63dTTVk9|_H&Bg z8smMorz(Cp#(R9aK=C6n&Sl;Uir*GG3O*QcVM>fYtc9C>;X?}chGPmo8jc?&Ghu#| z!i2XUr82^g9Hnv&$R1U;PWYgLg>ajK`EW$Ro^V*fT)0)iY`8_i?(hKxGvWOT+Tmse zyTTy_)8QrsJHw3%c7z)gY!3$&48!{rYzyyI&Ooe3yoXl1*8Lm^%5ARXX3rh+n zd`EvbjEVJ;VR+$38GYx1DoJ7c%t27^68>Tv(O*3=JEW(2LIcuQJz*0XibBqO)36kB z++>ERkmCz9Tm-3gLr35wqGKd*I?<65I2G@B37XCuYC=9(b?k(EYSj@G@@=b*qkxQY zGzE_FIi>$z&|0qHE+88neIcJ)bqt1l&#EIa zK;5owM`hf!h>8sRev$+$)+n&mI0(XJo8)np=;YHIrRW0{TY zGp78gWlan9xd6CmOYq@iXjs(62lNerf0t%yO~W3F%h?UoWulKFVdqUNIGpISRmAjl zB!UG6N0YrC>v?jls(%DXz;t}EVxtne(*0$1qz1)wsOwfUKvr0^3IKKE7T0^*RYwVHMD zZ#vmjt?&Bi08KUnpPxOPoKkQsIpeV>J@)rJ_>zL7$E+qdP=EmWnmjl)&Jq9eO5yqI$JTdHIyY{m#bK9M7qTrWjI6&YMAsO{IOn& z+SbAyY8(5?c3jzf)bj8Ix?;s~@0M~|8)I{lS~GeD`L_Jk|HIz92itYs_kHJa-}jz- z5Ah-{0bJ~J01+1w6~LAZz=TX=BjT$PE!m@FI32fTTTO-`>F80}W?Nahl{ggIvNmgT zY_wJr{J}9*Itj`d;QjLt;MgbSZV8ck8|li$Q!N7QDL4hLH%Bp?&Bk(kOQ;0$eQfKO(Wob4<` zvZUnp&T=FxkqjfbDUw~0?2bfd!tuf0NcKf?b0j$6^=>tiTOv6S3GR5kI~2)UB!|W4 zLq(HLGWvhh`?DkDChc^DsJ!k-G>f*0;8X-E5^e+AV2?9dj9E@vZ0Xt+dCX%;`Hab7KMAH zo)Cq5q;S-cJ;yuGcE@`q3-{aULUE_XpR?@|+<`;TcH zfyW)MaWCDTb&8GqzFTu|iY3{bV@VVuL3x}3gdE5wf|>-ao+3(^E~0m&e0=ziTH)pX z9$G3~vP}7Pnl{&Y?MX8cAJl^r!54JwK`8e(b#boREy0|+*sVE9y{|n`m%BRTh7SxI zO=}QZz4o(YUV2vYKpD9TS5$~=&xf?jf}d#Pu-ee^q@x*%sAxr}Iju(ck;KKXl>|s+ z(ey%*+L1-;+<=u!DH`xv5C=$fA-az}1y#MtKec8BJgu5W<;$HQ~4} zc+SIaM%xT>`>{1cS}q`MR8M;VN%{0~Nkn(~wG_&SU%8i13PY`oHxyRdYUdmewAaq@ zIG1ux(AnvJ<#EOyJ&iMdX`Jy(P4z3nDIim@8krhr{L(mE1(`;xPa0?BYMk*)<7|}# zQT>fBV4kjE$~_8=f_EPp{&gn^1kB!%-wnlku!?TVV`o6Bgk9O`7dxrj6@$F%>#Q7@ zx*T#IX#;HMrS@`H=QEge)IL^b9#(_|=4Saq63iQQz4pi%%r^NMnS0M7poB3*z9$S) zEmle|Au5tyG8809I6Jp-7jC{&>vO%{bW1YJL8}!*{J97tJk#OH63FGJ#&XtiYzh_C zpE>y~eJJWI>H~71uPTKHOAA=c8YpxU-!6w^>F1eoPhUfU{+Q`B-DX);kL*!Y^ka`@ zMsP?*GiOv^I+a?NJJ?UR#?zZ4xlM`O!A?#97%kt}9jwj>l(TXNvjLTUC*a0|UQ~K< zl75kB)loJb9iH-~+4RIKt~zWL_|8fW0HDQR?Dl$_0LNemE@KG0TVAsfrc?}o zL<8{CtxC>z-W_9)Zqc3vpoR% z-~q@r%>btI0RDQnS0a*!F(E^<^rRLAzXWEOO&}Xxe6?R*6&h=4NTCoo%HNg0Zr>ZwZS0ev+%Bq@ z$PS4M+2Nc)|J^^sL6A$_v@0V9?<Z zI1?}2<~RDa4vj7CZn`DLq4ReQe8PD2h@;PSQu~rR#)&sO3}Lw$0+)g0A;_3Epcn#2 zDot^&j?BGj?GPS84?3cpVB6@AxmTbiPQ0G`NY($addE>mv#cBHObXULaO&`>ych8O zi4KQ|yd#>RKEaE4aDGYP03fUN4!`mz32HL`t9+E!EDvl-(BWI_e0EeV*-IIX%%14J z<7`)Q0yraig*U$mxW{Y;vFzncj%%3HriU_UAAyv1UE3$G@m8F)F8jx#7}0W~d-QCF zD+1+Unyqimy(KzdJOX){%IG_9eIk+60Ctg{6BY8DFuz|%|K%2amqV*F#Eh4xm>MPI z7!&TABxtvm6;73A(&&JO_2&x@p89!zz!t~@SVQcMg?w9}S6#2GeR&yu*hJ90NCZt< zuzUe3>tNF=4#o?4tdUMjJ-({7$5&Y^hel&bPdV$Xp`sqgcu?1S7y4T2R@@aupYF>P zi46RM9P!c0z_B=8f4Y?c1y9!(TN#Ll>H4Ww1|niw=N*(vah^`sPm~O;ClZ1JX{g7X zWKCQ+1?Vw7k~*h@rNQl|dDw_NRp& z0zjo2$`~!BW2GhBZS`~C#+FP5`<#>x>9gIDYK10*2iXN*b9$=td+GW2Q_4C#?{Dw? zVM_l9hyqpj$cx`-;;L1Bmt?@LZkb$%l~ z|5i%B;`H{;Z>RLDGIBLMD9^)7LtzXr_VVy9dw9$Tn*qMym(R|`056l)Dpk5~!wA5C z#@=hkH)f=wG%{^%#i?Y#B>6-cF~-Y@v>Ou3IZZuOekK@zfl$-4FiEGra7QAC8T6pY zVaBX=WAHM+C3peFHlQH&NjeBH2|T6)CQq3XD7h^q7=fxsptLw>QG$GwNxA^q8FQg1 zLSy<2ai;K8uzCF@-~}0oIDbPwB@CzQ-)eHd()|2w{geVXgSZ1a2`mRYY-I*>R9gu5&QXpnajahYmTkO4Ghhix7th#`$XeywW@g%XAw_+CvTy1FhG(Tfd zg%tG0Bo=RIEYpqNn9|}+*`nYF~JwYznaRooZRKUazEHFC+e_NHqzLx-gVAF2k9vg)r?AU0iZUjqQ) zAd?Y88HjJNP@3`2=tlFvc)oOg+|MvxLR;XR(g1wqS-^NEV7$Djw*|&K7RWH(u0V#d zoMPLzBNz{KF#@n!;%KKy+T9)!X}W7jcxDeI4g@5WUV)kVnVDdve%VQ`AYDR$T#4Ce zAI_iYCC>i3k=_6``hyG}0*(BXMa&IAxL%xKQ#(BtzEOR6forkE1ybzMC{oZ`- zw4(j)$OuD746YvSx;9#wg;wZr=Epyav_kKY?5rIAyBgBQ6x?XDA@b{VWqUmhW5IFk zgv89=r^EWL^ShqE!%-C4XWge~??r2Kd_rNb?uVoCxWqkBwhpVu>PA>QI5u|Ik4@VL z0Wu;Jl|%pF3gIWRaBu9c|JYKk$wakje6P2%zr^$?TJoN*rmPiIyz$;Hzez>YdB|P<4scMdIMv$8r@K%QY;#QVas$2 zwW=zW1sJ8y+gVASw=3ZsYhyMUq0QwIVV6>gtgl>&N>Pc-uvR75F1$_Eg(i9_ ziwTl`c{-c~%H}yAb+qPumNC?^t4#Pj$(>tL4qi7^Q{N#lwJ@Mh~T4B)<1Fz;A$ z9O0)xAF~+O!Mu`c?y)Ag$c-kfuT3qo&Xb#I%#SU0_O{LB2}@-^xSIfws$NDf`ZX(S zf(qEx1vPOTPTQ-YP3$edhRr5lK8|05D%PpMHb#3|rSpn0(oOQSEpw7s1e=qXetaq$ zugj-|%#ZvCrpoMQSJfsfxG?J`OIZ2TPY=W} zwSvgBl-IVad&!1w*O>F#wWU1C8ET6ov5Gv@oGMtSOyQGc6jcQeO}w!XiZ_@h)SY^2 zCxInqk|Z1I7PSo8zDnkaBSzGd{xwNu{iqy&t*=NX`_ZqdL@Uem^( zMLvuXR5SI^iLMU_1!LL`$KFpIBF8&FrvO9JXS$ffVS<Okznh{z2Z}d18*4DH z_=tuO&nL~5$*=v)$g-kVw);xCYN@W!I*VKUw?L)%Z;=Fp9sN>I5OE2-#49WR$a#FY|==#oiAH|lsMVg(t{eAFoji7G=yH_&JRu{{hz z&NK=*iI+l@S*mOqy;L*;Fa*C~)E0wn*tJDrJHIUsGhkc7HGHokJR4xqk8+(gFcQpX<$UC`GOA26ahOMR-8Je<~E7dR*yrdw)z_)wShwJ z?d85)hMZ<7vx!8^Yd?a*ue9%UinSO-O0)wHwTx5 z5}`&3VwJ)h$oxG`6#7gQn80V;^Fv*05kcs}l)uIOp7JLNK=R&J#ZOsy{_j&o5Y|sS z=Xa2$ogzz7_NRK6+zAP{=*lsic^eU^zFppf4`dCr_2dWXRZ7pR&}lVWNR4vLjVT z3~sxY*Rhuv8Gf_eoa&YprQQGx)t*51JLo;#{hQGsP`UE_X+lEEZ%~j2Xg~{IZH1Zr zddhDr%yxcTVQzBzU7kVqSWp@@rE{fE8-X98U+bfjy?P$3;598~pU@v2l=IM9O#rYt z7H`5eTHXM7>0y0?uub0p|9-5Bv%;bo__R(~6)jDtN!;%G@np~bGl97$lyv^7A#Q5( z6wh?T(D$_+s#%1-4uM&z+S#hu2rFVg>C8Io;NplCz^%OFy`{Y-M!4-yhkWL&6viQZ zIs-qx+{Zf7(7^Q<0>xJqQ>0;8jfVAlukk`tK)p;&@pH26e?^A<=;G}9pYvqLvY)t30~mtB z;QHfz)|oqBmD4Q-Sw>H*Ou}Clwr)=Dgx@Wr7JTft5J{MkX{V)Wm2GC;UH_jgb;}V& zxDbkf@Kw3&UJ7BPh!1}L%cdHh{_pg)$yea@;)B=lzh;Id%E_4F@7H<#MF)eiC=YmA z@*pzk{)AYNaJi_Vb5M_BnRCRl4VaCYv)!lklKrdEL{zS|OOuS^N*%3W+7WR82#p}x zF083Hz{24Lv@^+?7m-06z*Qh1+(&Qn_cErQlBXnj4Je=;wRxbz7wzI$${!?QMpufg zmT3Asu{{=*!i_`3TcR273d7BaQFmIfROBSE)G-&<6}~PLSel=^NqI<^-ouAqq_BeZ za$$ACnq^|&0&Jlz3ECh2- z)FW8soM=l($vKR1Q(FjVax`|A!6gRv)Nilp^X;e`HuXf7V$ORO?*0lY^b8?}Hx0Oy zU0OxKZfZ4pFU6aCb}evGFCi~A9b}O38vQp}$D2adK3MV|Q*{6fTEkJ32qS+k;(4bj zF5@Q%I^(Z_AhQl_0^nE;iO-JCjOeCXIyzLsMBd?zED?yD{Q-*H*GcUv&e0K>&O16= zf_5QCzhX_4Emtap;_$k*1I2?dqB|X;O9jY+Vj(8jUX!>Fu@^sI?q(X~Q7RBuD=LM} znap`~Q1zg%X-+(1;E1SQvdf`@gwN&~mA7YUMuim^g*o(Gkx?|NdjN+2Hfii8fw-c;}3>^y{Qz^)sB41Izr3W!6cKjv1L-I#2;L0WsgEFu4zQ~D_c1Ut0dA38gyk#BT!C(lgwvG-`Zk7poAjd4p1zk6{( zOO=A13Xlj0Og77PW$TiEbo&trKOHoz*s8tJ5&jBiWrQ1DY+%YhIwGJi5A#7vF`!43 zoa+9Kc=~W8A5n69=LaJBK^7zUUT|ySLnHm*P6K^#VxWAxWth{dTbGhEOaXqUVXEI3 z@OUWw=wL=G5=W$9AP7;Zq zsAX!Vz9{7ya^vsG$I)cy=9nWw$Q4u3FnBG;hdmH4jS@PqQ}lwdaR#K+yjS9qN|e$bEd^M6D0YdNm7H@ zystz(fuCvIZ%IXAZGt>546#Rw{isJOg8k?=rS@QVm?_O6zE-DNxO=cKDrmDI+pIuW zRKeRPs2*I1)qhw&PxhA>LhaNBy#F(Lr$+>4#AhZ3sXQh2)Blow#dDpr87ZG zq7{{xMBfQ~(nqT!=kX~Rg)Tu!p^z)ALZ+}u?4)=D6y6%|z>YV_fRs(hG2?2K*TXC< zPPI|-QZPj@%9|#HdOV4T7#t7xGdPk*O`ThZ2i`R_KoDam72sL}dz%J!W^^>k%of6q zR=2)y@GVyvZ$&9K1nt*|uU|jJu<3S-8&TDa4t_iu12>`(8}X=jkLr~NwTH`P>LD<(1hEfAz7WraGK7Ql4Ns1toXGl961~HKK06-l*myBx-VB%;}U?98+ ztgXRqM%#XouEsi8Tv{q~k0i6NTR3LZViP(fu#0#M8E13 zYql@Igvejyiwgj`AaV8o^5m(~k@^#sXU=`B`T2O3V&mMiMNoHuPL0-k#RRu7?OKlI%W7?A)>10?;Gq7$)`)wrkRf|R0^kpz1coL zoE;pOj<#@lC_eWhU}$L=algfoLVjFoxM6*I>d%nCTt#3a1g|PEZ-Fu-FriS5cas0W zcF|_w?)ufiCV`o_EwsT70+UuGFvWG>kidMi26kq2>sEnz<$+eW@(*cQ9lig+_$V@y zo@Bzk4jU$od=rxb&^D7IGi++@z@sghX~W=)#EIvi)JwmV=0B(kYW1kqy&EId z1*Sn;6hn||;3o~cC6vN&5vfw*(FB+YBY1nEboT(ZOB&7MGVDYD4ExYO!#?!S3HvY@ zG24gr^P5br%w=iTS;T3^+f@fJfvyABAVdyU$UljZ;T?Al4%K;rb^`*Ve(f!uH)s7E z8bMss*pF#^4bub~fWJoeVDB8TRhdZ(Qo8DD6M(lQA|k*tW?j!UO5+mBPrehVWS)>* zG{ro@xXf9lOswB8hI)khp0zqS+u=k(Q{&I3=bumMXPt6&NlHJL(&tn9Kc@8Wr}P(6 z`uUXpPbvLEN`En>ms9#nDgEV?{z^)}n9_fc(tnuJU+robNe@~)hA#9^>%*gsK9u2? zrlhdr*pB3w{vpe_3NtCmb(Wg+Qm_zMKiwSQ%piyLT}TviVwwn~cHrb3uEU1!tQe7HisSJ+uvI;CzSWTpW#)OC{z&b$`h<#2j zz=#H=04KvlfpA^8fF^kcMi@%YWBn-d>sekDE>8Tl`a0Y`$J4z==LNhRAyT_A=TxVq>x41O>j(OI5XljC732exk?mGdq**d zf4Nb=S|>~v^FP$jJlF52pu|FmmjG0IlB!Zun+A4} zl}5BHgM0WrgG0O*P+NBM129qlzCrRC+>apWo4jVib|$f`AaH|?6!#5ec`dMPBnnJQ zTVf^sbWvtQmeu@)^@kr<!fmCeTh^v zqJKoHiNtS^?kD|C(p6FxB}UTa{|hOavi>d7gQQ<36$HORx<>lHk{%}gZPJSLtE3~+ z%cSFKb~InZ1pQDi3yR>=V3y>a;4FO5MzS1FE0Orf?xfSsR5t}d?TW;EZFNMWsf_&$ zBDQ^zu&-TD`y+w(^mI!k2O>Eb33^=b)*?9^NfpT`5>b!@Z6FnDV(JuFP=2=0#7Cy8 z@nSVbhz!4{2kWi(-l3w4^84~2FDggL=_lT%>H7va;pRC`3MyFO%vZ3?77donfRoXW z3^}=UVliep;YUCj+k<6Vf)-mgF_Jc0hqCNBDM;6nh`?^tR+Q{!TrHRBq>&=RZ97am zJKBnX4R?q-C}+sGRLDg|B7f`B+cdi5Ik3c>7+uRvvXDl{crZVSh;4Kpc}3%8{X*V$njZjSBN`S@ zFqiKw9n*<~K`evyCC}(z!iDvH^pI6<2ywI&xx%AzIoDme3rj~A>lcsJZ}FispFZZZ zWu>VYleao~>ZlUF1c#he>DBckO5On`iFMRB}56MW_24F8IXS;~^0v7nW}?$$5liSxObH=nU6 z1ZsT8V$%?fWruloB}gQ^asJosrrEZ&;OgsN%|J0s`bA_{wiL{S(7c=nKDip8;c`yA zq$aW;OgS{}pSg7#$S)2HroWBnJO=w|A2G*^iw+Io$t#VDpNRs^GOKAFiW6Fqh|r}> zd$9^s*}q@vL()q0Fn@p`47SwCw!tXfQ2q_6%zAQRh^E_9`pr6}6FLQi*t4Q}cl@Jy zYnKVjmX2R#^@MKQ8JMd{l{um;4A5rX;e)Y=_n>)#<7Jc8e&bes(y2Sz^eirj))EZj zN#HrtUOy>%bznbCcpwYUKNc@pFbgE@>m&KNeL8n;)h67SX#^)VM&T=1*lXog< zVjU)jmqvkfI~NNoS-!OvhCDC^q^t{~C^6mSEUe!Q%r7Y<+1pxKnH-poP|ns8gx;8f zID!y(*;r~16I01<-s;x-58&p#7^H0>@C}bVISkeHwh_p|7WJ~>np^n~A z)|0j|>q**Kf8#33OXgeT&g4A$8G~-i_4Bs)A?adfT)n2SY1=o81Mq#j93M)t| z7oTqx#}21>LV7}XLUcm$CgdjfjqVLH%>bYU?lH-7>KahTG-1*TRy>_xw%$7^H;ZgS zJ$$bo=6C?6@~}u#63dKB+eV1* zf#wVsw%oCRL9;^v$L2Ef*>o=7)@oQRLiTrbCd*8{M@PQ|bY|qCgqk?K(Z2O<8sJl$ zsZ{9=TilL-LyqA1P)k?-%U8tQ4sy)xfSB8_*pn~gWLdW`3O&*c*q`Jt%XyN2f_um*Jt-;84eE;Zvl*SG z&^r+1z@ErN4r&R~AhcI4akL9^yM6_hXGaA;-`e>^R}RVLYMJdj>=1fCV!iXJF8{h>ORqZzoK#J`FiiYr-*G>mSb6saDr2A zM8o>%+3ve}$*hCc+8rQ=#%Mn`CYAQ!X{P|Rpm zWGCN!wtFTz`HoY)b)07c68?1IL5}e0rDf3%K5yj7%^u911A#acP`nC3qSKTO*7e@| z#NLmj!HexRd>|%1mKZL?F*W?4>cqbTN9zY{^Yw;An{xqgo8)s-0>j^kLd!r;N)<@jsZ8^m;Ua;Nb5jWL}BgG9iM zFx}jCOgB|XJ6Sr-X^%mB*UfZuxyCI_*X}@Ox~a@MS7o|V?;FQ-Q#$TxC!xI=qrzc` z>q0+B!=N9|%^ED~kT5j76-o1JLFT|FW`}Y)YD@bpl7vYh1G^`>XJn@iLP#x#z)7zM zl2fRN0Du7JlBg7o!lEZ&Tf|m>=k1eCpN-micON}{^h=s0%;uGIxdf~?;a)t$b5TuY}G?)FI8G2IcLWpkQ zDa{9le8{xhNU~_78?kZbXh+HU7kf++mm@vWFD@C|!sQ(NFfH2&Jd<=W*I?-~Ug5#)QCK>2IX8F~E}!0+%Q=&)R93jWX)+;> z%K|b>C;JU9*EZ|~nl62~ zE-r6%Dsy?eFNMoXXReFOb2l@cCN9r?76&wDW{b-wW*l?PjAMe!J>N(M2}(H4H(*Wx z@NJrJ6fO_$K>c9jLA{$fyxA>3XgEAqvckuS!)4WO%i&`ELh0GK^;DuPlw2=|7jj7Q zvBlweb9b;j5G=SU9A2%QuO6>%dTewPHu)g#jWCz{LOK1ahR+C4O!{RdmWg78ERxXf zbon(7SNOVu`WNVtoGPc+1Ciqq4?Ql;##NgrT&hs=);m<#YhDyBQtO1<1;<~8?J^LSce zbKUxoCyabEEhu#By$(n8Gs3#d{(PJ^@+A6Nt}Yu?C8_jW5uxbQX1lqL*gQ~=RlO9h;kxHb#1%y2`?)iM}j?_XmeUiMlM7nX{VLm>@<|q57E^+bY0c z4`t|8QPUn7fJgaF0)fUPek*@t^|b{8005@GRK61vT!Y0^T^gJOOJ%T}6j<<=sg!0rZj`A4KhZnElbN|Ju{rNn?~;~-t>RbEkLNKn6@IJ<`hibg@Aalyhje^{ zkSIs+ZUurnyFc`mnF#kt3kdw)0SKv-fgtUdfY7sS5Z?gAj+nHYv{)~+Ac5nd)q1f^ z#IYs$*;VfD=5lU5^e{a6EQX@#PG^Ldq;=Hv|^8g8i&P9T*tP>n;&3xd2QNNl$pH^w8&WkjwG=8KholJ!6~4p4SSYLW4oqlkETo4>YhkwFL~`!_a_X#{wA)+ZEUf zhRvk}h9$s2XIo6UE&7FUOkj|oP;ckK0|d^`TTFCVm%(jGAT%6Greas0>W&vr_ukI~ ziuZwPQIp9zuE|-_&kN6tFy2_&fqsMBJHvbVs{g=v=^0T(4bm1_yqMPY;kl9jR0Q{= z0&yMH>g;@56ojPHz*H&s@XTpKdhMS<@#!<>6m+=AC>=elw&LXB`T8Zq9?E9EW~VvW z6Eq@|2oOm(TpcC*73AlMz zNFDB4RF}W?8#=9l>J8Ddty(WrE6OU9y9^;-kC)tR>a9e)G8ZBfVA2rVOv)p*^;^^XXWOfPDjF9yKyGH z*FPKa#)a*)jwl)}VnLnnj@T}?6ePwR6iJ~qQTKC5i#zvo8+q%iav)jxnXvidANqI- zeXJ;n8}Biy);*RWv+TR!u`{BmiNVT(L_0`+XDAXm2eLQH^Tye0zkc_J|9iNNnpbr;H%d?QT* z)H!*5E}t30r>O#Vz;MT-WPDTzHT2rgptYZ$FM~76r%SIC$pev` zqjtWe>&dA+FS281TORqYxtv+#(>te1L{dFh$0R=e(w%^j=W@I~SD{{0Ub^#!Z*gS8SY)-)(MI?{N+ef z+;=?TfzVNhu*ShiDw1~~Thk~yBIG;(9f^oF5HO`_y&S2qxli-zm}~yMZg-}T*f6^hvt(7OZp+k)15?@S_lVAg zd^hLCYWg{1f{tofdSu+!Q2@HYkqZJu`e=bEObXx3($h0t!2r>J_Z{%D+#DgRSr8Em z-Mae`Cg2qgt$?2V2{AbNCh2Z*?J+;*|JUE`sgG>a?fyq5x?O#xTDp-RiXUNv0FA6XLulTUfB~amN-$sDE0LE2yVyNshZ0NzQT;k{rL*galti za6k9$^-bQY9E&rE@1N*)`>D&N!|GA=Ry|Y{5Vc1SlcgUaq3$6~S3UKx&)pZPhur$4 zC06w?G>u1@bPa)|`dlmTdEGnd81=Ap>>o3Y@S)-Xla}_oCV2LK=KS>I;~BYUI4Qh` zx}ABZ>S`1yOwX;T(d%*^1*^;814{QX?9=&v%$aeYp)eEIP_)VmC;}X)%`VHkJTt}8 zP`n=EX_&x10qn1PC9E0RGv|A6`uJQqY5LN>hsW!(1J>(jcgdK-Ygx|ji9B2)J(Sv4lA_y0s$sxOc99&f#aQzF+PuyqB}@zo2oBW|>`KJdBPB zyp)=)m~(>N>X_nyk40Zt=HXTmj--gAL3&trtbWhchrhr67&OeP^p0zx1+c48_QPL=8kTw z`ZUSRVDwgg*|fRK$fzEoj($gL^V9Vg`npeXbc`8Eb*mQPZp9M~lr^T_ zM;@v#u^B5tIpAfVp6fr}`GsAldoQfeRzz+63))w+ z7yDDS^2^nM zTwY~h->6E_Yx#wmezkYDOJ4Xcx8fJn^G=dmPj!xvu&oI4B)q2c7LvJBofFi>l;f}t8aP;nM$Q5Cok&Z^k5J+9 z-qPvL+bGSMG8))&wNi>Ji;+=-R?-9smtsT$_URU&PjoBooS?q9cE-1N{+fQRciwiY z_dW^|69+M_Yr&x_Mx1ke%^YuZ6dlqZ{J*vH*Gv=jlQ0+E@Xic}nyfp^0A9&(bQaxE z&kBwlQ^(oCYP$D67TJVf$S!)|_Cst2!;cTvi<0Q;+KZ%KAnek}*_e`k9SBe{^rfn_ zE-dISnHN)APa@n*8qjDo8G~J~KfN!FFNb5T*H4he_z?aD%*xtCK+5v?CP?Q+8vXRX z7@!E|iG5}@orKiW9kWOYBpShz2diTbBhZGUTj(3gB>GKjavF__?s8(@J0X6Qv0a-0DDq|BE zJFicl?S8feMs8Gt7YWE{Iv~f9r4)Z9V3|0;r0#7h^}GUW5acqkHQG#3bqI8hG zBx!uFb~Hr2hcMap{sm^$5^dbJYZ9eEZVo>#qz2q^&&x|-fhS`q&Q5rv-&^)hWp!Q^nnn3kDnp$B3o7=K4)miq?yZ(NyW zDhp+1Eeh-R>Ir3LG)eF5pvHPqV@zSLM~!6}A9PSzK3I)OrEDQW+o}It)P#Eemx*Z$ zg`ubamGV&1e?V$&fZ?j2VGR~mlAgeT%`_b(oMqjUz0;jP(np)96czi0KF2B+GG&Wp zsWFl1u-ZG31!Cu+nQZkYGF7|(&)x~M_Z8%NB2^kUsX~-UNp6|>7}A;Fh|Rsqz|38( z_HMDup#9YJfkL?lwX9@azpqfP1>KeC6}~ECNc6he(pWc6uYJtN!p7h>lWSjg7crnh zD$`BbTf#kPT*2N)H|75HL0Xu2;ED>u%JNmFU}hW2>;X1SijUP#0>oqWt3SkV2o&gD ztDTi*>mjIYXEDbYg?@plYtR@BZ8EmNE}#>Qfqs8)$(^O5=@N0R{z|5o^+03hX^hs# ztl*PQaD|U2mH#YKOwu%IGTBPz9E9uZUACGR+Qiy?Yv=KOp-K{Q;&3RvQx?4gK&4xW zIDt>j5{e$fj>t0fl_1P*)K^%X3~9EsAX5^^5LiBuMWgg1w~(&KZTBOK(`<5TZeWx1 zSBuHnn6wn`F!k^J10f)6(qbWpX~2wy5tS}T_tUF(N0mjd=xFJcvcOQQqw3XXL5)o+ zpsh=MU!SH?8ANV6t5n$oGzw%(qlt^!{YYFyKT4y@Lh6@ZsLAK%&tjB>_I#bGx_m+P z(+~}?D9BVnSuRgY#cL`|mzu_vf!WYPs@aCPD@xNQe_J4fAS2tuiFqzo0lR*l?`uOk zQ<@Xq&-aO|lnlo4RO=jkcH?jIQ{l1uEa$!A$HHxyeN=W!wA@*ITI1sLBEiPoj6ISIGU&!K_&e2+ zYS~7;!NLbcU1b7Cx*XLUp;Nu7T2eAEa?19>yhzCwsNP5dKaIAOJsy-KrVoK6l}k3z zPcMhVZ?D)NR?T2o--=P)ClpKcfiF87red8PrjC>W)BF{!<_TjsWts_N76IaLop3*|_*k z<_K7APfBNEQu;D+?0HhkhLt=i-ObN5Dc!}-G%3A_>Qpu4#BG_|PfBMdCZ$~3_+!(j zC!8z96&2bPq%01%*rSIUmsqw(qiy8kT9#QNnr#fz^*T*{50@Rn)@`_2Jb5+DXtrwg zL|}vyM%AIF@(@&>;xcLmd>!*n#JT64Gx9Ev4>7~QPmc*T=b7g%)iK^{;)(Bti6_V- zWTXDPE~&2n6QT<6J8L?6D5j&c)tnT54?&0stZ`K%A*94mB*)Go59Pf{ZV3XhWp)sn zaIBiX*GJ?Ot=y{)7tklAe5|S_vVg%{HOersn-7Rf;t4{NVnB2Jtean0vC)_rQ5q~U zq68qoo@(iYWSbmnv_dvYz*ufu$d#RFYb2CSHbbP7ZH5Rf!6R-AhRIgPv1%%fYp$Sl zx;oshd|T6^;qvIdRzN;2Z3BESM%-RMrl?%&A<@k2Ec`E$#mv$5fgLcC3-Zi`ywlSx zUXA8yJLzZltBNkNSGXz4bk(wOp)Cs++Olxr%CgX4qTT>jg)G$khOR@B(R+s1>b?Bp zNViZuLVW4E#`Ej42tsoInvH|7P0T1N+;m<~x$}$d&M&q*j|9GwAb01fsp-5#wrB`D zXSUcO2MU25EOfQDm7KCOp!j@4b2J3Y8L@qvvQHp~K~iHd+`)-Awk+dK@swDX(ND8=bh*tJPar0X(FcvU>`Zxj5?hN(X_nhLN_)z( z{Ai3yWdV>0rk1U!MXQ9bSj%Dpfqe=6Gt-C_CA{c}!O10R$w5BXepSlgAY1pYGN!R-vd2;EseZn8D^=HvbSjHU}A>%|po3<|4#2 znhVUbo`_4mXN!V&-D(D5FVn$)C?zMdG(RupiI=`U7A6Ddh-K?IK9O%r91tI5*S5d8 zg+^LtLhovR>SI)bnZP&F6$(m#)~3{Zhc~647v~*{X)Q2OjWn zph1%|i^J+Hlpwx`IHWeh=A3u~jmTyXi!)PR(l1&>^P5Rk^E4Kx)>p+uvN$bkLRM#s zQ^-uy@U&C}$V&7`SsjKl6=bi4N6VNS$+vkrrf>k<7nD(-&G%R$HZ8O+UJa!mCVdjsFc~C6 z(b4k?1UcW+LVH*7gtcINX`dnu7k_n{s9Qo3jc4(PE@ki6L~KkEto!hI5%;=4NAw1u z8!xD>MFOD5aH@Z+fjt$c6=@rocFTIo!Rn66@$J-yM_tS$E-UczuOjOmV9A0bC8Ace z-h1^sdZDBB-Ulx-SCy-nu#z}l9zNFAG(J>&1e)Kiy}9!`NNrJJ6Z2B0rOlM59UeL0 zbY26Q%{_>bu(grQZkd2nUO}k+lYDtEmBojBNSZk zol~yH#qW2j+wW7i6@|i3qxFF8j4nt{U|rY*)}0{=MiM9iUjZesYlG6Q0>5hhME8e# z4x?a3mWHz+Yf4{w%is2J1#4RY>rA0QVW(5!(v)j>F zmnwp`gvgF+69`l9=vWF^_h}wHmtphsZ}0~5m#=Yvqi5zWGe>M|iciroUPU4f`p{c)bdZ!Y(iTBv%CSbq$% zsQ{uIXMELo(GcewsN&-`g2|p!eZmvXgQf9;lBw~c$ooA59cT+XbGRADBriPzw>R{( z6e0M8BrT;21(*!U9~PU^m-5!NG`yv_^^Ku&|C@eKiG{zH-z0d=IJpTG)YX(v*G^E6 zfI=hM>}L_8aCFyiGF_@K*-XVT5YJIRzqhF$ON*LL^)7YIPt~I8Mxi+o`C+7yfhuL3 zalFhDtf8^vGcSEvI^KVhEqD9rq)1%fAbi@dFY#KvW_$-@bo|=yKGk0%&_?~&XOu8A zz8}V8y)__MHkz1qr!u#y=>06u%IDXyIOCVmO4E?7w`GGcSVMQ~GL#2M5P|O}fw=`^ z9hE6%18k1>9~dnMO>uM>S1|>SG2`4ZnG+nG^i1qIUZQu{F3S!|G}K(PX-k4G$b|8P zm}MK_hw%vtc5DKLWU=+5R^`L`jGrDaGTY~5Oq^5@w$3)Hr%8GUD-x)kge_hT{qFp$ z8ZeZ8r#Ce{zpywnJI9DplZ)fj)}8ERRVz2Sy8uZ8=Gbl_mu)1`Jw1bbxK6lXpaNRl zK_#GRb0Np2I>a3ZWIe1aht3q#Tj;iXXYI4C2XEuY9FYUiP;o%&3Sy1B+s<_aA?9{~^q z6dH_!*vVB~H!fpD9z=Yg)a3mUyp++w{z4groDLzqdq z3iTS~2vWSWwI+&3P(Txnp_I|67Wu6fbyk8}oTI@-s%MAvQvDigeQt>Z_?otJZaqsO z=n^VO=oEUvVH)m`He&m4p$=L|!xBTj5F}2GLDYa) zS7oI!^TZZ$=-r}`^xX`Nm-ko-1~{W=gjH8A@5!USlvAn%T_^&R7IHWC@B{Nx);i>y2zqFWL1$SiP$i4 zau!IT0w3CKoF(zRNSs8rK+43Qa9>D~)u(La0-6Ipq4^@i(2H(AA1DS=^q}nanpVZ2{mBFHUee^XF|i zomoL9a1$YHz(i~!i@H$LIZMPm$>~KenX9#LBbQC)LTN$Yws~C2`Z{=gCtd&aOfmOm zY2a4MS~@9uqc}7@2%c2+qK9iz^^%WmRgd%9s{WF#q0;6;QuS^#bUkfODEn7&vLAuIv?$ znWryxW!x}gOP-H}!1>^2RiArf+4DiE`sfVGK#CnDK%{8wD2^8p8^SEKLwZq+gIrKF zvxC?Tu_+IP3VR|cctU~JJS9V;%_US_k;Rv~I}73o8=!anHo)coyxUv*_;lIww6XH= z`0&K6dgocmpZ1%ogJV^6yjD*UrNF#vZF#yAM^06Tb$V;3ep3#VI}GW_W>_P0)MVlg z>ZGGjAp{o!-K%7-HibBhr^9)u>k*0PLQw7@GH+@!k=7j!NzH|Lh!awKI5=pVuHsAS za44Dt_YsjIX%^RJU#yxDSg7} z?VTS^>5nW_YZdj>8wWUu-FMeIdu;S+)e!d((_iHTNhcr9B1sDC8-C^2sx7OEAyF=9)$bY!5zOUA0;7HE3 zhfvokA3@?vpf$;f{8hP`O75PLiwn5P-k-A9q`9~;dsW9-#Opzv5yn7-yF{I<*+`Du zM2&P;7+z9t!H8qIwek5C+X|eKIXA7Z#f7^^9dBr zp^A2`l%a-JrJ~S{1tZ>eC-hyY*BQ`vQ(?^AnqKN_gy=oA4mALxuYJq#KNPY!j%!UR zmSUHekj#_IO3!wma(b%! zW>gAO3ZjS;l;;{vJfh{Cf>yO_xI7J~1Bi)=XQhMVDpv`5j$2S@GWW30iRYzclhr}9n^5u(z_)_>G`#Obx2?F-)ej*sXd`{U{%XkShdkPA(mj* zuSq;{>+0`0J=^{Llz!dm?VUeN=^yoz&Y@=}kPud4*Vp=)KoScV*wTt#iSGp4OS7T{ zsfaBX>!}YR<@`3_G@*6gln6X)9Wi+#sKfQk%SG$Fyo}KZ23}nbb#myT(SEDixzQTU zql&&yHyw4(OXtsxW>GVyL}SvD3AP*u*hnAJH!VubS5`zP*=`HXv!O68Dqk} zYfwko&@AIs{C7W79r-BDuHMNzR2x34^f~M&LnJn>tK#+iaF_=Uh+o}QyAE=EYjI|1Quxhqz-NJAo~VZNU_ITku5Q6|wXk6IfDbtJQ~c zM}-%9x5klLIN@Jg(>dLgzl@l(agdG1qQmvZ212$TC*Igdh&RQ_e%L%TINh^ohmxte z(ZC{YDr{K^%0Q?UEw0ZmFQ4wcEX@G-v_$H&v!NF*%_hBYV{9+Iur1qVahhO zgeI!BQ^;#~SlWy$NQZaaIXIEpgrxUCK3mv|J+8WnA&I9V09m?ivsO1V|H!L$v(@OC zF=slSTDnta4xguK)(x2_^%J+-0@E0a_SM*=+GA|i+i*r2Y1k(`ShbUGuiBZ-6f(@J zeKQ%}7ND+<{MEr*GR)o#%x;L#>KDV7q>-(ZmPQhk2KJk=Fn{Agv_|r3ACF}Y1!L`#fxHh3rloy3H5|)Pwfq#Cnlb9~q@`=ZVTa!-3GqQk(+3(=T%awD7nE`&KG z$%nxa1&8mGZQMJjVZ?m;P~4jDB0Sp?l`J%tf7buS`M6|HL8zdy;en}6o~ zOP!C6k4U@>)~X}VU{i5K5mwKggS~hiX2!b*`-qEUb$sn%I}jiQg^I3nUJtVy`voAC zwfcdW_7iNjTFqLuKc7{*$jqw!+KGmRw{3|Ab6;BPuEDn~om<4-tm4^Qq&yRfsCm&IAd*=rt`N1@oLx)+yXiDH|Q1648 z@6uGRh?m}jdUJufyu`~68XLV)WNIQ793_Q5nu%9^e zO&hjdKy*jWz;PI8A$F^H(kn*I!#da|vCLMHNyDW*Y`+cAhGCNCyhvjY`{?Ab6BHV3 zA35KtMnCl3;$$1NTNy0OTzp>>hDO-Bc(}GQ|8Kpo##;DZ*eyFHVbYZvb>O<#W`L)0I<^SXN ze)8}8Y8<|!8|jlURZ>Z>m1gHN$c$&bM1AmJ^}*BA9FukmKA{VwtVA{^%Gp;1$JF?s_Q~`yb7QxA&-jueV*F$>#1cq1&CMFB<*Q1#=+gilu^jNfg)o@ zbLV)2<{aZ8D7sS-(Oc{pjyQ29Lkciiuu2+0SF%Tg#l|;b17~kY$k_3&>vNdZAHUm{ zJ2cCr_toU%vqOjh!nnH)f`#FGd*}2k9BaE{$cY{H!7p2l_?strD=`I=0LG9_dt$8f z3|^}h(b(7ecMXm%eXHbnV)TZyO{|PxoSKE&R^27MOI=-;x2Zkt3`mP>>C_HV4eHV> zgm_4`SPe_KnUrmCM$u$hwr$pA3zBW9BlNTVdD{C71kz&zfuq&raE6_^J6{^3WsML_zkQ;cV_;Cj}b4q@vG0o?PW#c$g$9 zvJhnxvO4t6HpGOQ3G#IZAM1u6RNyAUmUkjV=d#Hd5rto`irn~)xCDKn-l?RXbin3W z0)^=S!(y?SvGXd8_UZDo!od2W(|sA-zWkk3g`Ol;?DnVi9GDWXPJLJc9yb|(XleLi zfk(kG=X>An#mvL?MF$8+P&i=qlcSr<;+N!sy84+CN^Jkm)94oK*(5F%sTG?IV&wv< zo+bzo8?urI@r+0hS$QbQO44^n*YBYTs^Tx}9>f1Ao`xTh*waD?dMGQ}q8F79&LW@L zc+W>KmF6RV(kmqm*|a3``V+<8_$sIq0E96{#@`moUhOw1d%dq9kBqWE_EQUGrdng{ ziLyn?7<+8$bYGMkg59BY8DU8nH3(bR8=+VDx=rfV+LiR9fi4-ARK#DtHM)2Tbcr5` z%;m$U@Lbx~(PSN^amW!QNP?nj7I%#T%UY zg&38tecYMys8Rr-bMSbK3p2pfmN)JMy|MZVEjmgCT^q%jaM_%2yU3rr-RhdWwzfuC zzaU!NT=s%YsyVKo!SWdG=0C6M>VSY?WOXcmw8&&`Bq^7-_{h$&F<7>d6sv-n9Q}{( z*y@8rsVDFR2aC1ht(kX%@3dB`!3XNhDp%$_hHWc_w8eP|F>GyeL$weiuZx3AwCtw|%5E0+B z&rj#d(XP=4L8vYni@9|_x5-}fnz1_)Gqs3iP*uX!9JNZq@G~D$BsL;)SANE5oOcU0 zf5Vnz=OzIcWKOs2M07ZY9+YfeqQwkO($5db1vlOjR*Iq?R-b_r-og#`{AQ&K{T;9`yV*-z0}BnzmjgqEn;cdk#p}_{ z=1;uL>|qTjvKSANFlT8zL`KAf?S)K7ZPM%AL(r`dk`$uEYD|ZdCUkcpfq4QT(ks>a zWKw!xiAq@(07AiObo&JsYQ8dnDvq4*eotoW)QEjI3T6v;&)Uh$_0=r_q?=~Nt| zbBbhlJZTQX)81ynApx*29>X^Xa9dLiI~rqtvC>Q{_(*v&d`W~QnP()HiE^3dX@Z=J z7D*1-0h`vGg2%->PsN~|71 z)e$#qo~EX>~$swaHtXO7!0Hhj|`xL?Mb0hRoK44NrAtDY2cm%mkm-Lf4-H zsM%0Ilr@b#j~#6w3+RvN(T?2i=wQW#v>YZ(R0HsKAGOjmo9 zbYpjny&YfckL0uoLZQ1u$*XwcucUXGtW)iS5)4!^z6J3bSm7W$;Y^~JruS!vqB4u7CJfDn|HL#pMv z@;lXdynksSt3VMfmW))Aw4hX`w4iJNsjxkeRjZdd@^d5#}W;I+>?4no- zf>uCaOZPcGuWiJH329pbDomO|f=@)=l55x(mTRPWI$*h0xHEI}Q11K44OHx5APEtc z)?o38?ijSQy7rZtmQ*v863(}0;IFEHx>jO-DA0cyS1s<78<7tR5zP2ZG}NZ(kM)dq$-p4vA~f(iA{k$k(+EcS3+T;d7(G?td&7vAhNo&Jt>?15>*3b{}%zyVDKpt5dg$yE(H72tP8e8Hm zESADUyMf4dSjN9Yco;gox*Y>io)ginsrF|%quAfE5X^?EX>17!`Wwm}gM zh1Wk|s=K(!h`{v;q$$hLY5=G#L#vEP5Lc&&U*9Dfmmm*QL2}uZua?0cDo|XTgyL(M z#Cb6$Du_>G+GS$OV~Z^JtD#3t&fKpp1nIe3aHELI9pWUo0;o(nbCVsq&^1PwVR5p+ z-GtFQdjH>`s><+dIY;)N(ehRl7%Qn+_hl zWe5#qnWH7h*5ZkP3&F}lX+=OKQ$e96TNY1Vl}c-r~x}_jeY& z(1;KVR>>(ijIf5giF>dhGC4~|#cYi*5iZwU9y6$=wZ(el?e*JydDXT2h53@u0U1gvVoi7 z_az*~h<7is4a9Kv3$ahU@RA@AkB4;NL0}b#b}1##plC<_7yXn?66n>_Y$+erW(}S^ z6pe2(0^vbi8<)wDZQ(L&RWB(^(nn*797O++1Cyje4$7j|c0)-tPB%oOTIHcI56?*C zXe~52m#XO#hdG{vEXBCNX62UKuK72g$k~;yPesx#zvk<{02nsvx372(JW@&UPL zp&yx-Nn&Bjh96`#mYaqA?(k0KVqt0m!^agWC>udS$#~UOtwv>gl9$7JN~IwIbbaWm zSn^G)+^^=+^KAF=net41Z_f`7)#`gXLl6QGSDYRbkQp6~u*QzA>_2C&;kiYcOc_Qh z{s9bo18NWP*|B`#0kR~1D8ok}er#d1C*Tx;bO}x&kb_tzd=~hS_J`Ag6N!t{!j2}o zAg6`>_j2Pfp3vxX*67@1%xZ_0J`^SqS_#3k-x;`~WKI!;fRhh^?-Wh>rxm!zWMj=f zEAOM&A3g%}f~86fl$q5mhRm#=v}hqirYl1xApAwgTPXOzh}Cr+Z8PeY5XsWWyy6rt zEkxV`pA2hKrku=OHT_)L)w<14+If}N)#`l%-3`w#Mf$yK(C2~D*i$iCwU^=o{sx6) zuml5VK}m6bPnyP>(z>3;ax`3ZM8{rH$~>(}ZJ8=-i4}<4*29Kxi{nrTEho9M2>}Odk@?K9-*07yB*JuRTpb zYfQa(n^%FWn+&5gpPZ@GN;uDBKFK93?HtB{8Ju&XD>$ML6r(zc~e+P2i$x^1bxc(@jUASc_7bb{bE z?^{CiVkQCu`b9%6m-?mI^T3<`j`Yq^m4wK)@gz`CdP}MqOFKl6HKPa-6x}cs7iK7; zK|No6*Kd6(hC9Vp}63%M|EiO5lz63 znsdaV1b#r>x`TSqhxdq~!xZ7wZoB-HA%mld9dpzeA zVhWo}0dpx-E(OVL3Xfaa8W=aMnlQL)i++=p*kz##=Vs4SV+RogQqaT&q=A&y_U7cw zYMd|IA*JosNl0l|nvl{87%fOS1Q>-BTT5API{e>m6`=1W^oj8Qgp@?zw-lt1VG$?f zG$Ibisb{kohM?&D$J2@?W~X9CSRN#T1pexNES^4LcH$Iwr?+<=PwA(`UYgn{zC=rZ zF>}yBHX8P_f4gC?-lO6!akBC(S|JXzm!~tCy~5tiWb!n}DfhIh6_Fm9bM|aP(jGKK zNc_B}yuWCJ?U2M~qEbE~X$6&%t4K&{)mo6WhJ8{v$Ic<~hd9UnAwR$#u1gP_IEQkx z2}!X9ObqhA9%ly1OpT?1*i$Ym6cZ#FE!81i0!+DUw|efe)g#kFdvU2pKMu*3>b#Y> z(QZBap}NoBR8{M$vrDS>UCUTAQ{EL!VgDM2k4l-Ip4q1)ChC`B`sH_8J|OBxJ}xLl z+aj`Y=EH(zoWXP~3iisk`jwi{&)fvXv_La_wCr9NR4jK^@JCNAez&jo_LyQUeC*j_ z^r07iHtyzb`oPa(AU2izBPw6~rz;bO!k&CsK_VQ@1ZS|aFstcV0a^xLPJME-jH#)7 zD9KcFCK`5apngf>C6wD z@|qS#mFsd580@Mtf{t8i#gwe>Qmszzo9M!{XVzP~pt75~&~9nH$8x}WZ+$#P<1Sjc zMUK~_%XEoHg|kzp;+Q5Egyy(fop;)8R@r6G8|3+W`8es=Y66|~!8c_)A#B&e)z;%=*&&_5<2XkJDv9*zzL%;Uqm0 z%*(l3H77@i9yyvi(<3vJ7JbEWxu!?Tn8?%8tgs>R*|U2ieZm718v)h?#Oo*llY=W}nP)4aQPycnD48j8u(U>><((ArAbuNaRptLCEjKp&V^)uV4^5 z^e^k(D-}seXyO6YM)Wiz* z(@EW-?T`U;ddsbY#4mA>IKE;whT_`s{9=P% zs2_7&MDOl|&B6)MD>Y|D)Z9-VTbsM@8nf{M?93$#$_^^-uHVoR0W0S>_}`E<<}SZK z!S9o{f1?u4PM^_NIK5bvR=w3MtGy4`Q$BnOV=uzpmg_046E4^Py89ti0)Ov{Yh~t= zm2-sxUZNOpU%+T*#B<4D+ggfKDC}^QTdp47g{hXiNyI7pz~lgZhg1lapp+5&LOoN$a$0iW&&9Aw8$IAy2 z%`6Y5Fva_zU|9D#A`=60MO!JT54y;}Z$HiDcgoygmxp|No13jRHCxdvArZMzg+$P9 z{YnSz_7L5J3O-@(Ua3}2bT_(ZyYHu4olns%7A`xV?3&tGH-YXysBK9Pmkj0(%LO60?woJI`_#pRKO z1dXC)fyMoQzov%#TJODA+pJf#wxe+ZsNA@Q`O&l8ck`0Nkr`CGV?Hh!sN`S(4W#$r z>E0Pizg;zzt6f&4yd?K?y?XWlsH4??a^Y}aH15vx?7mZKvg_|Y+kJa<{miLe#S};& zJ)@{;kAgEUr=gG=r#8iu1hw@>%ZuSPR^0$qf@Cutp+_b{Yh?XQ-8-Jmlr)Pu1(+e< zSt*mmJ81REPU}=<;E!Yp_$6pTNGG~)*9yS0P$0=-aHiMGKoFhm%z&j!LI+}QgH+Vu zObjrwoZ*@?)w4>k31rjDMC~Yn)IiV>iP0{#c#s_6IoLw#;&Ffp(zt9P)wEnKrC&k{UlszNbEv$!Da`O@lBf@!?N&k5 zYzh%SLiW_$Z$U+xYE##g1uNx9iI6$b*$e7AjsTv)xq4l(?x1DkMxKuIlI?lh2dzi7Cs8rUb86OrkL zAH;v$h2L42C+9@BI@{^;Ygx9dTm-QXggY7}^2TxCT{0Yo3hV5EF5UzjF)ShvlQqMw z%e%~ zcn~eIr{!UBD-x|*w(W``eD46ze4s#GMlA@4U;QaAu-Qx3+2?SNvXF*GAAnp`p+#T(R^hqB!|2uG10O@rgA+J z)!$SrL?CThA+v2OcP3FTM;2x)WTqw2h@Q|UuE~yT zGPaE+0x`8M5eXK9Gy&L_NU|@k!4i@Av%MvPgRW(XEHspmshY`bL8=HHO9TeaHb%Cy zx3NU#*}Il4k=dOsk?Cro)L$%-hK`g)lYP(T8VX12&K9MYO>ZobVy_5%Tj)J35mwA{ zi;3K?Y>8|p_r?-gDE2~Qi3pl)OJw$jED^5K`v00c^XNFQ>#)y`!Mp)5Aoh*?0B+z0 z4EBZV$RZ`$vPeg(Wm&`k7?2|ZGtkTcl+s!nQglq)TA2n^hDU zK8KPeA4P&wDN-HB!b#;*|B>48v6`xBBlUORw_rekT9Q9n@C@Jgz2)Bf?!E86d*6HC z_t`XRo3geiVt;hXv^&}pk(tJ1lbE9S^F;hk2W*GnUo#WFrzf(^y;A2h!^_fH7RqI^ zxXcq-=A4aqr6;0!{((Iay;Sr6&J+1tpT}3QBEnbjSdV7hm>VAc6&oIUfVHrza+evk z^Lapt+R3v72&yTE5aiW^17{;zeBV~PYTw1 z-}ODSn%jEsyS~>;lIE-5^*tKwj@ergvKaBfx?!!5e;5|A((=Jz>$O1Zsi$WBbt}E} z?l8+-d$X9uBATp<`sp}wAvHZYeX5B#P!`+*D;L}d{n#bI)AeJr#nJuUE>Hb^o_kRZ z`P5--)_byr&&KioInM#%EnARy>Fhf+2k}5z-npyU@1^X6{NpJzYtxVRcgYs2JLZ|@ z@pyNxxl-0hom*bP!>%0fs^Oz2|IEE|0M1QYSd;*1&1J z530%!fhy+C*nPYLzW2lSAv)%TQ_T#_V9Yz-472pxx81SM!z~R6A_Pm|c!k58>e#I^ z;5qnIEy;!(Tk0A(3>m^a@Pq(Qqw=T}hXcr@21hNdO7#sus1+WNLHT;4zTw7}a05?i zRdR4&3zgHSnn@K7iVCZBMFZhB$NMv2s-{7OiG*yv1mS=cVrm7CD#TL@o~j0(-r#(X z;HjZPP~%Y!9{Jj+w61QDkYBn|L-lGC3z_Q$q}>%IC`t-ZC{WZiGzX2E7&}?guG&z1 z^0$Ixws#s;yeojSHGKYqXVd5gkSz)Xt8_qjdzl1bV~~1<_$}46Dpd*z6@?^JLPD^i zxkeAiYC(v}!+KZ76z@moII2C65O%fa0OP|w-J;*GE`v=zjB~5JUw~~(Mz1+MV3G_A zD3Ren|LI`m@{lkaXzd8;$5c3>bh5c7=5DT((+NBm%-llAN6?JJ#yY7hb`InLQc&^y zIxqOZSV+KX+6XW)#CWvb6pwx+RGw-S{B(q?8=0FbMUpZXQ5&11KXX`VG;m&&*+q~W z4JFuTx4~;<`A;OS2fa^@@(}7LbyO)(Btv?}6 zoQP!oZIm@arkv!ggxZP z!J;m}^_OuqWXS@GVx`8aWi)Q{w)S~1xPkGu`RTS2&WGACBnuckG`J!Q7-h>~1;zz- zh~MT^l>@m}zwALegb!~wmYQ$#`7n(RXA_DGv5^C^!ak4#u7WPuxJ0pp@p@lMKEE5| z!`COV4V)rHE%l;?Rs|UC*7_j-Y0=qgh(?%dDB9A@K7YtqFZ70xh0~3YI0iO9LXhWh z0$Z=S&&LntOk8sXDvbJ^WHNEfW0Km~X`9ztC~FStt(G-5YPGBtnFX>2-bz`+0GqEe zISK1{G<8MRYTjKYYn04sV9A=#wynqlM#(Z*oBzm~?`m5W`Am{^RqHUWaSd4)Vl!o3 zh|HAr8o02ldSbvdSpw&UtunSa?~APY+F?k`d%fra{U4!k2A4s~JO#aqyN=z&8w zqKcLyVbZ28Ris%@X$78x2!I27W)5RSsAp4M<~GwpSmF+nPjUToMj5f%#_PV}E z6y4FIu2qjZrbN3?Y>*yx_FGSETT`pQ&};&*Mz~lS%Sxb~4g^bcm_$}&K}o?_7T%$K zD-;LGS}i#BX185KaWIf}DfU3f#rr7C0abW4xxycW&#O+FIb^Cmyq3x%B^5jgAa8_- zC?;(rWqEB(Gul9i&9($bMltLL{e3fw4ttMCa zgK*^040)-ExZf?+;>p+PdAx8i>jBJeu}nnO<^T>X`ykM18GxXSb7rPeo|`a-xGZ_# zLSWe~+racM+e(LdtgqTAJ6sYLGa)L%#+!H;;?6dh`qEr4nKjI5rFs|_H`n6nR2#J? z#So>$>(#zfW$cLs*T-5)g!EYcKBfz!!3Z7ZX$ZEbD>5w#SCS6u50uxSOBFa>Bpk(V z;8ZxZ*!GqHQM_7QEL@^0dH#cJx41>}A_E8#9c*Q+<5JZ&*Fgv~;GhdHgszEnZWCv# zPIFY?h|#EVER=2&BBxA}IXu+X%b-~f1? zA>o^8{>*lv<_3YzBPFnhhJ;Q$tij_oIO2k+F}C1g@-*sqxfo~mr&F~#G0V)s2QaFc zRz{D;2 zMVU0h=2{7jYh{$6EZ_!}Xp+DU0#_>mFf>T*L5(&+&Iz|Gt$AxAU93Yrz977ky`^6!RVKR&W<*V( z_Q0B9aN&$7)>8XlvigFWSY54?uGVQCqdKa_<7r%oMp<12jCHx(RZ&U0O5&laDPu8j z+`MO33$#<5BdsNsR##y<-=+@N68W9mEx`4II{MPBFVF8rOU%m)Qo+1@dr;`s74)T3 z!LGZoTl@!Ifo4`Nnp3S}Ktv1eBC8hrwq=n%*j{E-M|xcaskGSVFA4@+ZjYCx8B=^V&xASJRERt=6=IDYE?J>5evy1I zyeV8JmQC}z*%h-MaCeCW*56pdx8141+zFsN83}gV!zDbgLkXX!w}eJp9y*Y((=$)8 z3>NcoM~o#4H&_gb=v!>40Xa2m1z#0Ts8R1Y#hi-$4gpE*nzabjD= zXOX1{JyVLIm-P{A3^PRNnhZ$oajXpVnR3<&{?-Weg;NE=AMP(cVnLu^uivDl9Y{O) zYj9X+N*AB_vcMVlTgL!mzj00RGAzEDCLJ#^TmV*T0i$XetT=yGpud)MYK$43R@gokKBo+EnfK&$MT*z4Je{2w1Hw$n zF>j_-76ME<8kF@x{x|N7V5&HqD0{&|gT`%b z?aCIEK0r;oR?m%cUWWeY>T(uacd^%Vtr3)MF6a^3IioizHLh(gf<*leJMK6KD=*mb zae~m(9H1_5^%F15b&dGQ%==Qx(+RRv>6e+`FLSFL%;DuPwAQb|)MuuH`fV6IRRm*z zEANZ;8eDJlT-_&HVxC;4$j5v|NB|D4E|6$8fh0UQD!9z2p@OkR7cB9WEx*U)Kl?o; z_j#RNmjwha$DE;q6D-gsdzj}`uLrp%QPXac$O|`wJ^}umT=weApDgFf5gV(*OL8fyuKNOt z*vobfPwa7Pl5TYZ>XD;K`G=+$ORA40nJSGJ z6whW8nOriRGRES`@x-BxAe$>I3;czUFLIx*6g$-)kos-?B7 ziC>go89yK3i%DI)fkM?za#7B2hF=B0pLp!jC6_86iBHBylDT_~^mHOKHl9A^ip{uH zg@Y#(KXuH;HRoQl{w24nowJa*+$NGRNb1OQ#eTj<=`sm<&lPZe$)jqc029iOT0obZ z&3V?OWZ_EC-t?&F-O*^YBib45igrhPqP@|+Xn%B|Bihl?(b>_}(cRJ0(c972(cdx9 z8SU)o?Ck97?C$L8?CtF9?C%`tigtB$b#`@ib$9i2^>+1j^>+<)N4q<^JG;BOySsb3 zd%OF(`@08vqCFiwojqMW-90@$y*+(B{XGM{(cX^U&fc!x?%tl>-rm06{@#JUXkSNP zXJ1!ecVACmZ(mQ%!ia3z9*Nk>>)NPq_!BztdUCRjJPp!BAzjZ z(^IL@c;=qnMlvTw$y7EunlMn!kO~^D(mc!ELP!O+8R;=&$Q4@*DL2Vd=tC;|tXfmq z=aniQP8?6Bj6HjeL~7J%1)WkpxdoY0k!{AQ6N!|O9Z!xVQ^$pbC8er`+VoUTh|-^Gnw?Mk5A;s%5aCb45k6n~2$(?WeyM7)d6kK$jwg(< zbVlZ3d?f)m=JKlGTU9o&b&3V3k_dQ>H@ZU#o zxpnB=7ay2uZ2H^MvX5QY*1rGtPapfUzdQTjLy!EMZ+`cwKY#YQ7k=`KH-G6XU$?EJ zyKiv!-oqdL^x20f`rcE2{@hPqdil*?x_l+2x^!^&!9#~XddFzu>?2?O+6yne>?v*Y3vayn%O!FT9v)5PPoMpdPe1d+S6^HD?fswqgU^5Qf%CJEJ$~Vv zPd@d`51;+~N67k~NOOD`Y3{>Uw#yyMvCAA0z^-~Yi6fArjsUn{S!`PA+I z@IT*qH(xSw*Du~EE!&VvH#Qyn%)Nj5oqw#ZS-;`XHP;`x^|ssZxc9z4d-j!Af4=nF z|B=Z)oSXXcqc5}{+tSwl#CLx1!ymu=+8bXv@aXyW=))V{{mwh@zVz<(M{fI6QLrqs zwf)z>Nu~St?!W5b%p>o-d&BXm=U-U(>FfXHzrFJ=y0=a}hf{g1<;)wtGgk*2{QmOO zPnPcXpX^y*oqxky7j*ktydht=ugL2z3KT`u(Xw?#Hw8Vu#!#_0=q>WHz{E?k{9YAs zmsa@)z2!v#e-d$d|uRKr|9`rSBE(u&`O!)5HoPXYbX3kq5IP*{5 zPZm|Fn&QfEW%$lOC{Q1`HMqlnD72FomAbthYNxM0puG7fDcTUb&bP~(3-0ljdH3`M zgWCgV-Yu^UwwLen8jRdp)Ozo2zE2kC@2_nP zRTm!$<-ZX4lgGj}zK(DBPXBBRN3{L{y|^<8E=EPj7^7pmAc9m zaJ%WU2hH|`yvh@Cm;2WFE7nzdsyy}HMt_rUllxBZNzc=spL$*izgqm)p4U7-b1(XT z<@vR-?nDr;}P!k^+!e%x845zADsQ{*NXdQ9=T8y+PyD*?AO1!ZTKr+-P(H7*Ji)*A0B(+ z!ndD#`cgoJtC|M)AN<7QPrUe-vqg3FEt{Wx&Sz}gyrs3PfAHFmUU&3{n{F0;8yZQB zoy^|-nft!**tfnjH^0!nACp_He&xBNC@Ny)|Y*xw5})=xH`PGcuMV$Z4d1BhXS7nxcw2Y zKmWx$TCNR-@{ixqa!`c=B^CX_P;b2#Q*wIfhOqmz>)PNAO#`Qk4uzV$*BtKimIgy- z9>4!9V^b=B=?hPvZGZTuXRi6ie>yWzwB6?!+7dbxYV}v#KY38KN6HU))<62+E6)7x zk4sK(_{8Z4KJPo}FYy)^MgHwj{vSfwV5;U&{;6Av*X18NeU10CSCv(L_UMk!y_$b* z+sFJNpXcoCo`BnTlfR+cbGme=Z!~;!sKk4_Z|^`;$xdG}nir!}bBMF0-a!hj5!nEorS5=03_4Qe2s%OxfznM2bCp7+Sq zcpQI6Ce%z~A};e^#yFK^a*G?I$?0U4X^#o-_Y;{k6f`n}(T&VhDwmu{v@?U9#J|vp zFE*;$qabW7KpezdVEO~`LZfP29d!;H`}W$7{ogmLAn*oHCC3L@u(R&Qhtu5spGH+A zW!Xt0fU`~J&3IzO#mnf-R>K4iuGp8XqOk<^W}DQO*!Z|H9M2|4jLCQ=K9R^JGFc;g zB0V)eY78fg(ZpCXl^Df?X@YAI-zCHo+6vdc%+Dl#u}O6ma4m;Jkd2SzG@Ha-Nu<(K z$4?kz_=Qty^M!z5w-d+=*L`~sCo-bVSNgK}ZL+VGKhO59FiGTzRZ5g*Sa;-mMN z8Kd}SOMqAe#O4AJKjT`wVj`UlDl$i@I70&nVx!JIzro~QA`^#2)(wF^6Wj*XvP!*l zz_!v&THK&ETck~;9OATtd^v&V3=>%@i#%qmo9Q^n&U1qb4HDHshM{T~2(@-X;T&l# z>5uuD+`mZa5V=zq)G&JGSHQ)ojf zK0ZkG(W#N#v8fbV#C7YIY+`(Dr>U6RU`(^BE!282q(?IGk$be>FEp#2tFh>4RkV8| znMzJfO&o)ybT*l51zx^IZ5oNEh;GLbW?}@S2Dgd3li8ej>yw!@b%imHwW!(y*s((e zU4Px_`h1Hzv>NjV@1I3dTNIkkZNzwjNtDGF!QXLhs?sc_^OQylN`L8;&TmvvdrV+0 zCZ@7E<3xNq!N?nrr$#U?X(O9F4y%p$B%OmdqP!bb%XAvkb38eXe=qKJGDT5x6hkzY z$lwT1O;GPkn@|pdgjVnkk;>4FV9-qEc#_gQxx0iiQtZELo|FmfNxr_JJ~ zm7{WmfNmr?uBDmZtah#D=}_x^O!Qq5Gm0Z*OLGi%?|?gxfT4c4(g2!kP=E(tEpf zi&HwcMeQV*IG)H^eAHlNwQXcP5l>A`nnJO1K#9i@LC;sZ&7-bQkjixY}=gD z2ezt6l+u+`;2&*efskC-?X=nDwD}&T5{NO5ozga^bYZL7!6Fa=bz(vSY9^-CXmXT^ zDQk=~DvWqWrl;dvq8Qlge5;BK$43pT(>iLy!nCS&lAB?yWvFS!SxBh$edpnYR<$0a zV#P4Blg8*&Muy^XhIzu6Ok|QEU20X;T4T*1QR&bFG=mPx<9+4 zfVF0+UYxM{51Uy}0KyQuUD)lL9pYZ6^uT4Mw>YIsJ5&)vcyJ`e4DdEp4XPH7liQuD zGdq_xciByw-KnZ=)8i-}v3?r4&hOO3o63k)GgpENCw!PgozbaD))K^%Du6IG3q(-{@#L+x;qDiw>mKDSPY3K zj*`l-n&xLl6EmIvqG)2FbLBh?sWMpfJiOGYf=eJY5xvdb0(T9dW-N87O^8bW8CJTM z?&CjosmMI-BuJAjDcveI-=#w0&&4N`rU%!h8m?m6NTw!n=9zWk;(|@HsLKSChS^J9 zDzM2&5kG*uTXnHwoQ|_3$l9aGH#IdrzEdJ7{1)~%3MT;V&gAZqux0+A+c4jQ4CwiG zIVr6Up{+N3_t zwb&=DXs;^07IoJwP24pl{_hekW@xdgpv9ciVx~`Ry3vZoWYWrIl6VPeBw`PD?M~uD z&iARtqxcXEDU8X9f(X#A@$)|H0fdQ{Y18(MgDKyyT5rguGa~e51bS{n?kwOsfwY8W zbNwn}$7;iRSzX(Oex;2IUTHs*9k^s?W`>kW*>#bhDYC_We4$nQvnRCWXd6u)Pv8#W zh$gIST#tb(N@#9i&F#xe1Gt(XmdR+5bmeaC;=mQQO5a+e+4BDD1A}HDM!fG+-+&?8l;unStxkvFdB-U9Dj4u@A4x*9*$rZb} zo54q2xa5kG;=;OKz>JuKZ=nGGBeW5Z7@Bvhjqepmv!s$U2hg6i7DXnAfY`{u>E*5xvGBq_Ngu4z{y=!?uoUxGYM6<;|bP$XBTbi4FXr*whRNlH5kO3yo`OZ!yE>Oq%FAG1T) z9p-9)v5y(S&Sa$Tzib98SPxs+&k$HOj%9@bE7EG4;B;o22;0scWpon@&T!gd>*~g1 zne>E>ykO<*BDGBqc$hW1dG7w%WAAMn)U<%g|HuM7eSDI^WZzASb2nq(;V2*{`;Pbl zIdK;hmzQ_oT)vb@17Z*;!!DN;@dNIh>B4{u;ik=Y$#BGnAP8)=3Joj; zh579I@Hv4Bvl>w^>$<20rew51fz~fg6_`6otjgN$ohE3Ftp=k(7i(Xzs;n+Dt$%jX5y!+L_MJdP>e)9VLZ)!Kd||Z%ie|S8jR+WuF5l(peeh!>NY;b?Dk2V5$1q*lgUYt`W%j)|Pz{?d z3sNlJghd5D5 z4wO>LtkP46*Iwsj4>|UpNOGt;#~pd=Eepk-k4)IS> z*{$Xk4=Dyg(CTQ09Q+Vpor>m3ifB3O3K`PS8=*e%l=N%2tb#Q5cJI~)h}#@SDbN#t zN+KIm^%=k>#rIwJqXLEx9Th#0Y!8kBdxpQG!ZOR(*DzrDh)LzMbaaVkV;e_TDh1m+ zT0`{fqg$Ev%6_rcz~V;3?lT@IL;2WhFiGuWqP^iA<2w}E@8d5~jE?absqN~I+WYQ` zWs;G7^;8n__M&S!ZVe@6-7| z%#>Doc-{rT#P!Relr=4^rMT9GKOM*_HgTJ#50OBr=FW%cXGw&1L@YnRBno*5AeG7^ z2dm&Y%+D)bp$~PQwQx>!7}I%<7j)uL*t4BZ>$1 z+YHfIb{P-yG~mIS6X653{OWdyQqxg7cVdxHu1tY7yz)sn?NqYEXh_HP|9S{Hc^kxw zaz_fxc%h%%v=>rcs1(1Lp^bprELg6hvY*X{Gkcu9kawO3$=MhaS6={nk@%Sl(5`fH z`+(h@uoxbA5n`1trd@&6MOCvBBqa=3T z@_XK^dr^7%8`!i?Z74ZZSj@|piTV(mK^rIp3Bnpd5FSP8gEAEaApoUdtcc^E&B9u- fD~`WE2Lav#aav7Dc1c26R(^tDw94Olij(j+V`pbv delta 1855 zcmcgteN2^Q6u;-?Ubt`(E}x=BNDKmHmtF1+6hGk3SxyYl3vSwMmk39EC?5f>R;dF^ zMPWU|2e>eSOtYF~FczUQ*o*tsVFsE^~8BJGOxkIVLZXh36I{P?uZl0CpkgNZvJs^7B8v$KOzp0BLM*K{XNo zDkwyyaBm-eSMNLOfTG#$eI^79g_rK}^e*}Y31WYdzmkXpM|DhF_K>`7eVKhP4phx1 z%a+R)@A9{ud~vK?aKXqwzf?z&4!rz>J(A_1PORDQ4#dJWtJ&|yYzK}L#d0uOz(X9X zAO}h*W>o4a#OrTxvadM&zCd!|XpTGb;%n!f?OZfJGhK6yhV5Bt}gT7$hjNi|!iHO{>uAwxIX}ODfve3={vKWifK8~Z%<`DlB zmECS!`iN{$C^TA{AqRhjuU1L(Bt|ryafJ+V;H^*}*db1}NlMtx-s#x5jJSo_t_)!7F2M!4yNVW&ZfbF*Lsj#f}n`;=bd~lo6heFBQAlfKfJM^$z zu-!vdM87e#k@a8MBh(m~aVYEo;}J5H53dBX*g7oO8-99ZvrPMKdPFC-T>VM& zz+I^wXJlVFkp$aV-b5G%6Kf_oUK191(>~7~HwFBw?VtbCfdsR$J2ZWW1c_C5KSICSL}*2%_D2{;Aq@be zQhB5hB|L}ud4(%iF*r@LLP&|{uq+KyB11GhOUFG*W|XEdSmU=xS;j(R)`a%r#3;9iVpPR7AzIY>&dW+rzFD(r;;5;qdKDh z*P}?MQs8$l^pLE(A=QOS@rwmo2&m44KqZy^Og5a{eUMBe%5kBWp1BCs zg53G(FM-}Ie!L%soeZ5+{}qJe8!2^t4W3vs-fy#yhg5tCLR@g5-yDQENaq&^VOA$6 zcHZ*)-mCjjY4TfG7Z)7Vy-cB4rBEoQQ2L-u1%)C2rNY#0;GfSxj4);3AIw4k6|rcE b5btd>YSbm!B?)Dj`3VZsW$8OlVI2MjA`fB; diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 06caf6119bea69b895da6b8f025f0147d66db725..98f61cc28ac443f8df43a1443ed6d1e1c7605ada 100644 GIT binary patch delta 1888 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 diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index b7150f9c4c350640c84ef908d233c9c9618f2dc4..2f97d122a1fa00b289b156b348c1109b333a669a 100644 GIT binary patch delta 158 zcmZqr#n|+Val=+dHVz&h9uAhtyBPyCw1iVDQj<$dQsYaC67z}^lS?x5^BA=G(lYZB zb25ulVbt5aUSloe=5(+1{F7s}>=<y9*D-Gvi#ou!`Lf3p#?99<`h}VD KizcVn%mx6-&NtHl delta 158 zcmZqr#n|+Val=+dHXa@x77mWdyBPyCG=)Vbs~YUSloeWNs@vM!m@aR&tXQtk^c^ zS;;ao>Td3_o+b(uRSql!a;65_F*E9Iz7n#Id9zdc6voXlTI=~YH$@!a+k7pfUzn*V Je{y=wYyec_HfjI> diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index e7533bbd880e220b5de92621dde2562f93cf6e01..37b28089b85847e3d3229679fa594ebc09d3b7c7 100644 GIT binary patch delta 157 zcmccgi}BJg#tkPK**JK3csN)lpJy!7&=pRtNKGy+NsTWlO3W)xOfJdH&tuTzOUukl z%*iZHjZezSPtIo0-<->|T9wgovZTfiAbCkchtY8Je~q<_o40$d=byYr%Z|}t@<%PX zNzrVZ`L$&k8Fe=6>P!;_3LbGR1ai!r?3fu1HkZ1tW8Rz=b%1ZPvgZ`W&1#wb!c6%^ JlegE*1^^XyH#h(Q delta 158 zcmccgi}BJg#tkPK*?4$(SU5N)pJy!7&=F3pNKGy+NsTWlO3W)xOfJdH&tuT#OUukl z%*iZHjZezSPtIo0+nmd^T9r|MvZTfiAbCkchf#m?e~q<_lcTNd7!4;cu#%g+!HRA3 zJ}X&9MuW|Ftfz?rMT-Lqft;s-cFc^1n^i*BF>jufK811f8m;yGn=eHi;M=U0*)Pmg Kls|cU&1?X1FFDKr From d11f5ca24ac8167f440ae55de649e4a9cb529e00 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 16 Mar 2018 15:30:41 +0100 Subject: [PATCH 16/29] Use match for Id --- demo/runtime/src/dispatch.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/demo/runtime/src/dispatch.rs b/demo/runtime/src/dispatch.rs index 263b9fe725009..ab9231333813f 100644 --- a/demo/runtime/src/dispatch.rs +++ b/demo/runtime/src/dispatch.rs @@ -50,11 +50,12 @@ macro_rules! impl_dispatch { impl Id { /// Derive `Some` value from a `u8`, or `None` if it's invalid. fn from_u8(value: u8) -> Option { - use self::*; - let functions = [ - $( Id::$fn_name ),* - ]; - functions.iter().map(|&f| f).find(|&f| value == f as u8) + match value { + $( + $id => Some(Id::$fn_name), + )* + _ => None, + } } } @@ -154,11 +155,12 @@ macro_rules! impl_meta_dispatch { impl Id { /// Derive `Some` value from a `u8`, or `None` if it's invalid. fn from_u8(value: u8) -> Option { - use self::*; - let functions = [ - $( Id::$camelcase ),* - ]; - functions.iter().map(|&f| f).find(|&f| value == f as u8) + match value { + $( + $id => Some(Id::$camelcase), + )* + _ => None, + } } } From d228593608e0a793103a0d93d0d1ad3fe48fc32f Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 16 Mar 2018 16:14:27 +0100 Subject: [PATCH 17/29] Generic mix. --- demo/runtime/src/safe_mix.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index fb31f54221999..313ce7aa9a3ae 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -16,28 +16,26 @@ //! Means of mixing a series of hashes to create a single secure hash. -fn sub_mix(seeds: &[u64]) -> u64 { - (seeds[0] & seeds[1]) | (seeds[1] & seeds[2]) | (seeds[0] & seeds[2]) -} +use rstd::ops::{BitAnd, BitOr}; -/// 3x3 mixing. -pub fn mix33(seeds: &[u64]) -> u64 { - let mut working = [0u64; 3]; - for i in 0..3 { - working[i] = sub_mix(&seeds[i * 3..i * 3 + 3]); - } - sub_mix(&working) +fn sub_mix(seeds: &[T]) -> T where + T: BitAnd + BitOr + Copy +{ + (seeds[0] & seeds[1]) | (seeds[1] & seeds[2]) | (seeds[0] & seeds[2]) } /// 3x3 mixing. -pub fn mix(seeds: &[u64]) -> Result { +pub fn mix(seeds: &[T]) -> Result where + T: BitAnd + BitOr, + T: Default + Copy +{ let max_depth = (0..12) .scan(1, |a, _| { *a *= 3; Some(*a) }) .position(|v| seeds.len() == v) .ok_or(())?; assert!(max_depth <= 11); - let mut accum = [[0u64; 3]; 12]; + let mut accum = [[T::default(); 3]; 12]; for i in 0..seeds.len() / 3 { // first level: accum[0][i % 3] = sub_mix(&seeds[i * 3..i * 3 + 3]); From a90fbe3346a2cdd03ab12a613bb50b35401c26c9 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 16 Mar 2018 16:46:43 +0100 Subject: [PATCH 18/29] Integrate random beacon --- demo/runtime/src/runtime/system.rs | 72 ++++++++++++++++-------------- demo/runtime/src/safe_mix.rs | 33 ++++++++++++++ 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 1c6c74ae0d125..4992b22dcc0bf 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -22,25 +22,25 @@ use rstd::mem; use runtime_io::{print, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; use runtime_support::{Hashable, storage, StorageValue, StorageMap}; -use environment::with_env; use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Header, Log}; -use block::Block; +use block::{self, Block}; use transaction::UncheckedTransaction; use runtime::{staking, session}; use dispatch; +use safe_mix::mix_iter; storage_items! { - pub Nonce: b"sys:non" => default map [ AccountId => TxOrder ]; - pub BlockHashAt: b"sys:old" => required map [ BlockNumber => Hash ]; + pub Nonce get(nonce): b"sys:non" => default map [ AccountId => TxOrder ]; + pub BlockHashAt get(block_hash): b"sys:old" => required map [ BlockNumber => Hash ]; + RandomSeed get(random_seed): b"sys:rnd" => required Hash; + // The current block number being processed. Set by `execute_block`. + Number get(block_number): b"sys:num" => required BlockNumber; + ParentHash get(parent_hash): b"sys:pha" => required Hash; + Digest: b"sys:dig" => default block::Digest; } pub const CODE: &'static[u8] = b":code"; -/// The current block number being processed. Set by `execute_block`. -pub fn block_number() -> BlockNumber { - with_env(|e| e.block_number) -} - pub struct PrivPass; impl_dispatch! { @@ -62,16 +62,17 @@ pub mod internal { /// Deposits a log and ensures it matches the blocks log data. pub fn deposit_log(log: Log) { - with_env(|e| e.digest.logs.push(log)); + let mut l = Digest::get(); + l.logs.push(log); + Digest::put(l); } /// Actually execute all transitioning for `block`. pub fn execute_block(mut block: Block) { // populate environment from header. - with_env(|e| { - e.block_number = block.header.number; - e.parent_hash = block.header.parent_hash; - }); + Number::put(block.header.number); + ParentHash::put(block.header.parent_hash); + RandomSeed::put(calculate_random()); // any initial checks initial_checks(&block); @@ -94,17 +95,14 @@ pub mod internal { /// This doesn't attempt to validate anything regarding the block. pub fn execute_transaction(utx: UncheckedTransaction, mut header: Header) -> Header { // populate environment from header. - with_env(|e| { - e.block_number = header.number; - e.parent_hash = header.parent_hash; - mem::swap(&mut header.digest, &mut e.digest); - }); + Number::put(header.number); + ParentHash::put(header.parent_hash); + Digest::put(&header.digest); + RandomSeed::put(calculate_random()); super::execute_transaction(utx); - with_env(|e| { - mem::swap(&mut header.digest, &mut e.digest); - }); + header.digest = Digest::get(); header } @@ -112,19 +110,16 @@ pub mod internal { /// except state-root. pub fn finalise_block(mut header: Header) -> Header { // populate environment from header. - with_env(|e| { - e.block_number = header.number; - e.parent_hash = header.parent_hash; - mem::swap(&mut header.digest, &mut e.digest); - }); + Number::put(header.number); + ParentHash::put(header.parent_hash); + Digest::put(&header.digest); + RandomSeed::put(calculate_random()); staking::internal::check_new_era(); session::internal::check_rotate_session(); header.state_root = storage_root().into(); - with_env(|e| { - mem::swap(&mut header.digest, &mut e.digest); - }); + header.digest = Digest::get(); post_finalise(&header); @@ -176,9 +171,12 @@ fn final_checks(block: &Block) { let ref header = block.header; // check digest - with_env(|e| { - assert!(header.digest == e.digest); - }); + assert!(header.digest == Digest::get()); + + Number::kill(); + ParentHash::kill(); + RandomSeed::kill(); + Digest::kill(); // check storage root. let storage_root = storage_root().into(); @@ -192,6 +190,13 @@ fn post_finalise(header: &Header) { BlockHashAt::insert(&header.number, &header.blake2_256().into()); } +fn calculate_random() -> Hash { + let c = block_number() - 1; + mix_iter((0..81) + .map(|i| if c >= i { block_hash(c - i) } else { Default::default() }) + ) +} + #[cfg(feature = "std")] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { use primitives::hexdisplay::HexDisplay; @@ -231,7 +236,6 @@ mod tests { use runtime_support::StorageValue; use codec::{Joiner, KeyedVec, Slicable}; use keyring::Keyring::*; - use environment::with_env; use primitives::hexdisplay::HexDisplay; use demo_primitives::{Header, Digest}; use transaction::{UncheckedTransaction, Transaction}; diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index 313ce7aa9a3ae..6edf7dde49732 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -17,6 +17,7 @@ //! Means of mixing a series of hashes to create a single secure hash. use rstd::ops::{BitAnd, BitOr}; +use rstd::cmp; fn sub_mix(seeds: &[T]) -> T where T: BitAnd + BitOr + Copy @@ -29,6 +30,8 @@ pub fn mix(seeds: &[T]) -> Result where T: BitAnd + BitOr, T: Default + Copy { + Ok(mix_iter(seeds.iter().cloned())) + /* let max_depth = (0..12) .scan(1, |a, _| { *a *= 3; Some(*a) }) .position(|v| seeds.len() == v) @@ -52,8 +55,38 @@ pub fn mix(seeds: &[T]) -> Result where } } Ok(accum[max_depth][0]) + */ } +pub fn mix_iter(seeds: I) -> T where + T: BitAnd + BitOr, + T: Default + Copy, + I: Iterator +{ + let mut accum = [[T::default(); 3]; 13]; + let mut max_depth = 0; + for (i, seed) in seeds.enumerate() { + accum[0][i % 3] = seed; + let mut index_at_depth = i; + for depth in 0..13 { + if index_at_depth % 3 != 2 { + break; + } + index_at_depth /= 3; + + // end of the threesome at depth. + accum[depth + 1][index_at_depth % 3] = sub_mix(&accum[depth]); + max_depth = cmp::max(max_depth, depth + 1); + if max_depth == 12 { + break; + } + } + } + accum[max_depth][0] +} + + + #[cfg(test)] mod tests { use super::*; From d35272706a905cf266ea356a9005a1ee483a3c55 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 16 Mar 2018 17:36:08 +0100 Subject: [PATCH 19/29] Update binaries. --- .../release/demo_runtime.compact.wasm | Bin 162042 -> 162758 bytes .../release/demo_runtime.wasm | Bin 162096 -> 162810 bytes .../release/polkadot_runtime.compact.wasm | Bin 134847 -> 134847 bytes .../release/polkadot_runtime.wasm | Bin 134896 -> 134896 bytes .../substrate_test_runtime.compact.wasm | Bin 32002 -> 32002 bytes .../release/substrate_test_runtime.wasm | Bin 32082 -> 32082 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index ce845090eb5805afcc14c9453de6756cbb1c7ac3..c184149e4ef8842141223090addff0c7e472abfa 100644 GIT binary patch delta 50869 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 aw{O_7b91+NAH82QQYK0D0B$01RR0f;A9>>d diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm index ae31620083885842c32dcc791330acd3a86a1158..3ad2c281ee8d2e37d45bb74f6dc467a837b6f50d 100644 GIT binary patch delta 50863 zcmc(I3xHi!b@ti&KIcAW?qnXB%w%THy_3fb_SdoqvTdF+%?^}DHbMKu58qxL- z%spqXz4zK{uf6tKYd_DP-_-o>ziQIX%B>re<2dSyy1Ucoe|q%|O26|RrSB?tWkg5f zkw`j{iSP~oVhAVs!hf1T6=4$o%cipYhXfjs+S*#iWFm2`<2o6yRVoPp5kz9CR5YeG zt5m9Vx$ZAs)v)H~HLGsiw&rcywyfN^b>*sUYd39luCBdy?Z%bs*KS?&wrkdJTD8tu zS$7kHt5E9Hr=>!n{!Pnglu(IrB~j#?fOky)^1z7W~;Nhrd~OolTQ7GnmT>T zv{{pH>$yGk?uTpM@p3{p7uD?^BD;0e+oRU)Ju~v8R_E<)jMuB|!A`F}H`_^j&vfSI zlukbee&b@eKa|wmhZi^W~D;lv#Cw^Ju%%MmDC?fe^RX|#j=+r7ou*Lx`HX54s=kl=Oiy_2p~YNYhybM)uZDouTnq(36gj8?5tsywN&ukM@Sfc~9uv+|p$;+s2JHdUQ`HH=cV+chBocJetWN=Z?}p&Rf{Fe@3s)xe-tI>Wmw~OB6|6JV!I7 z`ctQ&q|;B0Dt%yXX-QvK6xsf~w61TlMhScR8r37EFZZ38*qbC3uv|_2QXwqq$Q`zd3CU+Ub%78}a*<1?{=v1@j%pje5G@bEZ3ATu^#p z!KtQsW}m(QX*Qki<2SMJPWU@#s9wbXyhJWuh%U`KZiAQT)jO5j;6{7(AfBGnt9S7^s6Y@BE_WNcC8itj zLZZJAr9|J~+ACDYh3ZeX_DLv;P;sW(-O4I8xCt)-z6!QIz?SSU)DRib^lFwp>IgLI zny@K}k$XrHlI~Q6RIh%7Aw0JcXRqFjoWSR*o`{n>mB}7a`4pdfR6bEOc-?3>i|E#m zs)90=*j&&8Eu{P1gsXC$t!~s!yQ;sSK#pGIrpS>*E}CY(ZTSc=IlYeI%6x}hV)!0; z&Ufy$&->)r=X}&Wi_XWCt6c`b!d%WpoqHVAxpA)4Ioa=;H-ZNREVZ@KId5PAl}0Y+ z6_;g+<%rY2*fDtzf?v5XbSR8q{0bz^;jhRXaNC9)=gD`fTY$<2OuKZ10+R?M^0*2=VpRfLVzOYW-B4UQ18|T z5MtOo7mA_5nvPYIwGi{vq2CC{M>i7YKb zhiK>!j|%Rff&z@zr5)I;gQs}~G5Le1c_;JbrI=1tsOVv59hF@aMJ4;8yz<&jQ5$!= zsl{q;#6`%ZN{&LCrMh9R@Y7w0_Pd&@7{*1cSa%Q7L0BQ0QIjH0U7I2x=9+iOUWogH z*Q*Idf{axF`I;IK>fOns5?*F~UPTrOJ%t2;kSNjsRGO3l?HJ11q4_jY7K}-CU|dOR zKMDqoQ4*1s^X7OLg`&b<0G9?J@9cH5<{>ejm>`6w_Q)T|rAdm;rVw|w6R3hG=qoc@oy zR8z-GV&WaonD}?M(Zoagz^|EVpw0jK6t&vFX_A_R^dFw2{sE8kC#(JX;A#H&DQe*O zvAiEiFQ2L&QOoz`y49Q2<0hvb5;SZohW-W30qy`(Ijkj zcenbT)6}ZMsm!t(ti$7K_y;<&0mvAl$ViRFF|U6NhFSe%@^?duDsvZ6+yG2~kN_`bOn&$tV-Oqw zqzVHN3;}^fG2-Mp3&4g{1}6cncps)0D5V6DAxN|;R)Gc}DbQdyQa(|Z5|K+m|!ajXvK_zi%T@xG8y0S1swECZ%< zl)Wzl0+NQ%hcX}_X$<`@K{5m+14XH(p{1$pig_cZLd`VTwvGe=%Xqgj00}9Xxq2iG zQ`2OjDYx0arQPwBDMwHqdP+R>XAlBRXtmVj~r0ZYW4Pz3^(nA;kFh-8@c zgRwMS7?nzxjw;m){6|w$;tm z-iX^~--u|x|L3#3!*|N(6to~TD8+@ASkDnP^m|*6BfYs9o(dQ+(FVsO zh|0Iypn~RPI!Na@#LVlraE#yK%Gf}$5uxrNBw5_KkpaxrKt-?(&EtR2BGQ~RCo~1% z$HsgI(7OHk7^{XV8CBv^o1n|OZvS*gj7+*{12@oRV0FPoj6|KZ^b?~v*iXzGyU7@3 zf^Jf0x(U=<&WI7->P5x?1{y65M#jKDTlHoHa>XDt9-(9qz}Tpgb+Ahnyn{`$ zA@UCP$cBV@i~d0770I;<6%34U&i-e<{R!CCLblQVI_`v!Z>>l34T|9n3&YXP4?Pt& z|4_QWXaZaQh~|f^vInCY*{~XRa9Y{?18n|s&#|4R=#F=f*Sw?~b{F7m(E)B{1Yk7?ZxI~aYzi;v_n=j(RzZ+Tmx)61M0 zjKezf7~5$myu#vdIu}xNMZN5DC~xD*L0!k8gQ7-#(?n2RK(m_YBJ_6xiqFVb2!Ge(6A}Q?GAYAAXk|Q>HJq^{z8wp|o2*R4?^@tSL2K@$ zy*-QnMi>9OQ74L#a3nH{Y2YO17?PgT$C*w1hao4dJ{}I{NAZZlElA4rFEl2mAu(O2 z&MCxTrh2uEuk|7~#sP408s{%#Ug8`CV%}~2o(7B3pr6BM_?>!DY5B4#Ma1cC-f%}h zitvhXF}yf(1al6=R-15CET$t-Fgm1+=2fF@0$QSFTHL5mgHo4fL7=DIZCG$WF-lL?+mXO5sd<+wy@ZXoUVYrcG+OykG7AFIg zmpBjjl086@Pi1P4pU@)sCX_aXR7Sy)=-F+UMQPvWwcqGDXJwnbNIn8yXfJU?ZPXdp z&`4ewqM=MMN`Iq-7fCtFwv;y1+y2a#Ua>;^J5^n-A_Q@!-*9m6)5HB8s7zRpN zHq2q6K}kT-n}w+$ND6phlOln|$z=~T4g{eh2l!plL%?@*44KuE{xMc=6efp)Uc%`< zNVcn_e~3(CG#WWOTL(uow*-ID3|=j}E~h}u$}5Bo$zYe-;!QP!+vu5D%vt3zt(RAs z*zsqgduB3W>dVPvLfCdG533_0Mz7JWuu@>j=QJR)CXB#(&Y5|XpKxPaJjFE$OMZ*A zb^&z-h&pOc0gg77NzikoaZ`)kJ1`o5csu$Z-gi78E|ALPLLD(Ke5*$VT_rlnG@YU} zu%Uz$SPRnL9Kqyf$%I?<}fc&darOwlA^GJ0Q=k3Vuy>~!0k6sc9r+4x&ev> z4U4%fqa-N||2x$VYhC>RQ|++U#d5V(Q0=S{XAX3ryJ;u`9-<3?UTS?|wlJ2w1dC_c zRuJo|0V<>o-`Rvx$q0cp21wCC%7|OEsR%$S4An!Vvxosk0Yeb@NlFH{W+(4=+yMvE7YQFTm=l z3}S6}V3~gkLk;;c<_={SBQgbMY`t{as!E9`K#N5wI*xilUQN9`osVGJ)XIa-)ANBG z!MSp%|LDhIR2=K2{xPdZYzOi51cOO3jVkT_P$M}Qw})bG^_k;M3SgN)$2k~?Bi*iw zj1vji833@JV3}Hv>T_D08fsM5qe}Otr>P~SucSLlr(Cca+XjAcQG03M1vBvW>;)&= z@Z7gd!Q0bsZ7NN_G*!CoEo}&W=q)GU_w)ocyo1wD` zSa&bgTsTLvoQmI@FC4}1+KaFxQToJ1v+?_bi!P31G9Cl&((@Oz*F}I8;s}7_F*8ew zA8$#Ycv<${dR>aqB2bQf*7&vGTWGwzT-$qy28|T);*L z>vt!_6XCKKj29kJ_=3)vg$PZ*L;Gx24DgO&3bdHG6&mg#9gBoG-tZLZcx!RIF}qTB zsNr`%e?@B%QB{7o4*hOd)8p1~xMT1#t7)RA2})$ai_1MO{F`<3{UN*X#<5%?%W$yz zjp7z2#LJ1mGoa@kX)9n`&9ZEx8!2Yf@VqezXgjp2GPdP#r46(f6w*q4SqiGT&Xj@5 z8;=_$U_eNJyC#$Q!^tcLbYfU(X+$C7cdN4B-2e>~2V>#i)9=pJk0VFkILREt3dvp( z>!q1`x?p3Q{g^B+Gnj8+FPa5Qz(P7buqZpmAJSB4|8iT^zfN1#yVz6bI=N*9NLM|y z21Zw0a?M9T0gU3&B8x>$%1D&07l%+pZPUd<4>GbeTZEtr-yJ%@Xh01I7%Su832@Tk zb#hlQ$*{^JDYS?Ihb}M(!F(yX0Bg$y(mx=Z#zrKY4@x@Wn$fO^An;3R#<5IzFJdbU z9Lq$7V`+fmoFpn7%Y?TbR3|*^SfZIsLU4K@k~Uy z-)w`%v8-V-IF=DWF@A#k;?m8byJ7%fQQ&O?QBUONxsj{UUi2?T-P6AW*Op;Kmhg(! z10rb#TZqfLLTp>cgr1flh1W_~$dUi)1$$3m(f~1{2CtNB(;x_raNHr$ zBy?C20Xzvz`_7GE{aW(V9%3j=vdBv&Op2cc_t^MZDYU$n&i{wEU{N>-|MHDD;UCq4 z#XqhIt+bP~Z>$B2e|!`EQ7u>unlOeYOmP!LpQgk0vlB5SP0o~jA}@^ zPz~eD%`S0JT_jU9nI5V$>Jg)T3c(J5P=f_s9?C!)mBY5cw!8?Hl%= zh37&pd^}c3oH5Hqq^ColunxWJ)X~NN2c_agIHvR`y`2Bbx#}ZkfA`1EQ+u;!Uoev4 z|9$?i&sDSi!8faSmQ$FwffcIno)zlWF!Yb+t?zvG$m`>H@B;OT>W%IG%D1Qwn(V)O zi~34Sxa)nVYqsdf{&mOk&+br*u?^_X4z(4fcPbZwe5X1ekFA}ug=uf6dd{yuNi9)t zDSi8%>3UCBN&AaxMhj*y-DmyNKd0{gz?F6T4t`Fhl)7Qx;m@mUw3^~Cd|Y(_&8o-M zZ3sPWLa{HZCjtD{7uDm5MVPpZW)}JPeo1*i>%Z;0s>wg{ZFN${b-mqOd(PEn7W%XH zt9h#1?|4bjy>Gu7PbZuyEDP0dGP@j~a)?1G>m|G=1n7OPwQfv>7H zkwT`=@A#TJG5uD^ToT%cn3%b9x#S3`YBNH~80lP2Hu&`M>^}YQrP@ zbuhTe|Mb_@O#iO0tAc9g`-N(}AAeHaIdeR+4a@k>%_U@b;wJm^Ne)5AV^yxxbNdUO zkoa`k8|cZ+@gILueRTTzLYF(~!t7M3bU#>u-A=iUHnj1r*>1PsPP(;_cMF$fd-mP+ z&+02mzeo9R{f2rlyE=g6;yg=A57HbPKX`>#cZ0>lRRh3-Ri*D%e!BJB1;VNJ?&# zKlE)iJK{a$`qTeaEvuafwZJugXcTP!^xyTbYDVpJ623c?pNJZ`6aCNqt6HUzzVID& zf$H&Z{EqrW%|wgt0)OgvF_Z9!OPO5GO6>WrTG7`DbB4dO+j{kmTD)PhWwt?DXn%O| zA?NnOBwESrba&DNSk=Pr$Qdp~s>bc~PdlU*L=SYMwQf74u528inT6pjbWYl><8DTz zn&dx!NOhdFvCze;x4K=n>ez0Ds!QXxf^fWyt@?uRsY_cMGSh4m?Wl9z#qaL86R znfiTuzNhwT{a&?i^B3~z_E;lpL2 z{)N9#a}q$@d0sZ<-~9{KshanF`WI+P)!|?JOZAr+vtpW{Ki}y8=9lWp0{TM>v0`8c zG`Vw7lG*DlPzQ|julkj`MYZ^cex*9QA>p%toErwy)=B8}oXAp))6@K^gi>@*HS{ zcBWV0nxyaX`(IQybo6k8ZjeT2TGL3*O}bbHIWOC?@3j9^Z&hlGfBCtjX`6S9hI^lO366B7~&VAyc{YY(Um7pszW>3ER+O6XnkH-#n^1 zixM8F>z78rv$7$!*X7a4AxCxjh75(-I|z9oVmxiaWM(`)3Hi%ukH?JFe~OQVY414`+%36@XJDE)Np{HZ>cKo>i>zk{o8`UGcQAeo1+vlKJ*xJo ziTPKkkCw`}vsjd5Jf3Hra zW;)7H&-2}v;flQ7Kk;St10+biBIf?iS7?^@efkyj74;VXo3E;atrv5yR(xKwnHz?; z4!tv)e$U>4FZ>0?i%VHQgM7njsOHzoIu zb<4BZ59b}3jB{JJl%D(IYSmvl|4U8r7X`3){g?hqscTEMU;ct%Y%Klc%kMInI!oK1 zm_kesJ@I$7*JaP~4o|^Op3ViS@ zAH+1Ncc5wVjw#&lpSGK+@0!9nT&$U3<$b2Qa|%y~b-Ep;$3_>GK6`+(!M{K7Dg1u& ztKXXPR8a87LY@|=$<12}gbj1BKzX<8!faD%^H&)sxAa&4av3WB(!ack$Zx2l2C+@Gz8z>t@oJ$Q{;yZ7vG4zg*!|E*8dU$+zvL#HD5wy_5KlucHFa9Z)0p9)7AL94wXU@j&C!e`f*wbGeM8mr6(shUM ziv1ooGoMDe#JAQNChxrjkRF%5BV@LY?A>=GfJHlukK3TR<5rK-fbwO7D7hmV4(+ zp6v7nq-cO4>6pl)r3IV4;kl)6K0BUgL;vmB<@E>V_Ufwv1-jLE;JoUaem=YS7dkX2DdvXtZ>>(b8d~p(z`sRp=k`2y2~b9Xy$+ zFj4mVOstOd4rVG3H}Bnk3c+gQ5l-@e8^dcrSHH_B&5Y1c1L zp1qv*8C>ngnTj+_n&)(Dqfu0qM!}k+(I};te)%3q;lOiW#_zIUt-!DUt7-V%|Eu4| z4GZ>u;rWRw!%hw|&`&|e&;R}2lcgv&K1xu9b{vFYVY{l-*GH?=*L|f&M&Aq6r~Ud% zYWd&)=ELfk_D!l7XbSY_G#vrcoAajMql2>} zgGvf1Y2QpYMsY@*0!&T30X<&&JQEkXOmc||vIx%gqQNULZSov=|D~V&=Lw~sp1-6h zhDfGXV2IKm>(JSX&0|B@JXTAmww5abKvGL$#J|9HH@F#5?7G6TfSh~6-Z3}6j%!6x zkd4Do!5Ju-E0O(UwbOwFS)y1hrU8ugmHzz26RyF*SMCvu$R0854U0Na9f9njROzRt z)Hnt~*p-81g(!A=aV3KM#d^PXW9!TTV;&vCzBTML!YtHMtZ~%BrNJ~|>Af$V+!ym) zPB(g;fFuG7S8i~Ko(awQMomhVN4dqN~gYZ zaxRIoPUCQ(macF#H`E^)v|&Y7P6&(23qosfT{e*=i zrm}VDb7EUNnqJz3A@VwM4)(mUsmN(9i$l+%Hp3DNnfilQsjjA2*hz3&)?&!|w?@^p z4}MWKO)j?%B#ZeV`C&N(VdXjd!I#uoD&{X$YEscIO=l}b2}@L>$fy(|R45`==m-&< zf`(eo;~WunwYnVn%fA9*`=3g0ADYRqCqK<|`{UqDb zJ60R=ZU-YPwhfbL!%2QThM`r=KQX4 zYV|WpzYXKP^-6Q7`30qC;_>fFV?T-CqjfhP7if)JUi|;o8oOZpr=z;vKP#dq;(bj- zpM=M*h{U)FUGSfa=sJL2iU_{tQH_l%{(GZ>XirqnLI@b9smuJ@m~KYsqcJ_%e^X3y z3GTP^y)v2@z7x~f0pn-lf?+{ie-fc1alwvq=fsvnW9R%_T(|k#5*qt|{K15tj>qQ_ zi%m9IYjL?l0duD?viXN72hUdbfNX?Uo0R zA>0RijNS5e*4v4k=YO+NO{#;bT?SJs`_z%uza^t4_n?5P-RIaNW42Vd3I`wRMBC)N zNIvF&C8JJJwf@T))l!kmMSizpA0DRVNWHap%0E4;x-x|D{tv7y$NUXhH35Q~ZC3ea z>`Sqouui-gS=5jDpUL4%V+>sw6#HYZY}YJjm?7n)1tovG%~Tq^P^f@rCZbR!H5O(-Q2z;NQyOFkL$;XJ>~)Z0W2EZ>BV8M+--?zmlVM$3?Ax%4*Q64A z8o^yTrT~!{l!;}0U)8Ginu+2s!`JaYGC{R9l!Z$cRbk*`zE`g%%uKoIfTwQ8zJak2 zDa%)oA9J&|oErbn>(z<=>8+}%w~UfK5H2(J9a>@t0D&l^3Ir2eLEG2}5228=OsDMOp;FfW)Z5?f@`P6_& zkYbnC1?BY|(s|fM4#6Y=?tDk#Ek-{ak_y+_-_WLRU;D1Q*H=oSeat9Kj`869PPjRX z4ofr~g>ie9*glTI^dekV0tICBQUt3=qL;3W7`+tXE*w3uuAa!K%1;4kH?AG&^0pUsKe_`aKf1gj+}9xyA%ycT0uLc5eW)f#3-)tX%|)?M z_+*O1nT9r8@I!R2ave;hkmQ)l8-pB6B-R)~UN`U*8Xhh#9>SWK*+vlOvM4;PbF&F1 zHD}utkJM!qCy$e~U|n42K8#B7T;CzCp(&69vPP1~VsLvqWQj75ZEks#in*sQg21nL zVTKT0gDcG-50g*DJXvL!!CXUfTVEwF0>}{^@IoM@kF_|QlZB{PCVe?S*Pj&f0XLKZ4R2UT=Oxo&L3`O=dZ|5Xgx*46?`ez+2)}P?LkYpQ?OZzE%JycIo2&mftaBp zn*;Z29-?Y=<~!6T4FAZ6e`24{$g|IR);@op!~!vvbxdc^vH$ltBgw)P5l3${VcBNF zj65WfWHU(8qs)p_MO>e0v?@0I;q6fo^rvFMepnNS(QKFZ4DLSmC!(Zu{<0PdIfS4v zWd+rS;u*xfB7Bi@ zTI`^#N{j3`#izW(&u0%mVpTyws-K zDO#*ByUN>NPJ+;I7~Ze z#JMvv0%T<4Y5md+MYajg8W`)$Stx2pKhZjfgup*eF2;%08b8)z;=)iGmTAIbd z_l~9c41QqHu}9Wy>uYeEKu{s?KAhLr5%Y>O%jOH5=ssY(>I<|rA#1^m4ke%F6sCjs?4#-Z2WM^Db-H26C z=`Of(2YYe)3;AWZVAFA%K%tNVbPe9k{a)lIEG{;hN`%IWvVl}Z&TQoA>fDU$+_1C= z65BC_jB4N(S~=~7iP3yJXjEWE$Ov&grT2p+>ri2tMk_QdC&S$a&WEY9vpiUY?Ar=_ zN#ahIB)N{|R&p6vPAtn})Q%n2*!zGJzx+F|E!PPyx5K51p>cUoMeyN31}2iZ85>>+ zPo&acY)7rJaM>Wj1^U=5V0%7fyCEEh+o4K(^#OJPEQ>uU&tCN}cw&40eDy6G@svFK zobTA@ckT0#eSXhAzi*#Eu+PKx`9u5sk$wKyK1b~HY5V+%ef~7=7C}*;^Na=j%s!vB z&!3YsjTn=4c?aVCxd@&|aQ!E)yJ0tpjKq1M%fK+)#A{FFPz4O!XdvvMf${YKUXKtv zH6c`4k-EhiW@IQRtf^ zgY?eDu*keAXDoenmcIINydUZK=_~$E1ilga8hHS5N}9*L6t7~0*YsN4DZV~?j;r*= zaLU--F{gn=D%)$q)hei+na)tne1-ATWH}|-?oNIHwqHR)#uZ6o(Dvl5(A?OcD@seC zd=f7uq}{1D`&4F+}%Z0K3s5JXu zP<$lhnQd&uy*~H;c;*!+E{?t-?nS{pbbnD%QinHEdtOQW|FiZJ7sKy+BeD}i<3qb( zwg97OxB>R^S}}YC!Mzsq|{dIc0cfHr4(0P5GAjc(i9&sF9d8w= zkySLcmG&wpmg)6WRbu$uDVx|Ve`uOQ7789M z9x?3YI*k@Ih z6U56-Ny8};{}fv0IkXIEe*^=zC++(lyi1FLxuymo?f1d9qou<&R*d__l?3sqPgq{) zU6$)Z5Qwj=4?*C6Wqk;e6`5dF*q{gP71bf_&w=mv)xhr}@lS%;&%w3h`vJTkv7RZ2 zqkII6-(`pg7s`xBc^I09ZA$-`9ip-_1YvMqt_lI5TcK%i36PN`!Z1EBiyZ+VJ6UcR zl6@Z(`7VeeDSZxe1RO)~{RrL)O@=hlmQx09*Hxl>uV z+@2)Y1xuj9jpkU4mp+MCjyjs5hlBNR;Z?DcO}T~G<;AHY3;{59OQ&;xu5xcPe97JH zVX#bA!<=>KMSwmUquwZBnFfdCY6=|g0m>Buv!dW22X2hc!{hcGw;e;$$Rb!>j2kel z<*-zH&b2a1m-HB_a;GIw;vP5@U}i$hcO#Nq2Ees@mIN03fm*-pn7aQbI z8zv!80tZ8R&Sm8Jtq%D2p_2^xwnQ^iT4Zg(0JKzC-T$>B`Bf0Z->}4@;qY-5 zX$HzT=8lO8Hmy-ml_4DY3!D9zlNyo-CkSn-qSbq7G9xYDgNn1S-!H%Zp!|Bc{QAT4 z>yOH>KQ6x#ITSAh!61LS9Q70Pii?N3yq}iA&y-((R(^f9{QC3qE3oG{PCWt;O2IAB z;V_*bX!Ce^pf0H()ocKgg;#1Ixqcbi`l#6tsE}}SLsU1=b%YlUVhxmKX;9C+X66HP zRPEN6Lie_B81#6s^DL40XyGvPuLUN$nQI9BY~)SYt&E zWV!;amRDw}wY1_dy8MwjY7-|qy1e@(-rzH7fzKoM;S^Q_ql;A?CQhMwdHie-#-wuM z>agM&E3O#aIZ;kq4V%Y9?GoB=9#!{Q;Iy{Hg;^WCs(2uKPjl(+zif)h$;Q&|znr6= zTv+u#&JAJL@`-g&X!zp(WD zo%iWy7MAXO-y)N_x%ABYZYAWJyPnWbEi9ez{-w5<8{Q8$f`BtHmD!qmXX)4Peqf4MhXK9dcn3)D^1=eBY`5yYK4JaQM7zW2ed zrpjayBxl0YO7-_#Q4Eis-9Jg#5r%`8f6eG<#aD7h@s%9RZ6CeI0)~$p7O-YOPax*) zh~OwpZa|soU|f3>Dai2_i9r_yaj?hhO;9}Ze1!dYM+6g7F>erlkcq=CbhCyX^Y-8> zbBPKekbMD%fKfuYRRP2;xz6&RzE9th7qIVF^ zxS>2qWNM6D)wM;!5YHie%BH&hN23wGdq^4LF^DVijN-OgAVShGQJJ*?J-o!nR3jiL zWOk5b5KF}P);qUsM}VFV<@4GWTxK=8kko)-+BaJPaKYY7a?5`n1XD(eXU zIAY|DA!urBE|xHF^E>R9)5q!Lt$Rg62n-wD_x}#d}@#G%QN!qb)L21 zf3wf$<9<3>JBItek9Duk)p&7 zV*ZrSgT%;WL_$&G(ss-{Akw})5iD(+IH>=a_fotXC@u3s8HhqKAbIV&6_2BG;+O@M ztEy8~RbIa)T-r9g2McuWbW_0`c4NO$o{RVP$C9!X1A=jfa5{H0z5S86T=>rI zc)UZ~fqO4bd?a+@V;)==YXjxT9a^;qQpMKRG|sk7nZ}5!DV75HqAY=mZ zsI|GVQ=o+~jH6;a1$qe6^`LAQZVgL7w_%8+{a4OVrx&5}x63t|G4DRvzealPR}Rso z8S-&^H+r;0gb>KBfJ1;mmn-MNo;#wcz+w;s9%Q1QG#Zf&Dsbj|ogKUq7=89m zKDlasmj!&lK6lEq&$-7weVSSL;z@4@+?yPqvb2O<`AK}}HO4#bcxCPpvyDgLRy2kg zxkDm%aETJYBiP*~sfa^HnYki9eIl=LNr~gWXwXRwShN!^{~ZHH#~^Wcmcb}ZZ^srR zY{NOamakpOVr4C*_Xf4Bs@xw?C-xH4injMkMX*cdm}C`?gZa{X{{&>2xd4)(*&-YW z-H9V61mN;41NeY_@~(T1L+-Ip-#+olV}XCjKJT^958Ed`87%Q1u}^$DSi&E(&msH# zEBh?|wSD;;`@G*i|JFV~Zl4eE3Aw`<26ED)hj46xH}K(gm%O6g&9`=q=%I>pxob}N z#sN@vChnO1UuyJXCFl0 zgQkWyda*N-rxG&)D-LFr#*T&>JL$a?2{d+;GcVX~!2M2SsAz1{UuE`(8e1^th#7@h z{DGq5E?<*8fS5FFUfd7_bseMTuHozMSU!~}skmg;P-<=lKbp*GMO>n}T{eIOw}n%e zlUR&}k{m_R*{+eVRA8f?@nrG+1o)|==!Sp6 z2bZ`_rY6{32|xMqC8|}u(?7ffCn)>;-!D<8B6P}9b=f42CI*yy2K>@~{0^Y1^V~Bq z7pDp?pSxA=LVxd4HC3JO|6r+_C&Lej+Znv*J8$ykPV>8$sk`-PVc%z$sp;`da7W-r zqdMW|lpgQ@_ChsX9rC*_QcLu}0)OpA>euQl|MItD&vP(1DSxha%vR9D{>pXA!=(=x z1m*bC!cU0eqNw1G3Vfmj(;d?tbL$Px0V9N4Z~P4xtDCX){M_}5M?c?piF!~Ep5_m2 zP$&4SFIDU9Jr(|UE>(+x9cCCl8?j@~FGB3*N{NWYZmyKTDObV1(?9z%!Tz}#Ias>6 zP7m#?xk7DLX}R*E4*bcz-QRwt;$29OU#S|}%^erGv{HyQcU<7uh@iXA|MivXMx?y% zDuoMQ{Q9>k-1TDe88U)=hKwNJ&We0@`%_lR`Obwa)zitLDK4hLb0_)T*Qg8h3sd}C z`8;^qKHQ}9`-pn;z9+9$G1Xk=e&rP+{?D&dOTm*A&dc$qTQ-iBFY3TxtfCUhuo72Z zFFg6q^}_Mn)`H`>L+^xsb*oz8KhUo}9q|0Bb!y2mThvrGXi-zyphb5ct3`nyExIZ| zyeX}hfN?Ww^j&zA8%GGKPwPv@Bzz=&oC*7C|EGlS%xNCO{X$OPjmP=*8V$Mc_w~A! zmsK@4R6u<|zvrLWq|ZUj+naDj-*W%eCSAx4FW~I&c+AXGp1-)jpWUptlZE@5^`+>6 z_2czlBJD@U>mvGbdyDQu$ZOGi*|7iFqIIloaH_r1D`;8Hq?mWVp+n>DApgn^{SG`1 zb?Ce;5f>W-CDwH6n^@wzI`vnPX!c}%x&LujcjEmCH_V{R8UD)+Go0w(o7c;b^69)@ z0|IfWJ?<6Vhwt=8$%74Dn*H(Ft`JQmM6+-FBt3zNP#}qWXmXe+87A_7IJu&%fhm<` zO`poL{5Mb4uXY4g4=>{Z4=UKOu3LLZ`f&G{COOqFoS;9VzPoSu1pPUsw(ToU)2$J? z12v1=%Ip?6=`TOyAUUHo0u1lm zsut$PU~u*wya*Q)7n%MuxXqPY|It)8xMGedD7RtTTh#RC&{W5tMb0N>4MqW{vw zb5`^h?WeL$7|vo0Ct1-JCXBYQU%_l5ct9Jt%LVE}jpySwefZ60 zLkh+y!{mDK+2&;U8R(jF<~dSzCdCCkcF2LF_4Mea#p}Y442Mh_!o@=$>MWKi#WhDE zuVNvK;%+8j7Rw-K2FMv`5illO(a?aPMi7f2z0ox2@bYcPpn(Q}!9{(tk_^jL_#}$W zfxXH>UY6xbb;@E;Zhh0}N4Gf^=F6>(nUQikL-QR~4@k^nel1qS1ro+V3YN?x9zM@f zQ*r%LAq8kcW^>pdap{LW27s-&XkKg$*0`_MbSm(qrm~ZPBk9U8CDw-d7{Hcn$%tO& z%IE=CIpI9Gd|V_&)<|DtvFKCwizZNx%rzYJHFf~gtqDSj!;1k;ou5`uule%#o|0|wU=sUc!v z&pMvY_NVM?#c=_7BHgdu*;3`sCRKmEz81=0z$8=;7xLJW%7=+@Mm?BZsO*L{VTXW) zvzhECfrCyIcEb@I_>g{B76O8V^JVELNH|~B2Pg!^tHZ9yo){c+#u@fXzFaNRQkIdj zXuOt03=3UhMIeVlRahSbNaAa?Rmy?&!WMVaL(=9^)n6zl1JYGp>8j{1xZxB@KwnIN4F9IUY!@tUh-5LqexX~gt| zveJTBo1ReCUIqjdP-9i?KMX9D{i%Yv(#1egq(Z0J{)B5gDoG&=E4x#DnZtqY8W+w7 zH5CO0S{iUYxK$&R+98rsVY?d3;xFb5q*NFx0RhRl&`MR?F8S^-WH%XNsj*fL`rlY2 z)1PpYlBI%ktA-wZEZgO#!fN3&bT(z?7cq7Fnlm=bj0CslLT)D}__w0~JTUdy%(2xVbiAfrN8 zSS15EmYo}5J7Pp3q6KN>=mh#G%A@gT2fYWnJG^8No;zG(G#7VHHDR$v+f#+(W$co4 z$3KAGP;$5kCo+%^Cxue}&OSY>h!aFjZW@P>!Av)WBgY!!5_UI~zgwek^UMW6Njp@L zUgxUZ1eP-lH=VSy$DksnM~2gd;BmL!kHOC~#4X7Sn1@5H#13O}u0MZXlEV9p&W}e? zC>9&RaE^f|NG{+>atbu>|8l-g7o|uVXx?Iukw>`k;W{&KT z49gFg^(K%Wq$MtxeQDHTqjjL2xYdsqAxPyh3Y`^%SQT6qBTC4`RAXLb^%>Yk`yyis z5x_7zV}LjY#6}V&=6uU*nj6TDL{($vWkN&RbtoMeVL6 zas&U37D*le<9Wgkv=P$RMvQ;$>W{pUet0crRi%0a_puQer^D`aoF{R61=}OX0-` z_L5RziIEHRq5&ZX24SU}c6Dl`_II5(71Ps5R~{iXc!vN&y7CB#pi=rn6I2YNg~|1p z%YPL2afMnaR=WH{6T49=E>yK_D-ZO_2CgRs@LwT}VP|Aj;+pl!3#k52&nyLtPj+gw3W$na&|Yu&~UOdX^Ncc=JMoH()qG zrtK0o+d7ySFapCai3vNSiGgq@OAp=Kx-4c(1siKZ4g>_E&B_hLx*!|3q?yhxJQ)Ce zU~uNcZN-3ppcOp}^$GKmd928b+HF{j@ya1vs*G2t$1z^P^{?TTNN8rvnuHfUqP?s{ ziO#~Vw?i?gAnYRT1Aj~fFq;TGxV~7B*!E&<_8EoSg=MJ$xL2MaJU zjSo+dM(M?eDdj|T^0*L+Rj~-6{a`bPEx=Yd8w1H~mYvH^sQGC)y-QJi9jGZDaGFdBGDvTN9}$`X8rsDzHF{8Kq<`PaNKEPM}8 zk*kupBAfsJLgcVvyV61$x$cQ@%8b45|4`(rB(6xo{l68tDv2xRo1rOnW@4JwC!Luf zMhDjjVqC@JL+G>T$Y(w$j4{^{OfO=Uh2}b#;uHIZkIdTJ-Dzs5+Ti*jv#6YA7%`3S z7tyfsC!&jsP!tSqxhRfs(22!MaPV5?J;B=$Sf%F_z$(2afpN{G>_EcV5It-AFh5R@ zaOue3b`(=^Woz6Ten0?Uy)N5o%w5^Kq-C*rBnWkY%UXk2 zRt0?=F>&VO1TlO%2||_7(K;~*BO~WpY!Dj7yg{`aCm7@E(w>jcJTER@;fuU9gk1+% zt9@KiQsq^Epo3vXBbc@`J}d?=@YiO3sHvC@=jkOz95mi*9@HXYh8&>U&ULe*tQkJJ zh1YVWSRX_6v1?+qKA43>(j3z9@M)QvDhS##6#$@~nRoymN;ZQ{dnb{n;0aF?nX3Ts;hS64-7l>ChDw+lt36AkNR#8rIeHw7!MmghAR63L}8}#Dj z(-O=d4@I1NY(&J7Ra_}`LmrFId0vGKf=t6nJC(dojxUN83MwYCl~QYY0=~k(fQyV% zVwkkx%3$RPqAYc`{f$4*7NMsdw05QZ0h{BXzZK!kM6%;Zo5DxJ;rhbKLPscj;j&(a zi-KHs<^pa4cOcqaM6frnV`${YZ0)hrRB8`Za5m;vOc&=>Ix*vI9o-t((mkd*q%p`s z<4M|f0P9RUfaVw$LLrnh)sUL6258<#u)(TH)Hbi!WrMqsKIeOUVyg5opGZCso3Fl) zcPgGjvv?wnC%MfJz$?YPPN)~?>>8mAhBCn%S&hV$)Pob)Y~i?HItYh4uKOToaguZ~~^UdkIjx;%oy@=VVp$P^dM>xJbFA6I$9raV!Xwr(P%CxagxXsPDmj%GO7J=jCgUmi!pFo&9&iZ9!hV`E_S%FYLFq7z%@-5}yRt%cX1XQ}Jv5gKE}nG`Evf-+^K5Jl2_FYm|BB~L~(;z^x^FoqC}t#f*Bm+46(>?Wx%wY3~R5d&eECB^$3Xzu5z~8qNqnti} z{Yjw#F&V~Z5e@!2GeT9v^Wzwu<30+|@~4{-vSKY{RG16QSsZ&p=tSDI$#h9$F@XcE8O*aV2Av|Xg>Y~yW6;6=hzX!#I8h@t1+xF!37{f6U*!x?)o>i5 zuDI>cxDzm@hD%4e85Ul4GH6R_!NrxJLr^(l2$)BBZb2|asNgCiDu)i``6)Qhb0aTC zAmTz)q|~vmIms5Mt5Z5{--KzH=L?N=;GmeM6v4E^Z8jL(g?H_1;hG5wV~biP3;eX9 zn9=5JH}<1*zbcmSt#9ApeLiA(=8u8jI62M_`AYXG(kq_7ZA-HNXRIV-GU##W%`#f& zR8P^{!4tC71ZL(3Az9;=kWuqiX$Lbypq+5F#hYs;c^?Z~MgW+Zr{3Z@VsZ)6YgzJL z2kBWaQ4uDh-$U*I5zv|p0f0`6Da{sTI|)5RE~OZi7ZAoyLiRJpi~_?L%5_QoQ)`@U z0@on_Pt6?0Sgik!Vq{tqZb5_hb9zc_5DEPlA?YIwffJmba=vRjEK;*YrDBN1O!x>} zV!RzfJ{{JFDY&Q-IIJME=>5Dx#ZnB!rEKtiR-tEgw}WwGsCeWmKeO0{^ju8@%3qez zAoL5HTLjUxACy;~ru{jYGsmKK1DW272M_k{XRF{H2Wu+*RRe(6T0l{6S7=4Qqg2cIKLwDP0N^c2C@|tJJO_6envZj03L%^VfG5K#0PcTqGu#uP zMaXqgP@DUVG)puQEDEgGvRotZ5CWZI;2{Ln1qARA!j7dypsMk(j|31?*0~hY0K|HY zDNHt9u^&nr=v?e+A>~*z65{fTJ=TIswVx}%14XrYCuOcPM2wNr7{r#sio%bl?vKSw zcYSU`0_2ER{nY0soQhQksVKz*uh;>ArVj^J_zv9?Y4w1&Mx;sa2R=WeDB^?Oi{=pV zacZ!<4|RxDY3?*=fQVaE4(@AofejKOQSdipp;T^Xk_(+>V}jwHDa7Hmp@ubv5#*Fv z@rDje+)z-Zhd;le>D_=P%uzH5CAZ*2(-)N9f6p1UjHx*C@U^Y#z9zMJ-*tbk(lNEz z-+GsN48d9NSMN)z2mR0cs$Jiq{KGy@8Qr1w&D^E#%I)htU4JI0cKE-3vu;s4_NA8V z$5rvE1sLq4BAqmKGrn+I@Ef1+Dbb5Wh&7D9!m)o%KO@F7JQ|TRw z{oWfoA@`1b-ltV#Qk}o=t^cGJDjX=f=QC@=D8Daf?X9HK8JW-@N1t{C(Csv$4=PDPZ#1k6TkB@HLa>F zps;0K{g|55aE!A22Od-Bo&Vgz>I+T|Rvump&pY9z>Kd4_hb?gIC4#^7H;Ph2K!@-gC$R(mC$H3#)sTPiNvVH=pf(*}yK(iJo6$7~{l2U8)aj4ZrgK*VK{K)p;F&du01Xh0FC+5rx=Ob-4%DTy z?lm`VbJuKKz13a0O^|)=Dt)mYt=rf9HhiU04edMkYJINKqmBN(EA=up>_5Fy-={|Q z-F}VUsN4e+(k&wy$HAJ2lS7H*!*b;~O;Y&C1b^@fJyQ?13O|bXx26+YZ`suf5Lk9GLfPGf2C=SJ(0QAFnvX~wCGj)9iv4eP> zQ4xC=-cfBd+)J%lQ~JhD8^N?T|LfQ4lk{+#|LV1RLUg1peS-hb*XkC3&UL!+f;%Sy zRjuPptU&buvARG4}{Vn=`rzExPwN5j~WcEA35JuN!ek)GvutkGTPEm?cr znyuUV`mS5Et-A-LU_lzG9khcGoWzrV6i$j6gaiB-=}6}`gM@Yj>Htm&bhN|oU#;^q z20PQaJ&5fD^ase$A+bXh&>sQXE6_ci{y(kOU2_k1rt4R&+`Mwt+HJSEn{HaO<=XX| z-j023o#~c?Kt>y%iQ<8$ro5JY9y#Jx= zHFsAYydGa+&HK+?k8_g+zjv*kR$DLxZCDFo8ZG$GuhDbQ+tZa!Y+Jjb?TA(YPJP4h@HgRx@JDuEvP@9BCyZk%X;=|87C#7>kfU^ayqeU(~W&ww<5!c4Q#x58)&tGn}}-E23BoE z+q@VAR)Q}BQw)N)lSw;lV9Ofx_dy$2zY=+N*}%%pTPA?ADNwtpDiz_W5P&W`p?3XO z`}NcnPuZlauGxewk~VM?1JBsNW)k~c5OdvT$9usBR;~i&F9k8HkY{kJKe%3ZpZUmC zXohVo`_``kHILcA*3DqSejB)U4FXS2g)o7#lR?ldXl8PK3;v9#jZXDnU61XVd%7tu zt?q$tCK64pWbG`&%~Xt`!44z=>3oD^mR<-lO;fXL{1PVZ>JRVt0=rcg+?k z%RM%*eiLXP?zv~3o}x#4{Om^EbIGm~Ou~&@LH&>o+(ee|J^{TA+H)F8*@I^bo)6&9 zRAm^kR|C4ZBDR9`6a2e2>SgYp6Vok~;)VXXY1NjMt8Nj2I(VZ0!bUwy4@~o?Y|`EC z{nH?_;MlSXoUEuVahktzlYZ0bJEnsjNW}^VbPeO(uww|Z!-$<#5&NYuc6hq~pPTd? zJv!Z=wpmYEv~vb@EGpKG6hq@pbA1u-ro@L3I}GS_Kt}O|5fe6;4z_ic1;M-V%RSSslPtJxRKy0-kIE*|i0EKo5^ZYo>^8#WQAr{J$vGqdU zNEkhMl0R>Yp4l>dQaX3d%GK_+m0Mt&T=7^O@8C&(af@!&qbG^2(Ss-ZpV^`dde6!J zkGAMmeeh)ecYKbX>^E=KClq(hfjMlgCjWO~S$hyWj97|rP`TfSu?G-4G$!_yFm?p7 z1BgXU!o07Bu>+^1Cu~`>&Huty-J*w1@xQlKPjrV*Nw=(8xsjG1aS-=y@B%hYziHF9 zHCv!1Pw|_!;RA*Py(ku%yprR|(6H=6?7*1VnlN?`Vy{MQWsBE_u?Kp~tu+Dq9&Q2@ z#Yk_udF@8nowci7P*=Bl?dp}=*0@{OZ-UMnnCpKTMCqZq{x9&HH9R++97Su3LG}*J zJ-Q=|Al69u$lUb$up^w+3MDwN+!4A$sz&DdkKd?gyMw1f4v~3A1w(tnRC`YK$K9k) zai2k|0i^1xNHr}?HPGi@caxs#-rolqL#p12R9K<3x?s4^|I|&oPY=xZ{|%}2p80;m z+x1E5k@@M!)qO6^(tLl#+jSGK`nYKw^fHD~e+T7Q99WQ!_pQ8f+x300NekfRppD?2 zIB&+E)w&hXivZR5gQ8uKuA{o!y7JmJZ`-i;X4A@@!tP&MzpX7O} z0{SUHptxYBF(L&Ik(gSpY~o(1fcBwGqH?_Lr$ZW$mY(PUp0EbaSHT72^4@oPx!Ajr z2kauL{wr^XvpI6Q-+ePq{|zj(!v;OHkoMu4{R?3i)@R|3BMwO9AYNz-3rB_>v^Wy77D0wX$Y6wQ M;Bm*_xL$YsKj~DCL;wH) delta 50720 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 diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 3b267251ec32b559aee3cb8598ec0cbf112dcf50..f78d2e41c5e968d4b5c75eb607dd041953c5689b 100644 GIT binary patch delta 4900 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 delta 4878 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 delta 4801 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 BKWP8} diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index 2f97d122a1fa00b289b156b348c1109b333a669a..fef578011de16d6246949eda51da268e7898e977 100644 GIT binary patch delta 205 zcmZqr#n|+Val>Xt4n|fU9v%)Bj>)?j11vO!Q!7%FOG{GYONtWniW8GdGV}8owD{68 z^AdA1i&Nv1a`Kb28MHb17#SQHxH*hvB&6lVCDk`OGaXeD5MWSXRAA6xVgL~=0#cjV zRSz;T>P|kXz5_@$Y3MNOZeFi3hjB8ul^vtr85wmp_gIJVGiq#p z>}AgelvEBZ1d2@!>|q3oDFtt2WYpVyC1f4*<`}K@{F|N9r!a1Aia5Zx`C5jK2ms&| BJGTG; delta 205 zcmZqr#n|+Val>Xt4pv4E9v&VJmdU#r11z+JQ!7%FOG{GYONtWniW8GdGV}8owE5C9 z^AdA1i&Nv1a`Kb28FV=L7#SQHxH*hvB&6lVB{eoXGaXghEU9{ciBWIzE%hBha4$7tCx>P}v$B{z9P6x-(gTC$9cnw#%x zhw(G2Z#J>EX9G%>I2HoMo;mg~0>z4*H!?EnZdP?&$GllA>Hy#7ridwwo3CZ)hyVck Cygd#8 diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index 37b28089b85847e3d3229679fa594ebc09d3b7c7..75aa4eea906c20956146bb1765e4905739bdd124 100644 GIT binary patch delta 205 zcmccgi}BJg#tp|AIT%@acz8HiI3}NGEVIxNPOV5yE-guoFDXjQD^5%<$;{7V(B(_Z z%uCG4EKZG2%E?d8X3*p0V`Ok-;N~!smzGnKlF`~+%XC{wK!8DkQGr2&i2+2g2*_>@ zS3StYXfRn)V+WADq@lxTu=&5n9LCAfR(6brlNVUYP2OO|wt1hGEF+`-<~!D5{EXV0 zjlJ#JfRe?5g+Q^Vfjx{sv7+FOjEshxRYKP>Z(gIdo`3VC^eK#+FGU>S+pLzUBLV8chDEB{wOWZ8N{NEF+`NW?h{y zenzd$E!OsIK)EB1g+MVgryfS2*kR|5jEn}GOI_D7Z%&Ikz_ Date: Fri, 16 Mar 2018 18:09:06 +0100 Subject: [PATCH 20/29] Fixes relating to with_ext removal. --- demo/executor/src/lib.rs | 15 +- demo/runtime/src/runtime/council.rs | 130 +++++++++--------- demo/runtime/src/runtime/council_vote.rs | 50 +++---- demo/runtime/src/runtime/democracy.rs | 36 ++--- demo/runtime/src/runtime/session.rs | 22 +-- demo/runtime/src/runtime/staking.rs | 60 ++++---- demo/runtime/src/runtime/system.rs | 12 +- .../release/demo_runtime.compact.wasm | Bin 162758 -> 162981 bytes .../release/demo_runtime.wasm | Bin 162810 -> 163032 bytes polkadot/runtime/src/runtime/governance.rs | 18 +-- polkadot/runtime/src/runtime/session.rs | 22 +-- polkadot/runtime/src/runtime/staking.rs | 30 ++-- polkadot/runtime/src/runtime/system.rs | 9 ++ .../release/polkadot_runtime.compact.wasm | Bin 134847 -> 134847 bytes .../release/polkadot_runtime.wasm | Bin 134896 -> 134896 bytes 15 files changed, 213 insertions(+), 191 deletions(-) diff --git a/demo/executor/src/lib.rs b/demo/executor/src/lib.rs index 5c6b2748d7a76..a619d565a2a5d 100644 --- a/demo/executor/src/lib.rs +++ b/demo/executor/src/lib.rs @@ -46,7 +46,8 @@ mod tests { use demo_primitives::{Hash, Header, BlockNumber, Digest}; use demo_runtime::transaction::{Transaction, UncheckedTransaction}; use demo_runtime::block::Block; - use demo_runtime::runtime::staking::{self, FreeBalanceOf, balance}; + use demo_runtime::runtime::staking::{FreeBalanceOf, balance}; + use demo_runtime::runtime::{staking, system}; use demo_runtime::dispatch; use ed25519::{Public, Pair}; @@ -98,7 +99,8 @@ mod tests { fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t: TestExternalities = map![ twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8], + twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -114,7 +116,8 @@ mod tests { fn successful_execution_with_foreign_code_gives_ok() { let mut t: TestExternalities = map![ twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8], + twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -229,7 +232,8 @@ mod tests { fn panic_execution_gives_error() { let mut t: TestExternalities = map![ twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8], + twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm"); @@ -241,7 +245,8 @@ mod tests { fn successful_execution_gives_ok() { let mut t: TestExternalities = map![ twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8], + twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm"); diff --git a/demo/runtime/src/runtime/council.rs b/demo/runtime/src/runtime/council.rs index 6363764f1a2e3..a929a20769ad5 100644 --- a/demo/runtime/src/runtime/council.rs +++ b/demo/runtime/src/runtime/council.rs @@ -522,7 +522,7 @@ mod tests { fn basic_environment_works() { let mut t = new_test_ext(); with_externalities(&mut t, || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(next_vote_from(1), 4); assert_eq!(next_vote_from(4), 4); assert_eq!(next_vote_from(5), 8); @@ -554,7 +554,7 @@ mod tests { #[test] fn simple_candidate_submission_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(candidates(), Vec::::new()); assert_eq!(candidate_reg_info(*Alice), None); assert_eq!(candidate_reg_info(*Bob), None); @@ -590,7 +590,7 @@ mod tests { let mut t = new_test_ext_with_candidate_holes(); with_externalities(&mut t, || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(candidates(), vec![AccountId::default(), AccountId::default(), Alice.to_raw_public()]); PublicPass::test(&Bob).submit_candidacy(1); @@ -606,7 +606,7 @@ mod tests { let mut t = new_test_ext_with_candidate_holes(); with_externalities(&mut t, || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(candidates(), vec![AccountId::default(), AccountId::default(), Alice.into()]); PublicPass::test(&Bob).submit_candidacy(0); @@ -623,7 +623,7 @@ mod tests { let mut t = new_test_ext_with_candidate_holes(); with_externalities(&mut t, || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Dave).submit_candidacy(3); }); } @@ -632,7 +632,7 @@ mod tests { #[should_panic(expected = "invalid candidate slot")] fn bad_candidate_slot_submission_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(candidates(), Vec::::new()); PublicPass::test(&Alice).submit_candidacy(1); }); @@ -642,7 +642,7 @@ mod tests { #[should_panic(expected = "invalid candidate slot")] fn non_free_candidate_slot_submission_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(candidates(), Vec::::new()); PublicPass::test(&Alice).submit_candidacy(0); PublicPass::test(&Bob).submit_candidacy(0); @@ -653,7 +653,7 @@ mod tests { #[should_panic(expected = "duplicate candidate submission")] fn dupe_candidate_submission_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(candidates(), Vec::::new()); PublicPass::test(&Alice).submit_candidacy(0); PublicPass::test(&Alice).submit_candidacy(1); @@ -664,7 +664,7 @@ mod tests { #[should_panic(expected = "candidate has not enough funds")] fn poor_candidate_submission_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(candidates(), Vec::::new()); PublicPass::test(&One).submit_candidacy(0); }); @@ -673,7 +673,7 @@ mod tests { #[test] fn voting_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Eve).submit_candidacy(0); @@ -702,7 +702,7 @@ mod tests { #[test] fn resubmitting_voting_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Dave).set_approvals(vec![true], 0); @@ -720,7 +720,7 @@ mod tests { #[test] fn retracting_voter_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Bob).submit_candidacy(1); @@ -767,7 +767,7 @@ mod tests { #[should_panic(expected = "retraction index mismatch")] fn invalid_retraction_index_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Charlie).submit_candidacy(0); PublicPass::test(&Alice).set_approvals(vec![true], 0); PublicPass::test(&Bob).set_approvals(vec![true], 0); @@ -779,7 +779,7 @@ mod tests { #[should_panic(expected = "retraction index invalid")] fn overflow_retraction_index_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Charlie).submit_candidacy(0); PublicPass::test(&Alice).set_approvals(vec![true], 0); PublicPass::test(&Alice).retract_voter(1); @@ -790,7 +790,7 @@ mod tests { #[should_panic(expected = "cannot retract non-voter")] fn non_voter_retraction_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Charlie).submit_candidacy(0); PublicPass::test(&Alice).set_approvals(vec![true], 0); PublicPass::test(&Bob).retract_voter(0); @@ -800,7 +800,7 @@ mod tests { #[test] fn simple_tally_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); assert!(!presentation_active()); PublicPass::test(&Bob).submit_candidacy(0); @@ -809,7 +809,7 @@ mod tests { PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); assert!(presentation_active()); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); @@ -833,14 +833,14 @@ mod tests { with_externalities(&mut new_test_ext(), || { assert!(staking::can_slash(&Dave, 10)); - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Eve).submit_candidacy(1); PublicPass::test(&Bob).set_approvals(vec![true, false], 0); PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); @@ -854,21 +854,21 @@ mod tests { #[test] fn retracting_inactive_voter_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1); internal::end_block(); @@ -889,21 +889,21 @@ mod tests { #[should_panic(expected = "candidate must not form a duplicated member if elected")] fn presenting_for_double_election_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Bob).set_approvals(vec![true], 1); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1); }); } @@ -911,25 +911,25 @@ mod tests { #[test] fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1); internal::end_block(); - with_env(|e| e.block_number = 11); + system::testing::set_block_number(11); PublicPass::test(&Alice).submit_candidacy(0); PublicPass::test(&Eve).reap_inactive_voter( @@ -949,21 +949,21 @@ mod tests { #[should_panic(expected = "bad reporter index")] fn retracting_inactive_voter_with_bad_reporter_index_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 8, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Eve.into(), 38, 1); internal::end_block(); @@ -979,21 +979,21 @@ mod tests { #[should_panic(expected = "bad target index")] fn retracting_inactive_voter_with_bad_target_index_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 8, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Eve.into(), 38, 1); internal::end_block(); @@ -1008,7 +1008,7 @@ mod tests { #[test] fn attempting_to_retract_active_voter_should_slash_reporter() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Charlie).submit_candidacy(1); PublicPass::test(&Dave).submit_candidacy(2); @@ -1019,18 +1019,18 @@ mod tests { PublicPass::test(&Eve).set_approvals(vec![false, false, false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PrivPass.set_desired_seats(3); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1); PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 1); internal::end_block(); @@ -1051,21 +1051,21 @@ mod tests { #[should_panic(expected = "reaper must be a voter")] fn attempting_to_retract_inactive_voter_by_nonvoter_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Bob).set_approvals(vec![true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PublicPass::test(&Eve).submit_candidacy(0); PublicPass::test(&Eve).set_approvals(vec![true], 1); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1); internal::end_block(); @@ -1081,7 +1081,7 @@ mod tests { #[should_panic(expected = "candidate not worthy of leaderboard")] fn presenting_loser_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Alice).submit_candidacy(0); PublicPass::test(&Ferdie).set_approvals(vec![true], 0); PublicPass::test(&Bob).submit_candidacy(1); @@ -1094,7 +1094,7 @@ mod tests { PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); @@ -1106,7 +1106,7 @@ mod tests { #[test] fn presenting_loser_first_should_not_matter() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Alice).submit_candidacy(0); PublicPass::test(&Ferdie).set_approvals(vec![true], 0); PublicPass::test(&Bob).submit_candidacy(1); @@ -1119,7 +1119,7 @@ mod tests { PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0); PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); @@ -1139,7 +1139,7 @@ mod tests { #[should_panic(expected = "cannot present outside of presentation period")] fn present_panics_outside_of_presentation_period() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); assert!(!presentation_active()); PublicPass::test(&Eve).present_winner(Eve.into(), 1, 0); }); @@ -1149,14 +1149,14 @@ mod tests { #[should_panic(expected = "index not current")] fn present_panics_with_invalid_vote_index() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Bob).submit_candidacy(0); PublicPass::test(&Eve).submit_candidacy(1); PublicPass::test(&Bob).set_approvals(vec![true, false], 0); PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1); }); } @@ -1165,7 +1165,7 @@ mod tests { #[should_panic(expected = "presenter must have sufficient slashable funds")] fn present_panics_when_presenter_is_poor() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); assert!(!presentation_active()); PublicPass::test(&Alice).submit_candidacy(0); @@ -1174,7 +1174,7 @@ mod tests { PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); assert_eq!(staking::balance(&Alice), 1); PublicPass::test(&Alice).present_winner(Alice.into(), 30, 0); }); @@ -1183,7 +1183,7 @@ mod tests { #[test] fn invalid_present_tally_should_slash() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); assert!(!presentation_active()); assert_eq!(staking::balance(&Dave), 40); @@ -1193,7 +1193,7 @@ mod tests { PublicPass::test(&Eve).set_approvals(vec![false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Bob.into(), 80, 0); assert_eq!(staking::balance(&Dave), 38); @@ -1203,7 +1203,7 @@ mod tests { #[test] fn runners_up_should_be_kept() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); assert!(!presentation_active()); PublicPass::test(&Alice).submit_candidacy(0); @@ -1219,7 +1219,7 @@ mod tests { internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); assert!(presentation_active()); PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); assert_eq!(leaderboard(), Some(vec![ @@ -1262,7 +1262,7 @@ mod tests { #[test] fn second_tally_should_use_runners_up() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PublicPass::test(&Alice).submit_candidacy(0); PublicPass::test(&Ferdie).set_approvals(vec![true], 0); PublicPass::test(&Bob).submit_candidacy(1); @@ -1275,19 +1275,19 @@ mod tests { PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0); internal::end_block(); - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0); PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0); PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0); PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0); internal::end_block(); - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); PublicPass::test(&Ferdie).set_approvals(vec![false, false, true, false], 1); PrivPass.set_desired_seats(3); internal::end_block(); - with_env(|e| e.block_number = 10); + system::testing::set_block_number(10); PublicPass::test(&Dave).present_winner(Charlie.into(), 81, 1); PublicPass::test(&Dave).present_winner(Dave.into(), 31, 1); internal::end_block(); diff --git a/demo/runtime/src/runtime/council_vote.rs b/demo/runtime/src/runtime/council_vote.rs index cf35f58c31e58..9c51a3e352300 100644 --- a/demo/runtime/src/runtime/council_vote.rs +++ b/demo/runtime/src/runtime/council_vote.rs @@ -242,7 +242,7 @@ mod tests { #[test] fn basic_environment_works() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(staking::bonding_duration(), 0); assert_eq!(cooloff_period(), 2); assert_eq!(voting_period(), 1); @@ -274,7 +274,7 @@ mod tests { #[test] fn referendum_cancellation_should_work_when_unanimous() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); @@ -287,7 +287,7 @@ mod tests { assert_eq!(proposals(), vec![(2, hash)]); internal::end_block(1); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); internal::end_block(2); assert_eq!(democracy::active_referendums(), vec![]); assert_eq!(staking::bonding_duration(), 0); @@ -297,7 +297,7 @@ mod tests { #[test] fn referendum_cancellation_should_fail_when_not_unanimous() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); @@ -308,7 +308,7 @@ mod tests { PublicPass::new(&Charlie).vote(hash, false); internal::end_block(1); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); internal::end_block(2); assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); }); @@ -317,7 +317,7 @@ mod tests { #[test] fn referendum_cancellation_should_fail_when_abstentions() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove); @@ -327,7 +327,7 @@ mod tests { PublicPass::new(&Bob).vote(hash, true); internal::end_block(1); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); internal::end_block(2); assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); }); @@ -336,7 +336,7 @@ mod tests { #[test] fn veto_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); @@ -350,13 +350,13 @@ mod tests { #[should_panic] fn double_veto_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).veto(hash); - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).veto(hash); }); @@ -366,13 +366,13 @@ mod tests { #[should_panic] fn retry_in_cooloff_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).veto(hash); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); }); } @@ -380,19 +380,19 @@ mod tests { #[test] fn retry_after_cooloff_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).veto(hash); - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).vote(hash, false); PublicPass::new(&Charlie).vote(hash, true); internal::end_block(3); - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); internal::end_block(4); assert_eq!(proposals().len(), 0); assert_eq!(democracy::active_referendums(), vec![(0, 7, bonding_duration_proposal(42), VoteThreshold::SimpleMajority)]); @@ -402,13 +402,13 @@ mod tests { #[test] fn alternative_double_veto_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).veto(hash); - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Charlie).veto(hash); assert_eq!(proposals().len(), 0); @@ -419,7 +419,7 @@ mod tests { #[test] fn simple_propose_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); let hash = proposal.blake2_256(); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); @@ -433,13 +433,13 @@ mod tests { #[test] fn unvoted_proposal_should_expire_without_action() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); assert_eq!(tally(&proposal.blake2_256()), (1, 0, 2)); internal::end_block(1); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); internal::end_block(2); assert_eq!(proposals().len(), 0); assert_eq!(democracy::active_referendums().len(), 0); @@ -449,7 +449,7 @@ mod tests { #[test] fn unanimous_proposal_should_expire_with_biased_referendum() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).vote(proposal.blake2_256(), true); @@ -457,7 +457,7 @@ mod tests { assert_eq!(tally(&proposal.blake2_256()), (3, 0, 0)); internal::end_block(1); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); internal::end_block(2); assert_eq!(proposals().len(), 0); assert_eq!(democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SuperMajorityAgainst)]); @@ -467,7 +467,7 @@ mod tests { #[test] fn majority_proposal_should_expire_with_unbiased_referendum() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); PublicPass::new(&Alice).propose(Box::new(proposal.clone())); PublicPass::new(&Bob).vote(proposal.blake2_256(), true); @@ -475,7 +475,7 @@ mod tests { assert_eq!(tally(&proposal.blake2_256()), (2, 1, 0)); internal::end_block(1); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); internal::end_block(2); assert_eq!(proposals().len(), 0); assert_eq!(democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SimpleMajority)]); @@ -486,7 +486,7 @@ mod tests { #[should_panic] fn propose_by_public_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let proposal = bonding_duration_proposal(42); PublicPass::new(&Dave).propose(Box::new(proposal)); }); diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index d5e893d9f3445..df392e8a5bae1 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -372,7 +372,7 @@ mod tests { #[test] fn locked_for_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); propose_sessions_per_era(&Alice, 2, 2u64); propose_sessions_per_era(&Alice, 4, 4u64); propose_sessions_per_era(&Alice, 3, 3u64); @@ -385,11 +385,11 @@ mod tests { #[test] fn single_proposal_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); propose_sessions_per_era(&Alice, 2, 1u64); democracy::internal::end_block(system::block_number()); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); let r = 0; PublicPass::test(&Alice).vote(r, true); @@ -408,7 +408,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_taken() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); propose_sessions_per_era(&Alice, 2, 5u64); PublicPass::test(&Bob).second(0); PublicPass::test(&Eve).second(0); @@ -423,7 +423,7 @@ mod tests { #[test] fn deposit_for_proposals_should_be_returned() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); propose_sessions_per_era(&Alice, 2, 5u64); PublicPass::test(&Bob).second(0); PublicPass::test(&Eve).second(0); @@ -440,7 +440,7 @@ mod tests { #[should_panic] fn proposal_with_deposit_below_minimum_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); propose_sessions_per_era(&Alice, 2, 0u64); }); } @@ -449,7 +449,7 @@ mod tests { #[should_panic] fn poor_proposer_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); propose_sessions_per_era(&Alice, 2, 11u64); }); } @@ -458,7 +458,7 @@ mod tests { #[should_panic] fn poor_seconder_should_panic() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); propose_sessions_per_era(&Bob, 2, 11u64); PublicPass::test(&Alice).second(0); }); @@ -472,25 +472,25 @@ mod tests { #[test] fn runners_up_should_come_after() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 0); + system::testing::set_block_number(0); propose_bonding_duration(&Alice, 2, 2u64); propose_bonding_duration(&Alice, 4, 4u64); propose_bonding_duration(&Alice, 3, 3u64); democracy::internal::end_block(system::block_number()); - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PublicPass::test(&Alice).vote(0, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); assert_eq!(staking::bonding_duration(), 4u64); - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); PublicPass::test(&Alice).vote(1, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); assert_eq!(staking::bonding_duration(), 3u64); - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); PublicPass::test(&Alice).vote(2, true); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); @@ -505,7 +505,7 @@ mod tests { #[test] fn simple_passing_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); PublicPass::test(&Alice).vote(r, true); @@ -523,7 +523,7 @@ mod tests { #[test] fn cancel_referendum_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); PublicPass::test(&Alice).vote(r, true); PrivPass.cancel_referendum(r); @@ -538,7 +538,7 @@ mod tests { #[test] fn simple_failing_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); PublicPass::test(&Alice).vote(r, false); @@ -556,7 +556,7 @@ mod tests { #[test] fn controversial_voting_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); PublicPass::test(&Alice).vote(r, true); PublicPass::test(&Bob).vote(r, false); @@ -577,7 +577,7 @@ mod tests { #[test] fn controversial_low_turnout_voting_should_work() { with_externalities(&mut new_test_ext(), || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); PublicPass::test(&Eve).vote(r, false); PublicPass::test(&Ferdie).vote(r, true); @@ -597,7 +597,7 @@ mod tests { assert_eq!(staking::era_length(), 1u64); assert_eq!(staking::total_stake(), 210u64); - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); PublicPass::test(&Dave).vote(r, true); PublicPass::test(&Eve).vote(r, false); diff --git a/demo/runtime/src/runtime/session.rs b/demo/runtime/src/runtime/session.rs index 72180db2e4555..ea3bbcd43f780 100644 --- a/demo/runtime/src/runtime/session.rs +++ b/demo/runtime/src/runtime/session.rs @@ -183,46 +183,46 @@ mod tests { let mut t = simple_setup(); with_externalities(&mut t, || { // Block 1: Change to length 3; no visible change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); PrivPass.set_length(3); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 0); // Block 2: Length now changed to 3. Index incremented. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); PrivPass.set_length(3); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); // Block 3: Length now changed to 3. Index incremented. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); // Block 4: Change to length 2; no visible change. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); PrivPass.set_length(2); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); // Block 5: Length now changed to 2. Index incremented. - with_env(|e| e.block_number = 5); + system::testing::set_block_number(5); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 2); // Block 6: No change. - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 2); // Block 7: Next index. - with_env(|e| e.block_number = 7); + system::testing::set_block_number(7); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 3); @@ -234,17 +234,17 @@ mod tests { let mut t = simple_setup(); with_externalities(&mut t, || { // Block 1: No change - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); check_rotate_session(); assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); // Block 2: Session rollover, but no change. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); check_rotate_session(); assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); // Block 3: Set new key for validator 2; no visible change. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); PublicPass::test(&[20; 32]).set_key([22; 32]); assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); @@ -252,7 +252,7 @@ mod tests { assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); // Block 4: Session rollover, authority 2 changes. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); check_rotate_session(); assert_eq!(consensus::authorities(), vec![[11u8; 32], [22u8; 32]]); }); diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index eb0521812f98e..f719120a5b4fc 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -571,7 +571,7 @@ mod tests { use keyring::Keyring::*; use environment::with_env; use demo_primitives::AccountId; - use runtime::{staking, session}; + use runtime::{staking, session, system}; use runtime::system::PrivPass; use runtime::staking::public::{Call, Dispatch}; use runtime::staking::privileged::{Call as PCall, Dispatch as PDispatch}; @@ -600,7 +600,7 @@ mod tests { assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); // Block 1: Add three validators. No obvious change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::Call::stake().dispatch(PublicPass::new(&Alice)); PublicPass::new(&Bob).stake(); PublicPass::new(&Dave).stake(); @@ -608,39 +608,39 @@ mod tests { assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); // Block 2: New validator set now. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); check_new_era(); assert_eq!(session::validators(), vec![Dave.to_raw_public(), Bob.into()]); // Block 3: Unstake highest, introduce another staker. No change yet. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); PublicPass::new(&Charlie).stake(); PublicPass::new(&Dave).unstake(); check_new_era(); // Block 4: New era - validators change. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); check_new_era(); assert_eq!(session::validators(), vec![Charlie.to_raw_public(), Bob.into()]); // Block 5: Transfer stake from highest to lowest. No change yet. - with_env(|e| e.block_number = 5); + system::testing::set_block_number(5); PublicPass::new(&Dave).transfer(Alice.to_raw_public(), 40); check_new_era(); // Block 6: Lowest now validator. - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); check_new_era(); assert_eq!(session::validators(), vec![Alice.to_raw_public(), Charlie.into()]); // Block 7: Unstake three. No change yet. - with_env(|e| e.block_number = 7); + system::testing::set_block_number(7); PublicPass::new(&Charlie).unstake(); check_new_era(); assert_eq!(session::validators(), vec![Alice.to_raw_public(), Charlie.into()]); // Block 8: Back to one and two. - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); check_new_era(); assert_eq!(session::validators(), vec![Alice.to_raw_public(), Bob.into()]); }); @@ -661,21 +661,21 @@ mod tests { assert_eq!(CurrentEra::get(), 0u64); // Block 1: No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); check_new_era(); assert_eq!(SessionsPerEra::get(), 2u64); assert_eq!(LastEraLengthChange::get(), 0u64); assert_eq!(CurrentEra::get(), 0u64); // Block 2: Simple era change. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); check_new_era(); assert_eq!(SessionsPerEra::get(), 2u64); assert_eq!(LastEraLengthChange::get(), 0u64); assert_eq!(CurrentEra::get(), 1u64); // Block 3: Schedule an era length change; no visible changes. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); PrivPass.set_sessions_per_era(3); check_new_era(); assert_eq!(SessionsPerEra::get(), 2u64); @@ -683,28 +683,28 @@ mod tests { assert_eq!(CurrentEra::get(), 1u64); // Block 4: Era change kicks in. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); check_new_era(); assert_eq!(SessionsPerEra::get(), 3u64); assert_eq!(LastEraLengthChange::get(), 4u64); assert_eq!(CurrentEra::get(), 2u64); // Block 5: No change. - with_env(|e| e.block_number = 5); + system::testing::set_block_number(5); check_new_era(); assert_eq!(SessionsPerEra::get(), 3u64); assert_eq!(LastEraLengthChange::get(), 4u64); assert_eq!(CurrentEra::get(), 2u64); // Block 6: No change. - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); check_new_era(); assert_eq!(SessionsPerEra::get(), 3u64); assert_eq!(LastEraLengthChange::get(), 4u64); assert_eq!(CurrentEra::get(), 2u64); // Block 7: Era increment. - with_env(|e| e.block_number = 7); + system::testing::set_block_number(7); check_new_era(); assert_eq!(SessionsPerEra::get(), 3u64); assert_eq!(LastEraLengthChange::get(), 4u64); @@ -714,7 +714,7 @@ mod tests { #[test] fn staking_balance_works() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 42); assert_eq!(FreeBalanceOf::get(*Alice), 42); assert_eq!(ReservedBalanceOf::get(*Alice), 0); @@ -738,7 +738,7 @@ mod tests { #[test] #[should_panic] fn staking_balance_transfer_when_bonded_panics() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); PublicPass::new(&Alice).stake(); PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); @@ -747,7 +747,7 @@ mod tests { #[test] fn reserving_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); assert_eq!(balance(&Alice), 111); @@ -765,7 +765,7 @@ mod tests { #[test] #[should_panic] fn staking_balance_transfer_when_reserved_panics() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 69); PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69); @@ -774,7 +774,7 @@ mod tests { #[test] fn deducting_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); assert!(deduct_unbonded(&Alice, 69)); assert_eq!(FreeBalanceOf::get(*Alice), 42); @@ -788,7 +788,7 @@ mod tests { twox_128(&BondageOf::key_for(*Alice)).to_vec() => vec![].and(&2u64) ]; with_externalities(&mut t, || { - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); assert_eq!(unlock_block(&Alice), LockStatus::LockedUntil(2)); assert!(!deduct_unbonded(&Alice, 69)); }); @@ -796,7 +796,7 @@ mod tests { #[test] fn refunding_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 42); refund(&Alice, 69); assert_eq!(FreeBalanceOf::get(*Alice), 111); @@ -805,7 +805,7 @@ mod tests { #[test] fn slashing_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 69); assert!(slash(&Alice, 69)); @@ -816,7 +816,7 @@ mod tests { #[test] fn slashing_incomplete_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 42); reserve_balance(&Alice, 21); assert!(!slash(&Alice, 69)); @@ -827,7 +827,7 @@ mod tests { #[test] fn unreserving_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); unreserve_balance(&Alice, 42); @@ -838,7 +838,7 @@ mod tests { #[test] fn slashing_reserved_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); assert!(slash_reserved(&Alice, 42)); @@ -849,7 +849,7 @@ mod tests { #[test] fn slashing_incomplete_reserved_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 42); assert!(!slash_reserved(&Alice, 69)); @@ -860,7 +860,7 @@ mod tests { #[test] fn transferring_reserved_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 111); assert!(transfer_reserved_balance(&Alice, &Bob, 42)); @@ -873,7 +873,7 @@ mod tests { #[test] fn transferring_incomplete_reserved_balance_should_work() { - with_externalities(&mut TestExternalities::default(), || { + with_externalities(&mut testing::externalities(1, 3, 1), || { FreeBalanceOf::insert(*Alice, 111); reserve_balance(&Alice, 42); assert!(!transfer_reserved_balance(&Alice, &Bob, 69)); diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 4992b22dcc0bf..598c2aa5a91b2 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -222,9 +222,16 @@ pub mod testing { pub fn externalities() -> TestExternalities { map![ - twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode() + twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode(), + twox_128(Number::key()).to_vec() => 1u64.encode(), + twox_128(ParentHash::key()).to_vec() => [69u8; 32].encode(), + twox_128(RandomSeed::key()).to_vec() => [0u8; 32].encode() ] } + + pub fn set_block_number(n: BlockNumber) { + Number::put(n); + } } #[cfg(test)] @@ -247,7 +254,8 @@ mod tests { fn staking_balance_transfer_dispatch_works() { let mut t: TestExternalities = map![ twox_128(&staking::FreeBalanceOf::key_for(*One)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TransactionFee::key()).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0] + twox_128(staking::TransactionFee::key()).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0], + twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode() ]; let tx = UncheckedTransaction { diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index c184149e4ef8842141223090addff0c7e472abfa..36a582957021e09d5138b933597ba47f6cf18d29 100644 GIT binary patch delta 32330 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 delta 32220 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 JzP~n0Eq}#o5M7(BIicI~M&l#Yyqj0{_U_y8LK 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 M$!oWE-X!(^3%VoeL;wH) diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm index 3ad2c281ee8d2e37d45bb74f6dc467a837b6f50d..a68f147497812000bf00b8030fc78864e63045b7 100644 GIT binary patch delta 32556 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 A0{{R3 diff --git a/polkadot/runtime/src/runtime/governance.rs b/polkadot/runtime/src/runtime/governance.rs index 9138a3eddfee7..80620d578f857 100644 --- a/polkadot/runtime/src/runtime/governance.rs +++ b/polkadot/runtime/src/runtime/governance.rs @@ -189,7 +189,7 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Approve it. Era length changes. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); public::approve(&two, 1); staking::internal::check_new_era(); @@ -212,13 +212,13 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Fail it. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); staking::internal::check_new_era(); assert_eq!(staking::era_length(), 1); // Block 2: Make proposal. Approve it. It should change era length. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); public::approve(&two, 2); staking::internal::check_new_era(); @@ -241,7 +241,7 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Will have only 1 vote. No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); staking::internal::check_new_era(); assert_eq!(staking::era_length(), 1); @@ -264,7 +264,7 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Will have only 1 vote. No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); public::approve(&two, 0); staking::internal::check_new_era(); @@ -288,7 +288,7 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Will have only 1 vote. No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); public::approve(&two, 1); public::approve(&two, 1); @@ -313,7 +313,7 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Will have only 1 vote. No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); public::propose(&two, &Proposal::StakingSetSessionsPerEra(2)); staking::internal::check_new_era(); @@ -337,7 +337,7 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Will have only 1 vote. No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::approve(&two, 1); staking::internal::check_new_era(); assert_eq!(staking::era_length(), 1); @@ -361,7 +361,7 @@ mod tests { assert!(!session::validators().into_iter().position(|v| &v == &one).is_none()); // Block 1: Make proposal. Will have only 1 vote. No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); public::propose(&one, &Proposal::StakingSetSessionsPerEra(2)); public::approve(&four, 1); staking::internal::check_new_era(); diff --git a/polkadot/runtime/src/runtime/session.rs b/polkadot/runtime/src/runtime/session.rs index 01a5f78bbc5a0..4eb5bf50553b4 100644 --- a/polkadot/runtime/src/runtime/session.rs +++ b/polkadot/runtime/src/runtime/session.rs @@ -217,46 +217,46 @@ mod tests { let mut t = simple_setup(); with_externalities(&mut t, || { // Block 1: Change to length 3; no visible change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); set_length(3); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 0); // Block 2: Length now changed to 3. Index incremented. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); set_length(3); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); // Block 3: Length now changed to 3. Index incremented. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); // Block 4: Change to length 2; no visible change. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); set_length(2); check_rotate_session(); assert_eq!(length(), 3); assert_eq!(current_index(), 1); // Block 5: Length now changed to 2. Index incremented. - with_env(|e| e.block_number = 5); + system::testing::set_block_number(5); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 2); // Block 6: No change. - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 2); // Block 7: Next index. - with_env(|e| e.block_number = 7); + system::testing::set_block_number(7); check_rotate_session(); assert_eq!(length(), 2); assert_eq!(current_index(), 3); @@ -268,17 +268,17 @@ mod tests { let mut t = simple_setup(); with_externalities(&mut t, || { // Block 1: No change - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); check_rotate_session(); assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); // Block 2: Session rollover, but no change. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); check_rotate_session(); assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); // Block 3: Set new key for validator 2; no visible change. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); set_key(&[20; 32], &[22; 32]); assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); @@ -286,7 +286,7 @@ mod tests { assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]); // Block 4: Session rollover, authority 2 changes. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); check_rotate_session(); assert_eq!(consensus::authorities(), vec![[11u8; 32], [22u8; 32]]); }); diff --git a/polkadot/runtime/src/runtime/staking.rs b/polkadot/runtime/src/runtime/staking.rs index cca0a92718420..7ed94b920215e 100644 --- a/polkadot/runtime/src/runtime/staking.rs +++ b/polkadot/runtime/src/runtime/staking.rs @@ -310,7 +310,7 @@ mod tests { assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); // Block 1: Add three validators. No obvious change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); stake(&one); stake(&two); stake(&four); @@ -318,39 +318,39 @@ mod tests { assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]); // Block 2: New validator set now. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); check_new_era(); assert_eq!(session::validators(), vec![four.clone(), two.clone()]); // Block 3: Unstake highest, introduce another staker. No change yet. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); stake(&three); unstake(&four); check_new_era(); // Block 4: New era - validators change. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); check_new_era(); assert_eq!(session::validators(), vec![three.clone(), two.clone()]); // Block 5: Transfer stake from highest to lowest. No change yet. - with_env(|e| e.block_number = 5); + system::testing::set_block_number(5); transfer(&four, &one, 40); check_new_era(); // Block 6: Lowest now validator. - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); check_new_era(); assert_eq!(session::validators(), vec![one.clone(), three.clone()]); // Block 7: Unstake three. No change yet. - with_env(|e| e.block_number = 7); + system::testing::set_block_number(7); unstake(&three); check_new_era(); assert_eq!(session::validators(), vec![one.clone(), three.clone()]); // Block 8: Back to one and two. - with_env(|e| e.block_number = 8); + system::testing::set_block_number(8); check_new_era(); assert_eq!(session::validators(), vec![one.clone(), two.clone()]); }); @@ -369,21 +369,21 @@ mod tests { assert_eq!(current_era(), 0u64); // Block 1: No change. - with_env(|e| e.block_number = 1); + system::testing::set_block_number(1); check_new_era(); assert_eq!(sessions_per_era(), 2u64); assert_eq!(last_era_length_change(), 0u64); assert_eq!(current_era(), 0u64); // Block 2: Simple era change. - with_env(|e| e.block_number = 2); + system::testing::set_block_number(2); check_new_era(); assert_eq!(sessions_per_era(), 2u64); assert_eq!(last_era_length_change(), 0u64); assert_eq!(current_era(), 1u64); // Block 3: Schedule an era length change; no visible changes. - with_env(|e| e.block_number = 3); + system::testing::set_block_number(3); set_sessions_per_era(3); check_new_era(); assert_eq!(sessions_per_era(), 2u64); @@ -391,28 +391,28 @@ mod tests { assert_eq!(current_era(), 1u64); // Block 4: Era change kicks in. - with_env(|e| e.block_number = 4); + system::testing::set_block_number(4); check_new_era(); assert_eq!(sessions_per_era(), 3u64); assert_eq!(last_era_length_change(), 4u64); assert_eq!(current_era(), 2u64); // Block 5: No change. - with_env(|e| e.block_number = 5); + system::testing::set_block_number(5); check_new_era(); assert_eq!(sessions_per_era(), 3u64); assert_eq!(last_era_length_change(), 4u64); assert_eq!(current_era(), 2u64); // Block 6: No change. - with_env(|e| e.block_number = 6); + system::testing::set_block_number(6); check_new_era(); assert_eq!(sessions_per_era(), 3u64); assert_eq!(last_era_length_change(), 4u64); assert_eq!(current_era(), 2u64); // Block 7: Era increment. - with_env(|e| e.block_number = 7); + system::testing::set_block_number(7); check_new_era(); assert_eq!(sessions_per_era(), 3u64); assert_eq!(last_era_length_change(), 4u64); diff --git a/polkadot/runtime/src/runtime/system.rs b/polkadot/runtime/src/runtime/system.rs index c7972c949a131..935f801924594 100644 --- a/polkadot/runtime/src/runtime/system.rs +++ b/polkadot/runtime/src/runtime/system.rs @@ -264,6 +264,15 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { } } +#[cfg(any(feature = "std", test))] +pub mod testing { + use super::*; + + pub fn set_block_number(n: BlockNumber) { + with_env(|e| e.block_number = n); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index f78d2e41c5e968d4b5c75eb607dd041953c5689b..859227ad9c2f37caa913a02756cd5499a7603629 100644 GIT binary patch delta 5202 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 VVxpyyL0i^LlWPC~ delta 5156 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 diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index c94892e20e7acf4ef80ea6b5da5949015a728201..760b46ba1e6f6b20fc19b89c5632c63ead8d941e 100644 GIT binary patch delta 5194 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 UeLj*Hz)AN-l33C*oIyO{Uk~h`X8-^I delta 5211 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 From ff2fa3cfcfd0fe9b2dab9c4f3e7b912e60eec822 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 16 Mar 2018 18:13:53 +0100 Subject: [PATCH 21/29] Remove dead code. --- demo/runtime/src/environment.rs | 82 ------------------------ demo/runtime/src/lib.rs | 1 - demo/runtime/src/runtime/council.rs | 1 - demo/runtime/src/runtime/council_vote.rs | 1 - demo/runtime/src/runtime/democracy.rs | 1 - demo/runtime/src/runtime/session.rs | 1 - demo/runtime/src/runtime/staking.rs | 1 - 7 files changed, 88 deletions(-) delete mode 100644 demo/runtime/src/environment.rs diff --git a/demo/runtime/src/environment.rs b/demo/runtime/src/environment.rs deleted file mode 100644 index a5849d91d1a9d..0000000000000 --- a/demo/runtime/src/environment.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. -// This file is part of Substrate Demo. - -// Substrate Demo 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. - -// Substrate Demo 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 Substrate Demo. If not, see . - -//! Environment API: Allows certain information to be accessed throughout the runtime. - -use rstd::boxed::Box; -use rstd::mem; -use rstd::cell::RefCell; -use rstd::rc::Rc; - -use demo_primitives::{BlockNumber, Digest, Hash}; - -#[derive(Default)] -/// The information that can be accessed globally. -pub struct Environment { - /// The current block number. - pub block_number: BlockNumber, - /// The current block's parent hash. - pub parent_hash: Hash, - /// The current block digest. - pub digest: Digest, -} - -/// Do something with the environment and return its value. Keep the function short. -pub fn with_env T>(f: F) -> T { - let e = env(); - let mut eb = e.borrow_mut(); - f(&mut *eb) -} - -#[cfg(target_arch = "wasm32")] -fn env() -> Rc> { - // Initialize it to a null value - static mut SINGLETON: *const Rc> = 0 as *const Rc>; - - unsafe { - if SINGLETON == 0 as *const Rc> { - // Make it - let singleton: Rc> = Rc::new(RefCell::new(Default::default())); - - // Put it in the heap so it can outlive this call - SINGLETON = mem::transmute(Box::new(singleton)); - } - - // Now we give out a copy of the data that is safe to use concurrently. - (*SINGLETON).clone() - } -} - -#[cfg(not(target_arch = "wasm32"))] -fn env() -> Rc> { - // Initialize it to a null value - thread_local!{ - static SINGLETON: RefCell<*const Rc>> = RefCell::new(0 as *const Rc>); - } - - SINGLETON.with(|s| unsafe { - if *s.borrow() == 0 as *const Rc> { - // Make it - let singleton: Rc> = Rc::new(RefCell::new(Default::default())); - - // Put it in the heap so it can outlive this call - *s.borrow_mut() = mem::transmute(Box::new(singleton)); - } - - // Now we give out a copy of the data that is safe to use concurrently. - (**s.borrow()).clone() - }) -} diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index 44c5c181e4a65..00eb217e15b5d 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -41,7 +41,6 @@ extern crate integer_sqrt; pub mod safe_mix; pub mod block; pub mod transaction; -pub mod environment; pub mod runtime; pub mod api; diff --git a/demo/runtime/src/runtime/council.rs b/demo/runtime/src/runtime/council.rs index a929a20769ad5..53e12133f6d34 100644 --- a/demo/runtime/src/runtime/council.rs +++ b/demo/runtime/src/runtime/council.rs @@ -508,7 +508,6 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; use keyring::Keyring::*; - use environment::with_env; use demo_primitives::AccountId; use runtime::{staking, session, democracy}; use super::public::Dispatch; diff --git a/demo/runtime/src/runtime/council_vote.rs b/demo/runtime/src/runtime/council_vote.rs index 9c51a3e352300..49221da892ac9 100644 --- a/demo/runtime/src/runtime/council_vote.rs +++ b/demo/runtime/src/runtime/council_vote.rs @@ -228,7 +228,6 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; use keyring::Keyring::{Alice, Bob, Charlie, Dave}; - use environment::with_env; use demo_primitives::AccountId; use runtime::democracy::VoteThreshold; use runtime::{staking, council, democracy}; diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index df392e8a5bae1..07adb160c832d 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -338,7 +338,6 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; use keyring::Keyring::*; - use environment::with_env; use demo_primitives::AccountId; use dispatch::PrivCall as Proposal; use runtime::staking::PublicPass; diff --git a/demo/runtime/src/runtime/session.rs b/demo/runtime/src/runtime/session.rs index ea3bbcd43f780..841a181139d83 100644 --- a/demo/runtime/src/runtime/session.rs +++ b/demo/runtime/src/runtime/session.rs @@ -151,7 +151,6 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; use keyring::Keyring; - use environment::with_env; use demo_primitives::AccountId; use runtime::{consensus, session}; diff --git a/demo/runtime/src/runtime/staking.rs b/demo/runtime/src/runtime/staking.rs index f719120a5b4fc..799de127cef1d 100644 --- a/demo/runtime/src/runtime/staking.rs +++ b/demo/runtime/src/runtime/staking.rs @@ -569,7 +569,6 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; use keyring::Keyring::*; - use environment::with_env; use demo_primitives::AccountId; use runtime::{staking, session, system}; use runtime::system::PrivPass; From c674963683396710dc13b86237e5b1d66a72bc69 Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 17 Mar 2018 09:44:01 +0100 Subject: [PATCH 22/29] Rework mixer into an iterator adaptor. --- demo/runtime/src/runtime/system.rs | 6 +-- demo/runtime/src/safe_mix.rs | 81 ++++++++++++------------------ 2 files changed, 35 insertions(+), 52 deletions(-) diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 598c2aa5a91b2..5c9188737c6ae 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -27,7 +27,7 @@ use block::{self, Block}; use transaction::UncheckedTransaction; use runtime::{staking, session}; use dispatch; -use safe_mix::mix_iter; +use safe_mix::Mixed; storage_items! { pub Nonce get(nonce): b"sys:non" => default map [ AccountId => TxOrder ]; @@ -192,9 +192,9 @@ fn post_finalise(header: &Header) { fn calculate_random() -> Hash { let c = block_number() - 1; - mix_iter((0..81) + (0..81) .map(|i| if c >= i { block_hash(c - i) } else { Default::default() }) - ) + .mixed() } #[cfg(feature = "std")] diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index 6edf7dde49732..da74f19499733 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -25,68 +25,51 @@ fn sub_mix(seeds: &[T]) -> T where (seeds[0] & seeds[1]) | (seeds[1] & seeds[2]) | (seeds[0] & seeds[2]) } -/// 3x3 mixing. +/// Mix a slice. pub fn mix(seeds: &[T]) -> Result where T: BitAnd + BitOr, T: Default + Copy { - Ok(mix_iter(seeds.iter().cloned())) - /* - let max_depth = (0..12) - .scan(1, |a, _| { *a *= 3; Some(*a) }) - .position(|v| seeds.len() == v) - .ok_or(())?; - assert!(max_depth <= 11); - - let mut accum = [[T::default(); 3]; 12]; - for i in 0..seeds.len() / 3 { - // first level: - accum[0][i % 3] = sub_mix(&seeds[i * 3..i * 3 + 3]); - - let mut index_at_depth = i; - for depth in 0..12 { - if index_at_depth % 3 != 2 { - break; - } - index_at_depth /= 3; + Ok(seeds.iter().cloned().mixed()) +} - // end of the threesome at depth. - accum[depth + 1][index_at_depth] = sub_mix(&accum[depth]); - } - } - Ok(accum[max_depth][0]) - */ +/// The mixed trait for mixing a ssequence. +pub trait Mixed { + /// The items in the sequence and simultaneously the return of the mixing. + type Item; + /// The output of the mixing algorithm on the sequence. + fn mixed(self) -> Self::Item; } -pub fn mix_iter(seeds: I) -> T where - T: BitAnd + BitOr, - T: Default + Copy, - I: Iterator +impl Mixed for I where + I: Iterator, + T: BitAnd + BitOr + Default + Copy { - let mut accum = [[T::default(); 3]; 13]; - let mut max_depth = 0; - for (i, seed) in seeds.enumerate() { - accum[0][i % 3] = seed; - let mut index_at_depth = i; - for depth in 0..13 { - if index_at_depth % 3 != 2 { - break; - } - index_at_depth /= 3; - - // end of the threesome at depth. - accum[depth + 1][index_at_depth % 3] = sub_mix(&accum[depth]); - max_depth = cmp::max(max_depth, depth + 1); - if max_depth == 12 { - break; + type Item = T; + fn mixed(self) -> Self::Item { + let mut accum = [[T::default(); 3]; 13]; + let mut max_depth = 0; + for (i, seed) in self.enumerate() { + accum[0][i % 3] = seed; + let mut index_at_depth = i; + for depth in 0..13 { + if index_at_depth % 3 != 2 { + break; + } + index_at_depth /= 3; + + // end of the threesome at depth. + accum[depth + 1][index_at_depth % 3] = sub_mix(&accum[depth]); + max_depth = cmp::max(max_depth, depth + 1); + if max_depth == 12 { + break; + } } } + accum[max_depth][0] } - accum[max_depth][0] } - - #[cfg(test)] mod tests { use super::*; From 74a59b9b94695002aa73b7a8a44f69a30b137f1a Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 19 Mar 2018 13:52:40 +0800 Subject: [PATCH 23/29] Link to paper. --- demo/runtime/src/safe_mix.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index da74f19499733..50be35153c882 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -15,6 +15,8 @@ // along with Substrate Demo. If not, see . //! Means of mixing a series of hashes to create a single secure hash. +//! +//! Described in http://www.cs.huji.ac.il/~nati/PAPERS/coll_coin_fl.pdf use rstd::ops::{BitAnd, BitOr}; use rstd::cmp; From 23ca1b2d1a9f68032cac987dd0a84b9be0669956 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 19 Mar 2018 14:01:04 +0800 Subject: [PATCH 24/29] Algorithm cleanups --- demo/runtime/src/runtime/democracy.rs | 2 +- demo/runtime/src/runtime/system.rs | 8 -------- demo/runtime/src/safe_mix.rs | 20 ++++++++++++-------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/demo/runtime/src/runtime/democracy.rs b/demo/runtime/src/runtime/democracy.rs index 35fef2d5d444d..d3d4a098be647 100644 --- a/demo/runtime/src/runtime/democracy.rs +++ b/demo/runtime/src/runtime/democracy.rs @@ -535,7 +535,7 @@ mod tests { system::testing::set_block_number(1); let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove); PublicPass::test(&Alice).vote(r, true); - PrivPass.cancel_referendum(r); + PrivPass::test().cancel_referendum(r); democracy::internal::end_block(system::block_number()); staking::internal::check_new_era(); diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index d2a07c5658823..7f980457e63df 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -40,16 +40,8 @@ storage_items! { Digest: b"sys:dig" => default block::Digest; } -storage_items! { - pub Nonce: b"sys:non" => default map [ AccountId => TxOrder ]; - pub BlockHashAt: b"sys:old" => required map [ BlockNumber => Hash ]; -} - pub const CODE: &'static[u8] = b":code"; - -pub struct PrivPass; - impl_dispatch! { pub mod privileged; fn set_code(new: Vec) = 0; diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index 50be35153c882..d7e1495825911 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -19,7 +19,8 @@ //! Described in http://www.cs.huji.ac.il/~nati/PAPERS/coll_coin_fl.pdf use rstd::ops::{BitAnd, BitOr}; -use rstd::cmp; + +const MAX_DEPTH: usize = 17; fn sub_mix(seeds: &[T]) -> T where T: BitAnd + BitOr + Copy @@ -49,26 +50,29 @@ impl Mixed for I where { type Item = T; fn mixed(self) -> Self::Item { - let mut accum = [[T::default(); 3]; 13]; - let mut max_depth = 0; + let mut accum = [[T::default(); 3]; MAX_DEPTH]; + let mut result = T::default(); for (i, seed) in self.enumerate() { accum[0][i % 3] = seed; let mut index_at_depth = i; - for depth in 0..13 { + for depth in 0..MAX_DEPTH { if index_at_depth % 3 != 2 { break; } index_at_depth /= 3; + result = sub_mix(&accum[depth]); // end of the threesome at depth. - accum[depth + 1][index_at_depth % 3] = sub_mix(&accum[depth]); - max_depth = cmp::max(max_depth, depth + 1); - if max_depth == 12 { + if depth == MAX_DEPTH - 1 { + // end of our stack - bail with result. break; + } else { + // save in the stack for parent computation + accum[depth + 1][index_at_depth % 3] = result; } } } - accum[max_depth][0] + result } } From 1bb150bacec56f1cdf0566cbe42df1de036a8b97 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 19 Mar 2018 14:53:46 +0800 Subject: [PATCH 25/29] Merge and fix test. --- demo/runtime/src/api.rs | 5 ++-- demo/runtime/src/runtime/system.rs | 44 ++++++++++++++---------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/demo/runtime/src/api.rs b/demo/runtime/src/api.rs index dd20c1d18014e..d590150061860 100644 --- a/demo/runtime/src/api.rs +++ b/demo/runtime/src/api.rs @@ -18,8 +18,9 @@ use runtime::{system, consensus, session}; impl_stubs!( execute_block => |block| system::internal::execute_block(block), - execute_transaction => |(header, utx)| system::internal::execute_transaction(utx, header), - finalise_block => |header| system::internal::finalise_block(header), + initialise_block => |header| system::internal::initialise_block(&header), + execute_transaction => |utx| system::internal::execute_transaction(utx), + finalise_block => |()| system::internal::finalise_block(), validator_count => |()| session::validator_count(), validators => |()| session::validators(), authorities => |()| consensus::authorities() diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 7f980457e63df..2ccf878643ec8 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -37,6 +37,7 @@ storage_items! { // The current block number being processed. Set by `execute_block`. Number get(block_number): b"sys:num" => required BlockNumber; ParentHash get(parent_hash): b"sys:pha" => required Hash; + TransactionsRoot get(transactions_root): b"sys:txr" => required Hash; Digest: b"sys:dig" => default block::Digest; } @@ -68,10 +69,7 @@ pub mod internal { /// Actually execute all transitioning for `block`. pub fn execute_block(mut block: Block) { - // populate environment from header. - Number::put(block.header.number); - ParentHash::put(block.header.parent_hash); - RandomSeed::put(calculate_random()); + initialise_block(&block.header); // any initial checks initial_checks(&block); @@ -90,35 +88,34 @@ pub mod internal { post_finalise(&block.header); } - /// Execute a transaction outside of the block execution function. - /// This doesn't attempt to validate anything regarding the block. - pub fn execute_transaction(utx: UncheckedTransaction, mut header: Header) -> Header { + /// Start the execution of a particular block. + pub fn initialise_block(mut header: &Header) { // populate environment from header. Number::put(header.number); ParentHash::put(header.parent_hash); - Digest::put(&header.digest); + TransactionsRoot::put(header.transaction_root); RandomSeed::put(calculate_random()); + } + /// Execute a transaction outside of the block execution function. + /// This doesn't attempt to validate anything regarding the block. + pub fn execute_transaction(utx: UncheckedTransaction) { super::execute_transaction(utx); - - header.digest = Digest::get(); - header } /// Finalise the block - it is up the caller to ensure that all header fields are valid /// except state-root. - pub fn finalise_block(mut header: Header) -> Header { - // populate environment from header. - Number::put(header.number); - ParentHash::put(header.parent_hash); - Digest::put(&header.digest); - RandomSeed::put(calculate_random()); - + pub fn finalise_block() -> Header { staking::internal::check_new_era(); session::internal::check_rotate_session(); - header.state_root = storage_root().into(); - header.digest = Digest::get(); + let header = Header { + number: block_number(), + parent_hash: parent_hash(), + state_root: storage_root().into(), + digest: Digest::get(), + transaction_root: transactions_root(), + }; post_finalise(&header); @@ -266,10 +263,9 @@ mod tests { signature: hex!("3a682213cb10e8e375fe0817fe4d220a4622d910088809ed7fc8b4ea3871531dbadb22acfedd28a100a0b7bd2d274e0ff873655b13c88f4640b5569db3222706").into(), }; - println!("TX: {}", HexDisplay::from(&tx.transaction.encode())); - with_externalities(&mut t, || { - internal::execute_transaction(tx, Header::from_block_number(1)); + internal::initialise_block(&Header::from_block_number(1)); + internal::execute_transaction(tx); assert_eq!(staking::balance(&One), 32); assert_eq!(staking::balance(&Two), 69); }); @@ -286,7 +282,7 @@ mod tests { let h = Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("cc3f1f5db826013193e502c76992b5e933b12367e37a269a9822b89218323e9f").into(), + state_root: hex!("5dd9af63b95f4c111123f1dfa3a9e3c504c60b6e9fd2cb0487bf2d8235aabb02").into(), transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), digest: Digest { logs: vec![], }, }; From 2e9fa0972ffe3b31916b7a81e771c6b70b5bdca0 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 19 Mar 2018 14:57:18 +0800 Subject: [PATCH 26/29] Docs. --- demo/runtime/src/safe_mix.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index d7e1495825911..6bdcc422cbb70 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -20,7 +20,7 @@ use rstd::ops::{BitAnd, BitOr}; -const MAX_DEPTH: usize = 17; +pub const MAX_DEPTH: usize = 17; fn sub_mix(seeds: &[T]) -> T where T: BitAnd + BitOr + Copy @@ -40,7 +40,9 @@ pub fn mix(seeds: &[T]) -> Result where pub trait Mixed { /// The items in the sequence and simultaneously the return of the mixing. type Item; - /// The output of the mixing algorithm on the sequence. + /// The output of the mixing algorithm on the sequence. Items in the sequence beyond + /// the largest power of three that fits within the the sequence up until `3 ** MAX_DEPTH` + /// are ignored. fn mixed(self) -> Self::Item; } From e4c2b273c97e4aea32fc8460b67359e1475aa3e4 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 19 Mar 2018 14:58:53 +0800 Subject: [PATCH 27/29] Fix typo. --- demo/runtime/src/safe_mix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index 6bdcc422cbb70..ba33dad9a3ff9 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -36,7 +36,7 @@ pub fn mix(seeds: &[T]) -> Result where Ok(seeds.iter().cloned().mixed()) } -/// The mixed trait for mixing a ssequence. +/// The mixed trait for mixing a sequence. pub trait Mixed { /// The items in the sequence and simultaneously the return of the mixing. type Item; From 90dd1a5a3aafdb3b7195d542b7c99e03934ba164 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 19 Mar 2018 15:32:10 +0800 Subject: [PATCH 28/29] rename --- demo/runtime/src/runtime/system.rs | 4 +- demo/runtime/src/safe_mix.rs | 60 +++++++++++++++--------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index 2ccf878643ec8..b371c6e9956bf 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -28,7 +28,7 @@ use transaction::UncheckedTransaction; use runtime::{staking, session}; use runtime::democracy::PrivPass; use dispatch; -use safe_mix::Mixed; +use safe_mix::TripletMix; storage_items! { pub Nonce get(nonce): b"sys:non" => default map [ AccountId => TxOrder ]; @@ -190,7 +190,7 @@ fn calculate_random() -> Hash { let c = block_number() - 1; (0..81) .map(|i| if c >= i { block_hash(c - i) } else { Default::default() }) - .mixed() + .triplet_mix() } #[cfg(feature = "std")] diff --git a/demo/runtime/src/safe_mix.rs b/demo/runtime/src/safe_mix.rs index ba33dad9a3ff9..7512d8db81a2d 100644 --- a/demo/runtime/src/safe_mix.rs +++ b/demo/runtime/src/safe_mix.rs @@ -29,29 +29,29 @@ fn sub_mix(seeds: &[T]) -> T where } /// Mix a slice. -pub fn mix(seeds: &[T]) -> Result where +pub fn triplet_mix(seeds: &[T]) -> Result where T: BitAnd + BitOr, T: Default + Copy { - Ok(seeds.iter().cloned().mixed()) + Ok(seeds.iter().cloned().triplet_mix()) } /// The mixed trait for mixing a sequence. -pub trait Mixed { +pub trait TripletMix { /// The items in the sequence and simultaneously the return of the mixing. type Item; /// The output of the mixing algorithm on the sequence. Items in the sequence beyond /// the largest power of three that fits within the the sequence up until `3 ** MAX_DEPTH` /// are ignored. - fn mixed(self) -> Self::Item; + fn triplet_mix(self) -> Self::Item; } -impl Mixed for I where +impl TripletMix for I where I: Iterator, T: BitAnd + BitOr + Default + Copy { type Item = T; - fn mixed(self) -> Self::Item { + fn triplet_mix(self) -> Self::Item { let mut accum = [[T::default(); 3]; MAX_DEPTH]; let mut result = T::default(); for (i, seed) in self.enumerate() { @@ -104,35 +104,35 @@ mod tests { } #[test] - fn mix_works_on_first_level() { - assert_eq!(mix(&[0, 0, 0][..]).unwrap(), 0); - assert_eq!(mix(&[0, 0, 1][..]).unwrap(), 0); - assert_eq!(mix(&[0, 1, 0][..]).unwrap(), 0); - assert_eq!(mix(&[0, 1, 1][..]).unwrap(), 1); - assert_eq!(mix(&[1, 0, 0][..]).unwrap(), 0); - assert_eq!(mix(&[1, 0, 1][..]).unwrap(), 1); - assert_eq!(mix(&[1, 1, 0][..]).unwrap(), 1); - assert_eq!(mix(&[1, 1, 1][..]).unwrap(), 1); - - assert_eq!(mix(&[0, 0, 0][..]).unwrap(), 0); - assert_eq!(mix(&[0, 0, 2][..]).unwrap(), 0); - assert_eq!(mix(&[0, 2, 0][..]).unwrap(), 0); - assert_eq!(mix(&[0, 2, 2][..]).unwrap(), 2); - assert_eq!(mix(&[2, 0, 0][..]).unwrap(), 0); - assert_eq!(mix(&[2, 0, 2][..]).unwrap(), 2); - assert_eq!(mix(&[2, 2, 0][..]).unwrap(), 2); - assert_eq!(mix(&[2, 2, 2][..]).unwrap(), 2); + fn triplet_mix_works_on_first_level() { + assert_eq!(triplet_mix(&[0, 0, 0][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[0, 0, 1][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[0, 1, 0][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[0, 1, 1][..]).unwrap(), 1); + assert_eq!(triplet_mix(&[1, 0, 0][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[1, 0, 1][..]).unwrap(), 1); + assert_eq!(triplet_mix(&[1, 1, 0][..]).unwrap(), 1); + assert_eq!(triplet_mix(&[1, 1, 1][..]).unwrap(), 1); + + assert_eq!(triplet_mix(&[0, 0, 0][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[0, 0, 2][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[0, 2, 0][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[0, 2, 2][..]).unwrap(), 2); + assert_eq!(triplet_mix(&[2, 0, 0][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[2, 0, 2][..]).unwrap(), 2); + assert_eq!(triplet_mix(&[2, 2, 0][..]).unwrap(), 2); + assert_eq!(triplet_mix(&[2, 2, 2][..]).unwrap(), 2); } #[test] - fn mix_works_on_second_level() { - assert_eq!(mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0][..]).unwrap(), 0); - assert_eq!(mix(&[0, 1, 1, 1, 0, 0, 1, 0, 1][..]).unwrap(), 1); - assert_eq!(mix(&[1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1); + fn triplet_mix_works_on_second_level() { + assert_eq!(triplet_mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0][..]).unwrap(), 0); + assert_eq!(triplet_mix(&[0, 1, 1, 1, 0, 0, 1, 0, 1][..]).unwrap(), 1); + assert_eq!(triplet_mix(&[1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1); } #[test] - fn mix_works_on_third_level() { - assert_eq!(mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1); + fn triplet_mix_works_on_third_level() { + assert_eq!(triplet_mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1); } } From f19771490e11ef6f9162fdbea8124a98a1dbea8c Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 19 Mar 2018 17:59:45 +0800 Subject: [PATCH 29/29] Fix tests. --- demo/executor/src/lib.rs | 30 +++++++++++++----- demo/runtime/src/runtime/system.rs | 25 +++++++++------ .../release/demo_runtime.compact.wasm | Bin 162981 -> 164653 bytes .../release/demo_runtime.wasm | Bin 163032 -> 164704 bytes .../release/polkadot_runtime.compact.wasm | Bin 134847 -> 134847 bytes .../release/polkadot_runtime.wasm | Bin 134896 -> 134896 bytes .../substrate_test_runtime.compact.wasm | Bin 32002 -> 32002 bytes .../release/substrate_test_runtime.wasm | Bin 32082 -> 32082 bytes 8 files changed, 38 insertions(+), 17 deletions(-) diff --git a/demo/executor/src/lib.rs b/demo/executor/src/lib.rs index a619d565a2a5d..8d94b475acbdd 100644 --- a/demo/executor/src/lib.rs +++ b/demo/executor/src/lib.rs @@ -77,10 +77,13 @@ mod tests { fn panic_execution_with_foreign_code_gives_error() { let mut t: TestExternalities = map![ twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8], + twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; - let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); + let r = Executor::new().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64))); + assert!(r.is_ok()); + let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&tx())); assert!(r.is_err()); } @@ -88,10 +91,13 @@ mod tests { fn panic_execution_with_native_equivalent_code_gives_error() { let mut t: TestExternalities = map![ twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0], - twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8] + twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8], + twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; - let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); + let r = Executor::new().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64))); + assert!(r.is_ok()); + let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&tx())); assert!(r.is_err()); } @@ -103,7 +109,9 @@ mod tests { twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; - let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); + let r = Executor::new().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64))); + assert!(r.is_ok()); + let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -120,7 +128,9 @@ mod tests { twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32] ]; - let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); + let r = Executor::new().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64))); + assert!(r.is_ok()); + let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -237,7 +247,9 @@ mod tests { ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm"); - let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&Header::from_block_number(1u64))); + assert!(r.is_ok()); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&tx())); assert!(r.is_err()); } @@ -250,7 +262,9 @@ mod tests { ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm"); - let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&Header::from_block_number(1u64))); + assert!(r.is_ok()); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { diff --git a/demo/runtime/src/runtime/system.rs b/demo/runtime/src/runtime/system.rs index b371c6e9956bf..8cd75b49ed258 100644 --- a/demo/runtime/src/runtime/system.rs +++ b/demo/runtime/src/runtime/system.rs @@ -109,12 +109,13 @@ pub mod internal { staking::internal::check_new_era(); session::internal::check_rotate_session(); + RandomSeed::kill(); let header = Header { - number: block_number(), - parent_hash: parent_hash(), + number: Number::take(), + digest: Digest::take(), + parent_hash: ParentHash::take(), + transaction_root: TransactionsRoot::take(), state_root: storage_root().into(), - digest: Digest::get(), - transaction_root: transactions_root(), }; post_finalise(&header); @@ -169,10 +170,8 @@ fn final_checks(block: &Block) { // check digest assert!(header.digest == Digest::get()); - Number::kill(); - ParentHash::kill(); - RandomSeed::kill(); - Digest::kill(); + // remove temporaries. + kill_temps(); // check storage root. let storage_root = storage_root().into(); @@ -180,6 +179,14 @@ fn final_checks(block: &Block) { assert!(header.state_root == storage_root, "Storage root must match that calculated."); } +fn kill_temps() { + Number::kill(); + ParentHash::kill(); + RandomSeed::kill(); + Digest::kill(); + TransactionsRoot::kill(); +} + fn post_finalise(header: &Header) { // store the header hash in storage; we can't do it before otherwise there would be a // cyclic dependency. @@ -282,7 +289,7 @@ mod tests { let h = Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("5dd9af63b95f4c111123f1dfa3a9e3c504c60b6e9fd2cb0487bf2d8235aabb02").into(), + state_root: hex!("cc3f1f5db826013193e502c76992b5e933b12367e37a269a9822b89218323e9f").into(), transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), digest: Digest { logs: vec![], }, }; diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index 36a582957021e09d5138b933597ba47f6cf18d29..b94b5ddc9b64bf467dac7444f9050dcef50f92bd 100644 GIT binary patch delta 46943 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

w#Z_>khYd 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 delta 44619 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 diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 859227ad9c2f37caa913a02756cd5499a7603629..3b3fb8f78c34f3325307db47c3986ea9cca59203 100644 GIT binary patch delta 4942 zcmcf^X?RrC^_@GJCA>&pAPE!JmznI#WF3u%JsC7Gz+f;Cq8p&s2Mo}W07B>xa*D(x(`#e`%%rKh7x4R`ZWqjS)%cYI zX^Ev@>Lx{J9;L&f8{}=r&6UnVuTC|{#^u*DEg=0C`zOa!TkE02B zV>#HqFoZsuH;Vi@&h>m=G(ZIHTvUZhuJMca16RKCz&eiBJos0DY`Xc%E_(A}C+SL~ zB}-o6V1zv{aE>4=F+Odr?_%bQ4EcAIFYc)u~8!|LYZfZ&LXL}_~7Jz`kLpHMxv`Fzfc54 zh#`KM%OZ@9HR?@-5ebmd_kX-K22YAQEztkFiL>S5me zq*SY$)~F`>W%W=mCveq^9(mWfRYZqD{PU4b+~C?ruLG%%r)z5Fk@ggtTpvu6YsS!_ zzqp4Syp6tyXs3oY)sCjN+8I0uF5Fbx#SJfc+(w(~4s#QW*WPoRVx(Pbf2pBoA=`ED z6Vm__zrLRP=Fz+6KN+UunJI4w#h{*UV90RE>mDN9UtQx2jvi|)F=4~rz2R%r9kcP4 zwy7LC?zvCB`-^1t+~OX#*-M$WX|qO&r2{vocvXJ3`Knjoo-OCG6JoYbN28Tnv+?`; ztrL;*udU;_o9E}${-8Jdx2La9|NEjlRvL{h-J*g2WHnX^QoCOjm2V#hK@cT=JTw#X zAjyyOTv6MW=`pK~JMV=d_sfHn-eC@TPz>ocTY$qpvy|sL_ri4(M7vJ44k5bv0e*DM zJ}Wiv%fmIHpSGQ$e|jz5^<-PF--xMbpv&M;%#K7s2!{X=MQNTij%1N6DVz4Szl2tr z_n#vWO;5F2{LzDQK<|*I(Y6CO3_Q3EF?8=6VYQxZes9y>oi#=CT&SBl9mSWpHT>^Q zPFI?mDvxrLM~e#_1eMbST8e&Bhcv~~DR1tD2-jC{z9_PQ(f2 z+Hzzc&LY>eqfG$e^weLndAmd&Tcn#RWxF0frbnu);XNx1z`d#QHl@-1U7e`%$onU_ z%DfLIa+QrAJcY>c?nN-qwW>Rkpun~d2Leo^^7|q5t&d(pZsG9+oQcmJPYvony>2;>k($=!rPI1a6!dPta}pN$U?pp5csDr{b_zcb?h<7CP&6E?3@l zI@>FI?R1SsvC$o8a$q*ScIIRJcKspF=M?b3KN zfFRiP%>=_pG}7!ZH-ge+aB$G3cUU6%qS+rW19lbQ0D5=tC4kFZ_YOZW0Y=5zl3^Ho zTMy%r%fbi2U>0hCD$ZGNfHg3e?KZ&(mJ|*P*<(gX;!=B!fK!h%_IOaUyTl*1f|=hl z%?9qZBfueR?hV|%EW%DM+bP0%gzkL-Fq`1wxj@)Pb|<>G2SPL8%wBvXz5XBO3=pGbfJ;hHp4b4*`eaAb+0B zWi27l$!WM3GsED`?k%D4GSS#MY-$+1g7tCV41>W&Pw)CN@w88|D;#FST(@k2$@qM6 zFOLBeL0BFK-vQju$`im0dG2)y@JF5b_Aam@{c{sO6++nRWT4#aT`8~zZ#mYG0uON< z6JUNl6|#e22Aet=vM?ytI2lG+e5tsFmEX-P&(m&lcvJOx1UotzqH80ibZqmsNNrMi zpEA9PD&CN+f}Y_j*buLR<4G!L)v!(t^lHQg8$K{B>H*ngQ^lH-mC@?`;9K}EllD|; zbS*mf5&jR0J4QSXWF2~UUz-9U@RJ2_V*wUpx!g6=@NCdmzS_fIw~Md8&cUGxtpmLG z1fqv;93JF5{XSo`rSHH%AI8%n&~=wASy&m9EGRJ!1!tB&KjngA%peJvLqQpfrAkJ4 zD>j3e5t0lNtTK2FW03H9EWLOs&e$2pEBG3n)0>M^@ul8kolcrb|NiB29^Ulc#VWBB zzoD0NILUGOUPSg@uEek9N;Qtv%~ys2_7b&U3!(2`-JmVs(m*_&{Z-~Deghm$QS13* zHFDp#0RCWtnQq+@XwmD{+mw~ffMqa~b~xFEsYsQrPLG z<&>#bInBnb<&f$%wzwSnyh3>^;hkXLwz|@laL;R=r8{9i59*>5rt=IjT%@qVN_Z8r z-NUNj40wpd4S2?jw)j0|jT-M~^}aw_5WUjMCwp z+*S)2ki)ubq0ig^Ok(NDwBW@En9824_3K7R`#$zxd$THZ~RI0ln7C>7ds2=%ht$C%bd=#RRzlgr6)pE;}(>2 z5u&MLO+{vDS!pI76qJ_H4BuQ9!eOe#TM=RetGNylV=+yUqQo6>i9`6iOORHMHT<~|r6ZO}S76B4?jMl~Kq=mwd|-)E z9Zxa-<4|*WD^|?rb;zz2l+HL&T7n$z(R! zcgBk(Qx=r^cu|i%xvW6IKX`(2upn2o_MxiM@ElqP7p&YocT#kJWYiq1xe_(P-+QkTev`;mCt?nG=SbU3P?#nnEG9f_XM)t2o_WL18|ItA+LG7< zdJ_A<@gzK?W=+fM@z*|&y~wRYZvQ=O^>G`LvG0&O6e(Wa?YIuWA0Dz~c2-Zuk)C8W z+(1T>x)gS|fmlg%3bPwX$dvXJ(a4KeT7i{3=s}9h^06&ENVOf2qbZ`f7oG4q;dRoD zYlG^fH-+u{4kjeFriw5u&y_sI)A0rLt%vkx6eVn`$J( z0~^vr!fTl0)xYVVryWjYiY@E zuX<2)MI$pGIqhg;t(&y#R{CR&Hn#G$;V*K1Wt47Gv9;g1^Ki7<-M`kKbHDRF&-Xm% zaBREo*mj*mL&AbIn&2RkDT?}w`0P~=>pt_E@_ zLHCVnaf+Ws{pQ2W6gJd;v)n6-Oug>AQD66F^iA zI3rPGG8Y@vSwt2Meb+7B60}YIg2n;uBzO?tp89sZ;(&SpI=>dfNV3! z5mr6Sl*d@txrLMDFRdnj1@IZnsDA&B*g}{59(9}@OHQarbAn83r!o_#)|q6XZn!r; zX?04_ZmLfHqHdU%6T0+8kG!*IDN&&l|5)D446c0QYakm9a{Y=K2cuKJUQ3bT6rXvNu>Bg>O=IY(b(K2o*!wnqi@KvX z^}B;AkjHMm=#4Liu3{GV(Jfv|LGu zT5^%{ua>cFn{Cq@e$*TO?dj{&|Gwx+5Jq83A992LV6`Fo)@MGV@V##6N=@&LocC~ z*26sn(&V%I4S~3WbVOqjX2^~sx3tW;jp_1%*M~NE!n`wRUt~>bEEh^J=Tg}cL&N{x zDdJA)m>-zL6ZF7xmiqk z_qlwp?9Fp4+!T|%^L#NpB;P#$34Xi&o{2sNezG5Mhu69<;&=N6!`P%OjuS&9!NLx{ z#$-1ZtYG~fo=(B~JeXR+ZYDYVE(})TWfl6_V0A+>tCA>Si;l*ktx6V&)L;=cLI!J) zWHHpU^fCgx3_)}+`;{SK)ooKuNq&`MrahIoYv{fK0?MH+w_VO9N8{zsE>C2kCtS&c zS@Pm5QJ5@e)0I_ZkSU9BVyMW_7{FP`4U&y~~r_0J1YT64V+YxU6ebgg?*Y2hR= zpgc@E)S`wGag}=_)O}!T5OrAc>vPUZYs}HpRN&Z=CK7fUQhAM+Xm)&S=`C zQ;ZzaK`SHA3WV<%d^iX!+IQKTZ7Tg!5FAGu#-f+kf3J7F&SNRv%mTV71YW_8b?HOl zo&e7@vv}J)8uW|7Py|z5xkF$wzU5qNMuLtY+z%|x$`gSdtiArqU>k#biP#wd7moC3N>D4@-tfJ?CoIO@i_+@R4d*&Krd zWl&CwJ#G_@IBAq}S^5^fPCp(mjB3EmeT4tR;?8;CcopvMx+e$1;b$x0!U~jPyygC}kA_w*hMjIO)OBA4oC0re3RS?~ zXLN5B?DEozt;!~hW};EmknS~BS`B?(p^_!=&LCf|J2Rz7&s&~m+Tbwr@v039m7@z6 zX|&u9ui|+&ycW)bx6Qw=1NLyETb9CE22s#N+m^v06fCKSYJ5MsPA!3fLohn8@YqsZ+2nPsjTC(uHfS;!9)v zW;Mx4J{r#l*vl)k(GxTr&+EHUV+51HWa$yGjJhN5j;H5&B9g`g`U6i!gf=Je0gqej zvdz^t4qrzUkB)HhPy(+PQI(~9Izr3^cM=N|h>(*y6R7YN3>n|^6H>t_HB^!6M{Xbd^9ZzAkky69x1%Q>c=FG;ctK<;Yh*p z#?VX*^Keh%660ajNuhxnk^!kKH^UlI`S2Mwb5)IbfxX;XC7SJGdDX(QWg;iFr}D$a zDyvhN>Q8Yq0?o*$NBaQZGNIV|ZAzBidgTnK%JJ@`C!?=n|6~pn*Kb&9W8X4x< z{7YQAgLI_R3N1;7bh=ebQpEKcxUa`lH^MuQ3P*-sR5T!w!GJu diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 760b46ba1e6f6b20fc19b89c5632c63ead8d941e..cb08a3c72bf5e04296d54ced6ad68b3184534674 100644 GIT binary patch delta 4920 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 diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index fef578011de16d6246949eda51da268e7898e977..7c3dabf1880e0073bf91f2edb05f842986644b07 100644 GIT binary patch delta 320 zcmZqr#n|+Val>Xt9#%#k9v&7B9#&Q+j>-EOn;A7WJ2M?snk=bmz-TzxOZ5eiG*){9 zBo)*%fn=Auzo3qSfCdwX5;KSrP~s5KoBT?Bg&kN_LWvzDs-VOopr;AoKL*dgo4Aplmap~MPOY@oy`ptt#gMh~Na0D}Uf0)qw<1BhS|keVE= zWzT3dd7+lvEX9Jp6;#kP2yZM=84Xt9!6Fk9v%)B4jxukrpfymn;F$NJ2M?s5)fceU{qkxU}69fECN!K z*;Nf0jV4>Fz5tR+YHxrfzj`K+tW@_G)Kw7BVB%0>22lb^90K~2Z>q1b1B*&1v4cbv zlvo7x6$KR-G?^I`1jBfl6a*YKvJ@B`4YC|NWF0vKz=}1LSV4*nlsEx?oA+zUGBWB+zN;O!y~BMwpJGm>0ayk pCtvmm2kO)I%mb3MJkM?xkA1_C6w4fq6$hZ0)~o$3JjXe3<`o_ zyi5uLjv84C42}j_jvca&90Fj)8cM7n#Rf{80*0FvG#m#LB3(xy9O^4QSXA$3jMf&1OzLj6ku&&KnsSO*faiu4A5jDIy%G pMJqB7NY0EryII+DJ^yC4Oh)F-X;E*u8I3mwr(I^+te&GS2mk{FQ{4an delta 320 zcmccgi}BJg#tp|Ac^FxFcz8HiICxlDnI>OmT*;`lxt8g+l7Ik%0;2+h1``8_U=fg= z9Ik4}Xgax5^#zbDQhNg=6 zEjvcT$se`kCjZxB+sv;m%gCrdSyv~5(Rg#4&LcLU{h7x0Kysz=dmuT}1mwCV(|jQL z$