Serialisable genesis config (#229)

* Genesis serialization

* Custom type for AuthorityId

* Merge w master

* Fixed a few minor issues

* Fixed unmerged file

* Renamed tag

* Deferred genesis loading

* Upated wasm runtime

* Minor issues
This commit is contained in:
Arkadiy Paronyan
2018-07-03 15:56:01 +02:00
committed by Gav Wood
parent 276c464b50
commit 9b885ba092
51 changed files with 557 additions and 368 deletions
@@ -42,7 +42,7 @@ use rstd::prelude::*;
use runtime_support::{storage, Parameter};
use runtime_support::dispatch::Result;
use runtime_support::storage::unhashed::StorageVec;
use primitives::traits::{RefInto, MaybeEmpty};
use primitives::traits::{RefInto, MaybeSerializeDebug, MaybeEmpty};
use primitives::bft::MisbehaviorReport;
pub const AUTHORITY_AT: &'static [u8] = b":auth:";
@@ -60,7 +60,7 @@ pub type KeyValue = (Vec<u8>, Vec<u8>);
pub trait Trait: system::Trait {
type PublicAux: RefInto<Self::AccountId> + MaybeEmpty; // MaybeEmpty is for Timestamp's usage.
type SessionKey: Parameter + Default;
type SessionKey: Parameter + Default + MaybeSerializeDebug;
}
decl_module! {
@@ -118,8 +118,12 @@ impl<T: Trait> Module<T> {
}
#[cfg(any(feature = "std", test))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait> {
pub authorities: Vec<T::SessionKey>,
#[serde(with = "substrate_primitives::bytes")]
pub code: Vec<u8>,
}
@@ -136,7 +140,7 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> ::std::result::Result<runtime_io::TestExternalities, String> {
use codec::{Slicable, KeyedVec};
let auth_count = self.authorities.len() as u32;
let mut r: runtime_io::TestExternalities = self.authorities.into_iter().enumerate().map(|(i, v)|
@@ -144,6 +148,6 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
).collect();
r.insert(AUTHORITY_COUNT.to_vec(), auth_count.encode());
r.insert(CODE.to_vec(), self.code);
r
Ok(r)
}
}
+13 -10
View File
@@ -545,6 +545,9 @@ impl<T: Trait> Module<T> {
}
#[cfg(any(feature = "std", test))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait> {
// for the voting onto the council
pub candidacy_bond: T::Balance,
@@ -587,11 +590,11 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> ::std::result::Result<runtime_io::TestExternalities, String> {
use codec::Slicable;
use runtime_io::twox_128;
map![
Ok(map![
twox_128(<CandidacyBond<T>>::key()).to_vec() => self.candidacy_bond.encode(),
twox_128(<VotingBond<T>>::key()).to_vec() => self.voter_bond.encode(),
twox_128(<PresentSlashPerVoter<T>>::key()).to_vec() => self.present_slash_per_voter.encode(),
@@ -606,7 +609,7 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
twox_128(<voting::CooloffPeriod<T>>::key()).to_vec() => self.cooloff_period.encode(),
twox_128(<voting::VotingPeriod<T>>::key()).to_vec() => self.voting_period.encode(),
twox_128(<voting::Proposals<T>>::key()).to_vec() => vec![0u8; 0].encode()
]
])
}
}
@@ -665,16 +668,16 @@ mod tests {
impl Trait for Test {}
pub fn new_test_ext(with_council: bool) -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![],
}.build_storage());
}.build_storage().unwrap());
t.extend(session::GenesisConfig::<Test>{
session_length: 1, //??? or 2?
validators: vec![10, 20],
broken_percent_late: 100,
}.build_storage());
}.build_storage().unwrap());
t.extend(staking::GenesisConfig::<Test>{
sessions_per_era: 1,
current_era: 0,
@@ -691,12 +694,12 @@ mod tests {
reclaim_rebate: 0,
early_era_slash: 0,
session_reward: 0,
}.build_storage());
}.build_storage().unwrap());
t.extend(democracy::GenesisConfig::<Test>{
launch_period: 1,
voting_period: 3,
minimum_deposit: 1,
}.build_storage());
}.build_storage().unwrap());
t.extend(GenesisConfig::<Test>{
candidacy_bond: 9,
voter_bond: 3,
@@ -714,8 +717,8 @@ mod tests {
term_duration: 5,
cooloff_period: 2,
voting_period: 1,
}.build_storage());
t.extend(timestamp::GenesisConfig::<Test>::default().build_storage());
}.build_storage().unwrap());
t.extend(timestamp::GenesisConfig::<Test>::default().build_storage().unwrap());
t
}
@@ -296,6 +296,9 @@ impl<T: Trait> Executable for Module<T> {
}
#[cfg(any(feature = "std", test))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait> {
pub launch_period: T::BlockNumber,
pub voting_period: T::BlockNumber,
@@ -335,18 +338,18 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> ::std::result::Result<runtime_io::TestExternalities, String> {
use codec::Slicable;
use runtime_io::twox_128;
map![
Ok(map![
twox_128(<LaunchPeriod<T>>::key()).to_vec() => self.launch_period.encode(),
twox_128(<VotingPeriod<T>>::key()).to_vec() => self.voting_period.encode(),
twox_128(<MinimumDeposit<T>>::key()).to_vec() => self.minimum_deposit.encode(),
twox_128(<ReferendumCount<T>>::key()).to_vec() => (0 as ReferendumIndex).encode(),
twox_128(<NextTally<T>>::key()).to_vec() => (0 as ReferendumIndex).encode(),
twox_128(<PublicPropCount<T>>::key()).to_vec() => (0 as PropIndex).encode()
]
])
}
}
@@ -406,16 +409,16 @@ mod tests {
}
fn new_test_ext() -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![],
}.build_storage());
}.build_storage().unwrap());
t.extend(session::GenesisConfig::<Test>{
session_length: 1, //??? or 2?
validators: vec![10, 20],
broken_percent_late: 100,
}.build_storage());
}.build_storage().unwrap());
t.extend(staking::GenesisConfig::<Test>{
sessions_per_era: 1,
current_era: 0,
@@ -432,13 +435,13 @@ mod tests {
reclaim_rebate: 0,
early_era_slash: 0,
session_reward: 0,
}.build_storage());
}.build_storage().unwrap());
t.extend(GenesisConfig::<Test>{
launch_period: 1,
voting_period: 1,
minimum_deposit: 1,
}.build_storage());
t.extend(timestamp::GenesisConfig::<Test>::default().build_storage());
}.build_storage().unwrap());
t.extend(timestamp::GenesisConfig::<Test>::default().build_storage().unwrap());
t
}
@@ -269,7 +269,7 @@ mod tests {
#[test]
fn staking_balance_transfer_dispatch_works() {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(staking::GenesisConfig::<Test> {
sessions_per_era: 0,
current_era: 0,
@@ -286,7 +286,7 @@ mod tests {
reclaim_rebate: 0,
early_era_slash: 0,
session_reward: 0,
}.build_storage());
}.build_storage().unwrap());
let xt = primitives::testing::TestXt((1, 0, Call::transfer(2.into(), 69)));
with_externalities(&mut t, || {
Executive::initialise_block(&Header::new(1, H256::default(), H256::default(), [69u8; 32].into(), Digest::default()));
@@ -297,11 +297,11 @@ mod tests {
}
fn new_test_ext() -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(consensus::GenesisConfig::<Test>::default().build_storage());
t.extend(session::GenesisConfig::<Test>::default().build_storage());
t.extend(staking::GenesisConfig::<Test>::default().build_storage());
t.extend(timestamp::GenesisConfig::<Test>::default().build_storage());
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(consensus::GenesisConfig::<Test>::default().build_storage().unwrap());
t.extend(session::GenesisConfig::<Test>::default().build_storage().unwrap());
t.extend(staking::GenesisConfig::<Test>::default().build_storage().unwrap());
t.extend(timestamp::GenesisConfig::<Test>::default().build_storage().unwrap());
t
}
@@ -56,27 +56,16 @@ use traits::{Verify, Lazy};
#[cfg(feature = "std")]
pub type StorageMap = HashMap<Vec<u8>, Vec<u8>>;
/// A simple function allowing StorageMap to be created.
#[cfg(feature = "std")]
pub type MakeStorage = Box<FnMut() -> StorageMap>;
/// Complex storage builder stuff.
#[cfg(feature = "std")]
pub trait BuildStorage {
fn build_storage(self) -> StorageMap;
}
#[cfg(feature = "std")]
impl BuildStorage for MakeStorage {
fn build_storage(mut self) -> StorageMap {
self()
}
fn build_storage(self) -> Result<StorageMap, String>;
}
#[cfg(feature = "std")]
impl BuildStorage for StorageMap {
fn build_storage(self) -> StorageMap {
self
fn build_storage(self) -> Result<StorageMap, String> {
Ok(self)
}
}
@@ -241,6 +230,9 @@ macro_rules! impl_outer_config {
( pub struct $main:ident for $concrete:ident { $( $config:ident => $snake:ident, )* } ) => {
__impl_outer_config_types! { $concrete $( $config $snake )* }
#[cfg(any(feature = "std", test))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct $main {
$(
pub $snake: Option<$config>,
@@ -248,14 +240,14 @@ macro_rules! impl_outer_config {
}
#[cfg(any(feature = "std", test))]
impl $crate::BuildStorage for $main {
fn build_storage(self) -> $crate::StorageMap {
fn build_storage(self) -> ::std::result::Result<$crate::StorageMap, String> {
let mut s = $crate::StorageMap::new();
$(
if let Some(extra) = self.$snake {
s.extend(extra.build_storage());
s.extend(extra.build_storage()?);
}
)*
s
Ok(s)
}
}
}
+10 -7
View File
@@ -220,6 +220,9 @@ impl<T: Trait> Executable for Module<T> {
}
#[cfg(any(feature = "std", test))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait> {
pub session_length: T::BlockNumber,
pub validators: Vec<T::AccountId>,
@@ -241,17 +244,17 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> ::std::result::Result<runtime_io::TestExternalities, String> {
use runtime_io::twox_128;
use codec::Slicable;
use primitives::traits::As;
map![
Ok(map![
twox_128(<SessionLength<T>>::key()).to_vec() => self.session_length.encode(),
twox_128(<CurrentIndex<T>>::key()).to_vec() => T::BlockNumber::sa(0).encode(),
twox_128(<CurrentStart<T>>::key()).to_vec() => T::Moment::zero().encode(),
twox_128(<Validators<T>>::key()).to_vec() => self.validators.encode(),
twox_128(<BrokenPercentLate<T>>::key()).to_vec() => self.broken_percent_late.encode()
]
])
}
}
@@ -297,19 +300,19 @@ mod tests {
type Session = Module<Test>;
fn new_test_ext() -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![1, 2, 3],
}.build_storage());
}.build_storage().unwrap());
t.extend(timestamp::GenesisConfig::<Test>{
period: 5,
}.build_storage());
}.build_storage().unwrap());
t.extend(GenesisConfig::<Test>{
session_length: 2,
validators: vec![1, 2, 3],
broken_percent_late: 30,
}.build_storage());
}.build_storage().unwrap());
t
}
@@ -29,6 +29,9 @@ use super::{Trait, ENUM_SET_SIZE, EnumSet, NextEnumSet, Intentions, CurrentEra,
ExistentialDeposit, TransactionByteFee, TransactionBaseFee, TotalStake,
SessionsPerEra, ValidatorCount, FreeBalance, SessionReward, EarlyEraSlash};
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait> {
pub sessions_per_era: T::BlockNumber,
pub current_era: T::BlockNumber,
@@ -120,7 +123,7 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
fn build_storage(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> Result<runtime_io::TestExternalities, String> {
let total_stake: T::Balance = self.balances.iter().fold(Zero::zero(), |acc, &(_, n)| acc + n);
let mut r: runtime_io::TestExternalities = map![
@@ -150,6 +153,6 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
for (who, value) in self.balances.into_iter() {
r.insert(twox_128(&<FreeBalance<T>>::key_for(who)).to_vec(), value.encode());
}
r
Ok(r)
}
}
@@ -60,7 +60,7 @@ impl Trait for Test {
}
pub fn new_test_ext(ext_deposit: u64, session_length: u64, sessions_per_era: u64, current_era: u64, monied: bool, reward: u64) -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
let balance_factor = if ext_deposit > 0 {
256
} else {
@@ -69,12 +69,12 @@ pub fn new_test_ext(ext_deposit: u64, session_length: u64, sessions_per_era: u64
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![],
}.build_storage());
}.build_storage().unwrap());
t.extend(session::GenesisConfig::<Test>{
session_length,
validators: vec![10, 20],
broken_percent_late: 30,
}.build_storage());
}.build_storage().unwrap());
t.extend(GenesisConfig::<Test>{
sessions_per_era,
current_era,
@@ -99,10 +99,10 @@ pub fn new_test_ext(ext_deposit: u64, session_length: u64, sessions_per_era: u64
reclaim_rebate: 0,
session_reward: reward,
early_era_slash: if monied { 20 } else { 0 },
}.build_storage());
}.build_storage().unwrap());
t.extend(timestamp::GenesisConfig::<Test>{
period: 5
}.build_storage());
}.build_storage().unwrap());
t
}
@@ -193,6 +193,9 @@ impl<T: Trait> Module<T> {
}
#[cfg(any(feature = "std", test))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait>(PhantomData<T>);
#[cfg(any(feature = "std", test))]
@@ -205,16 +208,16 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> Result<runtime_io::TestExternalities, String> {
use runtime_io::twox_128;
use codec::Slicable;
map![
Ok(map![
twox_128(&<BlockHash<T>>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(),
twox_128(<Number<T>>::key()).to_vec() => 1u64.encode(),
twox_128(<ParentHash<T>>::key()).to_vec() => [69u8; 32].encode(),
twox_128(<RandomSeed<T>>::key()).to_vec() => [0u8; 32].encode(),
twox_128(<ExtrinsicIndex<T>>::key()).to_vec() => [0u8; 4].encode()
]
])
}
}
@@ -107,6 +107,9 @@ impl<T: Trait> Executable for Module<T> {
}
#[cfg(any(feature = "std", test))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait> {
pub period: T::Moment,
}
@@ -123,13 +126,13 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> runtime_primitives::StorageMap {
fn build_storage(self) -> ::std::result::Result<runtime_primitives::StorageMap, String> {
use runtime_io::twox_128;
use codec::Slicable;
map![
Ok(map![
twox_128(<BlockPeriod<T>>::key()).to_vec() => self.period.encode(),
twox_128(<Now<T>>::key()).to_vec() => T::Moment::sa(0).encode()
]
])
}
}
@@ -169,8 +172,8 @@ mod tests {
#[test]
fn timestamp_works() {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(GenesisConfig::<Test> { period: 0 }.build_storage());
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(GenesisConfig::<Test> { period: 0 }.build_storage().unwrap());
with_externalities(&mut t, || {
Timestamp::set_timestamp(42);
@@ -182,8 +185,8 @@ mod tests {
#[test]
#[should_panic(expected = "Timestamp must be updated only once in the block")]
fn double_timestamp_should_fail() {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(GenesisConfig::<Test> { period: 5 }.build_storage());
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(GenesisConfig::<Test> { period: 5 }.build_storage().unwrap());
with_externalities(&mut t, || {
Timestamp::set_timestamp(42);
@@ -195,8 +198,8 @@ mod tests {
#[test]
#[should_panic(expected = "Timestamp but increment by at least <BlockPeriod> between sequential blocks")]
fn block_period_is_enforced() {
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(GenesisConfig::<Test> { period: 5 }.build_storage());
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(GenesisConfig::<Test> { period: 5 }.build_storage().unwrap());
with_externalities(&mut t, || {
Timestamp::set_timestamp(42);