Browse Source

node: Fix node tests.

Shamil Gadelshin 4 years ago
parent
commit
13664bb7a1
13 changed files with 1067 additions and 803 deletions
  1. 136 0
      Cargo.lock
  2. 13 0
      node/Cargo.toml
  3. 1 1
      node/bin/main.rs
  4. 95 19
      node/src/chain_spec.rs
  5. 2 2
      node/src/cli.rs
  6. 71 75
      node/src/command.rs
  7. 1 1
      node/src/lib.rs
  8. 4 4
      node/src/node_executor.rs
  9. 127 129
      node/src/node_rpc.rs
  10. 450 426
      node/src/service.rs
  11. 49 0
      runtime/src/constants.rs
  12. 89 120
      runtime/src/lib.rs
  13. 29 26
      runtime/src/primitives.rs

+ 136 - 0
Cargo.lock

@@ -1985,6 +1985,7 @@ dependencies = [
  "sc-rpc",
  "sc-rpc-api",
  "sc-service",
+ "sc-service-test",
  "sc-telemetry",
  "sc-tracing",
  "sc-transaction-pool",
@@ -2008,6 +2009,7 @@ dependencies = [
  "structopt",
  "substrate-browser-utils",
  "substrate-frame-rpc-system",
+ "tempfile",
  "tokio 0.1.22",
  "tracing",
  "vergen",
@@ -5633,6 +5635,43 @@ dependencies = [
  "wasm-timer",
 ]
 
+[[package]]
+name = "sc-service-test"
+version = "2.0.0-rc4"
+source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478fe5d4f51e1fa71f7db9fd4#00768a1f21a579c478fe5d4f51e1fa71f7db9fd4"
+dependencies = [
+ "env_logger",
+ "fdlimit",
+ "futures 0.1.29",
+ "futures 0.3.4",
+ "hex-literal",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.10.2",
+ "sc-block-builder",
+ "sc-client-api",
+ "sc-client-db",
+ "sc-executor",
+ "sc-light",
+ "sc-network",
+ "sc-service",
+ "sp-api",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-core",
+ "sp-externalities",
+ "sp-panic-handler",
+ "sp-runtime",
+ "sp-state-machine",
+ "sp-storage",
+ "sp-transaction-pool",
+ "sp-trie",
+ "substrate-test-runtime",
+ "substrate-test-runtime-client",
+ "tempfile",
+ "tokio 0.1.22",
+]
+
 [[package]]
 name = "sc-state-db"
 version = "0.8.0-rc4"
@@ -6198,6 +6237,20 @@ dependencies = [
  "wasm-timer",
 ]
 
+[[package]]
+name = "sp-consensus-aura"
+version = "0.8.0-rc4"
+source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478fe5d4f51e1fa71f7db9fd4#00768a1f21a579c478fe5d4f51e1fa71f7db9fd4"
+dependencies = [
+ "parity-scale-codec",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-std",
+ "sp-timestamp",
+]
+
 [[package]]
 name = "sp-consensus-babe"
 version = "0.8.0-rc4"
@@ -6814,6 +6867,89 @@ dependencies = [
  "tokio 0.2.22",
 ]
 
+[[package]]
+name = "substrate-test-client"
+version = "2.0.0-rc4"
+source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478fe5d4f51e1fa71f7db9fd4#00768a1f21a579c478fe5d4f51e1fa71f7db9fd4"
+dependencies = [
+ "futures 0.3.4",
+ "hash-db",
+ "parity-scale-codec",
+ "sc-client-api",
+ "sc-client-db",
+ "sc-consensus",
+ "sc-executor",
+ "sc-light",
+ "sc-service",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-core",
+ "sp-keyring",
+ "sp-runtime",
+ "sp-state-machine",
+]
+
+[[package]]
+name = "substrate-test-runtime"
+version = "2.0.0-rc4"
+source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478fe5d4f51e1fa71f7db9fd4#00768a1f21a579c478fe5d4f51e1fa71f7db9fd4"
+dependencies = [
+ "cfg-if",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-rpc-runtime-api",
+ "log",
+ "memory-db",
+ "pallet-babe",
+ "pallet-timestamp",
+ "parity-scale-codec",
+ "parity-util-mem",
+ "sc-service",
+ "serde",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-block-builder",
+ "sp-consensus-aura",
+ "sp-consensus-babe",
+ "sp-core",
+ "sp-finality-grandpa",
+ "sp-inherents",
+ "sp-io",
+ "sp-keyring",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-runtime-interface",
+ "sp-session",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-trie",
+ "sp-version",
+ "substrate-wasm-builder-runner",
+ "trie-db",
+]
+
+[[package]]
+name = "substrate-test-runtime-client"
+version = "2.0.0-rc4"
+source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478fe5d4f51e1fa71f7db9fd4#00768a1f21a579c478fe5d4f51e1fa71f7db9fd4"
+dependencies = [
+ "futures 0.3.4",
+ "parity-scale-codec",
+ "sc-block-builder",
+ "sc-client-api",
+ "sc-consensus",
+ "sc-light",
+ "sc-service",
+ "sp-api",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-core",
+ "sp-runtime",
+ "substrate-test-client",
+ "substrate-test-runtime",
+]
+
 [[package]]
 name = "substrate-wasm-builder-runner"
 version = "1.0.6"

+ 13 - 0
node/Cargo.toml

@@ -127,6 +127,19 @@ wasm-bindgen = { version = "0.2.57", optional = true }
 wasm-bindgen-futures = { version = "0.4.7", optional = true }
 browser-utils = { package = 'substrate-browser-utils', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true}
 
+[dev-dependencies]
+#sc-keystore = { version = "2.0.0-rc4", path = "../../../client/keystore" }
+#sc-consensus = { version = "0.8.0-rc4", path = "../../../client/consensus/common" }
+sc-consensus-babe = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', features = ["test-helpers"]}
+#sc-consensus-epochs = { version = "0.8.0-rc4", path = "../../../client/consensus/epochs" }
+sc-service-test = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+#futures = "0.3.4"
+tempfile = "3.1.0"
+#assert_cmd = "1.0"
+#nix = "0.17"
+#serde_json = "1.0"
+#regex = "1"
+#platforms = "0.2.1"
 
 #[dependencies.substrate-basic-authorship]
 #git = 'https://github.com/paritytech/substrate.git'

+ 1 - 1
node/bin/main.rs

@@ -20,4 +20,4 @@
 
 fn main() -> sc_cli::Result<()> {
     joystream_node::command::run()
-}
+}

+ 95 - 19
node/src/chain_spec.rs

@@ -20,22 +20,22 @@
 #![allow(clippy::identity_op)]
 
 use node_runtime::{AccountId, GenesisConfig};
-use sp_runtime::{Perbill};
-use sp_core::{Pair, Public, sr25519};
-use sp_runtime::traits::{IdentifyAccount, Verify};
-use sp_consensus_babe::AuthorityId as BabeId;
-use sp_finality_grandpa::AuthorityId as GrandpaId;
 use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
-use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
 use serde_json as json;
+use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
+use sp_consensus_babe::AuthorityId as BabeId;
+use sp_core::{sr25519, Pair, Public};
+use sp_finality_grandpa::AuthorityId as GrandpaId;
+use sp_runtime::traits::{IdentifyAccount, Verify};
+use sp_runtime::Perbill;
 
-use node_runtime::{ContractsConfig,
+use node_runtime::{
     versioned_store::InputValidationLengthConstraint as VsInputValidation,
     AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig, ContentWorkingGroupConfig,
-    CouncilConfig, CouncilElectionConfig, DataObjectStorageRegistryConfig,
+    ContractsConfig, CouncilConfig, CouncilElectionConfig, DataObjectStorageRegistryConfig,
     DataObjectTypeRegistryConfig, ElectionParameters, GrandpaConfig, ImOnlineConfig, IndicesConfig,
-    MembersConfig, MigrationConfig, ProposalsCodexConfig, SessionConfig, SessionKeys,
-    Signature, StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig, SystemConfig,
+    MembersConfig, MigrationConfig, ProposalsCodexConfig, SessionConfig, SessionKeys, Signature,
+    StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig, SystemConfig,
     VersionedStoreConfig, DAYS, WASM_BINARY,
 };
 
@@ -100,7 +100,12 @@ fn session_keys(
     im_online: ImOnlineId,
     authority_discovery: AuthorityDiscoveryId,
 ) -> SessionKeys {
-    SessionKeys { grandpa, babe, im_online, authority_discovery }
+    SessionKeys {
+        grandpa,
+        babe,
+        im_online,
+        authority_discovery,
+    }
 }
 
 impl Alternative {
@@ -241,14 +246,16 @@ pub fn testnet_genesis(
         }),
         pallet_indices: Some(IndicesConfig { indices: vec![] }),
         pallet_session: Some(SessionConfig {
-            keys: initial_authorities.iter().map(|x| {
-                (x.0.clone(), x.0.clone(), session_keys(
-                    x.2.clone(),
-                    x.3.clone(),
-                    x.4.clone(),
-                    x.5.clone(),
-                ))
-            }).collect::<Vec<_>>(),
+            keys: initial_authorities
+                .iter()
+                .map(|x| {
+                    (
+                        x.0.clone(),
+                        x.0.clone(),
+                        session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()),
+                    )
+                })
+                .collect::<Vec<_>>(),
         }),
         pallet_contracts: Some(ContractsConfig {
             current_schedule: pallet_contracts::Schedule {
@@ -384,3 +391,72 @@ pub fn testnet_genesis(
         }),
     }
 }
+
+#[cfg(test)]
+pub(crate) mod tests {
+    use super::*;
+    use crate::service::{new_full, new_light};
+    use sc_service_test;
+
+    fn local_testnet_genesis_instant_single() -> GenesisConfig {
+        testnet_genesis(
+            vec![get_authority_keys_from_seed("Alice")],
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            vec![get_authority_keys_from_seed("Alice").0],
+        )
+    }
+
+    /// Local testnet config (single validator - Alice)
+    pub fn integration_test_config_with_single_authority() -> ChainSpec {
+        ChainSpec::from_genesis(
+            "Integration Test",
+            "test",
+            ChainType::Development,
+            local_testnet_genesis_instant_single,
+            vec![],
+            None,
+            None,
+            None,
+            Default::default(),
+        )
+    }
+
+    fn local_testnet_genesis() -> GenesisConfig {
+        testnet_genesis(
+            vec![
+                get_authority_keys_from_seed("Alice"),
+                get_authority_keys_from_seed("Bob"),
+            ],
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            vec![
+                get_authority_keys_from_seed("Alice").0,
+                get_authority_keys_from_seed("Bob").0,
+            ],
+        )
+    }
+
+    /// Local testnet config (multivalidator Alice + Bob)
+    pub fn integration_test_config_with_two_authorities() -> ChainSpec {
+        ChainSpec::from_genesis(
+            "Integration Test",
+            "test",
+            ChainType::Development,
+            local_testnet_genesis,
+            vec![],
+            None,
+            None,
+            None,
+            Default::default(),
+        )
+    }
+
+    #[test]
+    #[ignore]
+    fn test_connectivity() {
+        sc_service_test::connectivity(
+            integration_test_config_with_two_authorities(),
+            |config| new_full(config),
+            |config| new_light(config),
+        );
+    }
+}

+ 2 - 2
node/src/cli.rs

@@ -37,8 +37,8 @@ pub enum Subcommand {
 
     /// The custom inspect subcommmand for decoding blocks and extrinsics.
     #[structopt(
-    name = "inspect",
-    about = "Decode given block or extrinsic using current native runtime."
+        name = "inspect",
+        about = "Decode given block or extrinsic using current native runtime."
     )]
     Inspect(node_inspect::cli::InspectCmd),
 

