Dump genesis to JSON file (#218)

* Merge remote-tracking branch 'origin/master' into gav-xts-dont-panic

* Update wasm.

* consensus, session and staking all panic-safe.

* Democracy doesn't panic in apply.

* Fix tests.

* Extra helper macro, council depanicked.

* Fix one test.

* Fix up all council tests. No panics!

* Council voting depanicked.

* Dispatch returns result.

* session & staking tests updated

* Fix democracy tests.

* Fix council tests.

* Fix up polkadot parachains in runtime

* Fix borked merge

* More Slicable support

Support general `Option` and array types.

* Basic storage types.

* Existential deposit for contract creation

* Basic implemnetation along with removals

* Fix tests.

* externalities builder fix.

* Tests.

* Fix up the runtime.

* Fix tests.

* Add generic `Address` type.

* Initial function integration of Address into Extrinsic.

* Fix build

* All tests compile.

* Fix (some) tests.

* Fix signing.

* Push error.

* transfer can accept Address

* Make Address generic over AccountIndex

* Fix test

* Make Council use Address for dispatch.

* Fix build

* Bend over backwards to support braindead derive.

* Repot some files.

* Fix tests.

* Fix grumbles

* Remove Default bound

* Fix build for new nightly.

* Make `apply_extrinsic` never panic, return useful Result.

* More merge hell

* Doesn't build, but might do soon

* Serde woes

* get substrate-runtime-staking compiling

* Polkadot builds again!

* Fix all build.

* Fix tests & binaries.

* Reserve some extra initial byte values of address for future format changes

* Make semantic of `ReservedBalance` clear.

* Fix panic handler.

* Integrate other balance transformations into the new model

Fix up staking tests.

* Fix runtime tests.

* Fix panic build.

* Tests for demonstrating interaction between balance types.

* Repot some runtime code

* Fix checkedblock in non-std builds

* Get rid of `DoLookup` phantom.

* Attempt to make transaction_pool work with lookups.

* Remove vscode settings

* New attempt at making transaction pool work.

* It builds again!

* --all builds

* Fix tests.

* New build.

* Test account nonce reset.

* polkadot transaction pool tests/framework.

* Initial draft (working).

* Address grumbles.

* Revert bad `map_or`

* Rebuild binaries, workaround.

* Avoid checking in vscode

* reconnecting, shared, slog

* CLI options for name and telemetry url

* ensure telemetry url imples enabled

* Avoid casting to usize early.

* Provide on-connect event for session message

* Better port

* heartbeat and some renaming

* transaction pool stuff

* minor renaming.

* report telemetry

* cleanups.

* Fix for previous cleanup

* dump genesis, dev mode, renaming

* Rework chain spec/config &c. to allow for genesis file loading.

* Avoid producing genesis storage when unneeded

* Allow reading JSON genesis state dumps

* tests work again

* better logging.

* Fix wasm build.

* Introduce PoC-1 spec

* Made block message compatible with poc-1

* Squashed changes for dumping genesis block.

* Binaries.

* Made block message compatible with poc-1

* Remove dead code.

* Fix bad merge.

* Argument passing and returning values when invoking sandboxed funcs (#189)

* Fixed block download sequence (#223)

* Trie-based execution proof (#177)

* TrieBasedBackend

* trie tests

* redunant return_value removed

* use Trie::get_with to record trie proofs

* Relaying tx/blocks by light clients (#190)

* do not import external transactions into light tx pool

* do not announce blocks on light clients

* blocks_are_not_announced_by_light_nodes
This commit is contained in:
Gav Wood
2018-06-21 19:18:05 +02:00
committed by GitHub
parent 2d99855ef7
commit 60f7b897a8
49 changed files with 686 additions and 488 deletions
+6 -1
View File
@@ -1381,14 +1381,19 @@ dependencies = [
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-primitives 0.1.0",
"polkadot-runtime 0.1.0",
"polkadot-service 0.2.0",
"polkadot-transaction-pool 0.1.0",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-client 0.1.0",
"substrate-network 0.1.0",
"substrate-primitives 0.1.0",
"substrate-rpc 0.1.0",
"substrate-rpc-servers 0.1.0",
"substrate-runtime-primitives 0.1.0",
"substrate-state-machine 0.1.0",
"substrate-telemetry 0.2.0",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1506,7 +1511,6 @@ dependencies = [
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"exit-future 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1525,6 +1529,7 @@ dependencies = [
"substrate-network 0.1.0",
"substrate-primitives 0.1.0",
"substrate-runtime-io 0.1.0",
"substrate-runtime-primitives 0.1.0",
"substrate-state-machine 0.1.0",
"substrate-telemetry 0.2.0",
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
-1
View File
@@ -56,7 +56,6 @@ members = [
"substrate/test-runtime",
"substrate/telemetry",
"substrate/keystore",
"demo/cli",
"demo/executor",
"demo/primitives",
+50 -61
View File
@@ -48,11 +48,10 @@ extern crate log;
pub mod error;
use std::sync::Arc;
use client::genesis;
use demo_primitives::Hash;
use demo_runtime::{GenesisConfig, ConsensusConfig, CouncilConfig, DemocracyConfig,
SessionConfig, StakingConfig, BuildExternalities};
use demo_runtime::{Block, Header, UncheckedExtrinsic};
SessionConfig, StakingConfig, BuildStorage};
use demo_runtime::{Block, UncheckedExtrinsic};
use futures::{Future, Sink, Stream};
struct DummyPool;
@@ -101,66 +100,56 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
// Create client
let executor = demo_executor::Executor::new();
struct GenesisBuilder;
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
let genesis_storage = GenesisConfig {
consensus: Some(ConsensusConfig {
code: vec![], // TODO
authorities: vec![god_key.clone()],
}),
system: None,
// block_time: 5, // 5 second block time.
session: Some(SessionConfig {
validators: vec![god_key.clone().into()],
session_length: 720, // that's 1 hour per session.
}),
staking: Some(StakingConfig {
current_era: 0,
intentions: vec![],
transaction_base_fee: 100,
transaction_byte_fee: 1,
transfer_fee: 0,
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
existential_deposit: 500,
balances: vec![(god_key.clone().into(), 1u64 << 63)].into_iter().collect(),
validator_count: 12,
sessions_per_era: 24, // 24 hours per era.
bonding_duration: 90, // 90 days per bond.
}),
democracy: Some(DemocracyConfig {
launch_period: 120 * 24 * 14, // 2 weeks per public referendum
voting_period: 120 * 24 * 28, // 4 weeks to discuss & vote on an active referendum
minimum_deposit: 1000, // 1000 as the minimum deposit for a referendum
}),
council: Some(CouncilConfig {
active_council: vec![],
candidacy_bond: 1000, // 1000 to become a council candidate
voter_bond: 100, // 100 down to vote for a candidate
present_slash_per_voter: 1, // slash by 1 per voter for an invalid presentation.
carry_count: 24, // carry over the 24 runners-up to the next council election
presentation_duration: 120 * 24, // one day for presenting winners.
approval_voting_period: 7 * 120 * 24, // one week period between possible council elections.
term_duration: 180 * 120 * 24, // 180 day term duration for the council.
desired_seats: 0, // start with no council: we'll raise this once the stake has been dispersed a bit.
inactive_grace_period: 1, // one addition vote should go by before an inactive voter can be reaped.
impl client::GenesisBuilder<Block> for GenesisBuilder {
fn build(self) -> (Header, Vec<(Vec<u8>, Vec<u8>)>) {
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
let genesis_config = GenesisConfig {
consensus: Some(ConsensusConfig {
code: vec![], // TODO
authorities: vec![god_key.clone()],
}),
system: None,
// block_time: 5, // 5 second block time.
session: Some(SessionConfig {
validators: vec![god_key.clone().into()],
session_length: 720, // that's 1 hour per session.
}),
staking: Some(StakingConfig {
current_era: 0,
intentions: vec![],
transaction_base_fee: 100,
transaction_byte_fee: 1,
transfer_fee: 0,
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
existential_deposit: 500,
balances: vec![(god_key.clone().into(), 1u64 << 63)].into_iter().collect(),
validator_count: 12,
sessions_per_era: 24, // 24 hours per era.
bonding_duration: 90, // 90 days per bond.
}),
democracy: Some(DemocracyConfig {
launch_period: 120 * 24 * 14, // 2 weeks per public referendum
voting_period: 120 * 24 * 28, // 4 weeks to discuss & vote on an active referendum
minimum_deposit: 1000, // 1000 as the minimum deposit for a referendum
}),
council: Some(CouncilConfig {
active_council: vec![],
candidacy_bond: 1000, // 1000 to become a council candidate
voter_bond: 100, // 100 down to vote for a candidate
present_slash_per_voter: 1, // slash by 1 per voter for an invalid presentation.
carry_count: 24, // carry over the 24 runners-up to the next council election
presentation_duration: 120 * 24, // one day for presenting winners.
approval_voting_period: 7 * 120 * 24, // one week period between possible council elections.
term_duration: 180 * 120 * 24, // 180 day term duration for the council.
desired_seats: 0, // start with no council: we'll raise this once the stake has been dispersed a bit.
inactive_grace_period: 1, // one addition vote should go by before an inactive voter can be reaped.
cooloff_period: 90 * 120 * 24, // 90 day cooling off period if council member vetoes a proposal.
voting_period: 7 * 120 * 24, // 7 day voting period for council members.
}),
}.build_storage();
cooloff_period: 90 * 120 * 24, // 90 day cooling off period if council member vetoes a proposal.
voting_period: 7 * 120 * 24, // 7 day voting period for council members.
}),
};
let storage = genesis_config.build_externalities();
let block = genesis::construct_genesis_block::<Block>(&storage);
(block.header, storage.into_iter().collect())
}
}
let client = Arc::new(client::new_in_mem(executor, GenesisBuilder)?);
let client = Arc::new(client::new_in_mem::<_, Block, _>(executor, genesis_storage)?);
let mut core = ::tokio_core::reactor::Core::new().expect("Unable to spawn event loop.");
let _rpc_servers = {
+2 -2
View File
@@ -51,7 +51,7 @@ mod tests {
use runtime_primitives::{ApplyOutcome, ApplyError, ApplyResult, MaybeUnsigned};
use {staking, system};
use demo_runtime::{Header, Block, UncheckedExtrinsic, Extrinsic, Call, Concrete, Staking,
BuildExternalities, GenesisConfig, SessionConfig, StakingConfig, BareExtrinsic};
BuildStorage, GenesisConfig, SessionConfig, StakingConfig, BareExtrinsic};
use ed25519::{Public, Pair};
const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm");
@@ -203,7 +203,7 @@ mod tests {
}),
democracy: Some(Default::default()),
council: Some(Default::default()),
}.build_externalities()
}.build_storage()
}
fn construct_block(number: BlockNumber, parent_hash: Hash, state_root: Hash, extrinsics: Vec<BareExtrinsic>) -> (Vec<u8>, Hash) {
+1 -1
View File
@@ -51,7 +51,7 @@ use runtime_primitives::generic;
use runtime_primitives::traits::{Convert, HasPublicAux, BlakeTwo256};
#[cfg(any(feature = "std", test))]
pub use runtime_primitives::BuildExternalities;
pub use runtime_primitives::BuildStorage;
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, Copy, PartialEq, Eq)]
+18 -28
View File
@@ -187,10 +187,10 @@ impl<B: LocalBackend<Block>> LocalPolkadotApi for Client<B, LocalCallExecutor<B,
mod tests {
use super::*;
use keyring::Keyring;
use client::{self, LocalCallExecutor};
use client::LocalCallExecutor;
use client::in_mem::Backend as InMemory;
use substrate_executor::NativeExecutionDispatch;
use runtime::{GenesisConfig, ConsensusConfig, SessionConfig, BuildExternalities};
use runtime::{GenesisConfig, ConsensusConfig, SessionConfig, BuildStorage};
fn validators() -> Vec<AccountId> {
vec![
@@ -207,33 +207,23 @@ mod tests {
}
fn client() -> Client<InMemory<Block>, LocalCallExecutor<InMemory<Block>, NativeExecutor<LocalDispatch>>, Block> {
struct GenesisBuilder;
let genesis_config = GenesisConfig {
consensus: Some(ConsensusConfig {
code: LocalDispatch::native_equivalent().to_vec(),
authorities: session_keys(),
}),
system: None,
session: Some(SessionConfig {
validators: validators(),
session_length: 100,
}),
council: Some(Default::default()),
democracy: Some(Default::default()),
parachains: Some(Default::default()),
staking: Some(Default::default()),
};
impl client::GenesisBuilder<Block> for GenesisBuilder {
fn build(self) -> (Header, Vec<(Vec<u8>, Vec<u8>)>) {
let genesis_config = GenesisConfig {
consensus: Some(ConsensusConfig {
code: LocalDispatch::native_equivalent().to_vec(),
authorities: session_keys(),
}),
system: None,
session: Some(SessionConfig {
validators: validators(),
session_length: 100,
}),
council: Some(Default::default()),
democracy: Some(Default::default()),
parachains: Some(Default::default()),
staking: Some(Default::default()),
};
let storage = genesis_config.build_externalities();
let block = ::client::genesis::construct_genesis_block::<Block>(&storage);
(block.header, storage.into_iter().collect())
}
}
::client::new_in_mem(LocalDispatch::new(), GenesisBuilder).unwrap()
::client::new_in_mem(LocalDispatch::new(), genesis_config.build_storage()).unwrap()
}
#[test]
+5
View File
@@ -24,12 +24,17 @@ futures = "0.1.17"
ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" }
fdlimit = "0.1"
parking_lot = "0.4"
serde_json = "1.0"
serde = "1.0"
substrate-client = { path = "../../substrate/client" }
substrate-state-machine = { path = "../../substrate/state-machine" }
substrate-rpc = { path = "../../substrate/rpc" }
substrate-rpc-servers = { path = "../../substrate/rpc-servers" }
substrate-network = { path = "../../substrate/network" }
substrate-primitives = { path = "../../substrate/primitives" }
substrate-runtime-primitives = { path = "../../substrate/runtime/primitives" }
substrate-telemetry = { path = "../../substrate/telemetry" }
polkadot-primitives = { path = "../primitives" }
polkadot-runtime = { path = "../runtime" }
polkadot-service = { path = "../service" }
polkadot-transaction-pool = { path = "../transaction-pool" }
File diff suppressed because one or more lines are too long
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.?
//! Predefined chains.
/// The chain specification (this should eventually be replaced by a more general JSON-based chain
/// specification).
#[derive(Clone, Debug)]
pub enum ChainSpec {
/// Whatever the current runtime is, with just Alice as an auth.
Development,
/// Whatever the current runtime is, with simple Alice/Bob auths.
LocalTestnet,
/// The PoC-1 testnet.
PoC1Testnet,
/// The PoC-2 testnet.
PoC2Testnet,
/// Custom Genesis file.
Custom(String),
}
impl<'a> From<&'a str> for ChainSpec {
fn from(s: &'a str) -> Self {
match s {
"dev" => ChainSpec::Development,
"local" => ChainSpec::LocalTestnet,
"poc-1" => ChainSpec::PoC1Testnet,
"poc-2" => ChainSpec::PoC2Testnet,
s => ChainSpec::Custom(s.into()),
}
}
}
impl From<ChainSpec> for String {
fn from(s: ChainSpec) -> String {
match s {
ChainSpec::Development => "dev".into(),
ChainSpec::LocalTestnet => "local".into(),
ChainSpec::PoC1Testnet => "poc-1".into(),
ChainSpec::PoC2Testnet => "poc-2".into(),
ChainSpec::Custom(f) => format!("custom ({})", f),
}
}
}
impl ::std::fmt::Display for ChainSpec {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
if let ChainSpec::Custom(n) = self {
write!(f, "Custom ({})", n)
} else {
write!(f, "{}", match *self {
ChainSpec::Development => "Development",
ChainSpec::LocalTestnet => "Local Testnet",
ChainSpec::PoC1Testnet => "PoC-1 Testnet",
ChainSpec::PoC2Testnet => "PoC-2 Testnet",
_ => unreachable!(),
})
}
}
}
+10 -2
View File
@@ -27,7 +27,7 @@ args:
- node-key:
long: node-key
value_name: KEY
help: Specify node secret key (64-character hex string).
help: Specify node secret key (64-character hex string)
takes_value: true
- collator:
long: collator
@@ -41,6 +41,14 @@ args:
long: light
help: Run in light client mode
takes_value: false
- dev:
long: dev
help: Run in development mode; implies --chain=dev --validator --key Alice
takes_value: false
- build-genesis:
long: build-genesis
help: Build a genesis.json file, outputing to stdout
takes_value: false
- port:
long: port
value_name: PORT
@@ -80,6 +88,6 @@ args:
- telemetry-url:
long: telemetry-url
value_name: TELEMETRY_URL
help: The URL of the telemetry server. Implies --telemetry.
help: The URL of the telemetry server. Implies --telemetry
takes_value: true
subcommands:
+82 -33
View File
@@ -31,13 +31,18 @@ extern crate fdlimit;
extern crate ed25519;
extern crate triehash;
extern crate parking_lot;
extern crate serde;
extern crate serde_json;
extern crate substrate_primitives;
extern crate substrate_state_machine as state_machine;
extern crate substrate_client as client;
extern crate substrate_network as network;
extern crate substrate_rpc;
extern crate substrate_rpc_servers as rpc;
extern crate substrate_runtime_primitives as runtime_primitives;
extern crate polkadot_primitives;
extern crate polkadot_runtime;
extern crate polkadot_service as service;
#[macro_use]
extern crate slog; // needed until we can reexport `slog_info` from `substrate_telemetry`
@@ -53,26 +58,40 @@ extern crate clap;
extern crate error_chain;
#[macro_use]
extern crate log;
#[macro_use]
extern crate hex_literal;
pub mod error;
mod informant;
mod chain_spec;
mod preset_config;
pub use chain_spec::ChainSpec;
pub use preset_config::PresetConfig;
use std::io;
use std::fs::File;
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use polkadot_primitives::Block;
use std::collections::HashMap;
use substrate_primitives::hexdisplay::HexDisplay;
use substrate_primitives::storage::{StorageData, StorageKey};
use substrate_telemetry::{init_telemetry, TelemetryConfig};
use runtime_primitives::StorageMap;
use polkadot_primitives::Block;
use futures::sync::mpsc;
use futures::{Sink, Future, Stream};
use tokio_core::reactor;
use service::{OptionChainSpec, ChainSpec};
const DEFAULT_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io:443";
struct Configuration(service::Configuration);
#[derive(Clone)]
struct SystemConfiguration {
chain_name: String,
}
impl substrate_rpc::system::SystemApi for Configuration {
impl substrate_rpc::system::SystemApi for SystemConfiguration {
fn system_name(&self) -> substrate_rpc::system::error::Result<String> {
Ok("parity-polkadot".into())
}
@@ -82,14 +101,16 @@ impl substrate_rpc::system::SystemApi for Configuration {
}
fn system_chain(&self) -> substrate_rpc::system::error::Result<String> {
Ok(match self.0.chain_spec {
ChainSpec::Development => "dev",
ChainSpec::LocalTestnet => "local",
ChainSpec::PoC2Testnet => "poc-2",
}.into())
Ok(self.chain_name.clone())
}
}
fn read_storage_json(filename: &str) -> Option<StorageMap> {
let file = File::open(PathBuf::from(filename)).ok()?;
let h: HashMap<StorageKey, StorageData> = ::serde_json::from_reader(&file).ok()?;
Some(h.into_iter().map(|(k, v)| (k.0, v.0)).collect())
}
/// Parse command line arguments and start the node.
///
/// IANA unassigned port ranges that we could use:
@@ -131,9 +152,16 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
info!("Node name: {}", config.name);
}
let chain_spec = matches.value_of("chain")
.map(ChainSpec::from)
.unwrap_or_else(|| if matches.is_present("dev") { ChainSpec::Development } else { ChainSpec::PoC2Testnet });
info!("Chain specification: {}", chain_spec);
config.chain_name = chain_spec.clone().into();
let _guard = if matches.is_present("telemetry") || matches.value_of("telemetry-url").is_some() {
let name = config.name.clone();
let chain = config.chain_spec.clone();
let chain_name = config.chain_name.clone();
Some(init_telemetry(TelemetryConfig {
url: matches.value_of("telemetry-url").unwrap_or(DEFAULT_TELEMETRY_URL).into(),
on_connect: Box::new(move || {
@@ -142,7 +170,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
"implementation" => "parity-polkadot",
"version" => crate_version!(),
"config" => "",
"chain" => <&'static str>::from(chain)
"chain" => chain_name.clone(),
);
}),
}))
@@ -162,32 +190,46 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
config.database_path = db_path(&base_path).to_string_lossy().into();
let mut role = service::Role::FULL;
if matches.is_present("collator") {
info!("Starting collator");
role = service::Role::COLLATOR;
} else if matches.is_present("validator") {
info!("Starting validator");
role = service::Role::VALIDATOR;
} else if matches.is_present("light") {
info!("Starting (light)");
role = service::Role::LIGHT;
} else {
info!("Starting (heavy)");
let (mut genesis_storage, boot_nodes) = PresetConfig::from_spec(chain_spec)
.map(PresetConfig::deconstruct)
.unwrap_or_else(|f| (Box::new(move ||
read_storage_json(&f)
.map(|s| { info!("{} storage items read from {}", s.len(), f); s })
.unwrap_or_else(|| panic!("Bad genesis state file: {}", f))
), vec![]));
if matches.is_present("build-genesis") {
info!("Building genesis");
for (i, (k, v)) in genesis_storage().iter().enumerate() {
print!("{}\n\"0x{}\": \"0x{}\"", if i > 0 {','} else {'{'}, HexDisplay::from(k), HexDisplay::from(v));
}
println!("\n}}");
return Ok(())
}
match matches.value_of("chain") {
None => (),
Some(n) => config.chain_spec = OptionChainSpec::from(n).inner()
.unwrap_or_else(|| panic!("Invalid chain name: {}", n)),
}
info!("Chain specification: {}", config.chain_spec);
config.genesis_storage = genesis_storage;
let role =
if matches.is_present("collator") {
info!("Starting collator");
service::Role::COLLATOR
} else if matches.is_present("light") {
info!("Starting (light)");
service::Role::LIGHT
} else if matches.is_present("validator") || matches.is_present("dev") {
info!("Starting validator");
service::Role::VALIDATOR
} else {
info!("Starting (heavy)");
service::Role::FULL
};
config.roles = role;
{
config.network.boot_nodes = matches
.values_of("bootnodes")
.map_or(Default::default(), |v| v.map(|n| n.to_owned()).collect());
config.network.boot_nodes.extend(boot_nodes);
config.network.config_path = Some(network_path(&base_path).to_string_lossy().into());
config.network.net_config_path = config.network.config_path.clone();
@@ -206,14 +248,21 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
}
config.keys = matches.values_of("key").unwrap_or_default().map(str::to_owned).collect();
if matches.is_present("dev") {
config.keys.push("Alice".into());
}
let sys_conf = SystemConfiguration {
chain_name: config.chain_name.clone(),
};
match role == service::Role::LIGHT {
true => run_until_exit(core, service::new_light(config.clone())?, &matches, config),
false => run_until_exit(core, service::new_full(config.clone())?, &matches, config),
true => run_until_exit(core, service::new_light(config)?, &matches, sys_conf),
false => run_until_exit(core, service::new_full(config)?, &matches, sys_conf),
}
}
fn run_until_exit<C>(mut core: reactor::Core, service: service::Service<C>, matches: &clap::ArgMatches, config: service::Configuration) -> error::Result<()>
fn run_until_exit<C>(mut core: reactor::Core, service: service::Service<C>, matches: &clap::ArgMatches, sys_conf: SystemConfiguration) -> error::Result<()>
where
C: service::Components,
client::error::Error: From<<<<C as service::Components>::Backend as client::backend::Backend<Block>>::State as state_machine::Backend>::Error>,
@@ -240,7 +289,7 @@ fn run_until_exit<C>(mut core: reactor::Core, service: service::Service<C>, matc
service.client(),
chain,
service.transaction_pool(),
Configuration(config.clone()),
sys_conf.clone(),
)
};
(
+222
View File
@@ -0,0 +1,222 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Polkadot chain configurations.
use std::collections::HashMap;
use ed25519;
use serde_json;
use substrate_primitives::{AuthorityId, storage::{StorageKey, StorageData}};
use runtime_primitives::{MakeStorage, BuildStorage, StorageMap};
use polkadot_runtime::{GenesisConfig, ConsensusConfig, CouncilConfig, DemocracyConfig,
SessionConfig, StakingConfig};
use chain_spec::ChainSpec;
enum Config {
Local(GenesisConfig),
Raw(&'static [u8]),
}
/// A configuration of a chain. Can be used to build a genesis block.
pub struct PresetConfig {
genesis_config: Config,
pub(crate) boot_nodes: Vec<String>,
}
impl BuildStorage for Config {
fn build_storage(self) -> StorageMap {
match self {
Config::Local(gc) => gc.build_storage(),
Config::Raw(json) => {
let h: HashMap<StorageKey, StorageData> = serde_json::from_slice(json).expect("Data is from an internal source and is guaranteed to be of the correct format");
h.into_iter().map(|(k, v)| (k.0, v.0)).collect()
}
}
}
}
impl PresetConfig {
/// Get a chain config from a spec, if it's predefined.
pub fn from_spec(chain_spec: ChainSpec) -> Result<Self, String> {
Ok(match chain_spec {
ChainSpec::PoC1Testnet => Self::poc_1_testnet_config(),
ChainSpec::Development => Self::development_config(),
ChainSpec::LocalTestnet => Self::local_testnet_config(),
ChainSpec::PoC2Testnet => Self::poc_2_testnet_config(),
ChainSpec::Custom(f) => return Err(f),
})
}
/// Provide the boot nodes and a storage-builder function.
// TODO: Change return type to FnOnce as soon as Box<FnOnce> is callable or BoxFn is stablised.
pub fn deconstruct(self) -> (MakeStorage, Vec<String>) {
let mut gc = Some(self.genesis_config);
let f = move || gc.take().map(BuildStorage::build_storage).unwrap_or_default();
(Box::new(f), self.boot_nodes)
}
/// PoC-1 testnet config.
fn poc_1_testnet_config() -> Self {
let genesis_config = Config::Raw(include_bytes!("../poc-1.json"));
let boot_nodes = vec![
"enode://a93a29fa68d965452bf0ff8c1910f5992fe2273a72a1ee8d3a3482f68512a61974211ba32bb33f051ceb1530b8ba3527fc36224ba6b9910329025e6d9153cf50@104.211.54.233:30333".into(),
"enode://051b18f63a316c4c5fef4631f8c550ae0adba179153588406fac3e5bbbbf534ebeda1bf475dceda27a531f6cdef3846ab6a010a269aa643a1fec7bff51af66bd@104.211.48.51:30333".into(),
"enode://c831ec9011d2c02d2c4620fc88db6d897a40d2f88fd75f47b9e4cf3b243999acb6f01b7b7343474650b34eeb1363041a422a91f1fc3850e43482983ee15aa582@104.211.48.247:30333".into(),
];
PresetConfig { genesis_config, boot_nodes }
}
/// PoC-2 testnet config.
fn poc_2_testnet_config() -> Self {
let initial_authorities = vec![
hex!["82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5"].into(),
hex!["4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7"].into(),
hex!["063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca5"].into(),
hex!["8101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c"].into(),
];
let endowed_accounts = vec![
hex!["f295940fa750df68a686fcf4abd4111c8a9c5a5a5a83c4c8639c451a94a7adfd"].into(),
];
let genesis_config = Config::Local(GenesisConfig {
consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/genesis.wasm").to_vec(), // TODO change
authorities: initial_authorities.clone(),
}),
system: None,
session: Some(SessionConfig {
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
session_length: 720, // that's 1 hour per session.
}),
staking: Some(StakingConfig {
current_era: 0,
intentions: initial_authorities.iter().cloned().map(Into::into).collect(),
transaction_base_fee: 100,
transaction_byte_fee: 1,
existential_deposit: 500,
transfer_fee: 0,
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
balances: endowed_accounts.iter().map(|&k|(k, 1u128 << 60)).collect(),
validator_count: 12,
sessions_per_era: 24, // 24 hours per era.
bonding_duration: 90, // 90 days per bond.
}),
democracy: Some(DemocracyConfig {
launch_period: 120 * 24 * 14, // 2 weeks per public referendum
voting_period: 120 * 24 * 28, // 4 weeks to discuss & vote on an active referendum
minimum_deposit: 1000, // 1000 as the minimum deposit for a referendum
}),
council: Some(CouncilConfig {
active_council: vec![],
candidacy_bond: 1000, // 1000 to become a council candidate
voter_bond: 100, // 100 down to vote for a candidate
present_slash_per_voter: 1, // slash by 1 per voter for an invalid presentation.
carry_count: 24, // carry over the 24 runners-up to the next council election
presentation_duration: 120 * 24, // one day for presenting winners.
approval_voting_period: 7 * 120 * 24, // one week period between possible council elections.
term_duration: 180 * 120 * 24, // 180 day term duration for the council.
desired_seats: 0, // start with no council: we'll raise this once the stake has been dispersed a bit.
inactive_grace_period: 1, // one addition vote should go by before an inactive voter can be reaped.
cooloff_period: 90 * 120 * 24, // 90 day cooling off period if council member vetoes a proposal.
voting_period: 7 * 120 * 24, // 7 day voting period for council members.
}),
parachains: Some(Default::default()),
});
let boot_nodes = vec![
"enode://a93a29fa68d965452bf0ff8c1910f5992fe2273a72a1ee8d3a3482f68512a61974211ba32bb33f051ceb1530b8ba3527fc36224ba6b9910329025e6d9153cf50@104.211.54.233:30333".into(),
"enode://051b18f63a316c4c5fef4631f8c550ae0adba179153588406fac3e5bbbbf534ebeda1bf475dceda27a531f6cdef3846ab6a010a269aa643a1fec7bff51af66bd@104.211.48.51:30333".into(),
"enode://c831ec9011d2c02d2c4620fc88db6d897a40d2f88fd75f47b9e4cf3b243999acb6f01b7b7343474650b34eeb1363041a422a91f1fc3850e43482983ee15aa582@104.211.48.247:30333".into(),
];
PresetConfig { genesis_config, boot_nodes }
}
fn testnet_config(initial_authorities: Vec<AuthorityId>) -> PresetConfig {
let endowed_accounts = vec![
ed25519::Pair::from_seed(b"Alice ").public().0.into(),
ed25519::Pair::from_seed(b"Bob ").public().0.into(),
ed25519::Pair::from_seed(b"Charlie ").public().0.into(),
ed25519::Pair::from_seed(b"Dave ").public().0.into(),
ed25519::Pair::from_seed(b"Eve ").public().0.into(),
ed25519::Pair::from_seed(b"Ferdie ").public().0.into(),
];
let genesis_config = Config::Local(GenesisConfig {
consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm").to_vec(),
authorities: initial_authorities.clone(),
}),
system: None,
session: Some(SessionConfig {
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
session_length: 10,
}),
staking: Some(StakingConfig {
current_era: 0,
intentions: initial_authorities.iter().cloned().map(Into::into).collect(),
transaction_base_fee: 1,
transaction_byte_fee: 0,
existential_deposit: 500,
transfer_fee: 0,
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
balances: endowed_accounts.iter().map(|&k|(k, (1u128 << 60))).collect(),
validator_count: 2,
sessions_per_era: 5,
bonding_duration: 2,
}),
democracy: Some(DemocracyConfig {
launch_period: 9,
voting_period: 18,
minimum_deposit: 10,
}),
council: Some(CouncilConfig {
active_council: endowed_accounts.iter().filter(|a| initial_authorities.iter().find(|&b| &a.0 == b).is_none()).map(|a| (a.clone(), 1000000)).collect(),
candidacy_bond: 10,
voter_bond: 2,
present_slash_per_voter: 1,
carry_count: 4,
presentation_duration: 10,
approval_voting_period: 20,
term_duration: 1000000,
desired_seats: (endowed_accounts.len() - initial_authorities.len()) as u32,
inactive_grace_period: 1,
cooloff_period: 75,
voting_period: 20,
}),
parachains: Some(Default::default()),
});
let boot_nodes = Vec::new();
PresetConfig { genesis_config, boot_nodes }
}
/// Development config (single validator Alice)
fn development_config() -> Self {
Self::testnet_config(vec![
ed25519::Pair::from_seed(b"Alice ").public().into(),
])
}
/// Local testnet config (multivalidator Alice + Bob)
fn local_testnet_config() -> Self {
Self::testnet_config(vec![
ed25519::Pair::from_seed(b"Alice ").public().into(),
ed25519::Pair::from_seed(b"Bob ").public().into(),
])
}
}
+1 -1
View File
@@ -71,7 +71,7 @@ use primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Log
use runtime_primitives::{generic, traits::{HasPublicAux, BlakeTwo256, Convert}};
#[cfg(feature = "std")]
pub use runtime_primitives::BuildExternalities;
pub use runtime_primitives::BuildStorage;
pub use consensus::Call as ConsensusCall;
pub use timestamp::Call as TimestampCall;
+7 -7
View File
@@ -199,9 +199,9 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> runtime_primitives::BuildExternalities for GenesisConfig<T>
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T>
{
fn build_externalities(mut self) -> runtime_io::TestExternalities {
fn build_storage(mut self) -> runtime_io::TestExternalities {
use std::collections::HashMap;
use runtime_io::twox_128;
use codec::Slicable;
@@ -229,7 +229,7 @@ mod tests {
use super::*;
use runtime_io::with_externalities;
use substrate_primitives::H256;
use runtime_primitives::BuildExternalities;
use runtime_primitives::BuildStorage;
use runtime_primitives::traits::{HasPublicAux, Identity, BlakeTwo256};
use runtime_primitives::testing::{Digest, Header};
use consensus;
@@ -264,19 +264,19 @@ mod tests {
type Parachains = Module<Test>;
fn new_test_ext(parachains: Vec<(Id, Vec<u8>)>) -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![1, 2, 3],
}.build_externalities());
}.build_storage());
t.extend(session::GenesisConfig::<Test>{
session_length: 1000,
validators: vec![1, 2, 3, 4, 5, 6, 7, 8],
}.build_externalities());
}.build_storage());
t.extend(GenesisConfig::<Test>{
parachains: parachains,
phantom: PhantomData,
}.build_externalities());
}.build_storage());
t
}
+1 -1
View File
@@ -4,7 +4,6 @@ version = "0.2.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1"
futures = "0.1.17"
parking_lot = "0.4"
tokio-timer = "0.1.2"
@@ -24,6 +23,7 @@ polkadot-api = { path = "../api" }
polkadot-transaction-pool = { path = "../transaction-pool" }
substrate-keystore = { path = "../../substrate/keystore" }
substrate-runtime-io = { path = "../../substrate/runtime-io" }
substrate-runtime-primitives = { path = "../../substrate/runtime/primitives" }
substrate-primitives = { path = "../../substrate/primitives" }
substrate-network = { path = "../../substrate/network" }
substrate-client = { path = "../../substrate/client" }
+8 -21
View File
@@ -18,16 +18,16 @@
use std::collections::HashMap;
use std::sync::Arc;
use client::{self, genesis, Client};
use client::{self, Client};
use client_db;
use codec::{self, Slicable};
use consensus;
use keystore::Store as Keystore;
use network;
use polkadot_api;
use runtime_primitives::MakeStorage;
use polkadot_executor::Executor as LocalDispatch;
use polkadot_runtime::{GenesisConfig, BuildExternalities};
use polkadot_primitives::{Block, BlockId, Hash, Header};
use polkadot_primitives::{Block, BlockId, Hash};
use state_machine;
use substrate_executor::NativeExecutor;
use transaction_pool::{self, TransactionPool};
@@ -48,7 +48,7 @@ pub trait Components {
type Executor: 'static + client::CallExecutor<Block> + Send + Sync;
/// Create client.
fn build_client(&self, settings: client_db::DatabaseSettings, executor: CodeExecutor, genesis: GenesisBuilder)
fn build_client(&self, settings: client_db::DatabaseSettings, executor: CodeExecutor, genesis_storage: MakeStorage)
-> Result<(Arc<Client<Self::Backend, Self::Executor, Block>>, Option<Arc<network::OnDemand<Block, network::Service<Block>>>>), error::Error>;
/// Create api.
@@ -63,19 +63,6 @@ pub trait Components {
-> Result<Option<consensus::Service>, error::Error>;
}
/// Genesis block builder.
pub struct GenesisBuilder {
pub config: GenesisConfig,
}
impl client::GenesisBuilder<Block> for GenesisBuilder {
fn build(self) -> (Header, Vec<(Vec<u8>, Vec<u8>)>) {
let storage = self.config.build_externalities();
let block = genesis::construct_genesis_block::<Block>(&storage);
(block.header, storage.into_iter().collect())
}
}
/// Components for full Polkadot service.
pub struct FullComponents {
/// Is this a validator node?
@@ -87,9 +74,9 @@ impl Components for FullComponents {
type Api = Client<Self::Backend, Self::Executor, Block>;
type Executor = client::LocalCallExecutor<client_db::Backend<Block>, NativeExecutor<LocalDispatch>>;
fn build_client(&self, db_settings: client_db::DatabaseSettings, executor: CodeExecutor, genesis: GenesisBuilder)
fn build_client(&self, db_settings: client_db::DatabaseSettings, executor: CodeExecutor, genesis_storage: MakeStorage)
-> Result<(Arc<client::Client<Self::Backend, Self::Executor, Block>>, Option<Arc<network::OnDemand<Block, network::Service<Block>>>>), error::Error> {
Ok((Arc::new(client_db::new_client(db_settings, executor, genesis)?), None))
Ok((Arc::new(client_db::new_client(db_settings, executor, genesis_storage)?), None))
}
fn build_api(&self, client: Arc<client::Client<Self::Backend, Self::Executor, Block>>) -> Arc<Self::Api> {
@@ -134,12 +121,12 @@ impl Components for LightComponents {
type Api = polkadot_api::light::RemotePolkadotApiWrapper<Self::Backend, Self::Executor>;
type Executor = client::RemoteCallExecutor<client::light::Backend<Block>, network::OnDemand<Block, network::Service<Block>>>;
fn build_client(&self, _settings: client_db::DatabaseSettings, executor: CodeExecutor, genesis: GenesisBuilder)
fn build_client(&self, _settings: client_db::DatabaseSettings, executor: CodeExecutor, genesis_storage: MakeStorage)
-> Result<(Arc<client::Client<Self::Backend, Self::Executor, Block>>, Option<Arc<network::OnDemand<Block, network::Service<Block>>>>), error::Error> {
let client_backend = client::light::new_light_backend();
let fetch_checker = Arc::new(client::light::new_fetch_checker(client_backend.clone(), executor));
let fetcher = Arc::new(network::OnDemand::new(fetch_checker));
let client = client::light::new_light(client_backend, fetcher.clone(), genesis)?;
let client = client::light::new_light(client_backend, fetcher.clone(), genesis_storage)?;
Ok((Arc::new(client), Some(fetcher)))
}
+7 -57
View File
@@ -17,64 +17,11 @@
//! Service configuration.
use transaction_pool;
use runtime_primitives::MakeStorage;
pub use network::Role;
pub use network::NetworkConfiguration;
/// The chain specification (this should eventually be replaced by a more general JSON-based chain
/// specification).
#[derive(Clone, Copy, Debug)]
pub enum ChainSpec {
/// Whatever the current runtime is, with just Alice as an auth.
Development,
/// Whatever the current runtime is, with simple Alice/Bob auths.
LocalTestnet,
/// The PoC-2 testnet.
PoC2Testnet,
}
/// Synonym for Option<ChainSpec> because we cannot `impl From<..> for Option<ChainSpec>`
pub struct OptionChainSpec(Option<ChainSpec>);
impl OptionChainSpec {
/// Return the inner part.
pub fn inner(self) -> Option<ChainSpec> {
self.0
}
}
impl<'a> From<&'a str> for OptionChainSpec {
fn from(s: &'a str) -> Self {
OptionChainSpec(Some(match s {
"dev" => ChainSpec::Development,
"local" => ChainSpec::LocalTestnet,
"poc-2" => ChainSpec::PoC2Testnet,
_ => return OptionChainSpec(None),
}))
}
}
impl From<ChainSpec> for &'static str {
fn from(s: ChainSpec) -> &'static str {
match s {
ChainSpec::Development => "dev",
ChainSpec::LocalTestnet => "local",
ChainSpec::PoC2Testnet => "poc-2",
}
}
}
impl ::std::fmt::Display for ChainSpec {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", match *self {
ChainSpec::Development => "Development",
ChainSpec::LocalTestnet => "Local Testnet",
ChainSpec::PoC2Testnet => "PoC-2 Testnet",
})
}
}
/// Service configuration.
#[derive(Clone)]
pub struct Configuration {
/// Node roles.
pub roles: Role,
@@ -88,8 +35,10 @@ pub struct Configuration {
pub database_path: String,
/// Additional key seeds.
pub keys: Vec<String>,
/// Chain specification.
pub chain_spec: ChainSpec,
/// The name of the chain.
pub chain_name: String,
/// Chain configuration.
pub genesis_storage: MakeStorage,
/// Telemetry server URL, optional - only `Some` if telemetry reporting is enabled
pub telemetry: Option<String>,
/// Node name.
@@ -105,7 +54,8 @@ impl Default for Configuration {
keystore_path: Default::default(),
database_path: Default::default(),
keys: Default::default(),
chain_spec: ChainSpec::Development,
chain_name: Default::default(),
genesis_storage: Box::new(Default::default),
telemetry: Default::default(),
name: "Anonymous".into(),
}
+4 -163
View File
@@ -31,6 +31,7 @@ extern crate polkadot_transaction_pool as transaction_pool;
extern crate substrate_keystore as keystore;
extern crate substrate_runtime_io as runtime_io;
extern crate substrate_primitives as primitives;
extern crate substrate_runtime_primitives as runtime_primitives;
extern crate substrate_network as network;
extern crate substrate_codec as codec;
extern crate substrate_executor;
@@ -48,8 +49,6 @@ extern crate error_chain;
extern crate slog; // needed until we can reexport `slog_info` from `substrate_telemetry`
#[macro_use]
extern crate log;
#[macro_use]
extern crate hex_literal;
mod components;
mod error;
@@ -59,20 +58,17 @@ use std::sync::Arc;
use std::thread;
use futures::prelude::*;
use tokio_core::reactor::Core;
use primitives::AuthorityId;
use transaction_pool::TransactionPool;
use keystore::Store as Keystore;
use polkadot_api::PolkadotApi;
use polkadot_primitives::{Block, BlockId, Hash};
use polkadot_runtime::{GenesisConfig, ConsensusConfig, CouncilConfig, DemocracyConfig,
SessionConfig, StakingConfig};
use client::{Client, BlockchainEvents};
use network::ManageNetwork;
use exit_future::Signal;
pub use self::error::{ErrorKind, Error};
pub use self::components::{Components, FullComponents, LightComponents};
pub use config::{Configuration, Role, OptionChainSpec, ChainSpec};
pub use config::{Configuration, Role};
/// Polkadot service.
pub struct Service<Components: components::Components> {
@@ -84,149 +80,6 @@ pub struct Service<Components: components::Components> {
_consensus: Option<consensus::Service>,
}
pub struct ChainConfig {
genesis_config: GenesisConfig,
boot_nodes: Vec<String>,
}
fn poc_2_testnet_config() -> ChainConfig {
let initial_authorities = vec![
hex!["82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5"].into(),
hex!["4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7"].into(),
hex!["063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca5"].into(),
hex!["8101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c"].into(),
];
let endowed_accounts = vec![
hex!["f295940fa750df68a686fcf4abd4111c8a9c5a5a5a83c4c8639c451a94a7adfd"].into(),
];
let genesis_config = GenesisConfig {
consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/genesis.wasm").to_vec(), // TODO change
authorities: initial_authorities.clone(),
}),
system: None,
session: Some(SessionConfig {
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
session_length: 720, // that's 1 hour per session.
}),
staking: Some(StakingConfig {
current_era: 0,
intentions: initial_authorities.iter().cloned().map(Into::into).collect(),
transaction_base_fee: 100,
transaction_byte_fee: 1,
existential_deposit: 500,
transfer_fee: 0,
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
balances: endowed_accounts.iter().map(|&k|(k, 1u128 << 60)).collect(),
validator_count: 12,
sessions_per_era: 24, // 24 hours per era.
bonding_duration: 90, // 90 days per bond.
}),
democracy: Some(DemocracyConfig {
launch_period: 120 * 24 * 14, // 2 weeks per public referendum
voting_period: 120 * 24 * 28, // 4 weeks to discuss & vote on an active referendum
minimum_deposit: 1000, // 1000 as the minimum deposit for a referendum
}),
council: Some(CouncilConfig {
active_council: vec![],
candidacy_bond: 1000, // 1000 to become a council candidate
voter_bond: 100, // 100 down to vote for a candidate
present_slash_per_voter: 1, // slash by 1 per voter for an invalid presentation.
carry_count: 24, // carry over the 24 runners-up to the next council election
presentation_duration: 120 * 24, // one day for presenting winners.
approval_voting_period: 7 * 120 * 24, // one week period between possible council elections.
term_duration: 180 * 120 * 24, // 180 day term duration for the council.
desired_seats: 0, // start with no council: we'll raise this once the stake has been dispersed a bit.
inactive_grace_period: 1, // one addition vote should go by before an inactive voter can be reaped.
cooloff_period: 90 * 120 * 24, // 90 day cooling off period if council member vetoes a proposal.
voting_period: 7 * 120 * 24, // 7 day voting period for council members.
}),
parachains: Some(Default::default()),
};
let boot_nodes = vec![
"enode://a93a29fa68d965452bf0ff8c1910f5992fe2273a72a1ee8d3a3482f68512a61974211ba32bb33f051ceb1530b8ba3527fc36224ba6b9910329025e6d9153cf50@104.211.54.233:30333".into(),
"enode://051b18f63a316c4c5fef4631f8c550ae0adba179153588406fac3e5bbbbf534ebeda1bf475dceda27a531f6cdef3846ab6a010a269aa643a1fec7bff51af66bd@104.211.48.51:30333".into(),
"enode://c831ec9011d2c02d2c4620fc88db6d897a40d2f88fd75f47b9e4cf3b243999acb6f01b7b7343474650b34eeb1363041a422a91f1fc3850e43482983ee15aa582@104.211.48.247:30333".into(),
];
ChainConfig { genesis_config, boot_nodes }
}
fn testnet_config(initial_authorities: Vec<AuthorityId>) -> ChainConfig {
let endowed_accounts = vec![
ed25519::Pair::from_seed(b"Alice ").public().0.into(),
ed25519::Pair::from_seed(b"Bob ").public().0.into(),
ed25519::Pair::from_seed(b"Charlie ").public().0.into(),
ed25519::Pair::from_seed(b"Dave ").public().0.into(),
ed25519::Pair::from_seed(b"Eve ").public().0.into(),
ed25519::Pair::from_seed(b"Ferdie ").public().0.into(),
];
let genesis_config = GenesisConfig {
consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm").to_vec(),
authorities: initial_authorities.clone(),
}),
system: None,
session: Some(SessionConfig {
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
session_length: 10,
}),
staking: Some(StakingConfig {
current_era: 0,
intentions: initial_authorities.iter().cloned().map(Into::into).collect(),
transaction_base_fee: 1,
transaction_byte_fee: 0,
existential_deposit: 500,
transfer_fee: 0,
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
balances: endowed_accounts.iter().map(|&k|(k, (1u128 << 60))).collect(),
validator_count: 2,
sessions_per_era: 5,
bonding_duration: 2,
}),
democracy: Some(DemocracyConfig {
launch_period: 9,
voting_period: 18,
minimum_deposit: 10,
}),
council: Some(CouncilConfig {
active_council: endowed_accounts.iter().filter(|a| initial_authorities.iter().find(|&b| &a.0 == b).is_none()).map(|a| (a.clone(), 1000000)).collect(),
candidacy_bond: 10,
voter_bond: 2,
present_slash_per_voter: 1,
carry_count: 4,
presentation_duration: 10,
approval_voting_period: 20,
term_duration: 1000000,
desired_seats: (endowed_accounts.len() - initial_authorities.len()) as u32,
inactive_grace_period: 1,
cooloff_period: 75,
voting_period: 20,
}),
parachains: Some(Default::default()),
};
let boot_nodes = Vec::new();
ChainConfig { genesis_config, boot_nodes }
}
fn development_config() -> ChainConfig {
testnet_config(vec![
ed25519::Pair::from_seed(b"Alice ").public().into(),
])
}
fn local_testnet_config() -> ChainConfig {
testnet_config(vec![
ed25519::Pair::from_seed(b"Alice ").public().into(),
ed25519::Pair::from_seed(b"Bob ").public().into(),
])
}
/// Creates light client and register protocol with the network service
pub fn new_light(config: Configuration) -> Result<Service<components::LightComponents>, error::Error> {
Service::new(components::LightComponents, config)
@@ -244,7 +97,7 @@ impl<Components> Service<Components>
client::error::Error: From<<<<Components as components::Components>::Backend as client::backend::Backend<Block>>::State as state_machine::Backend>::Error>,
{
/// Creates and register protocol with the network service
fn new(components: Components, mut config: Configuration) -> Result<Self, error::Error> {
fn new(components: Components, config: Configuration) -> Result<Self, error::Error> {
use std::sync::Barrier;
let (signal, exit) = ::exit_future::signal();
@@ -262,23 +115,12 @@ impl<Components> Service<Components>
info!("Generated a new keypair: {:?}", key.public());
}
let ChainConfig { genesis_config, boot_nodes } = match config.chain_spec {
ChainSpec::Development => development_config(),
ChainSpec::LocalTestnet => local_testnet_config(),
ChainSpec::PoC2Testnet => poc_2_testnet_config(),
};
config.network.boot_nodes.extend(boot_nodes);
let genesis_builder = components::GenesisBuilder {
config: genesis_config,
};
let db_settings = client_db::DatabaseSettings {
cache_size: None,
path: config.database_path.into(),
};
let (client, on_demand) = components.build_client(db_settings, executor, genesis_builder)?;
let (client, on_demand) = components.build_client(db_settings, executor, config.genesis_storage)?;
let api = components.build_api(client.clone());
let best_header = client.best_block_header()?;
@@ -300,7 +142,6 @@ impl<Components> Service<Components>
let barrier = ::std::sync::Arc::new(Barrier::new(2));
on_demand.map(|on_demand| on_demand.set_service_link(Arc::downgrade(&network)));
let thread = {
let client = client.clone();
let network = network.clone();
+5 -4
View File
@@ -46,6 +46,7 @@ use parking_lot::RwLock;
use runtime_primitives::generic::BlockId;
use runtime_primitives::bft::Justification;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, Hashing, HashingFor, Zero};
use runtime_primitives::BuildStorage;
use state_machine::backend::Backend as StateBackend;
use state_machine::CodeExecutor;
@@ -61,21 +62,21 @@ pub struct DatabaseSettings {
}
/// Create an instance of db-backed client.
pub fn new_client<E, F, Block>(
pub fn new_client<E, S, Block>(
settings: DatabaseSettings,
executor: E,
genesis_builder: F,
genesis_storage: S,
) -> Result<client::Client<Backend<Block>, client::LocalCallExecutor<Backend<Block>, E>, Block>, client::error::Error>
where
Block: BlockT,
<Block::Header as HeaderT>::Number: As<u32>,
Block::Hash: Into<[u8; 32]>, // TODO: remove when patricia_trie generic.
E: CodeExecutor,
F: client::GenesisBuilder<Block>,
S: BuildStorage,
{
let backend = Arc::new(Backend::new(&settings)?);
let executor = client::LocalCallExecutor::new(backend.clone(), executor);
Ok(client::Client::new(backend, executor, genesis_builder)?)
Ok(client::Client::new(backend, executor, genesis_storage)?)
}
mod columns {
+16 -23
View File
@@ -22,24 +22,19 @@ use parking_lot::{Mutex, RwLock};
use primitives::AuthorityId;
use runtime_primitives::{bft::Justification, generic::BlockId};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, One};
use runtime_primitives::BuildStorage;
use primitives::storage::{StorageKey, StorageData};
use codec::{Slicable};
use codec::Slicable;
use state_machine::{self, Ext, OverlayedChanges, Backend as StateBackend, CodeExecutor};
use backend::{self, BlockImportOperation};
use blockchain::{self, Info as ChainInfo, Backend as ChainBackend};
use call_executor::{CallExecutor, LocalCallExecutor};
use {error, in_mem, block_builder, runtime_io, bft};
use {error, in_mem, block_builder, runtime_io, bft, genesis};
/// Type that implements `futures::Stream` of block import events.
pub type BlockchainEventStream<Block> = mpsc::UnboundedReceiver<BlockImportNotification<Block>>;
/// Polkadot Client genesis block builder.
pub trait GenesisBuilder<B: BlockT> {
/// Build genesis block.
fn build(self) -> (B::Header, Vec<(Vec<u8>, Vec<u8>)>);
}
/// Polkadot Client
pub struct Client<B, E, Block> where Block: BlockT {
backend: Arc<B>,
@@ -146,18 +141,18 @@ impl<Block: BlockT> JustifiedHeader<Block> {
}
/// Create an instance of in-memory client.
pub fn new_in_mem<E, F, Block>(
pub fn new_in_mem<E, Block, S>(
executor: E,
genesis_builder: F
genesis_storage: S
) -> error::Result<Client<in_mem::Backend<Block>, LocalCallExecutor<in_mem::Backend<Block>, E>, Block>>
where
E: CodeExecutor,
F: GenesisBuilder<Block>,
S: BuildStorage,
Block: BlockT,
{
let backend = Arc::new(in_mem::Backend::new());
let executor = LocalCallExecutor::new(backend.clone(), executor);
Client::new(backend, executor, genesis_builder)
Client::new(backend, executor, genesis_storage)
}
impl<B, E, Block: BlockT> Client<B, E, Block> where
@@ -167,20 +162,18 @@ impl<B, E, Block: BlockT> Client<B, E, Block> where
error::Error: From<<<B as backend::Backend<Block>>::State as StateBackend>::Error>,
{
/// Creates new Polkadot Client with given blockchain and code executor.
pub fn new<F>(
pub fn new<S: BuildStorage>(
backend: Arc<B>,
executor: E,
genesis_builder: F,
) -> error::Result<Self>
where
F: GenesisBuilder<Block>
{
build_genesis_storage: S,
) -> error::Result<Self> {
if backend.blockchain().header(BlockId::Number(Zero::zero()))?.is_none() {
trace!("Empty database, writing genesis block");
let (genesis_header, genesis_store) = genesis_builder.build();
let genesis_storage = build_genesis_storage.build_storage();
let genesis_block = genesis::construct_genesis_block::<Block>(&genesis_storage);
info!("Initialising Genesis block/state (state: {}, header-hash: {})", genesis_block.header().state_root(), genesis_block.header().hash());
let mut op = backend.begin_operation(BlockId::Hash(Default::default()))?;
op.reset_storage(genesis_store.into_iter())?;
op.set_block_data(genesis_header, Some(vec![]), None, true)?;
op.reset_storage(genesis_storage.into_iter())?;
op.set_block_data(genesis_block.deconstruct().0, Some(vec![]), None, true)?;
backend.commit_operation(op)?;
}
Ok(Client {
@@ -493,7 +486,7 @@ mod tests {
#[test]
fn client_initialises_from_genesis_ok() {
let client = test_client::new();
let genesis_hash = client.block_hash(0).unwrap().unwrap();
let _genesis_hash = client.block_hash(0).unwrap().unwrap();
assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Alice.to_raw_public().into())).unwrap(), 1000);
assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Ferdie.to_raw_public().into())).unwrap(), 0);
+2 -2
View File
@@ -16,14 +16,14 @@
//! Tool for creating the genesis block.
use std::collections::HashMap;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Hashing as HashingT, Zero};
use runtime_primitives::StorageMap;
/// Create a genesis block, given the initial storage.
pub fn construct_genesis_block<
Block: BlockT
> (
storage: &HashMap<Vec<u8>, Vec<u8>>
storage: &StorageMap
) -> Block {
let state_root = <<<Block as BlockT>::Header as HeaderT>::Hashing as HashingT>::trie_root(storage.clone().into_iter());
let extrinsics_root = <<<Block as BlockT>::Header as HeaderT>::Hashing as HashingT>::trie_root(::std::iter::empty::<(&[u8], &[u8])>());
+1 -1
View File
@@ -53,7 +53,7 @@ pub use client::{
new_in_mem,
BlockStatus, BlockOrigin, BlockchainEventStream, BlockchainEvents,
Client, ClientInfo, ChainHead,
ImportResult, GenesisBuilder,
ImportResult,
};
pub use blockchain::Info as ChainInfo;
pub use call_executor::{
+6 -5
View File
@@ -25,10 +25,11 @@ use state_machine::backend::Backend as StateBackend;
use runtime_primitives::generic::BlockId;
use runtime_primitives::bft::Justification;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT};
use runtime_primitives::BuildStorage;
use blockchain::{self, BlockStatus};
use backend;
use call_executor::{CallResult, RemoteCallExecutor, check_execution_proof};
use client::{Client, GenesisBuilder};
use client::Client;
use error;
use in_mem::Blockchain as InMemBlockchain;
@@ -228,18 +229,18 @@ pub fn new_light_backend<B: BlockT>() -> Arc<Backend<B>> {
}
/// Create an instance of light client.
pub fn new_light<F, B, Block>(
pub fn new_light<F, S, Block>(
backend: Arc<Backend<Block>>,
fetcher: Arc<F>,
genesis_builder: B,
genesis_storage: S,
) -> error::Result<Client<Backend<Block>, RemoteCallExecutor<Backend<Block>, F>, Block>>
where
F: Fetcher<Block>,
B: GenesisBuilder<Block>,
S: BuildStorage,
Block: BlockT,
{
let executor = RemoteCallExecutor::new(backend.clone(), fetcher);
Client::new(backend, executor, genesis_builder)
Client::new(backend, executor, genesis_storage)
}
/// Create an instance of fetch data checker.
+1 -1
View File
@@ -29,9 +29,9 @@ substrate-serializer = { path = "../../substrate/serializer" }
substrate-runtime-support = { path = "../../substrate/runtime-support" }
substrate-runtime-primitives = { path = "../../substrate/runtime/primitives" }
substrate-bft = { path = "../../substrate/bft" }
substrate-codec = { path = "../../substrate/codec" }
[dev-dependencies]
env_logger = "0.4"
substrate-codec = { path = "../../substrate/codec" }
substrate-keyring = { path = "../../substrate/keyring" }
substrate-test-client = { path = "../../substrate/test-client" }
+1 -1
View File
@@ -32,6 +32,7 @@ extern crate substrate_client as client;
extern crate substrate_runtime_support as runtime_support;
extern crate substrate_runtime_primitives as runtime_primitives;
extern crate substrate_bft;
extern crate substrate_codec as codec;
extern crate serde;
extern crate serde_json;
extern crate futures;
@@ -42,7 +43,6 @@ extern crate ed25519;
#[macro_use] extern crate error_chain;
#[cfg(test)] extern crate env_logger;
#[cfg(test)] extern crate substrate_codec as codec;
#[cfg(test)] extern crate substrate_keyring as keyring;
#[cfg(test)] extern crate substrate_test_client as test_client;
+36 -2
View File
@@ -19,7 +19,7 @@
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT};
use service::Role as RoleFlags;
pub use self::generic::{BlockAnnounce, RemoteCallRequest, ConsensusVote, SignedConsensusVote, FromBlock};
pub use self::generic::{BlockAnnounce, RemoteCallRequest, ConsensusVote, SignedConsensusVote, FromBlock, Body};
pub type RequestId = u64;
@@ -169,10 +169,44 @@ pub struct RemoteCallResponse {
/// Generic types.
pub mod generic {
use primitives::AuthorityId;
use codec::Slicable;
use runtime_primitives::bft::Justification;
use ed25519;
use super::{Role, BlockAttribute, RemoteCallResponse, RequestId, Transactions, Direction};
use primitives::bytes;
/// Emulates Poc-1 extrinsic primitive.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct V1Extrinsic(#[serde(with="bytes")] pub Vec<u8>);
// Alternative block format for poc-1 compatibility.
// TODO: remove this after poc-2
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(untagged)]
/// Serialized block body type.
pub enum Body<Extrinsic> {
/// Poc-1. Extrinsics as bytes.
V1(Vec<V1Extrinsic>),
/// Poc-2 or later. A structured type.
Extrinsics(Vec<Extrinsic>),
}
impl<Extrinsic> Body<Extrinsic> where Extrinsic: Slicable {
/// Extracts extrinsic from the body.
pub fn to_extrinsics(self) -> Vec<Extrinsic> {
match self {
Body::Extrinsics(e) => e,
Body::V1(e) => {
e.into_iter().filter_map(|bytes| {
let bytes = bytes.0.encode();
Slicable::decode(&mut bytes.as_slice())
}).collect()
}
}
}
}
/// Block data sent in the response.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct BlockData<Header, Hash, Extrinsic> {
@@ -181,7 +215,7 @@ pub mod generic {
/// Block header if requested.
pub header: Option<Header>,
/// Block body if requested.
pub body: Option<Vec<Extrinsic>>,
pub body: Option<Body<Extrinsic>>,
/// Block receipt if requested.
pub receipt: Option<Vec<u8>>,
/// Block message queue if requested.
+1 -1
View File
@@ -262,7 +262,7 @@ impl<B: BlockT> Protocol<B> where
let block_data = message::generic::BlockData {
hash: hash,
header: if get_header { Some(header) } else { None },
body: if get_body { self.chain.body(&BlockId::Hash(hash)).unwrap_or(None) } else { None },
body: (if get_body { self.chain.body(&BlockId::Hash(hash)).unwrap_or(None) } else { None }).map(|body| message::Body::Extrinsics(body)),
receipt: None,
message_queue: None,
justification: if get_justification { self.chain.justification(&BlockId::Hash(hash)).unwrap_or(None) } else { None },
+1 -1
View File
@@ -259,7 +259,7 @@ impl<B: BlockT> ChainSync<B> where
is_best,
header,
justification,
block.body
block.body.map(|b| b.to_extrinsics()),
);
match result {
Ok(ImportResult::AlreadyInChain) => {
@@ -22,10 +22,10 @@ use rstd::vec::Vec;
/// Contract storage key.
#[derive(PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord))]
pub struct StorageKey(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Contract storage entry data.
#[derive(PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord))]
pub struct StorageData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
+2 -2
View File
@@ -34,7 +34,7 @@ fn should_return_header() {
Ok(Some(ref x)) if x == &Header {
parent_hash: 0.into(),
number: 0,
state_root: "9c70014029b05f780858f654bfcf297ca708b3663d32bc81486193e84a2f2f3d".into(),
state_root: "987aa0851a133413b42c6d9aa3c91b1dddc2ad5337508ee8815116b11e44c64d".into(),
extrinsics_root: "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".into(),
digest: Default::default(),
}
@@ -70,7 +70,7 @@ fn should_notify_about_latest_block() {
// assert notification send to transport
let (notification, next) = core.run(transport.into_future()).unwrap();
assert_eq!(notification, Some(
r#"{"jsonrpc":"2.0","method":"test","params":{"result":{"digest":{"logs":[]},"extrinsicsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","number":1,"parentHash":"0x45a44c50cae6ffcc413b65d6b4444a572fa4be2e5d1cd026cc113f9d8f9bc368","stateRoot":"0x987aa0851a133413b42c6d9aa3c91b1dddc2ad5337508ee8815116b11e44c64d"},"subscription":0}}"#.to_owned()
r#"{"jsonrpc":"2.0","method":"test","params":{"result":{"digest":{"logs":[]},"extrinsicsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","number":1,"parentHash":"0x27f04d7574733bb155bbf5a0399fcc99d3c4dbf15bf99862d261bced9444179a","stateRoot":"0x987aa0851a133413b42c6d9aa3c91b1dddc2ad5337508ee8815116b11e44c64d"},"subscription":0}}"#.to_owned()
));
// no more notifications on this channel
assert_eq!(core.run(next.into_future()).unwrap().0, None);
@@ -134,9 +134,9 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T>
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_externalities(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> runtime_io::TestExternalities {
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)|
@@ -583,9 +583,9 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T>
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_externalities(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> runtime_io::TestExternalities {
use codec::Slicable;
use runtime_io::twox_128;
@@ -613,7 +613,7 @@ mod tests {
pub use super::*;
pub use runtime_io::with_externalities;
pub use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::BuildStorage;
use primitives::traits::{HasPublicAux, Identity, BlakeTwo256};
use primitives::testing::{Digest, Header};
@@ -658,15 +658,15 @@ 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_externalities();
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![],
}.build_externalities());
}.build_storage());
t.extend(session::GenesisConfig::<Test>{
session_length: 1, //??? or 2?
validators: vec![10, 20],
}.build_externalities());
}.build_storage());
t.extend(staking::GenesisConfig::<Test>{
sessions_per_era: 1,
current_era: 0,
@@ -681,12 +681,12 @@ mod tests {
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
}.build_externalities());
}.build_storage());
t.extend(democracy::GenesisConfig::<Test>{
launch_period: 1,
voting_period: 3,
minimum_deposit: 1,
}.build_externalities());
}.build_storage());
t.extend(GenesisConfig::<Test>{
candidacy_bond: 9,
voter_bond: 3,
@@ -704,7 +704,7 @@ mod tests {
term_duration: 5,
cooloff_period: 2,
voting_period: 1,
}.build_externalities());
}.build_storage());
t
}
@@ -331,9 +331,9 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T>
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_externalities(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> runtime_io::TestExternalities {
use codec::Slicable;
use runtime_io::twox_128;
@@ -353,7 +353,7 @@ mod tests {
use super::*;
use runtime_io::with_externalities;
use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::BuildStorage;
use primitives::traits::{HasPublicAux, Identity, BlakeTwo256};
use primitives::testing::{Digest, Header};
@@ -398,15 +398,15 @@ mod tests {
}
fn new_test_ext() -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![],
}.build_externalities());
}.build_storage());
t.extend(session::GenesisConfig::<Test>{
session_length: 1, //??? or 2?
validators: vec![10, 20],
}.build_externalities());
}.build_storage());
t.extend(staking::GenesisConfig::<Test>{
sessions_per_era: 1,
current_era: 0,
@@ -421,12 +421,12 @@ mod tests {
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
}.build_externalities());
}.build_storage());
t.extend(GenesisConfig::<Test>{
launch_period: 1,
voting_period: 1,
minimum_deposit: 1,
}.build_externalities());
}.build_storage());
t
}
@@ -216,7 +216,7 @@ mod tests {
use staking::Call;
use runtime_io::with_externalities;
use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::BuildStorage;
use primitives::traits::{HasPublicAux, Identity, Header as HeaderT, BlakeTwo256, AuxLookup};
use primitives::testing::{Digest, Header, Block};
@@ -262,7 +262,7 @@ mod tests {
#[test]
fn staking_balance_transfer_dispatch_works() {
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(staking::GenesisConfig::<Test> {
sessions_per_era: 0,
current_era: 0,
@@ -277,7 +277,7 @@ mod tests {
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
}.build_externalities());
}.build_storage());
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()));
@@ -288,10 +288,10 @@ mod tests {
}
fn new_test_ext() -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
t.extend(consensus::GenesisConfig::<Test>::default().build_externalities());
t.extend(session::GenesisConfig::<Test>::default().build_externalities());
t.extend(staking::GenesisConfig::<Test>::default().build_externalities());
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
}
@@ -52,12 +52,32 @@ pub mod bft;
use traits::{Verify, Lazy};
/// A set of key value pairs for storage.
#[cfg(feature = "std")]
pub type BuiltExternalities = HashMap<Vec<u8>, Vec<u8>>;
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")]
pub trait BuildExternalities {
fn build_externalities(self) -> BuiltExternalities;
impl BuildStorage for MakeStorage {
fn build_storage(mut self) -> StorageMap {
self()
}
}
#[cfg(feature = "std")]
impl BuildStorage for StorageMap {
fn build_storage(self) -> StorageMap {
self
}
}
/// Ed25519 signature verify.
@@ -227,12 +247,12 @@ macro_rules! impl_outer_config {
)*
}
#[cfg(any(feature = "std", test))]
impl $crate::BuildExternalities for $main {
fn build_externalities(self) -> $crate::BuiltExternalities {
let mut s = $crate::BuiltExternalities::new();
impl $crate::BuildStorage for $main {
fn build_storage(self) -> $crate::StorageMap {
let mut s = $crate::StorageMap::new();
$(
if let Some(extra) = self.$snake {
s.extend(extra.build_externalities());
s.extend(extra.build_storage());
}
)*
s
@@ -185,9 +185,9 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T>
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_externalities(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> runtime_io::TestExternalities {
use runtime_io::twox_128;
use codec::Slicable;
use primitives::traits::As;
@@ -204,7 +204,7 @@ mod tests {
use super::*;
use runtime_io::with_externalities;
use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::BuildStorage;
use primitives::traits::{HasPublicAux, Identity, BlakeTwo256};
use primitives::testing::{Digest, Header};
@@ -235,15 +235,15 @@ mod tests {
type Session = Module<Test>;
fn new_test_ext() -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: vec![1, 2, 3],
}.build_externalities());
}.build_storage());
t.extend(GenesisConfig::<Test>{
session_length: 2,
validators: vec![1, 2, 3],
}.build_externalities());
}.build_storage());
t
}
@@ -1031,8 +1031,8 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T> {
fn build_externalities(self) -> runtime_io::TestExternalities {
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
fn build_storage(self) -> runtime_io::TestExternalities {
use runtime_io::twox_128;
use codec::Slicable;
@@ -18,7 +18,7 @@
#![cfg(test)]
use primitives::BuildExternalities;
use primitives::BuildStorage;
use primitives::traits::{HasPublicAux, Identity};
use primitives::testing::{Digest, Header};
use substrate_primitives::H256;
@@ -54,7 +54,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) -> runtime_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
let mut t = system::GenesisConfig::<Test>::default().build_storage();
let balance_factor = if ext_deposit > 0 {
256
} else {
@@ -63,11 +63,11 @@ 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_externalities());
}.build_storage());
t.extend(session::GenesisConfig::<Test>{
session_length,
validators: vec![10, 20],
}.build_externalities());
}.build_storage());
t.extend(GenesisConfig::<Test>{
sessions_per_era,
current_era,
@@ -82,7 +82,7 @@ pub fn new_test_ext(ext_deposit: u64, session_length: u64, sessions_per_era: u64
creation_fee: 0,
contract_fee: 0,
reclaim_rebate: 0,
}.build_externalities());
}.build_storage());
t
}
@@ -203,9 +203,9 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T>
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_externalities(self) -> runtime_io::TestExternalities {
fn build_storage(self) -> runtime_io::TestExternalities {
use runtime_io::twox_128;
use codec::Slicable;
@@ -98,9 +98,9 @@ pub struct GenesisConfig<T: Trait> {
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> runtime_primitives::BuildExternalities for GenesisConfig<T>
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T>
{
fn build_externalities(self) -> runtime_primitives::BuiltExternalities {
fn build_storage(self) -> runtime_primitives::StorageMap {
use runtime_io::twox_128;
use codec::Slicable;
map![
@@ -116,7 +116,7 @@ mod tests {
use runtime_io::with_externalities;
use runtime_support::storage::StorageValue;
use substrate_primitives::H256;
use runtime_primitives::BuildExternalities;
use runtime_primitives::BuildStorage;
use runtime_primitives::traits::{HasPublicAux, BlakeTwo256};
use runtime_primitives::testing::{Digest, Header};
@@ -142,8 +142,8 @@ mod tests {
#[test]
fn timestamp_works() {
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
t.extend(GenesisConfig::<Test> { now: 42 }.build_externalities());
let mut t = system::GenesisConfig::<Test>::default().build_storage();
t.extend(GenesisConfig::<Test> { now: 42 }.build_storage());
with_externalities(&mut t, || {
assert_eq!(<Timestamp as Store>::Now::get(), 42);
@@ -18,6 +18,7 @@
use client::{self, Client};
use keyring::Keyring;
use runtime_primitives::StorageMap;
use runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
use runtime;
use bft;
@@ -37,7 +38,7 @@ pub trait TestClient {
impl TestClient for Client<Backend, Executor, runtime::Block> {
fn new_for_tests() -> Self {
client::new_in_mem(NativeExecutor::new(), GenesisBuilder).unwrap()
client::new_in_mem(NativeExecutor::new(), genesis_storage()).unwrap()
}
fn justify_and_import(&self, origin: client::BlockOrigin, block: runtime::Block) -> client::error::Result<()> {
@@ -93,17 +94,9 @@ fn genesis_config() -> GenesisConfig {
], 1000)
}
struct GenesisBuilder;
impl client::GenesisBuilder<runtime::Block> for GenesisBuilder {
fn build(self) -> (runtime::Header, Vec<(Vec<u8>, Vec<u8>)>) {
fn genesis_storage() -> StorageMap {
let mut storage = genesis_config().genesis_map();
let block: runtime::Block = client::genesis::construct_genesis_block(&storage);
storage.extend(additional_storage_with_genesis(&block));
(
block.header,
storage.into_iter().collect()
)
}
storage
}