diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index e58fd510ed..1c30e4f727 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -1076,7 +1076,6 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", - "polkadot-executor 0.1.0", "substrate-client 0.1.0", "substrate-executor 0.1.0", "substrate-primitives 0.1.0", diff --git a/substrate/candidate-agreement/src/lib.rs b/substrate/candidate-agreement/src/lib.rs index 2cf4be5c54..cfcc51bd32 100644 --- a/substrate/candidate-agreement/src/lib.rs +++ b/substrate/candidate-agreement/src/lib.rs @@ -314,7 +314,7 @@ impl SharedTable { /// Provide an iterator yielding pairs of (statement, received_from). pub fn import_statements(&self, iterable: I) -> U where - I: IntoIterator::SignedTableStatement, Option)>, + I: Iterator::SignedTableStatement, Option)>, U: ::std::iter::FromIterator>, { let mut inner = self.inner.lock(); diff --git a/substrate/cli/src/genesis.rs b/substrate/cli/src/genesis.rs index 25c1744ab1..78a6c526c2 100644 --- a/substrate/cli/src/genesis.rs +++ b/substrate/cli/src/genesis.rs @@ -45,7 +45,7 @@ mod tests { use state_machine::execute; use state_machine::OverlayedChanges; use state_machine::backend::InMemory; - use substrate_executor::executor; + use polkadot_executor::executor; use polkadot_primitives::{AccountId, Hash, BlockNumber, Header, Digest, UncheckedTransaction, Transaction, Function}; use ed25519::Pair; diff --git a/substrate/cli/src/lib.rs b/substrate/cli/src/lib.rs index 04c7700c28..67803bb74b 100644 --- a/substrate/cli/src/lib.rs +++ b/substrate/cli/src/lib.rs @@ -24,14 +24,15 @@ extern crate triehash; extern crate substrate_codec as codec; extern crate substrate_state_machine as state_machine; extern crate substrate_client as client; -extern crate substrate_executor; extern crate substrate_primitives as primitives; extern crate substrate_runtime_io as runtime_io; extern crate polkadot_rpc_servers as rpc; extern crate polkadot_primitives; -extern crate polkadot_executor as executor; +extern crate polkadot_executor; extern crate native_runtime; +#[macro_use] +extern crate hex_literal; #[macro_use] extern crate clap; #[macro_use] @@ -39,6 +40,7 @@ extern crate error_chain; #[macro_use] extern crate log; +mod genesis; pub mod error; /// Parse command line arguments and start the node. @@ -61,8 +63,29 @@ pub fn run(args: I) -> error::Result<()> where init_logger(log_pattern); // Create client - let executor = executor::executor(); - let client = client::new_in_mem(executor)?; // TODO: pass in genesis builder. + let executor = polkadot_executor::executor(); + let mut storage = Default::default(); + let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"]; + let genesis_config = native_runtime::runtime::genesismap::GenesisConfig { + validators: vec![god_key.clone()], + authorities: vec![god_key.clone()], + balances: vec![(god_key.clone(), 1u64 << 63)].into_iter().collect(), + block_time: 5, // 5 second block time. + session_length: 720, // that's 1 hour per session. + sessions_per_era: 24, // 24 hours per era. + bonding_duration: 90, // 90 days per bond. + approval_ratio: 667, // 66.7% approvals required for legislation. + }; + + let prepare_genesis = || { + storage = genesis_config.genesis_map(); + let block = genesis::construct_genesis_block(&storage); + use native_runtime::runtime::genesismap::additional_storage_with_genesis; + storage.extend(additional_storage_with_genesis(&block).into_iter()); + use codec::Slicable; + (primitives::block::Header::from_slice(&mut block.header.to_vec().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) + }; + let client = client::new_in_mem(executor, prepare_genesis)?; // TODO: pass in genesis builder. let address = "127.0.0.1:9933".parse().unwrap(); let handler = rpc::rpc_handler(client); diff --git a/substrate/client/src/Cargo.toml b/substrate/client/src/Cargo.toml new file mode 100644 index 0000000000..aa8989d2af --- /dev/null +++ b/substrate/client/src/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "polkadot-cli" +version = "0.1.0" +authors = ["Parity Technologies "] +description = "Polkadot node implementation in Rust." + +[dependencies] +clap = { version = "2.27", features = ["yaml"] } +env_logger = "0.4" +error-chain = "0.11" +log = "0.3" +hex-literal = "0.1" +ed25519 = { path = "../ed25519" } +triehash = { version = "0.1" } +substrate-client = { path = "../client" } +substrate-codec = { path = "../codec" } +substrate-runtime-io = { path = "../runtime-io" } +substrate-state-machine = { path = "../state-machine" } +substrate-executor = { path = "../executor" } +substrate-primitives = { path = "../primitives" } +polkadot-rpc-servers = { path = "../rpc-servers" } +polkadot-primitives = { path = "../polkadot-primitives" } +polkadot-executor = { path = "../polkadot-executor" } +native-runtime = { path = "../native-runtime" } diff --git a/substrate/client/src/backend.rs b/substrate/client/src/backend.rs index 563dd03699..0eb12cf18b 100644 --- a/substrate/client/src/backend.rs +++ b/substrate/client/src/backend.rs @@ -30,6 +30,8 @@ pub trait BlockImportOperation { fn state(&self) -> error::Result; /// Append block data to the transaction. fn import_block(&mut self, header: block::Header, body: Option, is_new_best: bool) -> error::Result<()>; + /// Inject storage data into the database. + fn reset_storage, Vec)>>(&mut self, iter: I) -> error::Result<()>; } /// Client backend. Manages the data layer. diff --git a/substrate/client/src/in_mem.rs b/substrate/client/src/in_mem.rs index 34475886c4..fe8064c01b 100644 --- a/substrate/client/src/in_mem.rs +++ b/substrate/client/src/in_mem.rs @@ -146,6 +146,11 @@ impl backend::BlockImportOperation for BlockImportOperation { }); Ok(()) } + + fn reset_storage, Vec)>>(&mut self, iter: I) -> error::Result<()> { + self.pending_state = state_machine::backend::InMemory::from(iter.collect()); + Ok(()) + } } /// In-memory backend. Keeps all states and blocks in memory. Useful for testing. diff --git a/substrate/client/src/lib.rs b/substrate/client/src/lib.rs index 3f29842c00..983ab2754f 100644 --- a/substrate/client/src/lib.rs +++ b/substrate/client/src/lib.rs @@ -30,10 +30,6 @@ extern crate parking_lot; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; -#[cfg(test)] -#[macro_use] -extern crate hex_literal; - pub mod error; pub mod blockchain; pub mod backend; @@ -104,8 +100,15 @@ pub enum BlockStatus { } /// Create an instance of in-memory client. -pub fn new_in_mem(executor: E) -> error::Result> where E: state_machine::CodeExecutor { - Client::new(in_mem::Backend::new(), executor) +pub fn new_in_mem( + executor: E, + build_genesis: F +) -> error::Result> + where + E: state_machine::CodeExecutor, + F: FnOnce() -> (block::Header, Vec<(Vec, Vec)>) +{ + Client::new(in_mem::Backend::new(), executor, build_genesis) } impl Client where @@ -114,19 +117,19 @@ impl Client where error::Error: From<<::State as state_machine::backend::Backend>::Error>, { /// Creates new Polkadot Client with given blockchain and code executor. - pub fn new(backend: B, executor: E) -> error::Result { + pub fn new( + backend: B, + executor: E, + build_genesis: F + ) -> error::Result + where + F: FnOnce() -> (block::Header, Vec<(Vec, Vec)>) + { if backend.blockchain().header(BlockId::Number(0))?.is_none() { trace!("Empty database, writing genesis block"); - // TODO: spec, coming in from new_in_mem's params. - let genesis_header = block::Header { - parent_hash: Default::default(), - number: 0, - state_root: Default::default(), - transaction_root: Default::default(), - digest: Default::default(), - }; - + let (genesis_header, genesis_store) = build_genesis(); let mut tx = backend.begin_transaction(BlockId::Hash(block::HeaderHash::default()))?; + tx.reset_storage(genesis_store.into_iter())?; tx.import_block(genesis_header, None, true)?; backend.commit_transaction(tx)?; } diff --git a/substrate/rpc/Cargo.toml b/substrate/rpc/Cargo.toml index be8fec54dd..c2c9ebce2f 100644 --- a/substrate/rpc/Cargo.toml +++ b/substrate/rpc/Cargo.toml @@ -10,8 +10,7 @@ jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" } substrate-client = { path = "../client" } substrate-primitives = { path = "../primitives" } substrate-state-machine = { path = "../state-machine" } -# TODO: Remove this and split out tests. -polkadot-executor = { path = "../polkadot-executor" } +substrate-executor = { path = "../executor" } [dev-dependencies] assert_matches = "1.1" diff --git a/substrate/rpc/src/chain/tests.rs b/substrate/rpc/src/chain/tests.rs index 952b20b35c..9fa60de3a8 100644 --- a/substrate/rpc/src/chain/tests.rs +++ b/substrate/rpc/src/chain/tests.rs @@ -14,13 +14,21 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use polkadot_executor as executor; +use substrate_executor as executor; use client; use super::*; #[test] fn should_return_header() { - let client = client::new_in_mem(executor::executor()).unwrap(); + let test_genesis_block = block::Header { + parent_hash: 0.into(), + number: 0, + state_root: 0.into(), + transaction_root: Default::default(), + digest: Default::default(), + }; + + let client = client::new_in_mem(executor::WasmExecutor, || (test_genesis_block.clone(), vec![])).unwrap(); assert_matches!( ChainApi::header(&client, "af65e54217fb213853703d57b80fc5b2bb834bf923046294d7a49bff62f0a8b2".into()), diff --git a/substrate/rpc/src/lib.rs b/substrate/rpc/src/lib.rs index a1cce746b3..cb7cae10cd 100644 --- a/substrate/rpc/src/lib.rs +++ b/substrate/rpc/src/lib.rs @@ -29,7 +29,7 @@ extern crate error_chain; extern crate jsonrpc_macros; #[cfg(test)] -extern crate polkadot_executor; +extern crate substrate_executor; #[cfg(test)] #[macro_use] extern crate assert_matches; diff --git a/substrate/rpc/src/state/tests.rs b/substrate/rpc/src/state/tests.rs index d15f42183e..7589c3084b 100644 --- a/substrate/rpc/src/state/tests.rs +++ b/substrate/rpc/src/state/tests.rs @@ -14,15 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use substrate_executor as executor; use super::*; -use polkadot_executor as executor; - use self::error::{Error, ErrorKind}; use client; #[test] fn should_return_storage() { - let client = client::new_in_mem(executor::executor()).unwrap(); + let test_genesis_block = block::Header { + parent_hash: 0.into(), + number: 0, + state_root: 0.into(), + transaction_root: Default::default(), + digest: Default::default(), + }; + + let client = client::new_in_mem(executor::WasmExecutor, || (test_genesis_block.clone(), vec![])).unwrap(); let genesis_hash = "af65e54217fb213853703d57b80fc5b2bb834bf923046294d7a49bff62f0a8b2".into(); assert_matches!( @@ -35,7 +42,15 @@ fn should_return_storage() { #[ignore] // TODO: [ToDr] reenable once we can properly mock the wasm executor env fn should_call_contract() { // TODO [ToDr] Fix test after we are able to mock state. - let client = client::new_in_mem(executor::executor()).unwrap(); + let test_genesis_block = block::Header { + parent_hash: 0.into(), + number: 0, + state_root: 0.into(), + transaction_root: Default::default(), + digest: Default::default(), + }; + + let client = client::new_in_mem(executor::WasmExecutor, || (test_genesis_block.clone(), vec![])).unwrap(); let genesis_hash = "af65e54217fb213853703d57b80fc5b2bb834bf923046294d7a49bff62f0a8b2".into(); assert_matches!(