+ 71 - 75
node/src/command.rs

@@ -14,91 +14,87 @@
 // You should have received a copy of the GNU General Public License
 // along with Joystream node.  If not, see <http://www.gnu.org/licenses/>.
 
-use crate::{chain_spec, service};
 use crate::cli::{Cli, Subcommand};
-use crate::node_rpc;
 use crate::node_executor;
+use crate::node_rpc;
+use crate::{chain_spec, service};
 
 use node_executor::Executor;
 use node_runtime::{opaque::Block, RuntimeApi};
 use sc_cli::{Result, SubstrateCli};
-use sc_finality_grandpa::{
-	self as grandpa,
-};
+use sc_finality_grandpa::{self as grandpa};
 
 impl SubstrateCli for Cli {
-	fn impl_name() -> &'static str {
-		"Joystream Node"
-	}
-
-	fn impl_version() -> &'static str {
-		"3.0.0"
-	}
-
-	fn description() -> &'static str {
-		"Joystream substrate node"
-	}
-
-	fn author() -> &'static str {
-		"Joystream contributors"
-	}
-
-	fn support_url() -> &'static str {
-		"https://www.joystream.org/"
-	}
-
-	fn copyright_start_year() -> i32 {
-		2019
-	}
-
-	fn executable_name() -> &'static str {
-		"joystream-node"
-	}
-
-	fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
-		Ok(match id {
-			"dev" => Box::new(chain_spec::Alternative::Development.load().unwrap()), //TODO
-			"local" => Box::new(chain_spec::Alternative::LocalTestnet.load().unwrap()),
-			path => Box::new(chain_spec::ChainSpec::from_json_file(
-				std::path::PathBuf::from(path),
-			)?),
-		})
-	}
+    fn impl_name() -> &'static str {
+        "Joystream Node"
+    }
+
+    fn impl_version() -> &'static str {
+        "3.0.0"
+    }
+
+    fn description() -> &'static str {
+        "Joystream substrate node"
+    }
+
+    fn author() -> &'static str {
+        "Joystream contributors"
+    }
+
+    fn support_url() -> &'static str {
+        "https://www.joystream.org/"
+    }
+
+    fn copyright_start_year() -> i32 {
+        2019
+    }
+
+    fn executable_name() -> &'static str {
+        "joystream-node"
+    }
+
+    fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
+        Ok(match id {
+            "dev" => Box::new(chain_spec::Alternative::Development.load().unwrap()), //TODO
+            "local" => Box::new(chain_spec::Alternative::LocalTestnet.load().unwrap()),
+            path => Box::new(chain_spec::ChainSpec::from_json_file(
+                std::path::PathBuf::from(path),
+            )?),
+        })
+    }
 }
 
 /// Parse command line arguments into service configuration.
 pub fn run() -> Result<()> {
-	let cli = Cli::from_args();
-
-	match &cli.subcommand {
-		None => {
-			let runner = cli.create_runner(&cli.run)?;
-			runner.run_node(
-				service::new_light,
-				service::new_full,
-				node_runtime::VERSION
-			)
-		}
-		Some(Subcommand::Inspect(cmd)) => {
-			let runner = cli.create_runner(cmd)?;
-
-			runner.sync_run(|config| cmd.run::<Block, RuntimeApi, Executor>(config))
-		}
-		Some(Subcommand::Benchmark(cmd)) => {
-			if cfg!(feature = "runtime-benchmarks") {
-				let runner = cli.create_runner(cmd)?;
-
-				runner.sync_run(|config| cmd.run::<Block, Executor>(config))
-			} else {
-				println!("Benchmarking wasn't enabled when building the node. \
-				You can enable it with `--features runtime-benchmarks`.");
-				Ok(())
-			}
-		}
-		Some(Subcommand::Base(subcommand)) => {
-			let runner = cli.create_runner(subcommand)?;
-
-			runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0))
-		}
-	}
+    let cli = Cli::from_args();
+
+    match &cli.subcommand {
+        None => {
+            let runner = cli.create_runner(&cli.run)?;
+            runner.run_node(service::new_light, service::new_full, node_runtime::VERSION)
+        }
+        Some(Subcommand::Inspect(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+
+            runner.sync_run(|config| cmd.run::<Block, RuntimeApi, Executor>(config))
+        }
+        Some(Subcommand::Benchmark(cmd)) => {
+            if cfg!(feature = "runtime-benchmarks") {
+                let runner = cli.create_runner(cmd)?;
+
+                runner.sync_run(|config| cmd.run::<Block, Executor>(config))
+            } else {
+                println!(
+                    "Benchmarking wasn't enabled when building the node. \
+				You can enable it with `--features runtime-benchmarks`."
+                );
+                Ok(())
+            }
+        }
+        Some(Subcommand::Base(subcommand)) => {
+            let runner = cli.create_runner(subcommand)?;
+
+            runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0))
+        }
+    }
 }

+ 1 - 1
node/src/lib.rs

@@ -5,5 +5,5 @@ pub mod members_config;
 #[macro_use]
 pub mod service;
 pub mod command;
-pub mod node_rpc;
 pub mod node_executor;
+pub mod node_rpc;

+ 4 - 4
node/src/node_executor.rs

@@ -3,8 +3,8 @@ use sc_executor::native_executor_instance;
 // Declare an instance of the native executor named `Executor`. Include the wasm binary as the
 // equivalent wasm code.
 native_executor_instance!(
-	pub Executor,
-	node_runtime::api::dispatch,
-	node_runtime::native_version,
-	frame_benchmarking::benchmarking::HostFunctions,
+    pub Executor,
+    node_runtime::api::dispatch,
+    node_runtime::native_version,
+    frame_benchmarking::benchmarking::HostFunctions,
 );

+ 127 - 129
node/src/node_rpc.rs

@@ -32,162 +32,160 @@
 
 use std::sync::Arc;
 
-use node_runtime::{opaque::Block, BlockNumber, AccountId, Index, Balance, Hash};
 use node_runtime::UncheckedExtrinsic;
-use sp_api::ProvideRuntimeApi;
-use sp_transaction_pool::TransactionPool;
-use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend};
-use sp_consensus::SelectChain;
-use sc_keystore::KeyStorePtr;
-use sp_consensus_babe::BabeApi;
-use sc_consensus_epochs::SharedEpochChanges;
+use node_runtime::{opaque::Block, AccountId, Balance, BlockNumber, Hash, Index};
 use sc_consensus_babe::{Config, Epoch};
 use sc_consensus_babe_rpc::BabeRpcHandler;
-use sc_finality_grandpa::{SharedVoterState, SharedAuthoritySet};
+use sc_consensus_epochs::SharedEpochChanges;
+use sc_finality_grandpa::{SharedAuthoritySet, SharedVoterState};
 use sc_finality_grandpa_rpc::GrandpaRpcHandler;
