diff --git a/.gitignore b/.gitignore index de1bc29db..0e2a95972 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,7 @@ windows-x86_64 windows-x86_64.tar.gz # Macro expand file -expand.rs \ No newline at end of file +expand.rs + +# For develop +purge_run.sh \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index e3253915f..3c7b2b050 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -685,21 +685,26 @@ dependencies = [ ] [[package]] -name = "darwinia-chainrelay" +name = "darwinia-eos-bridge" version = "0.1.0" dependencies = [ - "darwinia-chainrelay-poa 0.1.0", + "merkle-mountain-range 0.1.0", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0 (git+https://github.com/paritytech/substrate.git)", "srml-support 2.0.0 (git+https://github.com/paritytech/substrate.git)", "srml-system 2.0.0 (git+https://github.com/paritytech/substrate.git)", ] [[package]] -name = "darwinia-chainrelay-poa" +name = "darwinia-ethereum-bridge" version = "0.1.0" dependencies = [ - "sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git)", - "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git)", + "merkle-mountain-range 0.1.0", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0 (git+https://github.com/paritytech/substrate.git)", + "srml-support 2.0.0 (git+https://github.com/paritytech/substrate.git)", + "srml-system 2.0.0 (git+https://github.com/paritytech/substrate.git)", ] [[package]] @@ -1030,6 +1035,10 @@ dependencies = [ "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fly-client" +version = "0.1.0" + [[package]] name = "fnv" version = "1.0.6" @@ -2343,6 +2352,16 @@ name = "memory_units" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "merkle-mountain-range" +version = "0.1.0" +dependencies = [ + "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 2.0.0 (git+https://github.com/paritytech/substrate.git)", + "srml-system 2.0.0 (git+https://github.com/paritytech/substrate.git)", +] + [[package]] name = "merlin" version = "1.2.1" @@ -2629,9 +2648,12 @@ dependencies = [ name = "node-runtime" version = "0.1.0" dependencies = [ + "darwinia-eos-bridge 0.1.0", + "darwinia-ethereum-bridge 0.1.0", "darwinia-staking 0.1.0", "evo-kton 0.1.0", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "merkle-mountain-range 0.1.0", "node-primitives 2.0.0", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index f4740a41b..63f5c0274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,6 @@ substrate-phragmen = { git = 'https://github.com/paritytech/substrate.git' } substrate-session = { git = 'https://github.com/paritytech/substrate.git' } substrate-wasm-interface = { git = 'https://github.com/paritytech/substrate.git' } - [build-dependencies] vergen = "3.0.4" @@ -60,20 +59,27 @@ path = 'node/src/main.rs' [workspace] members = [ -# "darwinia-client", + "core/merkle-mountain-range", + "core/fly-client", "core/sr-eth-primitives", "core/sr-rlp", + +# "darwinia-client", + "node/cli", "node/executor", "node/primitives", "node/runtime", "node/rpc-client", - "srml/staking", - "srml/kton", + "srml/support", "srml/try", - "srml/chainrelay", - "srml/chainrelay/poa" + + "srml/chainrelay/bridge/eos", + "srml/chainrelay/bridge/ethereum", + + "srml/kton", + "srml/staking", ] exclude = ["node/runtime/wasm"] @@ -84,4 +90,3 @@ build = 'build.rs' edition = '2018' name = 'darwinia' version = '0.3.2' - diff --git a/build.sh b/build.sh deleted file mode 100755 index ed12ac26d..000000000 --- a/build.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -e - -PROJECT_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" - -export CARGO_INCREMENTAL=0 - -bold=$(tput bold) -normal=$(tput sgr0) - -# Save current directory. -pushd . >/dev/null - -for SRC in node/runtime/wasm -do - echo "${bold}Building webassembly binary in $SRC...${normal}" - cd "$PROJECT_ROOT/$SRC" - - ./build.sh - - cd - >> /dev/null -done - -# Restore initial directory. -popd >/dev/null diff --git a/core/fly-client/Cargo.toml b/core/fly-client/Cargo.toml new file mode 100644 index 000000000..017d81375 --- /dev/null +++ b/core/fly-client/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "fly-client" +version = "0.1.0" +authors = ["Xavier Lau "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[features] +default = ["std"] +std = [] diff --git a/core/fly-client/src/lib.rs b/core/fly-client/src/lib.rs new file mode 100644 index 000000000..8731421b3 --- /dev/null +++ b/core/fly-client/src/lib.rs @@ -0,0 +1 @@ +#![cfg_attr(not(feature = "std"), no_std)] diff --git a/core/merkle-mountain-range/Cargo.toml b/core/merkle-mountain-range/Cargo.toml new file mode 100644 index 000000000..648603357 --- /dev/null +++ b/core/merkle-mountain-range/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "merkle-mountain-range" +version = "0.1.0" +authors = ["Xavier Lau "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +blake2 = { version = "0.8.1", default-features = false } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +rstd = { package = "sr-std", git = 'https://github.com/paritytech/substrate.git', default-features = false } +system = { package = "srml-system", git = 'https://github.com/paritytech/substrate.git', default-features = false } + +[features] +default = ["std"] +std = [ + "codec/std", + "blake2/std", + "rstd/std", +] diff --git a/core/merkle-mountain-range/src/common.rs b/core/merkle-mountain-range/src/common.rs new file mode 100644 index 000000000..e2b6770af --- /dev/null +++ b/core/merkle-mountain-range/src/common.rs @@ -0,0 +1,131 @@ +use blake2::Digest; +// for `vec![]` macro +use rstd::vec; +use rstd::vec::Vec; + +const ALL_ONES: usize = usize::max_value(); + +pub type Hash = Vec; + +pub fn peak_map_height(mut index: usize) -> (usize, usize) { + if index == 0 { + return (0, 0); + } + + let mut peak_size = ALL_ONES >> index.leading_zeros(); + let mut bitmap = 0; + while peak_size != 0 { + bitmap <<= 1; + if index >= peak_size { + index -= peak_size; + bitmap |= 1; + } + + peak_size >>= 1; + } + + (bitmap, index) +} + +pub fn peak_indexes(size: usize) -> Vec { + if size == 0 { + return vec![]; + } + + let mut peak_size = ALL_ONES >> size.leading_zeros(); + let mut num_left = size; + let mut sum_prev_peaks = 0; + let mut peaks = vec![]; + + while peak_size != 0 { + if num_left >= peak_size { + sum_prev_peaks += peak_size; + num_left -= peak_size; + + peaks.push(sum_prev_peaks - 1); + } + + peak_size >>= 1; + } + + if num_left > 0 { + vec![] + } else { + peaks + } +} + +#[inline] +pub fn is_leaf(index: usize) -> bool { + bintree_height(index) == 0 +} + +#[inline] +pub fn bintree_height(index: usize) -> usize { + if index == 0 { + 0 + } else { + peak_map_height(index).1 + } +} + +pub fn family_branch(index: usize, last_index: usize) -> Vec<(usize, usize)> { + let (peak_map, height) = peak_map_height(index); + let mut peak = 1 << height; + let mut branch = vec![]; + let mut current = index; + let mut sibling; + while current < last_index { + if (peak_map & peak) != 0 { + current += 1; + sibling = current - 2 * peak; + } else { + current += 2 * peak; + sibling = current - 1; + } + if current > last_index { + break; + } + + branch.push((current, sibling)); + peak <<= 1; + } + + branch +} + +pub fn family(index: usize) -> (usize, usize) { + let (peak_map, height) = peak_map_height(index); + let peak = 1 << height; + + if (peak_map & peak) != 0 { + (index + 1, index + 1 - 2 * peak) + } else { + (index + 2 * peak, index + 2 * peak - 1) + } +} + +#[inline] +pub fn is_left_sibling(index: usize) -> bool { + let (peak_map, height) = peak_map_height(index); + let peak = 1 << height; + (peak_map & peak) == 0 +} + +#[inline] +pub fn leaf_index(n: usize) -> usize { + if n == 0 { + 0 + } else { + 2 * n - n.count_ones() as usize + } +} + +#[inline] +pub fn chain_two_hash(left: H, right: H) -> Hash +where + D: Digest, + H: AsRef<[u8]>, +{ + D::new().chain(left).chain(right).result().to_vec() +} diff --git a/core/merkle-mountain-range/src/lib.rs b/core/merkle-mountain-range/src/lib.rs new file mode 100644 index 000000000..bb358893e --- /dev/null +++ b/core/merkle-mountain-range/src/lib.rs @@ -0,0 +1,17 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![feature(test)] + +#[cfg(all(feature = "std", test))] +extern crate test; + +mod common; +mod merkle_mountain_range; +mod merkle_proof; + +#[allow(unused)] +#[cfg(all(feature = "std", test))] +mod tests; + +pub use common::*; +pub use merkle_mountain_range::MerkleMountainRange; +pub use merkle_proof::MerkleProof; diff --git a/core/merkle-mountain-range/src/merkle_mountain_range.rs b/core/merkle-mountain-range/src/merkle_mountain_range.rs new file mode 100644 index 000000000..e097323c6 --- /dev/null +++ b/core/merkle-mountain-range/src/merkle_mountain_range.rs @@ -0,0 +1,159 @@ +use core::{marker::PhantomData, ops::Index}; + +use blake2::Digest; +use codec::{Decode, Encode}; +use rstd::{borrow::ToOwned, vec::Vec}; + +use crate::*; + +#[derive(Clone, Debug, Default, Encode, Decode)] +pub struct MerkleMountainRange { + hashes: Vec, + _hasher: PhantomData, +} + +impl MerkleMountainRange { + pub fn new(hashes: Vec) -> Self { + Self { + hashes, + _hasher: PhantomData, + } + } + + #[inline] + pub fn len(&self) -> usize { + self.hashes.len() + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.hashes.is_empty() + } + + #[inline] + pub fn get(&self, index: usize) -> Option<&Hash> { + self.hashes.get(index) + } + + #[inline] + pub fn push(&mut self, hash: Hash) -> usize { + self.hashes.push(hash); + self.len() - 1 + } + + pub fn append>(&mut self, hash: H) -> Option { + let hash = hash.as_ref(); + + if self.is_empty() { + return Some(self.push(hash.to_owned())); + } + + let mut index = self.len(); + let (peak_map, height) = peak_map_height(index); + + if height != 0 { + return None; + } + + self.push(hash.to_owned()); + + let mut peak = 1; + while (peak_map & peak) != 0 { + let new_hash = chain_two_hash::(&self[index + 1 - 2 * peak], &self[self.len() - 1]); + self.push(new_hash); + + peak *= 2; + index += 1; + } + + Some(index) + } + + pub fn root(&self) -> Option { + if self.is_empty() { + None + } else { + // TODO: bagging strategy + // Some( + // peak_indexes(self.len()) + // .into_iter() + // .fold(D::new(), |hasher, peak_index| { + // hasher.chain(&self[peak_index]) + // }) + // .result() + // .to_vec(), + // ) + + let mut hash = None; + for peak_index in peak_indexes(self.len()).into_iter().rev() { + hash = match hash { + None => Some(self[peak_index].to_owned()), + Some(right_peak) => Some(chain_two_hash::(&self[peak_index], &right_peak)), + } + } + + hash + } + } + + pub fn to_merkle_proof(&self, index: usize) -> Option { + if !is_leaf(index) { + return None; + } + + let family_branch = family_branch(index, self.len()); + let peak_index = if let Some((current, _)) = family_branch.last() { + *current + } else { + index + }; + let mut path: Vec<_> = family_branch + .into_iter() + .map(|(_, sibling)| self.get(sibling).unwrap().to_owned()) + .collect(); + path.append(&mut self.peak_path(peak_index)); + + Some(MerkleProof { + mmr_size: self.len(), + path, + }) + } + + pub fn peak_path(&self, peak_index: usize) -> Vec { + let mut peaks: Vec<_> = peak_indexes(self.len()) + .into_iter() + .filter(|peak_index_| *peak_index_ < peak_index) + .map(|peak_index| self[peak_index].to_owned()) + .collect(); + if let Some(peak) = self.bag_the_rhs(peak_index) { + peaks.push(peak); + } + peaks.reverse(); + + peaks + } + + pub fn bag_the_rhs(&self, peak_index: usize) -> Option { + let peak_indexes: Vec<_> = peak_indexes(self.len()) + .into_iter() + .filter(|peak_index_| *peak_index_ > peak_index) + .collect(); + let mut hash = None; + for peak_index in peak_indexes.into_iter().rev() { + hash = match hash { + None => Some(self[peak_index].to_owned()), + Some(right_peak) => Some(chain_two_hash::(&self[peak_index], &right_peak)), + } + } + + hash + } +} + +impl Index for MerkleMountainRange { + type Output = Hash; + + fn index(&self, index: usize) -> &Self::Output { + &self.hashes[index] + } +} diff --git a/core/merkle-mountain-range/src/merkle_proof.rs b/core/merkle-mountain-range/src/merkle_proof.rs new file mode 100644 index 000000000..d9984eb54 --- /dev/null +++ b/core/merkle-mountain-range/src/merkle_proof.rs @@ -0,0 +1,80 @@ +use blake2::Digest; +use rstd::vec::Vec; + +use crate::*; + +#[derive(Clone, Debug)] +pub struct MerkleProof { + pub mmr_size: usize, + // + // λ cargo bench b1 + // Finished bench [optimized] target(s) in 0.00s + // Running target/release/deps/mmr-0c4d672df8c18022 + // + // running 1 test + // test tests::b1 ... bench: 42,015 ns/iter (+/- 23) + // + // test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured; 2 filtered out + pub path: Vec, + // + // λ cargo bench b1 + // Finished bench [optimized] target(s) in 0.00s + // Running target/release/deps/mmr-0c4d672df8c18022 + // + // running 1 test + // test tests::b1 ... bench: 42,299 ns/iter (+/- 37) + // + // test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured; 2 filtered out + // pub path: VecDeque, +} + +impl MerkleProof { + pub fn verify(&self, root: H, hash: H, index: usize) -> bool + where + D: Digest, + H: AsRef<[u8]>, + { + self.clone().verify_consume::(root, hash, index) + } + + fn verify_consume(&mut self, root: H, hash: H, index: usize) -> bool + where + D: Digest, + H: AsRef<[u8]>, + { + let root = root.as_ref(); + let hash = hash.as_ref(); + let peak_indexes = peak_indexes(self.mmr_size); + + if self.path.is_empty() { + return root == hash; + } + + let sibling = self.path.remove(0); + // let sibling = self.path.pop_front().unwrap(); + let sibling = sibling.as_ref(); + let (parent_index, sibling_index) = family(index); + + match peak_indexes.binary_search(&index) { + Ok(x) => { + let parent = if x == peak_indexes.len() - 1 { + chain_two_hash::(sibling, hash) + } else { + chain_two_hash::(hash, sibling) + }; + self.verify::(root, &parent, parent_index) + } + _ if parent_index > self.mmr_size => { + self.verify::(root, &chain_two_hash::(sibling, hash), parent_index) + } + _ => { + let parent = if is_left_sibling(sibling_index) { + chain_two_hash::(sibling, hash) + } else { + chain_two_hash::(hash, sibling) + }; + self.verify::(root, &parent, parent_index) + } + } + } +} diff --git a/core/merkle-mountain-range/src/tests/mod.rs b/core/merkle-mountain-range/src/tests/mod.rs new file mode 100644 index 000000000..5ef77be3b --- /dev/null +++ b/core/merkle-mountain-range/src/tests/mod.rs @@ -0,0 +1,73 @@ +pub mod support; + +use std::time::Instant; + +use blake2::{Blake2b, Digest}; +use test::Bencher; + +use crate::*; +// pub use support::{Digest, *}; + +type Hasher = Blake2b; +// type Hasher = DebugHasher; + +fn mmr_with_count(count: usize) -> MerkleMountainRange { + let mut mmr = MerkleMountainRange::::new(vec![]); + for i in 0..count { + let hash = usize_to_hash(i); + mmr.append(&hash); + } + + mmr +} + +fn usize_to_hash(x: usize) -> Hash { + Hasher::digest(&x.to_le_bytes()).to_vec() +} + +#[test] +fn t1() { + let mmr = mmr_with_count(6); + let a = chain_two_hash::(&mmr[0], &mmr[1]); + let b = chain_two_hash::(&a, &mmr[5]); + let c = chain_two_hash::(&mmr[7], &mmr[8]); + let d = chain_two_hash::(&b, &c); + assert_eq!(mmr.root().unwrap(), d); +} + +#[test] +fn t2() { + let mmr = mmr_with_count(6); + let root = mmr.root().unwrap(); + let index = 0; + let hash = usize_to_hash(index); + let proof = mmr.to_merkle_proof(index).unwrap(); + assert!(proof.verify::(root, hash, index)); +} + +#[bench] +fn b1(b: &mut Bencher) { + let mmr = mmr_with_count(10_000_000); + let index = 23_333; + let mmr_index = leaf_index(index); + let root = mmr.root().unwrap(); + let hash = usize_to_hash(index); + let proof = mmr.to_merkle_proof(mmr_index).unwrap(); + + b.iter(|| assert!(proof.verify::(root.clone(), hash.clone(), mmr_index))); +} + +#[test] +fn b2() { + let mmr = mmr_with_count(100_000_000); + let index = 233_333; + let mmr_index = leaf_index(index); + let root = mmr.root().unwrap(); + let hash = usize_to_hash(index); + + let start = Instant::now(); + let proof = mmr.to_merkle_proof(mmr_index).unwrap(); + proof.verify::(root, hash, mmr_index); + let elapsed = start.elapsed(); + println!("{}", elapsed.as_nanos()); +} diff --git a/core/merkle-mountain-range/src/tests/support.rs b/core/merkle-mountain-range/src/tests/support.rs new file mode 100644 index 000000000..23676e244 --- /dev/null +++ b/core/merkle-mountain-range/src/tests/support.rs @@ -0,0 +1,41 @@ +pub struct DebugHasher; + +pub trait Digest { + fn new() -> Self; + + fn chain>(self, data: B) -> Self + where + Self: Sized; + + fn result(self) -> Vec; + + fn digest(data: &[u8]) -> Vec; +} + +impl Specify for DebugHasher { + fn new() -> Self { + DebugHasher + } +} + +impl Digest for D { + fn new() -> Self { + ::new() + } + + fn chain>(self, data: B) -> Self { + self + } + + fn result(self) -> Vec { + unimplemented!() + } + + fn digest(data: &[u8]) -> Vec { + unimplemented!() + } +} + +pub trait Specify { + fn new() -> Self; +} diff --git a/core/sr-eth-primitives/Cargo.toml b/core/sr-eth-primitives/Cargo.toml index c11ecf277..22275e9ee 100644 --- a/core/sr-eth-primitives/Cargo.toml +++ b/core/sr-eth-primitives/Cargo.toml @@ -19,7 +19,6 @@ rlp_derive = { git = "https://github.com/paritytech/parity-ethereum.git" } ethereum-types = "0.8.0" keccak-hash = "0.4.0" - [dev-dependencies] support = { package = "srml-support", git = 'https://github.com/paritytech/substrate.git'} rustc-hex = "2.0" diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index bc21360a0..5b21cd1c1 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -21,13 +21,13 @@ use grandpa_primitives::AuthorityId as GrandpaId; use hex_literal::hex; use im_online::sr25519::AuthorityId as ImOnlineId; use node_primitives::{AccountId, Balance}; -use node_runtime::constants::{currency::*, time::*}; +use node_runtime::constants::currency::*; use node_runtime::Block; pub use node_runtime::GenesisConfig; use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, KtonConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, SudoConfig, SystemConfig, COIN, - DAYS, MILLI, SECS_PER_BLOCK, WASM_BINARY, + WASM_BINARY, }; use primitives::{crypto::UncheckedInto, Pair, Public}; use serde::{Deserialize, Serialize}; @@ -40,6 +40,8 @@ use substrate_telemetry::TelemetryEndpoints; const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; +// TODO: docs +#[allow(missing_docs)] #[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)] pub struct Extensions { /// Block numbers with known hashes. @@ -54,6 +56,7 @@ pub fn flaming_fir_config() -> Result { ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..]) } +#[allow(missing_docs)] pub fn crayfish_fir_config() -> Result { ChainSpec::from_json_bytes(&include_bytes!("../res/crayfish-fir.json")[..]) } @@ -209,15 +212,6 @@ pub fn testnet_genesis( .collect(), vesting: vec![], }), - kton: Some(KtonConfig { - balances: endowed_accounts - .iter() - .cloned() - .map(|k| (k, ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), ENDOWMENT))) - .collect(), - vesting: vec![], - }), indices: Some(IndicesConfig { ids: endowed_accounts .iter() @@ -231,6 +225,28 @@ pub fn testnet_genesis( .map(|x| (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone()))) .collect::>(), }), + contracts: Some(ContractsConfig { + current_schedule: contracts::Schedule { + enable_println, // this should only be enabled on development chains + ..Default::default() + }, + gas_price: 1 * MILLICENTS, + }), + sudo: Some(SudoConfig { key: root_key }), + babe: Some(BabeConfig { authorities: vec![] }), + im_online: Some(ImOnlineConfig { keys: vec![] }), + authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }), + grandpa: Some(GrandpaConfig { authorities: vec![] }), + + kton: Some(KtonConfig { + balances: endowed_accounts + .iter() + .cloned() + .map(|k| (k, ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), ENDOWMENT))) + .collect(), + vesting: vec![], + }), staking: Some(StakingConfig { current_era: 0, current_era_total_reward: 80_000_000 * COIN / 63720, @@ -245,18 +261,6 @@ pub fn testnet_genesis( .collect(), invulnerables: initial_authorities.iter().map(|x| x.1.clone()).collect(), }), - contracts: Some(ContractsConfig { - current_schedule: contracts::Schedule { - enable_println, // this should only be enabled on development chains - ..Default::default() - }, - gas_price: 1 * MILLICENTS, - }), - sudo: Some(SudoConfig { key: root_key }), - babe: Some(BabeConfig { authorities: vec![] }), - im_online: Some(ImOnlineConfig { keys: vec![] }), - authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }), - grandpa: Some(GrandpaConfig { authorities: vec![] }), } } @@ -319,6 +323,8 @@ pub fn local_testnet_config() -> ChainSpec { ) } +// TODO: docs +#[allow(missing_docs)] pub fn darwinia_genesis_verbose( initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)>, root_key: AccountId, @@ -359,15 +365,6 @@ pub fn darwinia_genesis_verbose( .collect(), vesting: vec![], }), - kton: Some(KtonConfig { - balances: endowed_accounts - .iter() - .cloned() - .map(|k| (k, ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), ENDOWMENT))) - .collect(), - vesting: vec![], - }), indices: Some(IndicesConfig { ids: endowed_accounts .iter() @@ -381,6 +378,28 @@ pub fn darwinia_genesis_verbose( .map(|x| (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone()))) .collect::>(), }), + contracts: Some(ContractsConfig { + current_schedule: contracts::Schedule { + enable_println, // this should only be enabled on development chains + ..Default::default() + }, + gas_price: 1 * MILLICENTS, + }), + sudo: Some(SudoConfig { key: root_key }), + babe: Some(BabeConfig { authorities: vec![] }), + im_online: Some(ImOnlineConfig { keys: vec![] }), + authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }), + grandpa: Some(GrandpaConfig { authorities: vec![] }), + + kton: Some(KtonConfig { + balances: endowed_accounts + .iter() + .cloned() + .map(|k| (k, ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), ENDOWMENT))) + .collect(), + vesting: vec![], + }), staking: Some(StakingConfig { current_era: 0, current_era_total_reward: 80_000_000 * COIN / 63720, @@ -395,18 +414,6 @@ pub fn darwinia_genesis_verbose( .collect(), invulnerables: initial_authorities.iter().map(|x| x.1.clone()).collect(), }), - contracts: Some(ContractsConfig { - current_schedule: contracts::Schedule { - enable_println, // this should only be enabled on development chains - ..Default::default() - }, - gas_price: 1 * MILLICENTS, - }), - sudo: Some(SudoConfig { key: root_key }), - babe: Some(BabeConfig { authorities: vec![] }), - im_online: Some(ImOnlineConfig { keys: vec![] }), - authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }), - grandpa: Some(GrandpaConfig { authorities: vec![] }), } } diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index 217b880b2..a039d8459 100644 --- a/node/cli/src/lib.rs +++ b/node/cli/src/lib.rs @@ -47,6 +47,8 @@ pub enum ChainSpec { FlamingFir, /// Whatever the current runtime is with the "global testnet" defaults. StagingTestnet, + // TODO: docs + #[allow(missing_docs)] CrayfishTestnet, } diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs index 398d458e6..6d3a44295 100644 --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -31,12 +31,13 @@ use std::sync::Arc; -use node_primitives::{Block, AccountId, Index, Balance}; +use node_primitives::{AccountId, Balance, Block, Index}; use sr_primitives::traits::ProvideRuntimeApi; use transaction_pool::txpool::{ChainApi, Pool}; /// Instantiate all RPC extensions. -pub fn create(client: Arc, pool: Arc>) -> jsonrpc_core::IoHandler where +pub fn create(client: Arc, pool: Arc>) -> jsonrpc_core::IoHandler +where C: ProvideRuntimeApi, C: client::blockchain::HeaderBackend, C: Send + Sync + 'static, @@ -45,15 +46,11 @@ pub fn create(client: Arc, pool: Arc>) -> jsonrpc_core::IoHa P: ChainApi + Sync + Send + 'static, M: jsonrpc_core::Metadata + Default, { - use srml_system_rpc::{System, SystemApi}; use srml_contracts_rpc::{Contracts, ContractsApi}; + use srml_system_rpc::{System, SystemApi}; let mut io = jsonrpc_core::IoHandler::default(); - io.extend_with( - SystemApi::to_delegate(System::new(client.clone(), pool)) - ); - io.extend_with( - ContractsApi::to_delegate(Contracts::new(client)) - ); + io.extend_with(SystemApi::to_delegate(System::new(client.clone(), pool))); + io.extend_with(ContractsApi::to_delegate(Contracts::new(client))); io } diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index bbfb50ac6..95be3fc5d 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -29,9 +29,6 @@ sudo = { package = "srml-sudo", git = 'https://github.com/paritytech/substrate.g node-primitives = {path = "../primitives", default-features = false } consensus_aura = { package = "substrate-consensus-aura-primitives", git = 'https://github.com/paritytech/substrate.git', default-features = false } substrate-keyring = { git = 'https://github.com/paritytech/substrate.git', optional = true } -# customed -kton = { package = "evo-kton", path = '../../srml/kton', default-features = false} -staking = { package = "darwinia-staking", path = "../../srml/staking", default-features = false} # new babe = { package = "srml-babe", git = 'https://github.com/paritytech/substrate.git', default-features = false } @@ -39,8 +36,10 @@ babe-primitives = { package = "substrate-consensus-babe-primitives", git = 'http system-rpc-runtime-api = { package = "srml-system-rpc-runtime-api", git = 'https://github.com/paritytech/substrate.git', default-features = false } sr-staking-primitives = { git = 'https://github.com/paritytech/substrate.git', default-features = false } substrate-session = { git = 'https://github.com/paritytech/substrate.git', default-features = false } -# new and no-used +# staking tests needed authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", git = 'https://github.com/paritytech/substrate.git', default-features = false } + +# new and no-used authority-discovery = { package = "srml-authority-discovery", git = 'https://github.com/paritytech/substrate.git', default-features = false } authorship = { package = "srml-authorship", git = 'https://github.com/paritytech/substrate.git', default-features = false } collective = { package = "srml-collective", git = 'https://github.com/paritytech/substrate.git', default-features = false } @@ -56,10 +55,17 @@ treasury = { package = "srml-treasury", git = 'https://github.com/paritytech/sub utility = { package = "srml-utility", git = 'https://github.com/paritytech/substrate.git', default-features = false } transaction-payment = { package = "srml-transaction-payment", git = 'https://github.com/paritytech/substrate.git', default-features = false } +kton = { package = "evo-kton", path = '../../srml/kton', default-features = false } +staking = { package = "darwinia-staking", path = "../../srml/staking", default-features = false } + +merkle-mountain-range = { path = "../../core/merkle-mountain-range", default-features = false } + +eos-bridge = { package = "darwinia-eos-bridge", path = "../../srml/chainrelay/bridge/eos", default-features = false } +ethereum-bridge = { package = "darwinia-ethereum-bridge", path = "../../srml/chainrelay/bridge/ethereum", default-features = false } + [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", git = 'https://github.com/paritytech/substrate.git' } - [features] default = ["std"] std = [ @@ -77,7 +83,6 @@ std = [ "indices/std", "session/std", "authorship/std", - "staking/std", "system/std", "timestamp/std", "treasury/std", @@ -93,8 +98,8 @@ std = [ "offchain-primitives/std", "babe-primitives/std", "system-rpc-runtime-api/std", - "kton/std", "authority-discovery/std", + "authority-discovery-primitives/std", "collective/std", "contracts-rpc-runtime-api/std", "elections/std", @@ -106,5 +111,17 @@ std = [ "transaction-payment/std", "sr-staking-primitives/std", "babe/std", - "substrate-session/std" + "substrate-session/std", + + # custom module + "kton/std", + "staking/std", + + # core struct + "merkle-mountain-range/std", + + # chainrelay + # bridge + "eos-bridge/std", + "ethereum-bridge/std", ] diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index ca57bdc8b..489934045 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -21,13 +21,13 @@ pub mod currency { use node_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 CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent. pub const DOLLARS: Balance = 100 * CENTS; } /// Time. pub mod time { - use node_primitives::{Moment, BlockNumber}; + use node_primitives::{BlockNumber, Moment}; /// Since BABE is probabilistic this is the average expected block time that /// we are targetting. Blocks will be produced at a minimum duration defined diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 219384502..82b44cd90 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -16,13 +16,13 @@ //! Some configurable implementations as associated type for the substrate runtime. +use crate::constants::fee::TARGET_BLOCK_FULLNESS; +use crate::{Authorship, Balances, MaximumBlockWeight, NegativeImbalance}; use node_primitives::Balance; -use sr_primitives::weights::Weight; use sr_primitives::traits::{Convert, Saturating}; +use sr_primitives::weights::Weight; use sr_primitives::Fixed64; -use support::traits::{OnUnbalanced, Currency}; -use crate::{Balances, Authorship, MaximumBlockWeight, NegativeImbalance}; -use crate::constants::fee::TARGET_BLOCK_FULLNESS; +use support::traits::{Currency, OnUnbalanced}; pub struct Author; impl OnUnbalanced for Author { @@ -36,15 +36,21 @@ impl OnUnbalanced for Author { pub struct CurrencyToVoteHandler; impl CurrencyToVoteHandler { - fn factor() -> Balance { (Balances::total_issuance() / u64::max_value() as Balance).max(1) } + fn factor() -> Balance { + (Balances::total_issuance() / u64::max_value() as Balance).max(1) + } } impl Convert for CurrencyToVoteHandler { - fn convert(x: Balance) -> u64 { (x / Self::factor()) as u64 } + fn convert(x: Balance) -> u64 { + (x / Self::factor()) as u64 + } } impl Convert for CurrencyToVoteHandler { - fn convert(x: u128) -> Balance { x * Self::factor() } + fn convert(x: u128) -> Balance { + x * Self::factor() + } } /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the @@ -131,9 +137,9 @@ impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { #[cfg(test)] mod tests { use super::*; - use sr_primitives::weights::Weight; - use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; use crate::constants::currency::*; + use crate::{AvailableBlockRatio, MaximumBlockWeight, Runtime}; + use sr_primitives::weights::Weight; fn max() -> Weight { MaximumBlockWeight::get() @@ -144,7 +150,7 @@ mod tests { } // poc reference implementation. - fn fee_multiplier_update(block_weight: Weight, previous: Fixed64) -> Fixed64 { + fn fee_multiplier_update(block_weight: Weight, previous: Fixed64) -> Fixed64 { let block_weight = block_weight as f32; let v: f32 = 0.00004; @@ -155,7 +161,7 @@ mod tests { // Current saturation in terms of weight let s = block_weight; - let fm = (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; + let fm = (v * (s / m - ss / m)) + (v.powi(2) * (s / m - ss / m).powi(2)) / 2.0; let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32) as i64); previous.saturating_add(addition_fm) } @@ -195,7 +201,9 @@ mod tests { loop { let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); fm = next; - if fm == Fixed64::from_rational(-1, 1) { break; } + if fm == Fixed64::from_rational(-1, 1) { + break; + } iterations += 1; } println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); @@ -219,14 +227,16 @@ mod tests { let mut iterations: u64 = 0; loop { let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); - if fm == next { break; } + if fm == next { + break; + } fm = next; iterations += 1; let fee = ::WeightToFee::convert(tx_weight); let adjusted_fee = fm.saturated_multiply_accumulate(fee); println!( "iteration {}, new fm = {:?}. Fee at this point is: \ - {} units, {} millicents, {} cents, {} dollars", + {} units, {} millicents, {} cents, {} dollars", iterations, fm, adjusted_fee, @@ -284,18 +294,9 @@ mod tests { #[test] fn stateful_weight_mil_collapse_to_minus_one() { - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, Fixed64::default())), - fm(-10000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(-10000))), - fm(-20000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(-20000))), - fm(-30000) - ); + assert_eq!(FeeMultiplierUpdateHandler::convert((0, Fixed64::default())), fm(-10000)); + assert_eq!(FeeMultiplierUpdateHandler::convert((0, fm(-10000))), fm(-20000)); + assert_eq!(FeeMultiplierUpdateHandler::convert((0, fm(-20000))), fm(-30000)); // ... assert_eq!( FeeMultiplierUpdateHandler::convert((0, fm(1_000_000_000 * -1))), @@ -320,22 +321,19 @@ mod tests { mb, 10 * mb, Weight::max_value() / 2, - Weight::max_value() - ].into_iter().for_each(|i| { + Weight::max_value(), + ] + .into_iter() + .for_each(|i| { FeeMultiplierUpdateHandler::convert((i, Fixed64::default())); }); // Some values that are all above the target and will cause an increase. let t = target(); - vec![t + 100, t * 2, t * 4] - .into_iter() - .for_each(|i| { - let fm = FeeMultiplierUpdateHandler::convert(( - i, - max_fm - )); - // won't grow. The convert saturates everything. - assert_eq!(fm, max_fm); - }); + vec![t + 100, t * 2, t * 4].into_iter().for_each(|i| { + let fm = FeeMultiplierUpdateHandler::convert((i, max_fm)); + // won't grow. The convert saturates everything. + assert_eq!(fm, max_fm); + }); } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 8f4e9aa8e..34c35a5dd 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -28,23 +28,18 @@ use client::{ }; use codec::{Decode, Encode}; pub use contracts::Gas; -use elections::VoteIndex; use grandpa::fg_primitives; use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; use im_online::sr25519::AuthorityId as ImOnlineId; use node_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature}; use rstd::prelude::*; -use sr_primitives::curve::PiecewiseLinear; use sr_primitives::traits::{self, BlakeTwo256, Block as BlockT, NumberFor, SaturatedConversion, StaticLookup}; use sr_primitives::transaction_validity::TransactionValidity; use sr_primitives::weights::Weight; - #[cfg(any(feature = "std", test))] pub use sr_primitives::BuildStorage; -use sr_primitives::{create_runtime_str, generic, impl_opaque_keys, key_types, ApplyResult, Perbill, Permill}; -use staking::EraIndex; -pub use staking::StakerStatus; -use substrate_primitives::u32_trait::{_1, _2, _3, _4}; +use sr_primitives::{create_runtime_str, generic, impl_opaque_keys, key_types, ApplyResult, Perbill}; +use substrate_primitives::u32_trait::{_1, _4}; use substrate_primitives::OpaqueMetadata; use support::traits::OnUnbalanced; pub use support::StorageValue; @@ -58,13 +53,16 @@ pub use timestamp::Call as TimestampCall; use version::NativeVersion; use version::RuntimeVersion; +use staking::EraIndex; +pub use staking::StakerStatus; + /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; use impls::{Author, CurrencyToVoteHandler, FeeMultiplierUpdateHandler, WeightToFee}; /// Constant values used within the runtime. pub mod constants; -use constants::{currency::*, time::*}; +use constants::time::*; // Make the WASM binary available. #[cfg(feature = "std")] @@ -172,9 +170,9 @@ impl balances::Trait for Runtime { type Balance = Balance; type OnFreeBalanceZero = (Staking, Session); type OnNewAccount = Indices; - type Event = Event; - type DustRemoval = (); type TransferPayment = (); + type DustRemoval = (); + type Event = Event; type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; @@ -194,13 +192,6 @@ impl transaction_payment::Trait for Runtime { type FeeMultiplierUpdate = FeeMultiplierUpdateHandler; } -impl kton::Trait for Runtime { - type Balance = Balance; - type Event = Event; - type OnMinted = (); - type OnRemoval = (); -} - parameter_types! { pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; @@ -262,19 +253,19 @@ parameter_types! { } impl session::Trait for Runtime { - type OnSessionEnding = Staking; - type SessionHandler = SessionHandlers; - type ShouldEndSession = Babe; type Event = Event; - type Keys = SessionKeys; type ValidatorId = ::AccountId; type ValidatorIdOf = staking::StashOf; - type SelectInitialValidators = Staking; + type ShouldEndSession = Babe; + type OnSessionEnding = Staking; + type SessionHandler = SessionHandlers; + type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type SelectInitialValidators = Staking; } impl session::historical::Trait for Runtime { - type FullIdentification = staking::Exposures; + type FullIdentification = staking::Exposure; type FullIdentificationOf = staking::ExposureOf; } @@ -286,30 +277,6 @@ parameter_types! { pub const ErasPerEpoch: EraIndex = 105120; } -// customed -parameter_types! { - // decimal 9 - pub const CAP: Balance = 10_000_000_000 * COIN; -} - -impl staking::Trait for Runtime { - type Ring = Balances; - type Kton = Kton; - type CurrencyToVote = CurrencyToVoteHandler; - type Event = Event; - type RingReward = (); - type RingSlash = (); - type KtonReward = (); - type KtonSlash = (); - type SessionsPerEra = SessionsPerEra; - type BondingDuration = BondingDuration; - // customed - type Cap = CAP; - type ErasPerEpoch = ErasPerEpoch; - type SessionLength = Period; - type SessionInterface = Self; -} - impl sudo::Trait for Runtime { type Event = Event; type Proposal = Call; @@ -329,8 +296,8 @@ type SubmitTransaction = TransactionSubmitter for Runtim } } +impl kton::Trait for Runtime { + type Balance = Balance; + type Event = Event; + type OnMinted = (); + type OnRemoval = (); +} + +parameter_types! { + // decimal 9 + pub const CAP: Balance = 10_000_000_000 * COIN; +} + +impl staking::Trait for Runtime { + type Ring = Balances; + type Kton = Kton; + type CurrencyToVote = CurrencyToVoteHandler; + type Event = Event; + type RingSlash = (); + type RingReward = (); + type KtonSlash = (); + type KtonReward = (); + type SessionsPerEra = SessionsPerEra; + type BondingDuration = BondingDuration; + type Cap = CAP; + type ErasPerEpoch = ErasPerEpoch; + type SessionLength = Period; + type SessionInterface = Self; +} + +impl eos_bridge::Trait for Runtime { + type Event = Event; +} + +impl ethereum_bridge::Trait for Runtime { + type Event = Event; + type Ring = Balances; +} + construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = node_primitives::Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Storage, Config, Event}, - Utility: utility::{Module, Call, Event}, - Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, - Timestamp: timestamp::{Module, Call, Storage, Inherent}, + AuthorityDiscovery: authority_discovery::{Module, Call, Config}, Authorship: authorship::{Module, Call, Storage}, - Indices: indices, + Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, Balances: balances::{default, Error}, - TransactionPayment: transaction_payment::{Module, Storage}, - Kton: kton, - Staking: staking::{default, OfflineWorker}, - Session: session::{Module, Call, Storage, Event, Config}, + Contracts: contracts, FinalityTracker: finality_tracker::{Module, Call, Inherent}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Contracts: contracts, - Sudo: sudo, ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, - AuthorityDiscovery: authority_discovery::{Module, Call, Config}, + Indices: indices, Offences: offences::{Module, Call, Storage, Event}, RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, + Session: session::{Module, Call, Storage, Event, Config}, + Sudo: sudo, + System: system::{Module, Call, Storage, Config, Event}, + Timestamp: timestamp::{Module, Call, Storage, Inherent}, + TransactionPayment: transaction_payment::{Module, Storage}, + Utility: utility::{Module, Call, Event}, + + Kton: kton, + Staking: staking::{default, OfflineWorker}, + EOSBridge: eos_bridge::{Storage, Module, Event, Call}, + EthereumBridge: ethereum_bridge::{Storage, Module, Event, Call}, } ); diff --git a/srml/chainrelay/Cargo.toml b/srml/chainrelay/bridge/eos/Cargo.toml similarity index 63% rename from srml/chainrelay/Cargo.toml rename to srml/chainrelay/bridge/eos/Cargo.toml index c42d9bb81..41d0482f7 100644 --- a/srml/chainrelay/Cargo.toml +++ b/srml/chainrelay/bridge/eos/Cargo.toml @@ -1,22 +1,26 @@ [package] -name = "darwinia-chainrelay" +name = "darwinia-eos-bridge" version = "0.1.0" -authors = ["hammeWang "] +authors = ["Xavier Lau "] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rstd = { package = "sr-std", git = 'https://github.com/paritytech/substrate.git', default-features = false } support = { package = "srml-support", git = 'https://github.com/paritytech/substrate.git', default-features = false } system = { package = "srml-system", git = 'https://github.com/paritytech/substrate.git', default-features = false } -poa = { package = "darwinia-chainrelay-poa", path = "../chainrelay/poa", default-features = false } + +merkle-mountain-range = { path = "../../../../core/merkle-mountain-range", default-features = false } [features] default = ["std"] std = [ + "codec/std", "rstd/std", "support/std", "system/std", - "poa/std", -] \ No newline at end of file + + "merkle-mountain-range/std", +] diff --git a/srml/chainrelay/bridge/eos/src/lib.rs b/srml/chainrelay/bridge/eos/src/lib.rs new file mode 100644 index 000000000..3add0e5d4 --- /dev/null +++ b/srml/chainrelay/bridge/eos/src/lib.rs @@ -0,0 +1,36 @@ +//! prototype module for bridging in ethereum poa blockcahin + +#![recursion_limit = "128"] +#![cfg_attr(not(feature = "std"), no_std)] + +use support::{decl_event, decl_module, decl_storage}; + +pub trait Trait: system::Trait { + type Event: From> + Into<::Event>; +} + +decl_storage! { + trait Store for Module as Bridge { + + } +} + +decl_module! { + pub struct Module for enum Call + where + origin: T::Origin + { + + } +} + +decl_event! { + pub enum Event + where + ::AccountId + { + TODO(AccountId), + } +} + +impl Module {} diff --git a/srml/chainrelay/bridge/ethereum/Cargo.toml b/srml/chainrelay/bridge/ethereum/Cargo.toml new file mode 100644 index 000000000..b85d0fd30 --- /dev/null +++ b/srml/chainrelay/bridge/ethereum/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "darwinia-ethereum-bridge" +version = "0.1.0" +authors = ["Xavier Lau "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +#blake2 = { version = "0.8.1", default-features = false } +serde = { version = "1.0.101", optional = true } + +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +rstd = { package = "sr-std", git = 'https://github.com/paritytech/substrate.git', default-features = false } +support = { package = "srml-support", git = 'https://github.com/paritytech/substrate.git', default-features = false } +system = { package = "srml-system", git = 'https://github.com/paritytech/substrate.git', default-features = false } + +merkle-mountain-range = { path = "../../../../core/merkle-mountain-range", default-features = false } + +[features] +default = ["std"] +std = [ +# "blake2/std", + "serde/std", + + "codec/std", + "rstd/std", + "support/std", + "system/std", + + "merkle-mountain-range/std", +] diff --git a/srml/chainrelay/bridge/ethereum/src/lib.rs b/srml/chainrelay/bridge/ethereum/src/lib.rs new file mode 100644 index 000000000..ad798f0a6 --- /dev/null +++ b/srml/chainrelay/bridge/ethereum/src/lib.rs @@ -0,0 +1,96 @@ +//! prototype module for bridging in ethereum poa blockcahin + +#![recursion_limit = "128"] +#![cfg_attr(not(feature = "std"), no_std)] + +// use blake2::Blake2b; +//use codec::{Decode, Encode}; +use rstd::vec::Vec; +use support::{ + decl_event, decl_module, decl_storage, + dispatch::Result, + traits::{Currency, LockableCurrency}, +}; +use system::ensure_signed; + +//use merkle_mountain_range::{MerkleMountainRange, Hash}; + +pub trait Trait: system::Trait { + type Event: From> + Into<::Event>; + type Ring: LockableCurrency; +} + +// config() require `serde = { version = "1.0.101", optional = true }` +// tracking issue: https://github.com/rust-lang/rust/issues/27812 +decl_storage! { + trait Store for Module as Bridge { + pub DepositPool get(deposit_pool) config(): RingBalanceOf; + pub DepositValue get(deposit_value): RingBalanceOf; + + // store Vec
or MPT
? + pub VerifiedHeader get(verified_header): Vec
; + pub UnverifiedHeader get(unverified_header): map PrevHash => Vec
; + } +} + +decl_module! { + pub struct Module for enum Call + where + origin: T::Origin + { + pub fn submit_header(origin, header: Header) { + let _relayer = ensure_signed(origin)?; + let _ = Self::verify(&header)?; + + // if header confirmed then return + // if header in unverified header then challenge + } + + // `Darwinia lock` corresponds to `TargetChain redeem` + pub fn lock(origin) { + let _locker = ensure_signed(origin)?; + } + + // `Darwinia redeem` corresponds to `TargetChain lock` + pub fn redeem(origin, _header: Header) { + let _redeemer = ensure_signed(origin)?; + } + } +} + +decl_event! { + pub enum Event + where + ::AccountId + { + TODO(AccountId), + } +} + +impl Module { + pub fn adjust_deposit_value() { + unimplemented!() + } + + /// 1. if exists? + /// 2. verify (difficulty + prev_hash + nonce) + /// 3. challenge + fn verify(_: &Header) -> Result { + unimplemented!() + } + + fn _punish(_who: &T::AccountId) -> Result { + unimplemented!() + } + + fn _release(_dest: &T::AccountId, _value: RingBalanceOf) -> Result { + unimplemented!() + } +} + +type RingBalanceOf = <::Ring as Currency<::AccountId>>::Balance; +// TODO: type +type Header = (); +type PrevHash = (); +// FIXME: currently, use SPV instead +// pub type MMR = MerkleMountainRange; diff --git a/srml/chainrelay/construct.md b/srml/chainrelay/construct.md new file mode 100644 index 000000000..f83a4367e --- /dev/null +++ b/srml/chainrelay/construct.md @@ -0,0 +1,29 @@ +- Bridge + - EOS bridge + - Ethereum bridge + - Deposit Pool (shared ?) + - Deposit Value (adjustable) + - Verified Header (Vec\
or MPT\
) + - Unverified (HashMap\ ?) + - ... + - ... +- Relayer + - ... + +--- + +- submit_header(relayer, header) +- lock() +- redeem(account, transaction) +- challenge(relayer) ? +- punish(relayer) ? +- reward(relayer) ? +- verify_submit(header) + 1. if exists? + 2. verify (difficulty + prev_hash + nonce) + 3. challenge +- verify_lock(transaction) + 1. get release value + 2. verify most-worked + 3. ... +- release(account, value) diff --git a/srml/chainrelay/poa/Cargo.toml b/srml/chainrelay/poa/Cargo.toml deleted file mode 100644 index 01ddf052e..000000000 --- a/srml/chainrelay/poa/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "darwinia-chainrelay-poa" -version = "0.1.0" -authors = ["hammeWang "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -sr-primitives = {git = 'https://github.com/paritytech/substrate.git', default-features = false } -substrate-primitives = {git = 'https://github.com/paritytech/substrate.git', default-features = false } - - -[features] -default = ["std"] -std = [ - "sr-primitives/std", - "substrate-primitives/std" -] \ No newline at end of file diff --git a/srml/chainrelay/poa/src/lib.rs b/srml/chainrelay/poa/src/lib.rs deleted file mode 100644 index 49fa16746..000000000 --- a/srml/chainrelay/poa/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ - -/// Handling eth poa(kovan) transaction verification etc. diff --git a/srml/chainrelay/src/lib.rs b/srml/chainrelay/src/lib.rs deleted file mode 100644 index 576e3ecde..000000000 --- a/srml/chainrelay/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! prototype module for bridging in ethereum poa blockcahin - -#![recursion_limit = "128"] -#![cfg_attr(not(feature = "std"), no_std)] - -use rstd::prelude::*; -use support::{decl_event, decl_module, decl_storage, ensure}; - -use poa::BestHeader; - -pub trait Trait: system::Trait {} - -decl_storage! { - trait Store for Module as Bridge { - // we don't need to start from genesis block - pub InitialBlock get(initial_block) config(): T::BlockNumber; - // BestHeader - pub BestHeader get(best_header): BestBLock; - - } -} diff --git a/srml/kton/src/lib.rs b/srml/kton/src/lib.rs index 7986fec35..8ca09a6f5 100644 --- a/srml/kton/src/lib.rs +++ b/srml/kton/src/lib.rs @@ -8,7 +8,6 @@ use sr_primitives::{ Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic, StaticLookup, Zero, }, - weights::SimpleDispatchInfo, RuntimeDebug, }; @@ -195,6 +194,28 @@ impl Currency for Module { Self::minimum_balance() } + // TODO: ready for hacking + fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { + >::mutate(|issued| { + issued.checked_sub(&amount).unwrap_or_else(|| { + amount = *issued; + Zero::zero() + }) + }); + PositiveImbalance::new(amount) + } + + // TODO: ready for hacking + fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { + >::mutate(|issued| { + *issued = issued.checked_add(&amount).unwrap_or_else(|| { + amount = Self::Balance::max_value() - *issued; + Self::Balance::max_value() + }) + }); + NegativeImbalance::new(amount) + } + fn free_balance(who: &T::AccountId) -> Self::Balance { >::get(who) } @@ -252,26 +273,6 @@ impl Currency for Module { Ok(()) } - fn withdraw( - who: &T::AccountId, - value: Self::Balance, - reason: WithdrawReason, - liveness: ExistenceRequirement, - ) -> result::Result { - let old_balance = Self::free_balance(who); - if let Some(new_balance) = old_balance.checked_sub(&value) { - if liveness == ExistenceRequirement::KeepAlive && new_balance < Self::minimum_balance() { - return Err("payment would kill account"); - } - - Self::ensure_can_withdraw(who, value, reason, new_balance)?; - Self::set_free_balance(who, new_balance); - Ok(NegativeImbalance::new(value)) - } else { - Err("too few free funds in account") - } - } - fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) { let free_balance = Self::free_balance(who); let free_slash = cmp::min(free_balance, value); @@ -323,6 +324,26 @@ impl Currency for Module { } } + fn withdraw( + who: &T::AccountId, + value: Self::Balance, + reason: WithdrawReason, + liveness: ExistenceRequirement, + ) -> result::Result { + let old_balance = Self::free_balance(who); + if let Some(new_balance) = old_balance.checked_sub(&value) { + if liveness == ExistenceRequirement::KeepAlive && new_balance < Self::minimum_balance() { + return Err("payment would kill account"); + } + + Self::ensure_can_withdraw(who, value, reason, new_balance)?; + Self::set_free_balance(who, new_balance); + Ok(NegativeImbalance::new(value)) + } else { + Err("too few free funds in account") + } + } + fn make_free_balance_be( who: &T::AccountId, balance: Self::Balance, @@ -345,28 +366,6 @@ impl Currency for Module { (imbalance, outcome) } - - // TODO: ready for hacking - fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { - >::mutate(|issued| { - issued.checked_sub(&amount).unwrap_or_else(|| { - amount = *issued; - Zero::zero() - }) - }); - PositiveImbalance::new(amount) - } - - // TODO: ready for hacking - fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { - >::mutate(|issued| { - *issued = issued.checked_add(&amount).unwrap_or_else(|| { - amount = Self::Balance::max_value() - *issued; - Self::Balance::max_value() - }) - }); - NegativeImbalance::new(amount) - } } impl LockableCurrency for Module diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 86e356811..db969d1dd 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -24,8 +24,6 @@ extern crate test; use codec::{CompactAs, Decode, Encode, HasCompact}; use rstd::{collections::btree_map::BTreeMap, prelude::*, result}; -#[cfg(feature = "std")] -use runtime_io::with_storage; use session::{historical::OnSessionEnding, SelectInitialValidators}; use sr_primitives::traits::{Bounded, CheckedSub, Convert, One, SaturatedConversion, Saturating, StaticLookup, Zero}; #[cfg(feature = "std")] @@ -116,7 +114,7 @@ impl Default for StakingBalance { pub struct StakingLedgers { pub stash: AccountId, // normal pattern: for ring - /// total_ring = nomarl_ring + time_deposit_ring + /// total_ring = normal_ring + time_deposit_ring #[codec(compact)] pub total_ring: RingBalance, #[codec(compact)] @@ -178,7 +176,7 @@ pub struct StakingLedgers { +pub struct IndividualExposure { /// The stash account of the nominator in question. who: AccountId, /// Amount of funds exposed. @@ -187,13 +185,13 @@ pub struct IndividualExpo { /// A snapshot of the stake backing a single validator in the system. #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] -pub struct Exposures { +pub struct Exposure { /// The total balance backing this validator. pub total: Power, /// The validator's own stash that is exposed. pub own: Power, /// The portions of nominators stashes that are exposed. - pub others: Vec>, + pub others: Vec>, } type RingBalanceOf = <::Ring as Currency<::AccountId>>::Balance; @@ -207,10 +205,13 @@ type RingNegativeImbalanceOf = <::Ring as Currency< = <::Kton as Currency<::AccountId>>::PositiveImbalance; type KtonNegativeImbalanceOf = <::Kton as Currency<::AccountId>>::NegativeImbalance; +// TODO +#[allow(unused)] type RawAssignment = (::AccountId, ExtendedBalance); +#[allow(unused)] type Assignment = (::AccountId, ExtendedBalance, ExtendedBalance); -type ExpoMap = - BTreeMap<::AccountId, Exposures<::AccountId, ExtendedBalance>>; +#[allow(unused)] +type ExpoMap = BTreeMap<::AccountId, Exposure<::AccountId, ExtendedBalance>>; pub trait Trait: timestamp::Trait + session::Trait { type Ring: LockableCurrency; @@ -273,7 +274,7 @@ decl_storage! { pub Nominators get(nominators): linked_map T::AccountId => Vec; - pub Stakers get(stakers): map T::AccountId => Exposures; + pub Stakers get(stakers): map T::AccountId => Exposure; pub CurrentElected get(current_elected): Vec; @@ -1023,7 +1024,7 @@ impl Module { session_index: SessionIndex, ) -> Option<( Vec, - Vec<(T::AccountId, Exposures)>, + Vec<(T::AccountId, Exposure)>, )> { if ForceNewEra::take() || session_index % T::SessionsPerEra::get() == 0 { let validators = T::SessionInterface::validators(); @@ -1151,7 +1152,7 @@ impl Module { let assignments = elected_set.assignments; // The return value of this is safe to be converted to u64. - /// Initialize the support of each candidate. + // Initialize the support of each candidate. let mut supports = >::new(); elected_stashes .iter() @@ -1214,7 +1215,7 @@ impl Module { let mut slot_stake = ExtendedBalance::max_value(); for (c, s) in supports.into_iter() { // build `struct exposure` from `support` - let exposure = Exposures { + let exposure = Exposure { own: s.own, // This might reasonably saturate and we cannot do much about it. The sum of // someone's stake might exceed the balance type if they have the maximum amount @@ -1224,8 +1225,8 @@ impl Module { others: s .others .into_iter() - .map(|(who, value)| IndividualExpo { who, value: value }) - .collect::>>(), + .map(|(who, value)| IndividualExposure { who, value: value }) + .collect::>>(), }; if exposure.total < slot_stake { slot_stake = exposure.total; @@ -1340,6 +1341,18 @@ impl session::OnSessionEnding for Module { } } +impl OnSessionEnding> for Module { + fn on_session_ending( + _ending: SessionIndex, + start_session: SessionIndex, + ) -> Option<( + Vec, + Vec<(T::AccountId, Exposure)>, + )> { + Self::new_session(start_session - 1) + } +} + impl OnFreeBalanceZero for Module { fn on_free_balance_zero(stash: &T::AccountId) { if let Some(controller) = >::take(stash) { @@ -1362,8 +1375,8 @@ impl SelectInitialValidators for Module { /// on that account. pub struct ExposureOf(rstd::marker::PhantomData); -impl Convert>> for ExposureOf { - fn convert(validator: T::AccountId) -> Option> { +impl Convert>> for ExposureOf { + fn convert(validator: T::AccountId) -> Option> { Some(>::stakers(&validator)) } } @@ -1384,7 +1397,7 @@ impl SessionInterface<::AccountId> for T where T: session::Trait::AccountId>, T: session::historical::Trait< - FullIdentification = Exposures<::AccountId, ExtendedBalance>, + FullIdentification = Exposure<::AccountId, ExtendedBalance>, FullIdentificationOf = ExposureOf, >, T::SessionHandler: session::SessionHandler<::AccountId>, @@ -1409,8 +1422,8 @@ where /// * 2 points to the block producer for each reference to a previously unreferenced uncle, and /// * 1 point to the producer of each referenced uncle block. impl authorship::EventHandler for Module { - fn note_author(author: T::AccountId) {} - fn note_uncle(author: T::AccountId, _age: T::BlockNumber) {} + fn note_author(_author: T::AccountId) {} + fn note_uncle(_author: T::AccountId, _age: T::BlockNumber) {} } pub struct StashOf(rstd::marker::PhantomData); diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 40ae4c955..6801a22a5 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -1,12 +1,22 @@ -use crate::{EraIndex, GenesisConfig, Module, Nominators, RewardDestination, StakerStatus, StakingBalance, Trait}; -use primitives::testing::{Header, UintAuthorityId}; -use primitives::traits::{Convert, IdentityLookup, OnInitialize, OpaqueKeys}; -use primitives::Perbill; -use runtime_io; -use srml_support::traits::{Currency, Get}; -use srml_support::{assert_ok, impl_outer_origin, parameter_types, EnumerableStorageMap}; use std::{cell::RefCell, collections::HashSet}; -use substrate_primitives::{Blake2Hasher, H256}; + +use sr_primitives::{ + testing::{Header, UintAuthorityId}, + traits::{BlakeTwo256, Convert, IdentityLookup, OnInitialize, OpaqueKeys}, + Perbill, +}; +use sr_staking_primitives::SessionIndex; +use srml_support::{ + assert_ok, impl_outer_origin, parameter_types, + traits::{Currency, Get}, + StorageLinkedMap, +}; +use substrate_primitives::H256; + +use crate::{ + phragmen::ExtendedBalance, EraIndex, GenesisConfig, Module, Nominators, RewardDestination, StakerStatus, + StakingBalance, Trait, +}; /// The AccountId alias in this test module. pub type AccountId = u64; @@ -33,7 +43,13 @@ thread_local! { pub struct TestSessionHandler; impl session::SessionHandler for TestSessionHandler { - fn on_new_session(_changed: bool, validators: &[(AccountId, Ks)]) { + fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} + + fn on_new_session( + _changed: bool, + validators: &[(AccountId, Ks)], + _queued_validators: &[(AccountId, Ks)], + ) { SESSION.with(|x| *x.borrow_mut() = (validators.iter().map(|x| x.0.clone()).collect(), HashSet::new())); } @@ -41,7 +57,6 @@ impl session::SessionHandler for TestSessionHandler { SESSION.with(|d| { let mut d = d.borrow_mut(); let value = d.0[validator_index]; - println!("on_disabled {} -> {}", validator_index, value); d.1.insert(value); }) } @@ -65,17 +80,28 @@ impl_outer_origin! { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; - +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} impl system::Trait for Test { type Origin = Origin; + type Call = (); type Index = u64; - type BlockNumber = u64; + type BlockNumber = BlockNumber; type Hash = H256; - type Hashing = ::primitives::traits::BlakeTwo256; + type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); } parameter_types! { pub const TransferFee: u64 = 0; @@ -87,31 +113,42 @@ impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = Staking; type OnNewAccount = (); - type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); + type Event = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; } parameter_types! { pub const Period: BlockNumber = 1; pub const Offset: BlockNumber = 0; + pub const UncleGenerations: u64 = 0; + pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(25); } impl session::Trait for Test { - type OnSessionEnding = Staking; - type Keys = UintAuthorityId; + type Event = (); + type ValidatorId = AccountId; + type ValidatorIdOf = crate::StashOf; type ShouldEndSession = session::PeriodicSessions; + type OnSessionEnding = session::historical::NoteHistoricalRoot; type SessionHandler = TestSessionHandler; - type Event = (); + type Keys = UintAuthorityId; + type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type SelectInitialValidators = Staking; } +impl session::historical::Trait for Test { + type FullIdentification = crate::Exposure; + type FullIdentificationOf = crate::ExposureOf; +} +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} impl timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; } impl kton::Trait for Test { @@ -122,17 +159,15 @@ impl kton::Trait for Test { } parameter_types! { - pub const SessionsPerEra: session::SessionIndex = 3; + pub const SessionsPerEra: SessionIndex = 3; pub const BondingDuration: EraIndex = 3; pub const ErasPerEpoch: EraIndex = 10; } - pub const COIN: u64 = 1_000_000_000; parameter_types! { // decimal 9 pub const CAP: Balance = 10_000_000_000 * COIN; } - impl Trait for Test { type Ring = Ring; type Kton = Kton; @@ -144,10 +179,10 @@ impl Trait for Test { type KtonReward = (); type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; - // customed type Cap = CAP; type ErasPerEpoch = ErasPerEpoch; type SessionLength = Period; + type SessionInterface = Self; } pub struct ExtBuilder { @@ -208,9 +243,9 @@ impl ExtBuilder { pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); - let (mut t, mut c) = system::GenesisConfig::default().build_storage::().unwrap(); + let mut storage = system::GenesisConfig::default().build_storage::().unwrap(); let balance_factor = if self.existential_deposit > 0 { 1_000 * COIN } else { @@ -221,12 +256,12 @@ impl ExtBuilder { } else { vec![10, 20] }; + let _ = session::GenesisConfig:: { - // NOTE: if config.nominate == false then 100 is also selected in the initial round. - validators, - keys: vec![], + keys: validators.iter().map(|x| (*x, UintAuthorityId(*x))).collect(), } - .assimilate_storage(&mut t, &mut c); + .assimilate_storage(&mut storage); + let _ = balances::GenesisConfig:: { balances: vec![ (1, 10 * balance_factor), @@ -246,12 +281,13 @@ impl ExtBuilder { ], vesting: vec![], } - .assimilate_storage(&mut t, &mut c); + .assimilate_storage(&mut storage); + let _ = kton::GenesisConfig:: { balances: vec![], vesting: vec![], } - .assimilate_storage(&mut t, &mut c); + .assimilate_storage(&mut storage); let stake_21 = if self.fair { 1000 } else { 2000 }; let stake_31 = if self.validator_pool { balance_factor * 1000 } else { 1 }; @@ -280,15 +316,15 @@ impl ExtBuilder { ], validator_count: self.validator_count, minimum_validator_count: self.minimum_validator_count, - session_reward: Perbill::from_millionths((1000000 * self.reward / balance_factor) as u32), + session_reward: Perbill::from_rational_approximation(1_000_000 * self.reward / balance_factor, 1_000_000), offline_slash: Perbill::from_percent(5), offline_slash_grace: 0, invulnerables: vec![], } - .assimilate_storage(&mut t, &mut c); - let _ = timestamp::GenesisConfig:: { minimum_period: 5 }.assimilate_storage(&mut t, &mut c); - let mut ext = t.into(); - runtime_io::with_externalities(&mut ext, || { + .assimilate_storage(&mut storage); + + let mut ext = runtime_io::TestExternalities::from(storage); + ext.execute_with(|| { let validators = Session::validators(); SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new())); }); @@ -387,7 +423,7 @@ pub fn bond_nominator(acc: u64, val: u64, target: Vec) { assert_ok!(Staking::nominate(Origin::signed(acc), target)); } -pub fn start_session(session_index: session::SessionIndex) { +pub fn start_session(session_index: SessionIndex) { for i in 0..(session_index - Session::current_index()) { System::set_block_number((i + 1).into()); Session::on_initialize(System::block_number()); diff --git a/srml/staking/src/phragmen.rs b/srml/staking/src/phragmen.rs index 07c139ebb..5ec9dcccf 100644 --- a/srml/staking/src/phragmen.rs +++ b/srml/staking/src/phragmen.rs @@ -34,7 +34,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::{collections::btree_map::BTreeMap, prelude::*}; -use sr_primitives::traits::{Bounded, Convert, Member, Saturating, SimpleArithmetic, Zero}; +use sr_primitives::traits::{Bounded, Member, Saturating, Zero}; use sr_primitives::{helpers_128bit::multiply_by_rational, Perbill, Rational128}; /// A type in which performing operations on balances and stakes of candidates and voters are safe. diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index b050145b7..cbad1534d 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -1,7 +1,6 @@ use super::MONTH_IN_SECONDS; use super::*; use crate::mock::*; -use runtime_io::with_externalities; use srml_support::traits::{Currency, WithdrawReason, WithdrawReasons}; use srml_support::{assert_err, assert_ok}; @@ -69,7 +68,7 @@ macro_rules! gen_paired_account { #[test] fn test_env_build() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { check_exposure_all(); assert_eq!(Staking::bonded(&11), Some(10)); @@ -132,7 +131,7 @@ fn test_env_build() { #[test] fn normal_kton_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { Kton::deposit_creating(&1001, 10 * COIN); assert_ok!(Staking::bond( Origin::signed(1001), @@ -194,7 +193,7 @@ fn normal_kton_should_work() { #[test] fn time_deposit_ring_unbond_and_withdraw_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { Timestamp::set_timestamp(13 * MONTH_IN_SECONDS as u64); assert_ok!(Staking::unbond(Origin::signed(10), StakingBalance::Ring(10 * COIN))); @@ -324,7 +323,7 @@ fn time_deposit_ring_unbond_and_withdraw_should_work() { #[test] fn normal_unbond_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let stash = 11; let controller = 10; let value = 200 * COIN; @@ -390,7 +389,7 @@ fn normal_unbond_should_work() { #[test] fn punished_unbond_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let stash = 1001; let controller = 1000; let promise_month = 36; @@ -471,7 +470,7 @@ fn punished_unbond_should_work() { #[test] fn transform_to_promised_ring_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let _ = Ring::deposit_creating(&1001, 100 * COIN); assert_ok!(Staking::bond( Origin::signed(1001), @@ -510,7 +509,7 @@ fn transform_to_promised_ring_should_work() { #[test] fn expired_ring_should_capable_to_promise_again() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let _ = Ring::deposit_creating(&1001, 100 * COIN); assert_ok!(Staking::bond( Origin::signed(1001), @@ -538,7 +537,7 @@ fn expired_ring_should_capable_to_promise_again() { #[test] fn inflation_should_be_correct() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let initial_issuance = 1_200_000_000 * COIN; let surplus_needed = initial_issuance - Ring::total_issuance(); let _ = Ring::deposit_into_existing(&11, surplus_needed); @@ -552,7 +551,7 @@ fn inflation_should_be_correct() { #[test] fn reward_should_work_correctly() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { // create controller account let _ = Ring::deposit_creating(&2000, COIN); let _ = Ring::deposit_creating(&1000, COIN); @@ -626,10 +625,10 @@ fn reward_should_work_correctly() { assert_eq!( Staking::stakers(2001), - Exposures { + Exposure { total: 1200000000000, own: 600000000000, - others: vec![IndividualExpo { + others: vec![IndividualExposure { who: 1001, value: 600000000000 }] @@ -642,7 +641,7 @@ fn reward_should_work_correctly() { #[test] fn slash_should_work() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let _ = Ring::deposit_creating(&1001, 100 * COIN); Kton::deposit_creating(&1001, 100 * COIN); @@ -678,7 +677,7 @@ fn slash_should_work() { #[test] fn test_inflation() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { assert_eq!(Staking::current_era_total_reward(), 80_000_000 * COIN / 10); start_era(20); assert_eq!(Staking::epoch_index(), 2); @@ -688,7 +687,7 @@ fn test_inflation() { #[test] fn set_controller_should_remove_old_ledger() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let stash = 11; let old_controller = 10; let new_controller = 12; @@ -703,7 +702,7 @@ fn set_controller_should_remove_old_ledger() { #[test] fn set_controller_should_not_change_ledger() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { assert_eq!(Staking::ledger(&10).unwrap().total_ring, 100 * COIN); assert_ok!(Staking::set_controller(Origin::signed(11), 12)); assert_eq!(Staking::ledger(&12).unwrap().total_ring, 100 * COIN); @@ -712,7 +711,7 @@ fn set_controller_should_not_change_ledger() { #[test] fn slash_should_not_touch_unlockings() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let old_ledger = Staking::ledger(&10).unwrap(); // only deposit_ring, no normal_ring assert_eq!( @@ -762,7 +761,7 @@ fn slash_should_not_touch_unlockings() { #[test] fn bond_over_max_promise_month_should_fail() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { gen_paired_account!(stash(123), controller(456)); assert_err!( Staking::bond( @@ -785,7 +784,7 @@ fn bond_over_max_promise_month_should_fail() { #[test] fn stash_already_bonded_and_controller_already_paired_should_fail() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { gen_paired_account!(unpaired_stash(123), unpaired_controller(456)); assert_err!( Staking::bond( @@ -812,7 +811,7 @@ fn stash_already_bonded_and_controller_already_paired_should_fail() { #[test] fn pool_should_be_increased_and_decreased_correctly() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let mut ring_pool = Staking::ring_pool(); let mut kton_pool = Staking::kton_pool(); @@ -874,7 +873,7 @@ fn pool_should_be_increased_and_decreased_correctly() { #[test] fn unbond_over_max_unlocking_chunks_should_fail() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { gen_paired_account!(stash(123), controller(456), promise_month(12)); let deposit_items_len = MAX_UNLOCKING_CHUNKS + 1; @@ -913,7 +912,7 @@ fn unbond_over_max_unlocking_chunks_should_fail() { #[test] fn unlock_value_should_be_increased_and_decreased_correctly() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { // normal Ring/Kton { let stash = 444; @@ -1038,7 +1037,7 @@ fn unlock_value_should_be_increased_and_decreased_correctly() { #[test] fn promise_extra_should_not_remove_unexpired_items() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { gen_paired_account!(stash(123), controller(456), promise_month(12)); let expired_item_len = 3; @@ -1076,7 +1075,7 @@ fn promise_extra_should_not_remove_unexpired_items() { #[test] fn unbond_zero_before_expiry() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let expiry_date = 12 * MONTH_IN_SECONDS as u64; let unbond_value = StakingBalance::Ring(COIN); @@ -1101,7 +1100,7 @@ fn unbond_zero_before_expiry() { // lost 3 Kton and 10_000 Ring's power for nominate #[test] fn yakio_q1() { - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { let stash = 777; let controller = 888; let _ = Ring::deposit_creating(&stash, 20_000); @@ -1165,7 +1164,7 @@ fn yakio_q1() { fn yakio_q2() { fn run(with_new_era: bool) -> u64 { let mut balance = 0; - with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || { + ExtBuilder::default().existential_deposit(0).build().execute_with(|| { gen_paired_account!(validator_1_stash(123), validator_1_controller(456), 0); gen_paired_account!(validator_2_stash(234), validator_2_controller(567), 0); gen_paired_account!(nominator_stash(345), nominator_controller(678), 0); @@ -1205,7 +1204,7 @@ fn yakio_q2() { let free_balance = run(false); let free_balance_with_new_era = run(true); - assert!(free_balance != 0); - assert!(free_balance_with_new_era != 0); + assert_ne!(free_balance, 0); + assert_ne!(free_balance_with_new_era, 0); assert!(free_balance > free_balance_with_new_era); } diff --git a/types.json b/types.json index 43cbe1fce..288eb5daf 100644 --- a/types.json +++ b/types.json @@ -35,13 +35,13 @@ "deposit_items": "Vec", "unlocking": "Vec" }, - "IndividualExpo": { + "IndividualExposure": { "who": "AccountId", "value": "ExtendedBalance" }, - "Exposures": { + "Exposure": { "total": "ExtendedBalance", "own": "ExtendedBalance", - "others": "Vec" + "others": "Vec" } } \ No newline at end of file