+use sc_keystore::KeyStorePtr;
 use sc_rpc_api::DenyUnsafe;
+use sp_api::ProvideRuntimeApi;
 use sp_block_builder::BlockBuilder;
+use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
+use sp_consensus::SelectChain;
+use sp_consensus_babe::BabeApi;
+use sp_transaction_pool::TransactionPool;
 
 /// Light client extra dependencies.
 pub struct LightDeps<C, F, P> {
-	/// The client instance to use.
-	pub client: Arc<C>,
-	/// Transaction pool instance.
-	pub pool: Arc<P>,
-	/// Remote access to the blockchain (async).
-	pub remote_blockchain: Arc<dyn sc_client_api::light::RemoteBlockchain<Block>>,
-	/// Fetcher instance.
-	pub fetcher: Arc<F>,
+    /// The client instance to use.
+    pub client: Arc<C>,
+    /// Transaction pool instance.
+    pub pool: Arc<P>,
+    /// Remote access to the blockchain (async).
+    pub remote_blockchain: Arc<dyn sc_client_api::light::RemoteBlockchain<Block>>,
+    /// Fetcher instance.
+    pub fetcher: Arc<F>,
 }
 
 /// Extra dependencies for BABE.
 pub struct BabeDeps {
-	/// BABE protocol config.
-	pub babe_config: Config,
-	/// BABE pending epoch changes.
-	pub shared_epoch_changes: SharedEpochChanges<Block, Epoch>,
-	/// The keystore that manages the keys of the node.
-	pub keystore: KeyStorePtr,
+    /// BABE protocol config.
+    pub babe_config: Config,
+    /// BABE pending epoch changes.
+    pub shared_epoch_changes: SharedEpochChanges<Block, Epoch>,
+    /// The keystore that manages the keys of the node.
+    pub keystore: KeyStorePtr,
 }
 
 /// Extra dependencies for GRANDPA
 pub struct GrandpaDeps {
-	/// Voting round info.
-	pub shared_voter_state: SharedVoterState,
-	/// Authority set info.
-	pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,
+    /// Voting round info.
+    pub shared_voter_state: SharedVoterState,
+    /// Authority set info.
+    pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,
 }
 
 /// Full client dependencies.
 pub struct FullDeps<C, P, SC> {
-	/// The client instance to use.
-	pub client: Arc<C>,
-	/// Transaction pool instance.
-	pub pool: Arc<P>,
-	/// The SelectChain Strategy
-	pub select_chain: SC,
-	/// Whether to deny unsafe calls
-	pub deny_unsafe: DenyUnsafe,
-	/// BABE specific dependencies.
-	pub babe: BabeDeps,
-	/// GRANDPA specific dependencies.
-	pub grandpa: GrandpaDeps,
+    /// The client instance to use.
+    pub client: Arc<C>,
+    /// Transaction pool instance.
+    pub pool: Arc<P>,
+    /// The SelectChain Strategy
+    pub select_chain: SC,
+    /// Whether to deny unsafe calls
+    pub deny_unsafe: DenyUnsafe,
+    /// BABE specific dependencies.
+    pub babe: BabeDeps,
+    /// GRANDPA specific dependencies.
+    pub grandpa: GrandpaDeps,
 }
 
 /// Instantiate all Full RPC extensions.
-pub fn create_full<C, P, M, SC>(
-	deps: FullDeps<C, P, SC>,
-) -> jsonrpc_core::IoHandler<M> where
-	C: ProvideRuntimeApi<Block>,
-	C: HeaderBackend<Block> + HeaderMetadata<Block, Error=BlockChainError> + 'static,
-	C: Send + Sync + 'static,
-	C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
-	C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber>,
-	C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance, UncheckedExtrinsic>,
-	C::Api: BabeApi<Block>,
-	C::Api: BlockBuilder<Block>,
-	P: TransactionPool + 'static,
-	M: jsonrpc_core::Metadata + Default,
-	SC: SelectChain<Block> +'static,
+pub fn create_full<C, P, M, SC>(deps: FullDeps<C, P, SC>) -> jsonrpc_core::IoHandler<M>
+where
+    C: ProvideRuntimeApi<Block>,
+    C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
+    C: Send + Sync + 'static,
+    C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
+    C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber>,
+    C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<
+        Block,
+        Balance,
+        UncheckedExtrinsic,
+    >,
+    C::Api: BabeApi<Block>,
+    C::Api: BlockBuilder<Block>,
+    P: TransactionPool + 'static,
+    M: jsonrpc_core::Metadata + Default,
+    SC: SelectChain<Block> + 'static,
 {
-	use substrate_frame_rpc_system::{FullSystem, SystemApi};
-	use pallet_contracts_rpc::{Contracts, ContractsApi};
-	use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
-
-	let mut io = jsonrpc_core::IoHandler::default();
-	let FullDeps {
-		client,
-		pool,
-		select_chain,
-		deny_unsafe,
-		babe,
-		grandpa,
-	} = deps;
-	let BabeDeps {
-		keystore,
-		babe_config,
-		shared_epoch_changes,
-	} = babe;
-	let GrandpaDeps {
-		shared_voter_state,
-		shared_authority_set,
-	} = grandpa;
-
-	io.extend_with(
-		SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe))
-	);
-	// Making synchronous calls in light client freezes the browser currently,
-	// more context: https://github.com/paritytech/substrate/pull/3480
-	// These RPCs should use an asynchronous caller instead.
-	io.extend_with(
-		ContractsApi::to_delegate(Contracts::new(client.clone()))
-	);
-	io.extend_with(
-		TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone()))
-	);
-	io.extend_with(
-		sc_consensus_babe_rpc::BabeApi::to_delegate(
-			BabeRpcHandler::new(
-				client,
-				shared_epoch_changes,
-				keystore,
-				babe_config,
-				select_chain,
-				deny_unsafe,
-			),
-		)
-	);
-	io.extend_with(
-		sc_finality_grandpa_rpc::GrandpaApi::to_delegate(
-			GrandpaRpcHandler::new(shared_authority_set, shared_voter_state)
-		)
-	);
-
-	io
+    use pallet_contracts_rpc::{Contracts, ContractsApi};
+    use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
+    use substrate_frame_rpc_system::{FullSystem, SystemApi};
+
+    let mut io = jsonrpc_core::IoHandler::default();
+    let FullDeps {
+        client,
+        pool,
+        select_chain,
+        deny_unsafe,
+        babe,
+        grandpa,
+    } = deps;
+    let BabeDeps {
+        keystore,
+        babe_config,
+        shared_epoch_changes,
+    } = babe;
+    let GrandpaDeps {
+        shared_voter_state,
+        shared_authority_set,
+    } = grandpa;
+
+    io.extend_with(SystemApi::to_delegate(FullSystem::new(
+        client.clone(),
+        pool,
+        deny_unsafe,
+    )));
+    // Making synchronous calls in light client freezes the browser currently,
+    // more context: https://github.com/paritytech/substrate/pull/3480
+    // These RPCs should use an asynchronous caller instead.
+    io.extend_with(ContractsApi::to_delegate(Contracts::new(client.clone())));
+    io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(
+        client.clone(),
+    )));
+    io.extend_with(sc_consensus_babe_rpc::BabeApi::to_delegate(
+        BabeRpcHandler::new(
+            client,
+            shared_epoch_changes,
+            keystore,
+            babe_config,
+            select_chain,
+            deny_unsafe,
+        ),
+    ));
+    io.extend_with(sc_finality_grandpa_rpc::GrandpaApi::to_delegate(
+        GrandpaRpcHandler::new(shared_authority_set, shared_voter_state),
+    ));
+
+    io
 }
 
 /// Instantiate all Light RPC extensions.
-pub fn create_light<C, P, M, F>(
-	deps: LightDeps<C, F, P>,
-) -> jsonrpc_core::IoHandler<M> where
-	C: sp_blockchain::HeaderBackend<Block>,
-	C: Send + Sync + 'static,
-	F: sc_client_api::light::Fetcher<Block> + 'static,
-	P: TransactionPool + 'static,
-	M: jsonrpc_core::Metadata + Default,
+pub fn create_light<C, P, M, F>(deps: LightDeps<C, F, P>) -> jsonrpc_core::IoHandler<M>
+where
+    C: sp_blockchain::HeaderBackend<Block>,
+    C: Send + Sync + 'static,
+    F: sc_client_api::light::Fetcher<Block> + 'static,
+    P: TransactionPool + 'static,
+    M: jsonrpc_core::Metadata + Default,
 {
-	use substrate_frame_rpc_system::{LightSystem, SystemApi};
-
-	let LightDeps {
-		client,
-		pool,
-		remote_blockchain,
-		fetcher
-	} = deps;
-	let mut io = jsonrpc_core::IoHandler::default();
-	io.extend_with(
-		SystemApi::<Hash, AccountId, Index>::to_delegate(LightSystem::new(client, remote_blockchain, fetcher, pool))
-	);
-
-	io
+    use substrate_frame_rpc_system::{LightSystem, SystemApi};
+
+    let LightDeps {
+        client,
+        pool,
+        remote_blockchain,
+        fetcher,
+    } = deps;
+    let mut io = jsonrpc_core::IoHandler::default();
+    io.extend_with(SystemApi::<Hash, AccountId, Index>::to_delegate(
+        LightSystem::new(client, remote_blockchain, fetcher, pool),
+    ));
+
+    io
 }

+ 450 - 426
node/src/service.rs

@@ -21,132 +21,137 @@
 
 //! Service implementation. Specialized wrapper over substrate service.
 
-use std::sync::Arc;
-use sc_finality_grandpa::{
-	self as grandpa, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider,
-};
 use node_runtime::opaque::Block;
 use node_runtime::RuntimeApi;
+use sc_consensus::LongestChain;
+use sc_finality_grandpa::{
+    self as grandpa, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider,
+};
 use sc_service::{
-	AbstractService, ServiceBuilder, config::Configuration, error::{Error as ServiceError},
+    config::Configuration, error::Error as ServiceError, AbstractService, ServiceBuilder,
 };
 use sp_inherents::InherentDataProviders;
-use sc_consensus::LongestChain;
+use std::sync::Arc;
 
-use crate::node_rpc;
 use crate::node_executor;
+use crate::node_rpc;
 
 /// Starts a `ServiceBuilder` for a full service.
 ///
 /// Use this macro if you don't actually need the full service, but just the builder in order to
 /// be able to perform chain operations.
 macro_rules! new_full_start {
-	($config:expr) => {{
-		use std::sync::Arc;
-
-		let mut import_setup = None;
-		let mut rpc_setup = None;
-		let inherent_data_providers = sp_inherents::InherentDataProviders::new();
-
-		let builder = sc_service::ServiceBuilder::new_full::<
-			Block, RuntimeApi, node_executor::Executor
-		>($config)?
-			.with_select_chain(|_config, backend| {
-				Ok(sc_consensus::LongestChain::new(backend.clone()))
-			})?
-			.with_transaction_pool(|builder| {
-				let pool_api = sc_transaction_pool::FullChainApi::new(
-					builder.client().clone(),
-				);
-				let config = builder.config();
-
-				Ok(sc_transaction_pool::BasicPool::new(
-					config.transaction_pool.clone(),
-					std::sync::Arc::new(pool_api),
-					builder.prometheus_registry(),
-				))
-			})?
-			.with_import_queue(|
-				_config,
-				client,
-				mut select_chain,
-				_transaction_pool,
-				spawn_task_handle,
-				prometheus_registry,
-			| {
-				let select_chain = select_chain.take()
-					.ok_or_else(|| sc_service::Error::SelectChainRequired)?;
-				let (grandpa_block_import, grandpa_link) = grandpa::block_import(
-					client.clone(),
-					&(client.clone() as Arc<_>),
-					select_chain,
-				)?;
-				let justification_import = grandpa_block_import.clone();
-
-				let (block_import, babe_link) = sc_consensus_babe::block_import(
-					sc_consensus_babe::Config::get_or_compute(&*client)?,
-					grandpa_block_import,
-					client.clone(),
-				)?;
-
-				let import_queue = sc_consensus_babe::import_queue(
-					babe_link.clone(),
-					block_import.clone(),
-					Some(Box::new(justification_import)),
-					None,
-					client,
-					inherent_data_providers.clone(),
-					spawn_task_handle,
-					prometheus_registry,
-				)?;
-
-				import_setup = Some((block_import, grandpa_link, babe_link));
-				Ok(import_queue)
-			})?
-			.with_rpc_extensions_builder(|builder| {
-				let grandpa_link = import_setup.as_ref().map(|s| &s.1)
-					.expect("GRANDPA LinkHalf is present for full services or set up failed; qed.");
-
-				let shared_authority_set = grandpa_link.shared_authority_set().clone();
-				let shared_voter_state = grandpa::SharedVoterState::empty();
-
-				rpc_setup = Some((shared_voter_state.clone()));
-
-				let babe_link = import_setup.as_ref().map(|s| &s.2)
-					.expect("BabeLink is present for full services or set up failed; qed.");
-
-				let babe_config = babe_link.config().clone();
-				let shared_epoch_changes = babe_link.epoch_changes().clone();
-
-				let client = builder.client().clone();
-				let pool = builder.pool().clone();
-				let select_chain = builder.select_chain().cloned()
-					.expect("SelectChain is present for full services or set up failed; qed.");
-				let keystore = builder.keystore().clone();
-
-				Ok(move |deny_unsafe| {
-					let deps = node_rpc::FullDeps {
-						client: client.clone(),
-						pool: pool.clone(),
-						select_chain: select_chain.clone(),
-						deny_unsafe,
-						babe: node_rpc::BabeDeps {
-							babe_config: babe_config.clone(),
-							shared_epoch_changes: shared_epoch_changes.clone(),
-							keystore: keystore.clone(),
-						},
-						grandpa: node_rpc::GrandpaDeps {
-							shared_voter_state: shared_voter_state.clone(),
-							shared_authority_set: shared_authority_set.clone(),
-						},
-					};
-
-					node_rpc::create_full(deps)
-				})
-			})?;
-
-		(builder, import_setup, inherent_data_providers, rpc_setup)
-	}}
+    ($config:expr) => {{
+        use std::sync::Arc;
+
+        let mut import_setup = None;
+        let mut rpc_setup = None;
+        let inherent_data_providers = sp_inherents::InherentDataProviders::new();
+
+        let builder = sc_service::ServiceBuilder::new_full::<
+            Block,
+            RuntimeApi,
+            node_executor::Executor,
+        >($config)?
+        .with_select_chain(|_config, backend| Ok(sc_consensus::LongestChain::new(backend.clone())))?
+        .with_transaction_pool(|builder| {
+            let pool_api = sc_transaction_pool::FullChainApi::new(builder.client().clone());
+            let config = builder.config();
+
+            Ok(sc_transaction_pool::BasicPool::new(
+                config.transaction_pool.clone(),
+                std::sync::Arc::new(pool_api),
+                builder.prometheus_registry(),
+            ))
+        })?
+        .with_import_queue(
+            |_config,
+             client,
+             mut select_chain,
+             _transaction_pool,
+             spawn_task_handle,
+             prometheus_registry| {
+                let select_chain = select_chain
+                    .take()
+                    .ok_or_else(|| sc_service::Error::SelectChainRequired)?;
+                let (grandpa_block_import, grandpa_link) = grandpa::block_import(
+                    client.clone(),
+                    &(client.clone() as Arc<_>),
+                    select_chain,
+                )?;
+                let justification_import = grandpa_block_import.clone();
+
+                let (block_import, babe_link) = sc_consensus_babe::block_import(
+                    sc_consensus_babe::Config::get_or_compute(&*client)?,
+                    grandpa_block_import,
+                    client.clone(),
+                )?;
+
+                let import_queue = sc_consensus_babe::import_queue(
+                    babe_link.clone(),
+                    block_import.clone(),
+                    Some(Box::new(justification_import)),
+                    None,
+                    client,
+                    inherent_data_providers.clone(),
+                    spawn_task_handle,
+                    prometheus_registry,
+                )?;
+
+                import_setup = Some((block_import, grandpa_link, babe_link));
+                Ok(import_queue)
+            },
+        )?
+        .with_rpc_extensions_builder(|builder| {
+            let grandpa_link = import_setup
+                .as_ref()
+                .map(|s| &s.1)
+                .expect("GRANDPA LinkHalf is present for full services or set up failed; qed.");
+
+            let shared_authority_set = grandpa_link.shared_authority_set().clone();
+            let shared_voter_state = grandpa::SharedVoterState::empty();
+
+            rpc_setup = Some((shared_voter_state.clone()));
+
+            let babe_link = import_setup
+                .as_ref()
+                .map(|s| &s.2)
+                .expect("BabeLink is present for full services or set up failed; qed.");
+
+            let babe_config = babe_link.config().clone();
+            let shared_epoch_changes = babe_link.epoch_changes().clone();
+
+            let client = builder.client().clone();
+            let pool = builder.pool().clone();
+            let select_chain = builder
+                .select_chain()
+                .cloned()
+                .expect("SelectChain is present for full services or set up failed; qed.");
+            let keystore = builder.keystore().clone();
+
+            Ok(move |deny_unsafe| {
+                let deps = node_rpc::FullDeps {
+                    client: client.clone(),
+                    pool: pool.clone(),
+                    select_chain: select_chain.clone(),
+                    deny_unsafe,
+                    babe: node_rpc::BabeDeps {
+                        babe_config: babe_config.clone(),
+                        shared_epoch_changes: shared_epoch_changes.clone(),
+                        keystore: keystore.clone(),
+                    },
+                    grandpa: node_rpc::GrandpaDeps {
+                        shared_voter_state: shared_voter_state.clone(),
+                        shared_authority_set: shared_authority_set.clone(),
+                    },
+                };
+
+                node_rpc::create_full(deps)
+            })
+        })?;
+
+        (builder, import_setup, inherent_data_providers, rpc_setup)
+    }};
 }
 
 /// Creates a full service from the configuration.
@@ -314,324 +319,343 @@ macro_rules! new_full {
 }
 
 /// Builds a new service for a full client.
-pub fn new_full(config: Configuration)
-				-> Result<impl AbstractService, ServiceError>
-{
-	new_full!(config).map(|(service, _)| service)
+pub fn new_full(config: Configuration) -> Result<impl AbstractService, ServiceError> {
+    new_full!(config).map(|(service, _)| service)
 }
 
 /// Builds a new service for a light client.
-pub fn new_light(config: Configuration)
-				 -> Result<impl AbstractService, ServiceError> {
-	let inherent_data_providers = InherentDataProviders::new();
-
-	let service = ServiceBuilder::new_light::<Block, RuntimeApi, node_executor::Executor>(config)?
-		.with_select_chain(|_config, backend| {
-			Ok(LongestChain::new(backend.clone()))
-		})?
-		.with_transaction_pool(|builder| {
-			let fetcher = builder.fetcher()
-				.ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;
-			let pool_api = sc_transaction_pool::LightChainApi::new(
-				builder.client().clone(),
-				fetcher,
-			);
-			let pool = sc_transaction_pool::BasicPool::with_revalidation_type(
-				builder.config().transaction_pool.clone(),
-				Arc::new(pool_api),
-				builder.prometheus_registry(),
-				sc_transaction_pool::RevalidationType::Light,
-			);
-			Ok(pool)
-		})?
-		.with_import_queue_and_fprb(|
-			_config,
-			client,
-			backend,
-			fetcher,
-			_select_chain,
-			_tx_pool,
-			spawn_task_handle,
-			registry,
-		| {
-			let fetch_checker = fetcher
-				.map(|fetcher| fetcher.checker().clone())
-				.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
-			let grandpa_block_import = grandpa::light_block_import(
-				client.clone(),
-				backend,
-				&(client.clone() as Arc<_>),
-				Arc::new(fetch_checker),
-			)?;
-
-			let finality_proof_import = grandpa_block_import.clone();
-			let finality_proof_request_builder =
-				finality_proof_import.create_finality_proof_request_builder();
-
-			let (babe_block_import, babe_link) = sc_consensus_babe::block_import(
-				sc_consensus_babe::Config::get_or_compute(&*client)?,
-				grandpa_block_import,
-				client.clone(),
-			)?;
-
-			let import_queue = sc_consensus_babe::import_queue(
-				babe_link,
-				babe_block_import,
-				None,
-				Some(Box::new(finality_proof_import)),
-				client,
-				inherent_data_providers.clone(),
-				spawn_task_handle,
-				registry,
-			)?;
-
-			Ok((import_queue, finality_proof_request_builder))
-		})?
-		.with_finality_proof_provider(|client, backend| {
-			// GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
-			let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;
-			Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
-		})?
-		.with_rpc_extensions(|builder| {
-			let fetcher = builder.fetcher()
-				.ok_or_else(|| "Trying to start node RPC without active fetcher")?;
-			let remote_blockchain = builder.remote_backend()
-				.ok_or_else(|| "Trying to start node RPC without active remote blockchain")?;
-
-			let light_deps = node_rpc::LightDeps {
-				remote_blockchain,
-				fetcher,
-				client: builder.client().clone(),
-				pool: builder.pool(),
-			};
-
-			Ok(node_rpc::create_light(light_deps))
-		})?
-		.build_light()?;
-
-	Ok(service)
+pub fn new_light(config: Configuration) -> Result<impl AbstractService, ServiceError> {
+    let inherent_data_providers = InherentDataProviders::new();
+
+    let service = ServiceBuilder::new_light::<Block, RuntimeApi, node_executor::Executor>(config)?
+        .with_select_chain(|_config, backend| Ok(LongestChain::new(backend.clone())))?
+        .with_transaction_pool(|builder| {
+            let fetcher = builder
+                .fetcher()
+                .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;
+            let pool_api =
+                sc_transaction_pool::LightChainApi::new(builder.client().clone(), fetcher);
+            let pool = sc_transaction_pool::BasicPool::with_revalidation_type(
+                builder.config().transaction_pool.clone(),
+                Arc::new(pool_api),
+                builder.prometheus_registry(),
+                sc_transaction_pool::RevalidationType::Light,
+            );
+            Ok(pool)
+        })?
+        .with_import_queue_and_fprb(
+            |_config,
+             client,
+             backend,
+             fetcher,
+             _select_chain,
+             _tx_pool,
+             spawn_task_handle,
+             registry| {
+                let fetch_checker = fetcher
+                    .map(|fetcher| fetcher.checker().clone())
+                    .ok_or_else(|| {
+                        "Trying to start light import queue without active fetch checker"
+                    })?;
+                let grandpa_block_import = grandpa::light_block_import(
+                    client.clone(),
+                    backend,
+                    &(client.clone() as Arc<_>),
+                    Arc::new(fetch_checker),
+                )?;
+
+                let finality_proof_import = grandpa_block_import.clone();
+                let finality_proof_request_builder =
+                    finality_proof_import.create_finality_proof_request_builder();
+
+                let (babe_block_import, babe_link) = sc_consensus_babe::block_import(
+                    sc_consensus_babe::Config::get_or_compute(&*client)?,
+                    grandpa_block_import,
+                    client.clone(),
+                )?;
+
+                let import_queue = sc_consensus_babe::import_queue(
+                    babe_link,
+                    babe_block_import,
+                    None,
+                    Some(Box::new(finality_proof_import)),
+                    client,
+                    inherent_data_providers.clone(),
+                    spawn_task_handle,
+                    registry,
+                )?;
+
+                Ok((import_queue, finality_proof_request_builder))
+            },
+        )?
+        .with_finality_proof_provider(|client, backend| {
+            // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
+            let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;
+            Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
+        })?
+        .with_rpc_extensions(|builder| {
+            let fetcher = builder
+                .fetcher()
+                .ok_or_else(|| "Trying to start node RPC without active fetcher")?;
+            let remote_blockchain = builder
+                .remote_backend()
+                .ok_or_else(|| "Trying to start node RPC without active remote blockchain")?;
+
+            let light_deps = node_rpc::LightDeps {
+                remote_blockchain,
+                fetcher,
+                client: builder.client().clone(),
+                pool: builder.pool(),
+            };
+
+            Ok(node_rpc::create_light(light_deps))
+        })?
+        .build_light()?;
+
+    Ok(service)
 }
 
 #[cfg(test)]
 mod tests {
-	use std::{sync::Arc, borrow::Cow, any::Any};
-	use sc_consensus_babe::{
-		CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY
-	};
-	use sc_consensus_epochs::descendent_query;
-	use sp_consensus::{
-		Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport,
-		RecordProof,
-	};
-	use node_primitives::{Block, DigestItem, Signature};
-	use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address};
-	use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION};
-	use codec::{Encode, Decode};
-	use sp_core::{crypto::Pair as CryptoPair, H256};
-	use sp_runtime::{
-		generic::{BlockId, Era, Digest, SignedPayload},
-		traits::{Block as BlockT, Header as HeaderT},
-		traits::Verify,
-		OpaqueExtrinsic,
-	};
-	use sp_timestamp;
-	use sp_finality_tracker;
-	use sp_keyring::AccountKeyring;
-	use sc_service::AbstractService;
-	use crate::service::{new_full, new_light};
-	use sp_runtime::traits::IdentifyAccount;
-	use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent};
-
-	type AccountPublic = <Signature as Verify>::Signer;
-
-	#[test]
-	// It is "ignored", but the node-cli ignored tests are running on the CI.
-	// This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`.
-	#[ignore]
-	fn test_sync() {
-		let keystore_path = tempfile::tempdir().expect("Creates keystore path");
-		let keystore = sc_keystore::Store::open(keystore_path.path(), None)
-			.expect("Creates keystore");
-		let alice = keystore.write().insert_ephemeral_from_seed::<sc_consensus_babe::AuthorityPair>("//Alice")
-			.expect("Creates authority pair");
-
-		let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
-
-		// For the block factory
-		let mut slot_num = 1u64;
-
-		// For the extrinsics factory
-		let bob = Arc::new(AccountKeyring::Bob.pair());
-		let charlie = Arc::new(AccountKeyring::Charlie.pair());
-		let mut index = 0;
-
-		sc_service_test::sync(
-			chain_spec,
-			|config| {
-				let mut setup_handles = None;
-				new_full!(config, |
-					block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
-					babe_link: &sc_consensus_babe::BabeLink<Block>,
-				| {
-					setup_handles = Some((block_import.clone(), babe_link.clone()));
-				}).map(move |(node, x)| (node, (x, setup_handles.unwrap())))
-			},
-			|config| new_light(config),
-			|service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| {
-				let mut inherent_data = inherent_data_providers
-					.create_inherent_data()
-					.expect("Creates inherent data.");
-				inherent_data.replace_data(sp_finality_tracker::INHERENT_IDENTIFIER, &1u64);
-
-				let parent_id = BlockId::number(service.client().chain_info().best_number);
-				let parent_header = service.client().header(&parent_id).unwrap().unwrap();
-				let parent_hash = parent_header.hash();
-				let parent_number = *parent_header.number();
-
-				futures::executor::block_on(
-					service.transaction_pool().maintain(
-						ChainEvent::NewBlock {
-							is_new_best: true,
-							hash: parent_header.hash(),
-							tree_route: None,
-							header: parent_header.clone(),
-						},
-					)
-				);
-
-				let mut proposer_factory = sc_basic_authorship::ProposerFactory::new(
-					service.client(),
-					service.transaction_pool(),
-					None,
-				);
-
-				let epoch_descriptor = babe_link.epoch_changes().lock().epoch_descriptor_for_child_of(
-					descendent_query(&*service.client()),
-					&parent_hash,
-					parent_number,
-					slot_num,
-				).unwrap().unwrap();
-
-				let mut digest = Digest::<H256>::default();
-
-				// even though there's only one authority some slots might be empty,
-				// so we must keep trying the next slots until we can claim one.
-				let babe_pre_digest = loop {
-					inherent_data.replace_data(sp_timestamp::INHERENT_IDENTIFIER, &(slot_num * SLOT_DURATION));
-					if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot(
-						slot_num,
-						&parent_header,
-						&*service.client(),
-						&keystore,
-						&babe_link,
-					) {
-						break babe_pre_digest;
-					}
-
-					slot_num += 1;
-				};
-
-				digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(babe_pre_digest));
-
-				let new_block = futures::executor::block_on(async move {
-					let proposer = proposer_factory.init(&parent_header).await;
-					proposer.unwrap().propose(
-						inherent_data,
-						digest,
-						std::time::Duration::from_secs(1),
-						RecordProof::Yes,
-					).await
-				}).expect("Error making test block").block;
-
-				let (new_header, new_body) = new_block.deconstruct();
-				let pre_hash = new_header.hash();
-				// sign the pre-sealed hash of the block and then
-				// add it to a digest item.
-				let to_sign = pre_hash.encode();
-				let signature = alice.sign(&to_sign[..]);
-				let item = <DigestItem as CompatibleDigestItem>::babe_seal(
-					signature.into(),
-				);
-				slot_num += 1;
-
-				let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
-				params.post_digests.push(item);
-				params.body = Some(new_body);
-				params.intermediates.insert(
-					Cow::from(INTERMEDIATE_KEY),
-					Box::new(BabeIntermediate::<Block> { epoch_descriptor }) as Box<dyn Any>,
-				);
-				params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
-
-				block_import.import_block(params, Default::default())
-					.expect("error importing test block");
-			},
-			|service, _| {
-				let amount = 5 * CENTS;
-				let to: Address = AccountPublic::from(bob.public()).into_account().into();
-				let from: Address = AccountPublic::from(charlie.public()).into_account().into();
-				let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
-				let best_block_id = BlockId::number(service.client().chain_info().best_number);
-				let (spec_version, transaction_version) = {
-					let version = service.client().runtime_version_at(&best_block_id).unwrap();
-					(version.spec_version, version.transaction_version)
-				};
-				let signer = charlie.clone();
-
-				let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
-
-				let check_spec_version = frame_system::CheckSpecVersion::new();
-				let check_tx_version = frame_system::CheckTxVersion::new();
-				let check_genesis = frame_system::CheckGenesis::new();
-				let check_era = frame_system::CheckEra::from(Era::Immortal);
-				let check_nonce = frame_system::CheckNonce::from(index);
-				let check_weight = frame_system::CheckWeight::new();
-				let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0);
-				let validate_grandpa_equivocation = pallet_grandpa::ValidateEquivocationReport::new();
-				let extra = (
-					check_spec_version,
-					check_tx_version,
-					check_genesis,
-					check_era,
-					check_nonce,
-					check_weight,
-					payment,
-					validate_grandpa_equivocation,
-				);
-				let raw_payload = SignedPayload::from_raw(
-					function,
-					extra,
-					(spec_version, transaction_version, genesis_hash, genesis_hash, (), (), (), ())
-				);
-				let signature = raw_payload.using_encoded(|payload|	{
-					signer.sign(payload)
-				});
-				let (function, extra, _) = raw_payload.deconstruct();
-				let xt = UncheckedExtrinsic::new_signed(
-					function,
-					from.into(),
-					signature.into(),
-					extra,
-				).encode();
-				let v: Vec<u8> = Decode::decode(&mut xt.as_slice()).unwrap();
-
-				index += 1;
-				OpaqueExtrinsic(v)
-			},
-		);
-	}
-
-	#[test]
-	#[ignore]
-	fn test_consensus() {
-		sc_service_test::consensus(
-			crate::chain_spec::tests::integration_test_config_with_two_authorities(),
-			|config| new_full(config),
-			|config| new_light(config),
-			vec![
-				"//Alice".into(),
-				"//Bob".into(),
-			],
-		)
-	}
+    use crate::node_executor;
+    use crate::node_rpc;
+    use crate::service::{new_full, new_light};
+    use codec::{Decode, Encode};
+    use node_runtime::RuntimeApi;
+    use node_runtime::{currency::CENTS, SLOT_DURATION};
+    use node_runtime::{opaque::Block, DigestItem, Signature};
+    use node_runtime::{Address, BalancesCall, Call, UncheckedExtrinsic};
+    use sc_consensus_babe::{BabeIntermediate, CompatibleDigestItem, INTERMEDIATE_KEY};
+    use sc_consensus_epochs::descendent_query;
+    use sc_finality_grandpa::{self as grandpa};
+    use sc_service::AbstractService;
+    use sp_consensus::{
+        BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy, Proposer,
+        RecordProof,
+    };
+    use sp_core::{crypto::Pair as CryptoPair, H256};
+    use sp_finality_tracker;
+    use sp_keyring::AccountKeyring;
+    use sp_runtime::traits::IdentifyAccount;
+    use sp_runtime::{
+        generic::{BlockId, Digest, Era, SignedPayload},
+        traits::Verify,
+        traits::{Block as BlockT, Header as HeaderT},
+        OpaqueExtrinsic,
+    };
+    use sp_timestamp;
+    use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool};
+    use std::{any::Any, borrow::Cow, sync::Arc};
+
+    type AccountPublic = <Signature as Verify>::Signer;
+
+    // Long running test. Run it locally only after the node changes.
+    #[test]
+    // It is "ignored", but the node-cli ignored tests are running on the CI.
+    // This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`.
+    #[ignore]
+    fn test_sync() {
+        let keystore_path = tempfile::tempdir().expect("Creates keystore path");
+        let keystore =
+            sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore");
+        let alice = keystore
+            .write()
+            .insert_ephemeral_from_seed::<sc_consensus_babe::AuthorityPair>("//Alice")
+            .expect("Creates authority pair");
+
+        let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
+
+        // For the block factory
+        let mut slot_num = 1u64;
+
+        // For the extrinsics factory
+        let bob = Arc::new(AccountKeyring::Bob.pair());
+        let charlie = Arc::new(AccountKeyring::Charlie.pair());
+        let mut index = 0;
+
+        sc_service_test::sync(
+            chain_spec,
+            |config| {
+                let mut setup_handles = None;
+                new_full!(
+                    config,
+                    |block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
+                     babe_link: &sc_consensus_babe::BabeLink<Block>| {
+                        setup_handles = Some((block_import.clone(), babe_link.clone()));
+                    }
+                )
+                .map(move |(node, x)| (node, (x, setup_handles.unwrap())))
+            },
+            |config| new_light(config),
+            |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| {
+                let mut inherent_data = inherent_data_providers
+                    .create_inherent_data()
+                    .expect("Creates inherent data.");
+                inherent_data.replace_data(sp_finality_tracker::INHERENT_IDENTIFIER, &1u64);
+
+                let parent_id = BlockId::number(service.client().chain_info().best_number);
+                let parent_header = service.client().header(&parent_id).unwrap().unwrap();
+                let parent_hash = parent_header.hash();
+                let parent_number = *parent_header.number();
+
+                futures::executor::block_on(service.transaction_pool().maintain(
+                    ChainEvent::NewBlock {
+                        is_new_best: true,
+                        hash: parent_header.hash(),
+                        tree_route: None,
+                        header: parent_header.clone(),
+                    },
+                ));
+
+                let mut proposer_factory = sc_basic_authorship::ProposerFactory::new(
+                    service.client(),
+                    service.transaction_pool(),
+                    None,
+                );
+
+                let epoch_descriptor = babe_link
+                    .epoch_changes()
+                    .lock()
+                    .epoch_descriptor_for_child_of(
+                        descendent_query(&*service.client()),
+                        &parent_hash,
+                        parent_number,
+                        slot_num,
+                    )
+                    .unwrap()
+                    .unwrap();
+
+                let mut digest = Digest::<H256>::default();
+
+                // even though there's only one authority some slots might be empty,
+                // so we must keep trying the next slots until we can claim one.
+                let babe_pre_digest = loop {
+                    inherent_data.replace_data(
+                        sp_timestamp::INHERENT_IDENTIFIER,
+                        &(slot_num * SLOT_DURATION),
+                    );
+                    if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot(
+                        slot_num,
+                        &parent_header,
+                        &*service.client(),
+                        &keystore,
+                        &babe_link,
+                    ) {
+                        break babe_pre_digest;
+                    }
+
+                    slot_num += 1;
+                };
+
+                digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(
+                    babe_pre_digest,
+                ));
+
+                let new_block = futures::executor::block_on(async move {
+                    let proposer = proposer_factory.init(&parent_header).await;
+                    proposer
+                        .unwrap()
+                        .propose(
+                            inherent_data,
+                            digest,
+                            std::time::Duration::from_secs(1),
+                            RecordProof::Yes,
+                        )
+                        .await
+                })
+                .expect("Error making test block")
+                .block;
+
+                let (new_header, new_body) = new_block.deconstruct();
+                let pre_hash = new_header.hash();
+                // sign the pre-sealed hash of the block and then
+                // add it to a digest item.
+                let to_sign = pre_hash.encode();
+                let signature = alice.sign(&to_sign[..]);
+                let item = <DigestItem as CompatibleDigestItem>::babe_seal(signature.into());
+                slot_num += 1;
+
+                let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
+                params.post_digests.push(item);
+                params.body = Some(new_body);
+                params.intermediates.insert(
+                    Cow::from(INTERMEDIATE_KEY),
+                    Box::new(BabeIntermediate::<Block> { epoch_descriptor }) as Box<dyn Any>,
+                );
+                params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
+
+                block_import
+                    .import_block(params, Default::default())
+                    .expect("error importing test block");
+            },
+            |service, _| {
+                let amount = 5 * CENTS;
+                let to: Address = AccountPublic::from(bob.public()).into_account().into();
+                let from: Address = AccountPublic::from(charlie.public()).into_account().into();
+                let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
+                let best_block_id = BlockId::number(service.client().chain_info().best_number);
+                let (spec_version, transaction_version) = {
+                    let version = service.client().runtime_version_at(&best_block_id).unwrap();
+                    (version.spec_version, version.transaction_version)
+                };
+                let signer = charlie.clone();
+
+                let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
+
+                let check_spec_version = frame_system::CheckSpecVersion::new();
+                let check_tx_version = frame_system::CheckTxVersion::new();
+                let check_genesis = frame_system::CheckGenesis::new();
+                let check_era = frame_system::CheckEra::from(Era::Immortal);
+                let check_nonce = frame_system::CheckNonce::from(index);
+                let check_weight = frame_system::CheckWeight::new();
+                let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0);
+                let validate_grandpa_equivocation =
+                    pallet_grandpa::ValidateEquivocationReport::new();
+                let extra = (
+                    check_spec_version,
+                    check_tx_version,
+                    check_genesis,
+                    check_era,
+                    check_nonce,
+                    check_weight,
+                    payment,
+                    validate_grandpa_equivocation,
+                );
+                let raw_payload = SignedPayload::from_raw(
+                    function,
+                    extra,
+                    (
+                        spec_version,
+                        transaction_version,
+                        genesis_hash,
+                        genesis_hash,
+                        (),
+                        (),
+                        (),
+                        (),
+                    ),
+                );
+                let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
+                let (function, extra, _) = raw_payload.deconstruct();
+                let xt =
+                    UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra)
+                        .encode();
+                let v: Vec<u8> = Decode::decode(&mut xt.as_slice()).unwrap();
+
+                index += 1;
+                OpaqueExtrinsic(v)
+            },
+        );
+    }
+
+    #[test]
+    #[ignore]
+    fn test_consensus() {
+        sc_service_test::consensus(
+            crate::chain_spec::tests::integration_test_config_with_two_authorities(),
+            |config| new_full(config),
+            |config| new_light(config),
+            vec!["//Alice".into(), "//Bob".into()],
+        )
+    }
 }

+ 49 - 0
runtime/src/constants.rs

@@ -0,0 +1,49 @@
+use crate::{BlockNumber, Moment};
+
+/// Constants for Babe.
+
+/// Since BABE is probabilistic this is the average expected block time that
+/// we are targetting. Blocks will be produced at a minimum duration defined
+/// by `SLOT_DURATION`, but some slots will not be allocated to any
+/// authority and hence no block will be produced. We expect to have this
+/// block time on average following the defined slot duration and the value
+/// of `c` configured for BABE (where `1 - c` represents the probability of
+/// a slot being empty).
+/// This value is only used indirectly to define the unit constants below
+/// that are expressed in blocks. The rest of the code should use
+/// `SLOT_DURATION` instead (like the timestamp module for calculating the
+/// minimum period).
+/// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
+pub const MILLISECS_PER_BLOCK: Moment = 6000;
+pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000;
+
+pub const SLOT_DURATION: Moment = 6000;
+
+pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES;
+pub const EPOCH_DURATION_IN_SLOTS: u64 = {
+    const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64;
+
+    (EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64
+};
+
+// These time units are defined in number of blocks.
+pub const MINUTES: BlockNumber = 60 / (SECS_PER_BLOCK as BlockNumber);
+pub const HOURS: BlockNumber = MINUTES * 60;
+pub const DAYS: BlockNumber = HOURS * 24;
+
+// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks.
+pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
+
+/// Tests only
+#[cfg(any(feature = "std", test))]
+pub mod currency {
+    use crate::primitives::Balance;
+
+    pub const MILLICENTS: Balance = 1_000_000_000;
+    pub const CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent.
+    pub const DOLLARS: Balance = 100 * CENTS;
+
+    pub const fn deposit(items: u32, bytes: u32) -> Balance {
+        items as Balance * 15 * CENTS + (bytes as Balance) * 6 * CENTS
+    }
+}

+ 89 - 120
runtime/src/lib.rs

@@ -13,25 +13,27 @@
 #[cfg(feature = "std")]
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
+mod constants;
 mod integration;
-mod primitives;
 mod migration;
+mod primitives;
 #[cfg(test)]
 mod tests; // Runtime integration tests
 
 use codec::Encode;
 use frame_support::inherent::{CheckInherentsResult, InherentData};
-use frame_support::traits::{KeyOwnerProofSystem};
+use frame_support::traits::KeyOwnerProofSystem;
 use frame_support::weights::{
     constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight},
-    IdentityFee, Weight,
+    Weight, WeightToFeeCoefficients, WeightToFeePolynomial,
 };
 use frame_support::{construct_runtime, debug, parameter_types, traits::Randomness};
+use pallet_contracts_rpc_runtime_api::ContractExecResult;
 use pallet_grandpa::fg_primitives;
 use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
 use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
 use pallet_session::historical as pallet_session_historical;
-use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
+use pallet_transaction_payment::Multiplier;
 use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
 use sp_api::impl_runtime_apis;
 use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
@@ -39,19 +41,22 @@ use sp_core::crypto::KeyTypeId;
 use sp_core::OpaqueMetadata;
 use sp_runtime::curve::PiecewiseLinear;
 use sp_runtime::generic::SignedPayload;
-use sp_runtime::traits::{OpaqueKeys,
-    BlakeTwo256, Block as BlockT, NumberFor, Saturating, StaticLookup,
+use sp_runtime::traits::{
+    BlakeTwo256, Block as BlockT, NumberFor, OpaqueKeys, Saturating, StaticLookup,
 };
 use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity};
-use sp_runtime::{create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult, FixedPointNumber, Perbill, Perquintill, SaturatedConversion};
+use sp_runtime::{
+    create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult, FixedPointNumber, Perbill,
+    Perquintill, SaturatedConversion,
+};
 use sp_std::boxed::Box;
 use sp_std::vec::Vec;
 #[cfg(feature = "std")]
 use sp_version::NativeVersion;
 use sp_version::RuntimeVersion;
 use system::EnsureRoot;
-use pallet_contracts_rpc_runtime_api::ContractExecResult;
 
+pub use constants::*;
 use integration::proposals::{CouncilManager, ExtrinsicProposalEncoder, MembershipOriginValidator};
 pub use primitives::*;
 
@@ -61,13 +66,12 @@ use storage::{data_directory, data_object_storage_registry, data_object_type_reg
 
 // Node dependencies
 pub use common;
-pub use versioned_store;
 pub use forum;
-pub use working_group;
 pub use governance::election_params::ElectionParameters;
 pub use pallet_staking::StakerStatus;
 pub use proposals_codex::ProposalsConfigParameters;
-
+pub use versioned_store;
+pub use working_group;
 
 /// This runtime version.
 pub const VERSION: RuntimeVersion = RuntimeVersion {
@@ -80,40 +84,6 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
     transaction_version: 1,
 };
 
-/// Constants for Babe.
-
-/// Since BABE is probabilistic this is the average expected block time that
-/// we are targetting. Blocks will be produced at a minimum duration defined
-/// by `SLOT_DURATION`, but some slots will not be allocated to any
-/// authority and hence no block will be produced. We expect to have this
-/// block time on average following the defined slot duration and the value
-/// of `c` configured for BABE (where `1 - c` represents the probability of
-/// a slot being empty).
-/// This value is only used indirectly to define the unit constants below
-/// that are expressed in blocks. The rest of the code should use
-/// `SLOT_DURATION` instead (like the timestamp module for calculating the
-/// minimum period).
-/// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
-pub const MILLISECS_PER_BLOCK: Moment = 6000;
-pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000;
-
-pub const SLOT_DURATION: Moment = 6000;
-
-pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES;
-pub const EPOCH_DURATION_IN_SLOTS: u64 = {
-    const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64;
-
-    (EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64
-};
-
-// These time units are defined in number of blocks.
-pub const MINUTES: BlockNumber = 60 / (SECS_PER_BLOCK as BlockNumber);
-pub const HOURS: BlockNumber = MINUTES * 60;
-pub const DAYS: BlockNumber = HOURS * 24;
-
-// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks.
-pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
-
 /// The version information used to identify this runtime when compiled natively.
 #[cfg(feature = "std")]
 pub fn native_version() -> NativeVersion {
@@ -293,38 +263,31 @@ impl pallet_balances::Trait for Runtime {
 }
 
 parameter_types! {
-    pub const TransactionByteFee: Balance = 1; // TODO: adjust fee
+    pub const TransactionByteFee: Balance = 0; // TODO: adjust fee
     pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
     pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000);
     pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128);
 }
 
-// type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
-//
-// pub struct DealWithFees;
-// impl OnUnbalanced<NegativeImbalance> for DealWithFees {
-//     fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item=NegativeImbalance>) {
-//         if let Some(fees) = fees_then_tips.next() {
-//             // // for fees, 80% to treasury, 20% to author
-//             // let mut split = fees.ration(80, 20);
-//             // if let Some(tips) = fees_then_tips.next() {
-//             //     // for tips, if any, 80% to treasury, 20% to author (though this can be anything)
-//             //     tips.ration_merge_into(80, 20, &mut split);
-//             // }
-//             // Treasury::on_unbalanced(split.0);
-//             // Author::on_unbalanced(split.1);
-//         }
-//     }
-// }
-
-
 impl pallet_transaction_payment::Trait for Runtime {
     type Currency = Balances;
-    type OnTransactionPayment = (); // TODO: adjust fee
+    type OnTransactionPayment = ();
     type TransactionByteFee = TransactionByteFee;
-    type WeightToFee = IdentityFee<Balance>; // TODO: adjust weight
-    type FeeMultiplierUpdate =
-        TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
+    type WeightToFee = NoWeights; // TODO: adjust weight
+    type FeeMultiplierUpdate = (); // TODO: adjust fee
+}
+
+pub struct NoWeights;
+impl WeightToFeePolynomial for NoWeights {
+    type Balance = Balance;
+
+    fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
+        Default::default()
+    }
+
+    fn calc(_weight: &u64) -> Self::Balance {
+        Default::default()
+    }
 }
 
 impl pallet_sudo::Trait for Runtime {
@@ -344,12 +307,12 @@ impl pallet_authorship::Trait for Runtime {
 }
 
 impl_opaque_keys! {
-	pub struct SessionKeys {
-		pub grandpa: Grandpa,
-		pub babe: Babe,
-		pub im_online: ImOnline,
-		pub authority_discovery: AuthorityDiscovery,
-	}
+    pub struct SessionKeys {
+        pub grandpa: Grandpa,
+        pub babe: Babe,
+        pub im_online: ImOnline,
+        pub authority_discovery: AuthorityDiscovery,
+    }
 }
 // NOTE: `SessionHandler` and `SessionKeys` are co-dependent: One key will be used for each handler.
 // The number and order of items in `SessionHandler` *MUST* be the same number and order of keys in
@@ -651,10 +614,10 @@ impl proposals_codex::Trait for Runtime {
 }
 
 parameter_types! {
-	pub const TombstoneDeposit: Balance = 1; // TODO: adjust fee
-	pub const RentByteFee: Balance = 1; // TODO: adjust fee
-	pub const RentDepositOffset: Balance = 0; // no rent deposit
-	pub const SurchargeReward: Balance = 0; // no reward
+    pub const TombstoneDeposit: Balance = 1; // TODO: adjust fee
+    pub const RentByteFee: Balance = 1; // TODO: adjust fee
+    pub const RentDepositOffset: Balance = 0; // no rent deposit
+    pub const SurchargeReward: Balance = 0; // no reward
 }
 
 impl pallet_contracts::Trait for Runtime {
@@ -761,6 +724,9 @@ pub type SignedExtra = (
     pallet_grandpa::ValidateEquivocationReport<Runtime>,
 );
 
+/// Digest item type.
+pub type DigestItem = generic::DigestItem<Hash>;
+
 /// Block header type as expected by this runtime.
 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
 
@@ -778,7 +744,10 @@ pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signatu
 
 /// Executive: handles dispatch to the various modules.
 pub type Executive =
-frame_executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
+    frame_executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
+
+#[cfg(any(feature = "std", test))]
+pub use pallet_balances::Call as BalancesCall;
 
 impl_runtime_apis! {
     impl sp_api::Core<Block> for Runtime {
@@ -907,49 +876,49 @@ impl_runtime_apis! {
 
     impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber>
     for Runtime
-	{
-		fn call(
-			origin: AccountId,
-			dest: AccountId,
-			value: Balance,
-			gas_limit: u64,
-			input_data: Vec<u8>,
-		) -> ContractExecResult {
-			let exec_result =
-				Contracts::bare_call(origin, dest, value, gas_limit, input_data);
-			match exec_result {
-				Ok(v) => ContractExecResult::Success {
-					status: v.status,
-					data: v.data,
-				},
-				Err(_) => ContractExecResult::Error,
-			}
-		}
-
-		fn get_storage(
-			address: AccountId,
-			key: [u8; 32],
-		) -> pallet_contracts_primitives::GetStorageResult {
-			Contracts::get_storage(address, key)
-		}
-
-		fn rent_projection(
-			address: AccountId,
-		) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {
-			Contracts::rent_projection(address)
-		}
-	}
+    {
+        fn call(
+            origin: AccountId,
+            dest: AccountId,
+            value: Balance,
+            gas_limit: u64,
+            input_data: Vec<u8>,
+        ) -> ContractExecResult {
+            let exec_result =
+                Contracts::bare_call(origin, dest, value, gas_limit, input_data);
+            match exec_result {
+                Ok(v) => ContractExecResult::Success {
+                    status: v.status,
+                    data: v.data,
+                },
+                Err(_) => ContractExecResult::Error,
+            }
+        }
+
+        fn get_storage(
+            address: AccountId,
+            key: [u8; 32],
+        ) -> pallet_contracts_primitives::GetStorageResult {
+            Contracts::get_storage(address, key)
+        }
+
+        fn rent_projection(
+            address: AccountId,
+        ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {
+            Contracts::rent_projection(address)
+        }
+    }
 
 
     impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
-		Block,
-		Balance,
-		UncheckedExtrinsic,
-	> for Runtime {
-		fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
-			TransactionPayment::query_info(uxt, len)
-		}
-	}
+        Block,
+        Balance,
+        UncheckedExtrinsic,
+    > for Runtime {
+        fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
+            TransactionPayment::query_info(uxt, len)
+        }
+    }
 
     impl sp_session::SessionKeys<Block> for Runtime {
         fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {

+ 29 - 26
runtime/src/primitives.rs

@@ -4,7 +4,10 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use sp_runtime::{traits::{Verify, IdentifyAccount}, MultiSignature};
+use sp_runtime::{
+    traits::{IdentifyAccount, Verify},
+    MultiSignature,
+};
 
 /// Priority for a transaction. Additive. Higher is better.
 pub type TransactionPriority = u64;
@@ -64,29 +67,29 @@ pub type ActorId = u64;
 /// GRANDPA. Any rewards for misbehavior reporting will be paid out to this
 /// account.
 pub mod report {
-	use super::{Signature, Verify};
-	use system::offchain::AppCrypto;
-	use sp_core::crypto::{key_types, KeyTypeId};
-
-	/// Key type for the reporting module. Used for reporting BABE and GRANDPA
-	/// equivocations.
-	pub const KEY_TYPE: KeyTypeId = key_types::REPORTING;
-
-	mod app {
-		use sp_application_crypto::{app_crypto, sr25519};
-		app_crypto!(sr25519, super::KEY_TYPE);
-	}
-
-	/// Identity of the equivocation/misbehavior reporter.
-	pub type ReporterId = app::Public;
-
-	/// An `AppCrypto` type to allow submitting signed transactions using the reporting
-	/// application key as signer.
-	pub struct ReporterAppCrypto;
-
-	impl AppCrypto<<Signature as Verify>::Signer, Signature> for ReporterAppCrypto {
-		type RuntimeAppPublic = ReporterId;
-		type GenericSignature = sp_core::sr25519::Signature;
-		type GenericPublic = sp_core::sr25519::Public;
-	}
+    use super::{Signature, Verify};
+    use sp_core::crypto::{key_types, KeyTypeId};
+    use system::offchain::AppCrypto;
+
+    /// Key type for the reporting module. Used for reporting BABE and GRANDPA
+    /// equivocations.
+    pub const KEY_TYPE: KeyTypeId = key_types::REPORTING;
+
+    mod app {
+        use sp_application_crypto::{app_crypto, sr25519};
+        app_crypto!(sr25519, super::KEY_TYPE);
+    }
+
+    /// Identity of the equivocation/misbehavior reporter.
+    pub type ReporterId = app::Public;
+
+    /// An `AppCrypto` type to allow submitting signed transactions using the reporting
+    /// application key as signer.
+    pub struct ReporterAppCrypto;
+
+    impl AppCrypto<<Signature as Verify>::Signer, Signature> for ReporterAppCrypto {
+        type RuntimeAppPublic = ReporterId;
+        type GenericSignature = sp_core::sr25519::Signature;
+        type GenericPublic = sp_core::sr25519::Public;
+    }
 }