diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000..a18ca02fb12d1 --- /dev/null +++ b/Makefile @@ -0,0 +1,50 @@ +SHELL := /bin/bash +#ENABLE_FEATURES ?= default + +default: release + +.PHONY: all + +all: format build test + +pre-clippy: unset-override + @rustup component add clippy-preview + +clippy: pre-clippy + @cargo clippy --all --all-targets -- \ + -A clippy::module_inception -A clippy::needless_pass_by_value \ + -A clippy::cyclomatic_complexity -A clippy::unreadable_literal \ + -A clippy::should_implement_trait -A clippy::verbose_bit_mask \ + -A clippy::implicit_hasher -A clippy::large_enum_variant \ + -A clippy::new_without_default -A clippy::new_without_default_derive \ + -A clippy::neg_cmp_op_on_partial_ord -A clippy::too_many_arguments \ + -A clippy::excessive_precision -A clippy::collapsible_if \ + -A clippy::blacklisted_name + +build: + cargo build #--features "${ENABLE_FEATURES}" + +release: + @cargo build --release #--features "${ENABLE_FEATURES}" + +test: + export LOG_LEVEL=DEBUG && \ + export RUST_BACKTRACE=1 && \ + cargo test #--features "${ENABLE_FEATURES}" --all -- --nocapture + +bench: + LOG_LEVEL=ERROR RUST_BACKTRACE=1 cargo bench #--features "${ENABLE_FEATURES}" --all -- --nocapture + +unset-override: + @# unset first in case of any previous overrides + @if rustup override list | grep `pwd` > /dev/null; then rustup override unset; fi + +pre-format: unset-override + @rustup component add rustfmt-preview + +format: pre-format + @cargo fmt --all -- --check >/dev/null || \ + cargo fmt --all + +clean: + @cargo clean diff --git a/api/src/implement.rs b/api/src/implement.rs index bd99b638c1dea..98a860cdd2340 100644 --- a/api/src/implement.rs +++ b/api/src/implement.rs @@ -35,31 +35,33 @@ impl ChainXApi for TClient { self.call_api_at(at, "timestamp", &()) } + fn index(&self, at: &BlockId, account: AccountId) -> Result { + self.call_api_at(at, "account_nonce", &account) + } + + fn lookup(&self, at: &BlockId, address: Address) -> Result> { + self.call_api_at(at, "lookup_address", &address) + } + fn evaluate_block(&self, at: &BlockId, block: Block) -> Result { let res: Result<()> = self.call_api_at(at, "execute_block", &block); match res { Ok(_) => Ok(true), - Err(err) => { - match err.kind() { - &ErrorKind::Execution(_) => Ok(false), - _ => Err(err), - } - } + Err(err) => match err.kind() { + &ErrorKind::Execution(_) => Ok(false), + _ => Err(err), + }, } } - fn validate_transaction(&self, at: &BlockId, tx: UncheckedExtrinsic) -> Result { + fn validate_transaction( + &self, + at: &BlockId, + tx: UncheckedExtrinsic, + ) -> Result { self.call_api_at(at, "validate_transaction", &tx) } - fn index(&self, at: &BlockId, account: AccountId) -> Result { - self.call_api_at(at, "account_nonce", &account) - } - - fn lookup(&self, at: &BlockId, address: Address) -> Result> { - self.call_api_at(at, "lookup_address", &address) - } - fn build_block(&self, at: &BlockId, inherent_data: InherentData) -> Result { let runtime_version = self.runtime_version_at(at)?; diff --git a/api/src/lib.rs b/api/src/lib.rs index cb04a39705b39..606352f0031d6 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -1,28 +1,31 @@ // Copyright 2018 chainpool. -extern crate sr_primitives as runtime_primitives; -extern crate substrate_executor as substrate_executor; -extern crate substrate_client_db as client_db; -extern crate substrate_client as client; extern crate parity_codec as codec; -extern crate substrate_primitives; extern crate sr_io as runtime_io; +extern crate sr_primitives as runtime_primitives; extern crate srml_executive; +extern crate substrate_client as client; +extern crate substrate_client_db as client_db; +extern crate substrate_executor as substrate_executor; +extern crate substrate_primitives; +extern crate chainx_executor; extern crate chainx_primitives as primitives; extern crate chainx_runtime as runtime; -extern crate chainx_executor; -use primitives::{ - AccountId, Block, BlockId, Hash, Index, SessionKey, Timestamp, BlockNumber, - UncheckedExtrinsic, InherentData, -}; -use runtime_primitives::{transaction_validity::TransactionValidity, traits::{CurrentHeight, BlockNumberToHash}}; +use chainx_executor::NativeExecutor; use client::block_builder::BlockBuilder as ClientBlockBuilder; pub use client::error::{Error, ErrorKind, Result}; -use substrate_primitives::Blake2Hasher; -use chainx_executor::NativeExecutor; +use primitives::{ + AccountId, Block, BlockId, BlockNumber, Hash, Index, InherentData, SessionKey, Timestamp, + UncheckedExtrinsic, +}; use runtime::Address; +use runtime_primitives::{ + traits::{BlockNumberToHash, CurrentHeight}, + transaction_validity::TransactionValidity, +}; +use substrate_primitives::Blake2Hasher; mod implement; @@ -40,11 +43,12 @@ pub type TExecutor = client::LocalCallExecutor; pub type TClientBlockBuilder = ClientBlockBuilder; - /// Trait encapsulating the ChainX API. /// /// All calls should fail when the exact runtime is unknown. -pub trait ChainXApi: CurrentHeight + BlockNumberToHash { +pub trait ChainXApi: + CurrentHeight + BlockNumberToHash +{ /// The block builder for this API type. type BlockBuilder: BlockBuilder; @@ -73,14 +77,22 @@ pub trait ChainXApi: CurrentHeight + BlockNumberToHash< /// and an error if we can't evaluate for some reason. fn evaluate_block(&self, at: &BlockId, block: Block) -> Result; - fn validate_transaction(&self, at: &BlockId, transaction: UncheckedExtrinsic) -> Result; + fn validate_transaction( + &self, + at: &BlockId, + transaction: UncheckedExtrinsic, + ) -> Result; /// Build a block on top of the given, with inherent extrinsics pre-pushed. fn build_block(&self, at: &BlockId, inherent_data: InherentData) -> Result; /// Attempt to produce the (encoded) inherent extrinsics for a block being built upon the given. /// This may vary by runtime and will fail if a runtime doesn't follow the same API. - fn inherent_extrinsics(&self, at: &BlockId, inherent_data: InherentData) -> Result>; + fn inherent_extrinsics( + &self, + at: &BlockId, + inherent_data: InherentData, + ) -> Result>; } /// Mark for all ChainX API implementations, that are making use of state data, stored locally. diff --git a/consensus/src/error.rs b/consensus/src/error.rs index 275530b8e9430..015c50cc0dfd6 100644 --- a/consensus/src/error.rs +++ b/consensus/src/error.rs @@ -5,33 +5,33 @@ use primitives::AuthorityId; error_chain! { - links { - ChainXApi(::chainx_api::Error, ::chainx_api::ErrorKind); - Bft(::bft::Error, ::bft::ErrorKind); - } + links { + ChainXApi(::chainx_api::Error, ::chainx_api::ErrorKind); + Bft(::bft::Error, ::bft::ErrorKind); + } - errors { - InvalidDutyRosterLength(expected: usize, got: usize) { - description("Duty Roster had invalid length"), - display("Invalid duty roster length: expected {}, got {}", expected, got), - } - NotValidator(id: AuthorityId) { - description("Local account ID not a validator at this block."), - display("Local account ID ({:?}) not a validator at this block.", id), - } - PrematureDestruction { - description("Proposer destroyed before finishing proposing or evaluating"), - display("Proposer destroyed before finishing proposing or evaluating"), - } - Timer(e: ::tokio::timer::Error) { - description("Failed to register or resolve async timer."), - display("Timer failed: {}", e), - } - Executor(e: ::futures::future::ExecuteErrorKind) { - description("Unable to dispatch agreement future"), - display("Unable to dispatch agreement future: {:?}", e), - } - } + errors { + InvalidDutyRosterLength(expected: usize, got: usize) { + description("Duty Roster had invalid length"), + display("Invalid duty roster length: expected {}, got {}", expected, got), + } + NotValidator(id: AuthorityId) { + description("Local account ID not a validator at this block."), + display("Local account ID ({:?}) not a validator at this block.", id), + } + PrematureDestruction { + description("Proposer destroyed before finishing proposing or evaluating"), + display("Proposer destroyed before finishing proposing or evaluating"), + } + Timer(e: ::tokio::timer::Error) { + description("Failed to register or resolve async timer."), + display("Timer failed: {}", e), + } + Executor(e: ::futures::future::ExecuteErrorKind) { + description("Unable to dispatch agreement future"), + display("Unable to dispatch agreement future: {:?}", e), + } + } } impl From<::bft::InputStreamConcluded> for Error { diff --git a/consensus/src/evaluation.rs b/consensus/src/evaluation.rs index c185b87e6f26d..ace3665243d7b 100644 --- a/consensus/src/evaluation.rs +++ b/consensus/src/evaluation.rs @@ -1,47 +1,47 @@ // Copyright 2018 Chainpool. //! ChainX block evaluation and evaluation errors. +use chainx_primitives::{Block, BlockNumber, Hash, Timestamp}; use chainx_runtime::{Block as ChainXGenericBlock, CheckedBlock}; -use chainx_primitives::{Block, Hash, BlockNumber, Timestamp}; use super::MAX_TRANSACTIONS_SIZE; use codec::{Decode, Encode}; error_chain! { - links { - ChainXApi(::chainx_api::Error, ::chainx_api::ErrorKind); - } + links { + ChainXApi(::chainx_api::Error, ::chainx_api::ErrorKind); + } - errors { - ProposalNotForChainX { - description("Proposal provided not a ChainX block."), - display("Proposal provided not a ChainX block."), - } - TimestampInFuture { - description("Proposal had timestamp too far in the future."), - display("Proposal had timestamp too far in the future."), - } - TooManyCandidates(expected: usize, got: usize) { - description("Proposal included more candidates than is possible."), - display("Proposal included {} candidates for {} parachains", got, expected), - } - WrongParentHash(expected: Hash, got: Hash) { - description("Proposal had wrong parent hash."), - display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got), - } - WrongNumber(expected: BlockNumber, got: BlockNumber) { - description("Proposal had wrong number."), - display("Proposal had wrong number. Expected {:?}, got {:?}", expected, got), - } - ProposalTooLarge(size: usize) { - description("Proposal exceeded the maximum size."), - display( - "Proposal exceeded the maximum size of {} by {} bytes.", - MAX_TRANSACTIONS_SIZE, MAX_TRANSACTIONS_SIZE.saturating_sub(*size) - ), - } - } + errors { + ProposalNotForChainX { + description("Proposal provided not a ChainX block."), + display("Proposal provided not a ChainX block."), + } + TimestampInFuture { + description("Proposal had timestamp too far in the future."), + display("Proposal had timestamp too far in the future."), + } + TooManyCandidates(expected: usize, got: usize) { + description("Proposal included more candidates than is possible."), + display("Proposal included {} candidates for {} parachains", got, expected), + } + WrongParentHash(expected: Hash, got: Hash) { + description("Proposal had wrong parent hash."), + display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got), + } + WrongNumber(expected: BlockNumber, got: BlockNumber) { + description("Proposal had wrong number."), + display("Proposal had wrong number. Expected {:?}, got {:?}", expected, got), + } + ProposalTooLarge(size: usize) { + description("Proposal exceeded the maximum size."), + display( + "Proposal exceeded the maximum size of {} by {} bytes.", + MAX_TRANSACTIONS_SIZE, MAX_TRANSACTIONS_SIZE.saturating_sub(*size) + ), + } + } } /// Attempt to evaluate a substrate block as a chainx block, returning error @@ -59,9 +59,10 @@ pub fn evaluate_initial( .and_then(|b| CheckedBlock::new(b).ok()) .ok_or_else(|| ErrorKind::ProposalNotForChainX)?; - let transactions_size = proposal.extrinsics.iter().fold(0, |a, tx| { - a + Encode::encode(tx).len() - }); + let transactions_size = proposal + .extrinsics + .iter() + .fold(0, |a, tx| a + Encode::encode(tx).len()); if transactions_size > MAX_TRANSACTIONS_SIZE { bail!(ErrorKind::ProposalTooLarge(transactions_size)) diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs index ddea24bc0230e..bc947f2e30ef8 100644 --- a/consensus/src/lib.rs +++ b/consensus/src/lib.rs @@ -1,22 +1,22 @@ // Copyright 2018 Chainpool. +extern crate parity_codec as codec; extern crate sr_primitives as runtime_primitives; extern crate srml_support as runtime_support; -extern crate substrate_primitives as primitives; -extern crate substrate_client as client; -extern crate parity_codec as codec; -extern crate substrate_transaction_pool; extern crate substrate_bft as bft; +extern crate substrate_client as client; extern crate substrate_network; +extern crate substrate_primitives as primitives; +extern crate substrate_transaction_pool; +extern crate chainx_api; +extern crate chainx_pool; extern crate chainx_primitives; extern crate chainx_runtime; -extern crate chainx_pool; -extern crate chainx_api; -extern crate rhododendron; extern crate exit_future; extern crate parking_lot; +extern crate rhododendron; #[macro_use] extern crate error_chain; extern crate futures; @@ -24,44 +24,45 @@ extern crate tokio; #[macro_use] extern crate log; -mod offline_tracker; +mod error; mod evaluation; +mod offline_tracker; mod service; -mod error; -use chainx_primitives::{BlockId, Hash, Block, Header, AccountId, BlockNumber, Timestamp, SessionKey}; -use primitives::{AuthorityId, ed25519}; +use chainx_api::ChainXApi; +use chainx_primitives::{ + AccountId, Block, BlockId, BlockNumber, Hash, Header, SessionKey, Timestamp, +}; +use codec::{Decode, Encode}; +use futures::future; +use futures::prelude::*; +use parking_lot::RwLock; +use primitives::{ed25519, AuthorityId}; use runtime_primitives::generic::Era; +use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::runtime::TaskExecutor; use tokio::timer::Delay; -use codec::{Decode, Encode}; -use chainx_api::ChainXApi; -use parking_lot::RwLock; -use futures::prelude::*; -use futures::future; -use std::sync::Arc; type TransactionPool = substrate_transaction_pool::Pool>; +pub use self::error::{Error, ErrorKind}; pub use self::offline_tracker::OfflineTracker; -pub use self::error::{ErrorKind, Error}; pub use service::Service; /// Shared offline validator tracker. pub type SharedOfflineTracker = Arc>; - // block size limit. const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024; /// A long-lived network which can create BFT message routing processes on demand. pub trait Network { /// The input stream of BFT messages. Should never logically conclude. - type Input: Stream, Error=Error>; + type Input: Stream, Error = Error>; /// The output sink of BFT messages. Messages sent here should eventually pass to all /// current authorities. - type Output: Sink, SinkError=Error>; + type Output: Sink, SinkError = Error>; fn communication_for( &self, @@ -74,8 +75,8 @@ pub trait Network { /// ChainX proposer factory. pub struct ProposerFactory - where - P: ChainXApi + Send + Sync + 'static, +where + P: ChainXApi + Send + Sync + 'static, { /// The client instance. pub client: Arc

, @@ -92,9 +93,9 @@ pub struct ProposerFactory } impl bft::Environment for ProposerFactory - where - N: Network, - P: ChainXApi + Send + Sync + 'static, +where + N: Network, + P: ChainXApi + Send + Sync + 'static, { type Proposer = Proposer

; type Input = N::Input; @@ -107,7 +108,7 @@ impl bft::Environment for ProposerFactory authorities: &[AuthorityId], sign_with: Arc, ) -> Result<(Self::Proposer, Self::Input, Self::Output), Error> { - use runtime_primitives::traits::{Hash as HashT, BlakeTwo256}; + use runtime_primitives::traits::{BlakeTwo256, Hash as HashT}; let parent_hash = parent_header.hash().into(); @@ -146,8 +147,7 @@ impl bft::Environment for ProposerFactory } /// The ChainX proposer logic. -pub struct Proposer -{ +pub struct Proposer { client: Arc, start: Instant, local_key: Arc, @@ -166,13 +166,22 @@ impl Proposer { use primitives::uint::U256; let validators_len = self.validators.len(); - let mut stake_weight = self.validators.iter() + let mut stake_weight = self + .validators + .iter() .map(|account| { let weight = self.client.stake_weight(&self.parent_id, *account).unwrap(); - if weight == 0 { 1 } else { weight } + if weight == 0 { + 1 + } else { + weight + } }) .collect::>(); - info!("validator stake weight:{:?}, round_numer:{:?}", stake_weight, round_number); + info!( + "validator stake weight:{:?}, round_numer:{:?}", + stake_weight, round_number + ); for i in 1..validators_len { stake_weight[i] = stake_weight[i] + stake_weight[i - 1]; } @@ -195,17 +204,17 @@ impl Proposer { } impl bft::Proposer for Proposer - where - C: ChainXApi + Send + Sync, +where + C: ChainXApi + Send + Sync, { type Error = Error; type Create = Result; - type Evaluate = Box>; + type Evaluate = Box>; fn propose(&self) -> Self::Create { use chainx_api::BlockBuilder; - use runtime_primitives::traits::{Hash as HashT, BlakeTwo256}; use chainx_primitives::InherentData; + use runtime_primitives::traits::{BlakeTwo256, Hash as HashT}; const MAX_VOTE_OFFLINE_SECONDS: Duration = Duration::from_secs(60); @@ -222,7 +231,10 @@ impl bft::Proposer for Proposer if !offline_indices.is_empty() { info!( "Submitting offline validators {:?} for slash-vote", - offline_indices.iter().map(|&i| self.validators[i as usize]).collect::>(), + offline_indices + .iter() + .map(|&i| self.validators[i as usize]) + .collect::>(), ) } @@ -238,22 +250,27 @@ impl bft::Proposer for Proposer { let mut unqueue_invalid = Vec::new(); - let result = self.transaction_pool.cull_and_get_pending(&BlockId::hash(self.parent_hash), |pending_iterator| { - let mut pending_size = 0; - for pending in pending_iterator { - if pending_size + pending.verified.encoded_size() >= MAX_TRANSACTIONS_SIZE { break; } - - match block_builder.push_extrinsic(pending.original.clone()) { - Ok(()) => { - pending_size += pending.verified.encoded_size(); + let result = self.transaction_pool.cull_and_get_pending( + &BlockId::hash(self.parent_hash), + |pending_iterator| { + let mut pending_size = 0; + for pending in pending_iterator { + if pending_size + pending.verified.encoded_size() >= MAX_TRANSACTIONS_SIZE { + break; } - Err(e) => { - trace!(target: "transaction-pool", "Invalid transaction: {}", e); - unqueue_invalid.push(pending.verified.hash().clone()); + + match block_builder.push_extrinsic(pending.original.clone()) { + Ok(()) => { + pending_size += pending.verified.encoded_size(); + } + Err(e) => { + trace!(target: "transaction-pool", "Invalid transaction: {}", e); + unqueue_invalid.push(pending.verified.hash().clone()); + } } } - } - }); + }, + ); if let Err(e) = result { warn!("Unable to get the pending set: {:?}", e); } @@ -262,15 +279,21 @@ impl bft::Proposer for Proposer } let block = block_builder.bake()?; - info!("generate a new block#{:}, producer:[{:}]", block.header.number, block_producer); - trace!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]", - block.header.number, - Hash::from(block.header.hash()), - block.header.parent_hash, - block.extrinsics.iter() - .map(|xt| format!("{}", BlakeTwo256::hash_of(xt))) - .collect::>() - .join(", ") + info!( + "generate a new block#{:}, producer:[{:}]", + block.header.number, block_producer + ); + trace!( + "Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]", + block.header.number, + Hash::from(block.header.hash()), + block.header.parent_hash, + block + .extrinsics + .iter() + .map(|xt| format!("{}", BlakeTwo256::hash_of(xt))) + .collect::>() + .join(", ") ); let substrate_block = Decode::decode(&mut block.encode().as_slice()) @@ -281,7 +304,8 @@ impl bft::Proposer for Proposer timestamp, &self.parent_hash, self.parent_number, - ).is_ok()); + ) + .is_ok()); Ok(substrate_block) } @@ -322,9 +346,9 @@ impl bft::Proposer for Proposer }; match timestamp_delay { - Some(duration) => future::Either::A(Delay::new(duration).map_err( - |e| Error::from(ErrorKind::Timer(e)), - )), + Some(duration) => future::Either::A( + Delay::new(duration).map_err(|e| Error::from(ErrorKind::Timer(e))), + ), None => future::Either::B(future::ok(())), } }; @@ -332,24 +356,35 @@ impl bft::Proposer for Proposer // refuse to vote if this block says a validator is offline that we // think isn't. let offline = proposal.noted_offline(); - if !self.offline.read().check_consistency( - &self.validators[..], - offline, - ) - { - return Box::new(futures::empty()); - } + if !self + .offline + .read() + .check_consistency(&self.validators[..], offline) + { + return Box::new(futures::empty()); + } // check block_producer match proposal.block_producer() { - Some(a) => { info!("current block#{:}, producer is [{:}]", self.parent_number + 1, a); } - None => { info!("current block#{:}, not set producer", self.parent_number + 1); } + Some(a) => { + info!( + "current block#{:}, producer is [{:}]", + self.parent_number + 1, + a + ); + } + None => { + info!( + "current block#{:}, not set producer", + self.parent_number + 1 + ); + } } - // evaluate whether the block is actually valid. // TODO: is it better to delay this until the delays are finished? - let evaluated = self.client + let evaluated = self + .client .evaluate_block(&self.parent_id, unchecked_proposal.clone()) .map_err(Into::into); @@ -367,27 +402,23 @@ impl bft::Proposer for Proposer Box::new(future) as Box<_> } - fn round_proposer(&self, round_number: usize, authorities: &[AuthorityId]) -> AuthorityId { - let offset = self.primary_index(round_number, authorities.len()); - let proposer = authorities[offset].clone(); - debug!(target: "bft", "proposer for round {} is {}", round_number, proposer); - - proposer - } - fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior)>) { + use chainx_primitives::UncheckedExtrinsic as GenericExtrinsic; + use chainx_runtime::{Call, ConsensusCall, UncheckedExtrinsic}; use rhododendron::Misbehavior as GenericMisbehavior; use runtime_primitives::bft::{MisbehaviorKind, MisbehaviorReport}; - use chainx_primitives::UncheckedExtrinsic as GenericExtrinsic; - use chainx_runtime::{Call, UncheckedExtrinsic, ConsensusCall}; let local_id = self.local_key.public().0.into(); let mut next_index = { - let cur_index = self.transaction_pool.cull_and_get_pending(&BlockId::hash(self.parent_hash), |pending| pending - .filter(|tx| tx.verified.sender == local_id) - .last() - .map(|tx| Ok(tx.verified.index())) - .unwrap_or_else(|| self.client.index(&self.parent_id, local_id)), + let cur_index = self.transaction_pool.cull_and_get_pending( + &BlockId::hash(self.parent_hash), + |pending| { + pending + .filter(|tx| tx.verified.sender == local_id) + .last() + .map(|tx| Ok(tx.verified.index())) + .unwrap_or_else(|| self.client.index(&self.parent_id, local_id)) + }, ); match cur_index { @@ -411,27 +442,55 @@ impl bft::Proposer for Proposer misbehavior: match misbehavior { GenericMisbehavior::ProposeOutOfTurn(_, _, _) => continue, GenericMisbehavior::DoublePropose(_, _, _) => continue, - GenericMisbehavior::DoublePrepare(round, (h1, s1), (h2, s2)) - => MisbehaviorKind::BftDoublePrepare(round as u32, (h1, s1.signature), (h2, s2.signature)), - GenericMisbehavior::DoubleCommit(round, (h1, s1), (h2, s2)) - => MisbehaviorKind::BftDoubleCommit(round as u32, (h1, s1.signature), (h2, s2.signature)), + GenericMisbehavior::DoublePrepare(round, (h1, s1), (h2, s2)) => { + MisbehaviorKind::BftDoublePrepare( + round as u32, + (h1, s1.signature), + (h2, s2.signature), + ) + } + GenericMisbehavior::DoubleCommit(round, (h1, s1), (h2, s2)) => { + MisbehaviorKind::BftDoubleCommit( + round as u32, + (h1, s1.signature), + (h2, s2.signature), + ) + } }, }; - let payload = (next_index, Call::Consensus(ConsensusCall::report_misbehavior(report))); + let payload = ( + next_index, + Call::Consensus(ConsensusCall::report_misbehavior(report)), + ); let signature = self.local_key.sign(&payload.encode()).into(); next_index += 1; let local_id = self.local_key.public().0.into(); let extrinsic = UncheckedExtrinsic { - signature: Some((chainx_runtime::RawAddress::Id(local_id), signature, payload.0, Era::immortal())), + signature: Some(( + chainx_runtime::RawAddress::Id(local_id), + signature, + payload.0, + Era::immortal(), + )), function: payload.1, }; - let uxt: GenericExtrinsic = Decode::decode(&mut extrinsic.encode().as_slice()).expect("Encoded extrinsic is valid"); - self.transaction_pool.submit_one(&BlockId::hash(self.parent_hash), uxt) + let uxt: GenericExtrinsic = Decode::decode(&mut extrinsic.encode().as_slice()) + .expect("Encoded extrinsic is valid"); + self.transaction_pool + .submit_one(&BlockId::hash(self.parent_hash), uxt) .expect("locally signed extrinsic is valid; qed"); } } + fn round_proposer(&self, round_number: usize, authorities: &[AuthorityId]) -> AuthorityId { + let offset = self.primary_index(round_number, authorities.len()); + let proposer = authorities[offset].clone(); + debug!(target: "bft", "proposer for round {} is {}", round_number, proposer); + + proposer + } + fn on_round_end(&self, round_number: usize, was_proposed: bool) { let primary_validator = self.primary_validator(round_number).unwrap(); @@ -441,14 +500,13 @@ impl bft::Proposer for Proposer let public = ed25519::Public::from_raw(primary_validator.0); info!( "Potential Offline Validator: {} failed to propose during assigned slot: {}", - public, - round_number, + public, round_number, ); } - self.offline.write().note_round_end( - primary_validator, was_proposed, - ); + self.offline + .write() + .note_round_end(primary_validator, was_proposed); } } diff --git a/consensus/src/offline_tracker.rs b/consensus/src/offline_tracker.rs index beb705e95df12..25f5f62dfd261 100644 --- a/consensus/src/offline_tracker.rs +++ b/consensus/src/offline_tracker.rs @@ -5,7 +5,7 @@ use chainx_primitives::AccountId; use std::collections::HashMap; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; // time before we report a validator. const REPORT_TIME: Duration = Duration::from_secs(60 * 5); @@ -50,7 +50,9 @@ pub struct OfflineTracker { impl OfflineTracker { /// Create a new tracker. pub fn new() -> Self { - OfflineTracker { observed: HashMap::new() } + OfflineTracker { + observed: HashMap::new(), + } } /// Note new consensus is starting with the given set of validators. @@ -63,7 +65,8 @@ impl OfflineTracker { /// Note that a round has ended. pub fn note_round_end(&mut self, validator: AccountId, was_online: bool) { - self.observed.entry(validator) + self.observed + .entry(validator) .or_insert_with(Observed::new) .note_round_end(was_online); } @@ -73,10 +76,12 @@ impl OfflineTracker { validators .iter() .enumerate() - .filter_map(|(i, v)| if self.is_online(v) { - None - } else { - Some(i as u32) + .filter_map(|(i, v)| { + if self.is_online(v) { + None + } else { + Some(i as u32) + } }) .collect() } @@ -96,7 +101,10 @@ impl OfflineTracker { } fn is_online(&self, v: &AccountId) -> bool { - self.observed.get(v).map(Observed::is_active).unwrap_or(true) + self.observed + .get(v) + .map(Observed::is_active) + .unwrap_or(true) } } diff --git a/consensus/src/service.rs b/consensus/src/service.rs index 47a1890c1fbcf..3bdab38b1dbd8 100644 --- a/consensus/src/service.rs +++ b/consensus/src/service.rs @@ -1,30 +1,29 @@ // Copyright 2018 Chainpool. //! Consensus service. +use std::sync::Arc; +use std::thread; /// Consensus service. A long running service that manages BFT agreement over the network. /// /// This uses a handle to an underlying thread pool to dispatch heavy work /// such as candidate verification while performing event-driven work /// on a local event loop. - use std::time::{Duration, Instant}; -use std::sync::Arc; -use std::thread; -use client::{BlockchainEvents, ChainHead, BlockBody}; use super::{Network, ProposerFactory}; use bft::{self, BftService}; +use client::{BlockBody, BlockchainEvents, ChainHead}; use ed25519; use error; +use futures::prelude::*; use tokio::executor::current_thread::TaskExecutor as LocalThreadHandle; use tokio::runtime::current_thread::Runtime as LocalRuntime; use tokio::runtime::TaskExecutor as ThreadPoolHandle; use tokio::timer::Interval; -use futures::prelude::*; -use chainx_primitives::{Block, Header}; use chainx_api::ChainXApi; +use chainx_primitives::{Block, Header}; use TransactionPool; const TIMER_DELAY_MS: Duration = Duration::from_millis(3000); @@ -33,17 +32,19 @@ const TIMER_INTERVAL_MS: Duration = Duration::from_millis(300); // spin up an instance of BFT agreement on the current thread's executor. // panics if there is no current thread executor. fn start_bft(header: Header, bft_service: Arc>) - where - F: bft::Environment + 'static, - C: bft::BlockImport + bft::Authorities + 'static, - F::Error: ::std::fmt::Debug, - >::Error: ::std::fmt::Display + Into, - >::Error: ::std::fmt::Display, +where + F: bft::Environment + 'static, + C: bft::BlockImport + bft::Authorities + 'static, + F::Error: ::std::fmt::Debug, + >::Error: ::std::fmt::Display + Into, + >::Error: ::std::fmt::Display, { let mut handle = LocalThreadHandle::current(); match bft_service.build_upon(&header) { - Ok(Some(bft_work)) => if let Err(e) = handle.spawn_local(Box::new(bft_work)) { - warn!(target: "bft", "Couldn't initialize BFT agreement: {:?}", e); + Ok(Some(bft_work)) => { + if let Err(e) = handle.spawn_local(Box::new(bft_work)) { + warn!(target: "bft", "Couldn't initialize BFT agreement: {:?}", e); + } } Ok(None) => trace!(target: "bft", "Could not start agreement on top of {}", header.hash()), Err(e) => warn!(target: "bft", "BFT agreement error: {}", e), @@ -67,14 +68,14 @@ impl Service { key: ed25519::Pair, block_delay: u64, ) -> Service - where - A: ChainXApi + Send + Sync + 'static, - C: BlockchainEvents + ChainHead + BlockBody, - C: bft::BlockImport + bft::Authorities + Send + Sync + 'static, - N: Network + Send + 'static, + where + A: ChainXApi + Send + Sync + 'static, + C: BlockchainEvents + ChainHead + BlockBody, + C: bft::BlockImport + bft::Authorities + Send + Sync + 'static, + N: Network + Send + 'static, { - use parking_lot::RwLock; use super::OfflineTracker; + use parking_lot::RwLock; let (signal, exit) = ::exit_future::signal(); let thread = thread::spawn(move || { @@ -104,10 +105,7 @@ impl Service { }) }; - let interval = Interval::new( - Instant::now() + TIMER_DELAY_MS, - TIMER_INTERVAL_MS, - ); + let interval = Interval::new(Instant::now() + TIMER_DELAY_MS, TIMER_INTERVAL_MS); let mut prev_best = match client.best_block_header() { Ok(header) => header.hash(), @@ -120,12 +118,13 @@ impl Service { } }; - let timed = - { - let c = client.clone(); - let s = bft_service.clone(); + let timed = { + let c = client.clone(); + let s = bft_service.clone(); - interval.map_err(|e| debug!(target: "bft", "Timer error: {:?}", e)).for_each(move |_| { + interval + .map_err(|e| debug!(target: "bft", "Timer error: {:?}", e)) + .for_each(move |_| { if let Ok(best_block) = c.best_block_header() { let hash = best_block.hash(); @@ -137,7 +136,7 @@ impl Service { } Ok(()) }) - }; + }; runtime.spawn(notifications); runtime.spawn(timed); diff --git a/cxrml/associations/src/lib.rs b/cxrml/associations/src/lib.rs index ee6ba64169c09..05051ff3f3f54 100644 --- a/cxrml/associations/src/lib.rs +++ b/cxrml/associations/src/lib.rs @@ -30,16 +30,16 @@ extern crate sr_primitives as runtime_primitives; // Needed for type-safe access to storage DB. #[macro_use] extern crate srml_support as runtime_support; -extern crate srml_system as system; extern crate srml_balances as balances; +extern crate srml_system as system; #[cfg(test)] mod tests; use rstd::prelude::*; +use runtime_primitives::traits::{CheckedAdd, CheckedSub, OnFinalise}; use runtime_support::dispatch::Result; use runtime_support::{StorageMap, StorageValue}; -use runtime_primitives::traits::{OnFinalise, CheckedAdd, CheckedSub}; use system::ensure_signed; @@ -48,7 +48,9 @@ pub trait OnCalcFee { } impl OnCalcFee for () { - fn on_calc_fee(_: &AccountId, _: Balance) -> Result { Ok(()) } + fn on_calc_fee(_: &AccountId, _: Balance) -> Result { + Ok(()) + } } pub trait Trait: system::Trait + balances::Trait { @@ -148,4 +150,3 @@ impl Module { Ok(()) } } - diff --git a/cxrml/associations/src/tests.rs b/cxrml/associations/src/tests.rs index 2aedef47d4b16..2837a577fe20f 100644 --- a/cxrml/associations/src/tests.rs +++ b/cxrml/associations/src/tests.rs @@ -1,4 +1,4 @@ #[test] fn it_works() { assert_eq!(2 + 2, 4); -} \ No newline at end of file +} diff --git a/cxrml/bridge/btc/src/b58.rs b/cxrml/bridge/btc/src/b58.rs index 127cea4e11f77..58c0df553546f 100644 --- a/cxrml/bridge/btc/src/b58.rs +++ b/cxrml/bridge/btc/src/b58.rs @@ -4,6 +4,7 @@ use rstd::prelude::Vec; static BASE58_CHARS: &'static [u8] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +#[rustfmt::skip] static BASE58_DIGITS: [Option; 128] = [ None, None, None, None, None, None, None, None, // 0-7 None, None, None, None, None, None, None, None, // 8-15 @@ -50,7 +51,8 @@ pub fn from(data: Vec) -> Result, &'static str> { } // Copy leading zeroes directly - let mut ret: Vec = data.iter() + let mut ret: Vec = data + .iter() .take_while(|&x| *x == BASE58_CHARS[0]) .map(|_| 0) .collect(); @@ -66,31 +68,8 @@ mod tests { fn test_from() { let s = String::from("mjKE11gjVN4JaC9U8qL6ZB5vuEBgmwik7b"); let v = &[ - 111, - 41, - 168, - 159, - 89, - 51, - 97, - 179, - 153, - 104, - 9, - 74, - 184, - 193, - 251, - 6, - 131, - 166, - 121, - 3, - 1, - 241, - 112, - 101, - 146, + 111, 41, 168, 159, 89, 51, 97, 179, 153, 104, 9, 74, 184, 193, 251, 6, 131, 166, 121, + 3, 1, 241, 112, 101, 146, ]; assert_eq!(from(s.as_bytes().to_vec()).unwrap(), v); } diff --git a/cxrml/bridge/btc/src/blockchain.rs b/cxrml/bridge/btc/src/blockchain.rs index a41bf70db2f69..42e57c610dbb3 100644 --- a/cxrml/bridge/btc/src/blockchain.rs +++ b/cxrml/bridge/btc/src/blockchain.rs @@ -1,22 +1,23 @@ +use rstd::marker::PhantomData; use rstd::prelude::*; use rstd::result::Result; -use rstd::marker::PhantomData; -use runtime_support::{StorageMap, StorageValue}; -use runtime_primitives::traits::As; -use {IrrBlock, BtcFee, NetworkId, AddressMap}; use runtime_io; +use runtime_primitives::traits::As; +use runtime_support::{StorageMap, StorageValue}; +use {AddressMap, BtcFee, IrrBlock, NetworkId}; -use primitives::hash::H256; use chain::BlockHeader; -use finacial_recordes::Symbol; -use finacial_recordes; +use financial_records; +use financial_records::Symbol; +use primitives::hash::H256; use script::Script; -use {Trait, BlockHeaderFor, BestIndex, NumberForHash, HashsForNumber, ParamsInfo, AccountMap, - Params, DepositCache, TxProposal}; - -use tx::{TxStorage, RollBack, Proposal}; +use { + AccountMap, BestIndex, BlockHeaderFor, DepositCache, HashsForNumber, NumberForHash, Params, + ParamsInfo, Trait, TxProposal, +}; +use tx::{Proposal, RollBack, TxStorage}; #[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Debug))] @@ -128,9 +129,7 @@ impl Chain { }; // remove related tx - TxStorage::::rollback_tx(&best_hash).map_err(|s| { - ChainErr::OtherErr(s) - })?; + TxStorage::::rollback_tx(&best_hash).map_err(|s| ChainErr::OtherErr(s))?; >::remove(&best_hash); // do not need to remove HashsForNumber @@ -174,8 +173,8 @@ impl Chain { match >::get(block_hash.clone()) { Some(height) => { if new_best_header.number > height + irr_block { - runtime_io::print("------finacial_recordes deposit"); - >::deposit( + runtime_io::print("------financial_records deposit"); + >::deposit( &account_id, &symbol, As::sa(amount), @@ -211,19 +210,19 @@ impl Chain { }; let address = keys::Address { kind: script_address[0].kind, - network: network, + network, hash: script_address[0].hash.clone(), }; let account_id = >::get(address); if account_id.is_some() { - >::withdrawal_finish( + >::withdrawal_finish( &account_id.unwrap(), &symbol, true, ); } } - let vec = >::get_withdraw_cache(&symbol); + let vec = >::get_withdraw_cache(&symbol); if vec.is_some() { let mut address_vec = Vec::new(); for (account_id, balance) in vec.unwrap() { @@ -331,7 +330,7 @@ impl Chain { None }) .collect(), - block_number: block_number, + block_number, }; if block_number > best_index.number { return Ok(BlockOrigin::SideChainBecomingCanonChain(origin)); diff --git a/cxrml/bridge/btc/src/lib.rs b/cxrml/bridge/btc/src/lib.rs index c950bcdfe9da1..a1cd39651eed7 100644 --- a/cxrml/bridge/btc/src/lib.rs +++ b/cxrml/bridge/btc/src/lib.rs @@ -17,11 +17,11 @@ extern crate parity_codec as codec; // for substrate // Needed for the set of mock primitives used in our tests. #[cfg(feature = "std")] -extern crate substrate_primitives; +extern crate base58; #[cfg(feature = "std")] extern crate rustc_hex as hex; #[cfg(feature = "std")] -extern crate base58; +extern crate substrate_primitives; // for substrate runtime // map!, vec! marco. @@ -33,57 +33,57 @@ extern crate sr_primitives as runtime_primitives; // Needed for type-safe access to storage DB. #[macro_use] extern crate srml_support as runtime_support; -extern crate srml_system as system; -extern crate srml_balances as balances; -extern crate srml_timestamp as timestamp; -#[cfg(test)] -extern crate cxrml_system as cxsystem; #[cfg(test)] extern crate cxrml_associations as associations; +extern crate cxrml_funds_financialrecords as financial_records; #[cfg(test)] extern crate cxrml_support as cxsupport; +#[cfg(test)] +extern crate cxrml_system as cxsystem; extern crate cxrml_tokenbalances as tokenbalances; -extern crate cxrml_funds_financialrecords as finacial_recordes; +extern crate srml_balances as balances; +extern crate srml_system as system; +extern crate srml_timestamp as timestamp; // bitcoin-rust -extern crate serialization as ser; -extern crate primitives; -extern crate bitcrypto; extern crate bit_vec; -extern crate script; -extern crate merkle; +extern crate bitcrypto; extern crate chain; extern crate keys; +extern crate merkle; +extern crate primitives; +extern crate script; +extern crate serialization as ser; #[cfg(test)] mod tests; -mod verify_header; +mod b58; mod blockchain; mod tx; -mod b58; +mod verify_header; +use chain::{BlockHeader, Transaction as BTCTransaction}; use codec::Decode; +use primitives::compact::Compact; +use primitives::hash::H256; use rstd::prelude::*; use rstd::result::Result as StdResult; -use runtime_support::dispatch::{Result, Parameter}; -use runtime_support::{StorageValue, StorageMap}; use runtime_primitives::traits::OnFinalise; -use system::ensure_signed; +use runtime_support::dispatch::{Parameter, Result}; +use runtime_support::{StorageMap, StorageValue}; use ser::deserialize; -use chain::{BlockHeader, Transaction as BTCTransaction}; -use primitives::hash::H256; -use primitives::compact::Compact; +use system::ensure_signed; +pub use blockchain::BestHeader; use blockchain::Chain; -use tx::{UTXO, validate_transaction, handle_input, handle_output, handle_proposal}; use keys::DisplayLayout; -pub use tx::RelayTx; -pub use blockchain::BestHeader; pub use keys::{Address, Error as AddressError}; +pub use tx::RelayTx; +use tx::{handle_input, handle_output, handle_proposal, validate_transaction, UTXO}; -pub trait Trait -: system::Trait + balances::Trait + timestamp::Trait + finacial_recordes::Trait +pub trait Trait: + system::Trait + balances::Trait + timestamp::Trait + financial_records::Trait { type Event: From> + Into<::Event>; } @@ -148,13 +148,13 @@ impl Params { retargeting_factor: u32, ) -> Params { Params { - max_bits: max_bits, - block_max_future: block_max_future, - max_fork_route_preset: max_fork_route_preset, + max_bits, + block_max_future, + max_fork_route_preset, - target_timespan_seconds: target_timespan_seconds, - target_spacing_seconds: target_spacing_seconds, - retargeting_factor: retargeting_factor, + target_timespan_seconds, + target_spacing_seconds, + retargeting_factor, double_spacing_seconds: target_spacing_seconds / 10, @@ -274,9 +274,8 @@ impl Module { pub fn push_header(origin: T::Origin, header: Vec) -> Result { let from = ensure_signed(origin)?; // parse header - let header: BlockHeader = deserialize(header.as_slice()).map_err( - |_| "can't deserialize the header vec", - )?; + let header: BlockHeader = + deserialize(header.as_slice()).map_err(|_| "can't deserialize the header vec")?; Self::process_header(header, &from)?; Ok(()) } @@ -284,9 +283,7 @@ impl Module { pub fn push_transaction(origin: T::Origin, tx: Vec) -> Result { let from = ensure_signed(origin)?; - let tx: RelayTx = Decode::decode(&mut tx.as_slice()).ok_or( - "parse RelayTx err", - )?; + let tx: RelayTx = Decode::decode(&mut tx.as_slice()).ok_or("parse RelayTx err")?; Self::process_tx(tx, &from)?; Ok(()) } @@ -294,15 +291,13 @@ impl Module { pub fn propose_transaction(origin: T::Origin, tx: Vec) -> Result { let from = ensure_signed(origin)?; - let tx: BTCTransaction = Decode::decode(&mut tx.as_slice()).ok_or( - "parse transaction err", - )?; + let tx: BTCTransaction = + Decode::decode(&mut tx.as_slice()).ok_or("parse transaction err")?; Self::process_btc_tx(tx, &from)?; Ok(()) } } - impl Module { pub fn verify_btc_address(data: &[u8]) -> StdResult { Address::from_layout(data) @@ -316,23 +311,22 @@ impl Module { // orphan block check if >::exists(&header.previous_header_hash) == false { - return Err( - "can't find the prev header in ChainX, may be a orphan block", - ); + return Err("can't find the prev header in ChainX, may be a orphan block"); } // check { - let c = verify_header::HeaderVerifier::new::(&header).map_err( - |e| e.info(), - )?; + let c = verify_header::HeaderVerifier::new::(&header).map_err(|e| e.info())?; c.check::()?; } // insert valid header into storage - >::insert(header.hash(), ( - header.clone(), - who.clone(), - >::block_number(), - )); + >::insert( + header.hash(), + ( + header.clone(), + who.clone(), + >::block_number(), + ), + ); >::insert_best_header(header).map_err(|e| e.info())?; diff --git a/cxrml/bridge/btc/src/tests.rs b/cxrml/bridge/btc/src/tests.rs index 6806c6f377eb4..3f3248ba3c473 100644 --- a/cxrml/bridge/btc/src/tests.rs +++ b/cxrml/bridge/btc/src/tests.rs @@ -1,16 +1,15 @@ extern crate srml_consensus as consensus; -use substrate_primitives::{H256 as S_H256, Blake2Hasher}; +use substrate_primitives::{Blake2Hasher, H256 as S_H256}; -use runtime_primitives::BuildStorage; -use runtime_primitives::traits::BlakeTwo256; -use runtime_primitives::testing::{Digest, DigestItem, Header}; +use self::base58::FromBase58; +use super::*; use runtime_io; use runtime_io::with_externalities; -use self::base58::FromBase58; +use runtime_primitives::testing::{Digest, DigestItem, Header}; +use runtime_primitives::traits::BlakeTwo256; +use runtime_primitives::BuildStorage; use runtime_support::StorageValue; -use super::*; - impl_outer_origin! { pub enum Origin for Test {} @@ -21,7 +20,6 @@ pub type AccountId = u64; #[derive(Clone, Eq, PartialEq)] pub struct Test; - impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -71,7 +69,7 @@ impl tokenbalances::Trait for Test { type Event = (); } -impl finacial_recordes::Trait for Test { +impl financial_records::Trait for Test { type Event = (); } @@ -112,7 +110,7 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { network_id: 1, utxo_max_index: 0, irr_block: 6, - btc_fee: 10, + btc_fee: 10, accounts_max_index: 0, receive_address: keys::Address::from_layout(&"mjKE11gjVN4JaC9U8qL6ZB5vuEBgmwik7b".from_base58().unwrap()).unwrap(), redeem_script: b"52210257aff1270e3163aaae9d972b3d09a2385e0d4877501dbeca3ee045f8de00d21c2103fd58c689594b87bbe20a9a00091d074dc0d9f49a988a7ad4c2575adeda1b507c2102bb2a5aa53ba7c0d77bdd86bb9553f77dd0971d3a6bb6ad609787aa76eb17b6b653ae".to_vec(), @@ -156,7 +154,7 @@ pub fn new_test_ext_err_genesisblock() -> runtime_io::TestExternalities (Vec, Vec) { (vec![b0.clone(), b1, b2, b3, b4], vec![b0, b1_fork, b2_fork]) } - fn current_time() -> u64 { use std::time; time::SystemTime::now() @@ -397,7 +394,6 @@ fn test() { }) } - #[test] fn test_init_blocks() { let (c1, _) = generate_blocks(); @@ -616,7 +612,6 @@ fn test_call() { }) } - pub fn new_test_ext2() -> runtime_io::TestExternalities { let mut r = system::GenesisConfig::::default() .build_storage() diff --git a/cxrml/bridge/btc/src/tx/mod.rs b/cxrml/bridge/btc/src/tx/mod.rs index 64fa74c87e8ed..38087afbde445 100644 --- a/cxrml/bridge/btc/src/tx/mod.rs +++ b/cxrml/bridge/btc/src/tx/mod.rs @@ -1,27 +1,31 @@ // Copyright 2018 Chainpool -use rstd::prelude::*; +use codec::Decode; use rstd::marker::PhantomData; +use rstd::prelude::*; use rstd::result::Result as StdResult; -use codec::Decode; use runtime_support::dispatch::Result; use runtime_support::{StorageMap, StorageValue}; -use primitives::hash::H256; +pub use self::proposal::{handle_proposal, Proposal}; +use super::{ + AccountMap, AccountsMaxIndex, AccountsSet, AddressMap, BlockHeaderFor, BlockTxids, CandidateTx, + DepositCache, NetworkId, NumberForHash, ReceiveAddress, RedeemScript, Trait, TxProposal, TxSet, + TxType, UTXOMaxIndex, UTXOSet, +}; +use b58::from; +use chain::{OutPoint, Transaction, TransactionInput, TransactionOutput}; +use keys; +use merkle::{parse_partial_merkle_tree, PartialMerkleTree}; use primitives::bytes::Bytes; -use chain::{Transaction, OutPoint, TransactionOutput, TransactionInput}; -use merkle::{PartialMerkleTree, parse_partial_merkle_tree}; +use primitives::hash::H256; use runtime_io; use script::script::Script; -use script::{SignatureChecker, builder, TransactionSignatureChecker, TransactionInputSigner, - SignatureVersion}; -use keys; -use b58::from; -use super::{TxType, Trait, ReceiveAddress, NetworkId, RedeemScript, AddressMap, AccountMap, - UTXOSet, TxSet, BlockTxids, BlockHeaderFor, NumberForHash, UTXOMaxIndex, - AccountsMaxIndex, AccountsSet, TxProposal, CandidateTx, DepositCache}; -pub use self::proposal::{handle_proposal, Proposal}; +use script::{ + builder, SignatureChecker, SignatureVersion, TransactionInputSigner, + TransactionSignatureChecker, +}; use system; mod proposal; @@ -123,7 +127,6 @@ impl UTXOStorage { } } - pub trait RollBack { fn rollback_tx(header: &H256) -> Result; } @@ -171,14 +174,16 @@ impl RollBack for TxStorage { let (_, _, tx_type, _, tx) = >::get(txid).unwrap(); match tx_type { TxType::Withdraw => { - let out_point_set = tx.inputs + let out_point_set = tx + .inputs .iter() .map(|input| input.previous_output.clone()) .collect(); >::update_from_outpoint(out_point_set, false); let mut out_point_set2: Vec = Vec::new(); let mut index = 0; - let _ = tx.outputs + let _ = tx + .outputs .iter() .map(|output| { if is_key(&output.script_pubkey, &receive_address) { @@ -291,8 +296,8 @@ fn compare_transaction(tx1: &Transaction, tx2: &Transaction) -> bool { if tx1.version == tx2.version && tx1.outputs == tx2.outputs && tx1.lock_time == tx2.lock_time { if tx1.inputs.len() == tx2.inputs.len() { for i in 0..tx1.inputs.len() { - if tx1.inputs[i].previous_output == tx2.inputs[i].previous_output && - tx1.inputs[i].sequence == tx2.inputs[i].sequence + if tx1.inputs[i].previous_output == tx2.inputs[i].previous_output + && tx1.inputs[i].sequence == tx2.inputs[i].sequence { return true; } @@ -318,7 +323,8 @@ pub fn handle_input( // To do: handle_input error not expect runtime_io::print("------handle_input error not expect-----"); } - let out_point_set = tx.inputs + let out_point_set = tx + .inputs .iter() .map(|input| input.previous_output.clone()) .collect(); @@ -326,7 +332,8 @@ pub fn handle_input( let mut new_utxo: Vec = Vec::new(); let mut index = 0; - let _ = tx.outputs + let _ = tx + .outputs .iter() .map(|output| { if is_key(&output.script_pubkey, &receive_address) { @@ -463,7 +470,7 @@ pub fn handle_output( TxType::RegisterDeposit, total_balance, ); - tx_type = TxType::RegisterDeposit; + tx_type = TxType::RegisterDeposit; } else { >::store_tx( tx, @@ -473,22 +480,15 @@ pub fn handle_output( TxType::Deposit, total_balance, ); - tx_type = TxType::Deposit; + tx_type = TxType::Deposit; }; >::add(new_utxos.clone()); - } if new_account { runtime_io::print("----new account-------"); let time = >::block_number(); let chainxaddr = >::get(send_address.clone()).unwrap(); - let account = ( - tx.hash(), - send_address.clone(), - chainxaddr, - time, - tx_type, - ); + let account = (tx.hash(), send_address.clone(), chainxaddr, time, tx_type); >::add(account); runtime_io::print("------insert new account in AccountsMap-----"); } diff --git a/cxrml/bridge/btc/src/tx/proposal.rs b/cxrml/bridge/btc/src/tx/proposal.rs index db7164fc98f93..7fbc2cc7393f0 100644 --- a/cxrml/bridge/btc/src/tx/proposal.rs +++ b/cxrml/bridge/btc/src/tx/proposal.rs @@ -1,15 +1,16 @@ // Copyright 2018 Chainpool -use super::{Trait, Transaction, TransactionOutput, TransactionInput, UTXOStorage, OutPoint, - TxStorage, Bytes, ReceiveAddress, RedeemScript, Result, Script, TxProposal, - CandidateTx}; use super::builder::Builder; -use super::keys::{Address, Type, Public}; -use super::{PhantomData, Vec}; +use super::keys::{Address, Public, Type}; use super::StorageValue; -use super::{SignatureChecker, TransactionSignatureChecker, TransactionInputSigner, - SignatureVersion}; - +use super::{ + Bytes, CandidateTx, OutPoint, ReceiveAddress, RedeemScript, Result, Script, Trait, Transaction, + TransactionInput, TransactionOutput, TxProposal, TxStorage, UTXOStorage, +}; +use super::{PhantomData, Vec}; +use super::{ + SignatureChecker, SignatureVersion, TransactionInputSigner, TransactionSignatureChecker, +}; fn verify_sign(sign: &Bytes, pubkey: &Bytes, tx: &Transaction, output: &TransactionOutput) -> bool { let tx_signer: TransactionInputSigner = tx.clone().into(); @@ -100,9 +101,7 @@ pub struct Proposal(PhantomData); impl Proposal { pub fn create_proposal(address: Vec<(Address, u64)>, fee: u64) -> Result { if None != >::get() { - return Err( - "There are candidates to reflect that the transaction is being processed", - ); + return Err("There are candidates to reflect that the transaction is being processed"); } let mut tx = Transaction { diff --git a/cxrml/bridge/btc/src/verify_header.rs b/cxrml/bridge/btc/src/verify_header.rs index 51307f9ac5e96..7ce19b85bfb36 100644 --- a/cxrml/bridge/btc/src/verify_header.rs +++ b/cxrml/bridge/btc/src/verify_header.rs @@ -3,17 +3,20 @@ use rstd::cmp; use rstd::result::Result as StdResult; +use chain::BlockHeader; use primitives::compact::Compact; use primitives::hash::H256; use primitives::U256; -use chain::BlockHeader; -use timestamp; +use super::{ + BlockHeaderFor, GenesisInfo, HashsForNumber, NetworkId, NumberForHash, Params, ParamsInfo, + Trait, +}; +use blockchain::ChainErr; +use runtime_primitives::traits::As; use runtime_support::dispatch::Result; use runtime_support::{StorageMap, StorageValue}; -use runtime_primitives::traits::As; -use super::{Trait, NumberForHash, HashsForNumber, BlockHeaderFor, ParamsInfo, NetworkId, Params, GenesisInfo}; -use blockchain::ChainErr; +use timestamp; pub struct HeaderVerifier<'a> { pub work: HeaderWork<'a>, @@ -49,7 +52,6 @@ impl<'a> HeaderVerifier<'a> { let now: T::Moment = >::get(); let current_time: u32 = now.as_() as u32; - Ok(HeaderVerifier { work: HeaderWork::new(header, this_height), proof_of_work: HeaderProofOfWork::new(header), @@ -76,10 +78,7 @@ pub struct HeaderWork<'a> { impl<'a> HeaderWork<'a> { fn new(header: &'a BlockHeader, height: u32) -> Self { - HeaderWork { - header: header, - height: height, - } + HeaderWork { header, height } } fn check(&self, p: &Params) -> Result { @@ -145,8 +144,8 @@ pub fn work_required_retarget( let mut retarget: U256 = last_bits.into(); let maximum: U256 = params.max_bits().into(); - retarget = retarget * - U256::from(retarget_timespan( + retarget = retarget + * U256::from(retarget_timespan( retarget_timestamp, last_timestamp, params, @@ -178,7 +177,7 @@ pub struct HeaderProofOfWork<'a> { impl<'a> HeaderProofOfWork<'a> { fn new(header: &'a BlockHeader) -> Self { - HeaderProofOfWork { header: header } + HeaderProofOfWork { header } } fn check(&self, p: &Params) -> Result { @@ -190,7 +189,6 @@ impl<'a> HeaderProofOfWork<'a> { } } - pub fn is_valid_proof_of_work(max_work_bits: Compact, bits: Compact, hash: &H256) -> bool { let maximum = match max_work_bits.to_u256() { Ok(max) => max, @@ -215,9 +213,9 @@ pub struct HeaderTimestamp<'a> { impl<'a> HeaderTimestamp<'a> { fn new(header: &'a BlockHeader, current_time: u32, max_future: u32) -> Self { HeaderTimestamp { - header: header, - current_time: current_time, - max_future: max_future, + header, + current_time, + max_future, } } diff --git a/cxrml/example/src/lib.rs b/cxrml/example/src/lib.rs index eef869bcfd9b1..25798425923c2 100644 --- a/cxrml/example/src/lib.rs +++ b/cxrml/example/src/lib.rs @@ -23,27 +23,26 @@ extern crate sr_primitives as primitives; // for substrate runtime module lib #[macro_use] extern crate srml_support as support; -extern crate srml_system as system; extern crate srml_balances as balances; +extern crate srml_system as system; // for chainx runtime module lib extern crate cxrml_support as cxsupport; -use rstd::prelude::*; use codec::Codec; -use support::StorageValue; +use primitives::traits::{As, OnFinalise, SimpleArithmetic}; +use rstd::prelude::*; use support::dispatch::Result; -use primitives::traits::{SimpleArithmetic, As, OnFinalise}; +use support::StorageValue; //use system::ensure_signed; -use cxsupport::storage::linked_node::{Node, NodeT, NodeIndex, LinkedNodeCollection, - MultiNodeIndex, MultiNodeIndexT, +use cxsupport::storage::linked_node::{ + LinkedNodeCollection, MultiNodeIndex, MultiNodeIndexT, Node, NodeIndex, NodeT, }; use cxsupport::storage::btree_map::CodecBTreeMap; - pub trait Trait: balances::Trait { /// The overarching event type. type Event: From> + Into<::Event>; @@ -54,7 +53,10 @@ decl_module! { } decl_event!( - pub enum Event where B = ::AccountId { + pub enum Event + where + B = ::AccountId, + { // Just a normal `enum`, here's a dummy event to ensure it compiles. /// Dummy event, just here so there's a generic type that's used. Test(B), @@ -65,7 +67,9 @@ decl_event!( /// must be Ord and Clone #[derive(Decode, Encode, Eq, PartialEq, Clone, Default)] pub struct Order - where AccountId: Codec + Clone + Ord + Default, Balance: Codec + SimpleArithmetic + Ord + As + Clone + Copy + Default +where + AccountId: Codec + Clone + Ord + Default, + Balance: Codec + SimpleArithmetic + Ord + As + Clone + Copy + Default, { pub id: AccountId, pub data: Balance, @@ -73,7 +77,9 @@ pub struct Order /// 1. impl NodeT for this Data struct, and point the which is index impl NodeT for Order - where AccountId: Codec + Clone + Ord + Default, Balance: Codec + SimpleArithmetic + Ord + As + Clone + Copy + Default +where + AccountId: Codec + Clone + Ord + Default, + Balance: Codec + SimpleArithmetic + Ord + As + Clone + Copy + Default, { type Index = AccountId; @@ -95,7 +101,7 @@ impl LinkedNodeCollection for LinkedNodes { /// 2.2 create a Phantom struct and let LinkedNodeCollection impl it, notice this LinkedNodeCollection's associate type /// if use Option Node, all type must be Option mode #[allow(unused)] -struct LinkedOptionNodes (support::storage::generator::PhantomData); +struct LinkedOptionNodes(support::storage::generator::PhantomData); impl LinkedNodeCollection for LinkedOptionNodes { type Header = OpNodeHeader; @@ -104,7 +110,7 @@ impl LinkedNodeCollection for LinkedOptionNodes { } #[allow(unused)] -struct LinkedOptionMultiKey (support::storage::generator::PhantomData); +struct LinkedOptionMultiKey(support::storage::generator::PhantomData); impl LinkedNodeCollection for LinkedOptionMultiKey { type Header = MultiHeader; @@ -186,13 +192,13 @@ impl Module { mod tests { use super::*; - use runtime_io::with_externalities; - use substrate_primitives::{H256, Blake2Hasher}; - use primitives::BuildStorage; - use primitives::traits::BlakeTwo256; use primitives::testing::{Digest, DigestItem, Header}; + use primitives::traits::BlakeTwo256; + use primitives::BuildStorage; + use runtime_io::with_externalities; + use substrate_primitives::{Blake2Hasher, H256}; - use support::{StorageValue, StorageMap}; + use support::{StorageMap, StorageValue}; // use support::generator::StorageMap; use cxsupport::storage::linked_node::Node; @@ -228,16 +234,22 @@ mod tests { } pub fn new_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 500, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 500, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); r.into() } @@ -354,7 +366,9 @@ mod tests { assert_eq!(OpNodeMap::::get(0).unwrap().next(), None); // 1 0 - node0.add_option_node_before::>(node1).unwrap(); + node0 + .add_option_node_before::>(node1) + .unwrap(); assert_eq!(OpNodeHeader::::get().unwrap().index(), 1); assert_eq!(OpNodeTail::::get().unwrap().index(), 0); assert_eq!(OpNodeMap::::get(0).unwrap().prev(), Some(1)); @@ -363,7 +377,9 @@ mod tests { assert_eq!(OpNodeMap::::get(1).unwrap().next(), Some(0)); // 1 0 2 - node0.add_option_node_after::>(node2).unwrap(); + node0 + .add_option_node_after::>(node2) + .unwrap(); assert_eq!(OpNodeHeader::::get().unwrap().index(), 1); assert_eq!(OpNodeTail::::get().unwrap().index(), 2); assert_eq!(OpNodeMap::::get(0).unwrap().prev(), Some(1)); @@ -373,7 +389,9 @@ mod tests { // 1 0 3 2 let mut node2 = OpNodeMap::::get(2).unwrap(); - node2.add_option_node_before::>(node3).unwrap(); + node2 + .add_option_node_before::>(node3) + .unwrap(); assert_eq!(OpNodeHeader::::get().unwrap().index(), 1); assert_eq!(OpNodeTail::::get().unwrap().index(), 2); assert_eq!(OpNodeMap::::get(0).unwrap().prev(), Some(1)); @@ -385,7 +403,9 @@ mod tests { // 1 4 0 3 2 let mut node1 = OpNodeMap::::get(1).unwrap(); - node1.add_option_node_after::>(node4).unwrap(); + node1 + .add_option_node_after::>(node4) + .unwrap(); assert_eq!(OpNodeHeader::::get().unwrap().index(), 1); assert_eq!(OpNodeTail::::get().unwrap().index(), 2); assert_eq!(OpNodeMap::::get(0).unwrap().prev(), Some(4)); @@ -398,19 +418,25 @@ mod tests { // remove_node // (1) 4 0 3 2 let mut node1 = OpNodeMap::::get(1).unwrap(); - node1.remove_option_node::>().unwrap(); + node1 + .remove_option_node::>() + .unwrap(); assert_eq!(OpNodeHeader::::get().unwrap().index(), 4); assert_eq!(OpNodeMap::::get(4).unwrap().prev(), None); // 4 0 3 (2) let mut node2 = OpNodeMap::::get(2).unwrap(); - node2.remove_option_node::>().unwrap(); + node2 + .remove_option_node::>() + .unwrap(); assert_eq!(OpNodeTail::::get().unwrap().index(), 3); assert_eq!(OpNodeMap::::get(3).unwrap().next(), None); // 4 (0) 3 let mut node0 = OpNodeMap::::get(0).unwrap(); - node0.remove_option_node::>().unwrap(); + node0 + .remove_option_node::>() + .unwrap(); assert_eq!(OpNodeHeader::::get().unwrap().index(), 4); assert_eq!(OpNodeMap::::get(4).unwrap().next(), Some(3)); assert_eq!(OpNodeTail::::get().unwrap().index(), 3); @@ -418,14 +444,18 @@ mod tests { // (4) 3 let mut node4 = OpNodeMap::::get(4).unwrap(); - node4.remove_option_node::>().unwrap(); + node4 + .remove_option_node::>() + .unwrap(); assert_eq!(OpNodeHeader::::get().unwrap().index(), 3); assert_eq!(OpNodeTail::::get().unwrap().index(), 3); assert_eq!(OpNodeMap::::get(3).unwrap().next(), None); // (3) let mut node3 = OpNodeMap::::get(3).unwrap(); - node3.remove_option_node::>().unwrap(); + node3 + .remove_option_node::>() + .unwrap(); assert_eq!(OpNodeHeader::::exists(), false); assert_eq!(OpNodeTail::::exists(), false); }) @@ -446,10 +476,16 @@ mod tests { // 4 node4.init_storage_withkey::, u32>(99); // 2 0 1 - node0.add_option_node_after_withkey::, u32>(node1, 10).unwrap(); - node0.add_option_node_before_withkey::, u32>(node2, 10).unwrap(); + node0 + .add_option_node_after_withkey::, u32>(node1, 10) + .unwrap(); + node0 + .add_option_node_before_withkey::, u32>(node2, 10) + .unwrap(); - node4.add_option_node_before_withkey::, u32>(node3, 99).unwrap(); + node4 + .add_option_node_before_withkey::, u32>(node3, 99) + .unwrap(); // test key 10 let test_v = [2_u64, 0, 1]; @@ -460,8 +496,12 @@ mod tests { v.push(node.index()); if let Some(next) = node.next() { index = next; - } else { break; } - } else { break; } + } else { + break; + } + } else { + break; + } } assert_eq!(v.as_slice(), test_v); @@ -473,8 +513,12 @@ mod tests { v.push(node.index()); if let Some(next) = node.next() { index = next; - } else { break; } - } else { break; } + } else { + break; + } + } else { + break; + } } assert_eq!(v.as_slice(), test_v); @@ -487,19 +531,28 @@ mod tests { // 3 (4) let mut node4 = Module::::op_node_map2(index).unwrap(); assert_eq!(node4.index(), 4); - node4.remove_option_node_withkey::, u32>(99).unwrap(); + node4 + .remove_option_node_withkey::, u32>(99) + .unwrap(); let node3 = Module::::op_node_map2(3).unwrap(); assert_eq!(node3.prev(), None); assert_eq!(node3.next(), None); - assert_eq!(Module::::multi_header(99).unwrap().index(), node3.index()); - assert_eq!(Module::::multi_tail(99).unwrap().index(), node3.index()); - + assert_eq!( + Module::::multi_header(99).unwrap().index(), + node3.index() + ); + assert_eq!( + Module::::multi_tail(99).unwrap().index(), + node3.index() + ); let index = Module::::multi_header(99).unwrap().index(); assert_eq!(node3.index(), 3); let mut node3 = Module::::op_node_map2(index).unwrap(); assert_eq!(node3.index(), 3); - node3.remove_option_node_withkey::, u32>(99).unwrap(); + node3 + .remove_option_node_withkey::, u32>(99) + .unwrap(); assert_eq!(node3.prev(), None); assert_eq!(node3.next(), None); assert_eq!(Module::::multi_header(99) == None, true); diff --git a/cxrml/exchange/matchorder/src/lib.rs b/cxrml/exchange/matchorder/src/lib.rs index 6dde0b520f48f..e7583d99b7333 100644 --- a/cxrml/exchange/matchorder/src/lib.rs +++ b/cxrml/exchange/matchorder/src/lib.rs @@ -42,12 +42,12 @@ extern crate srml_system as system; // for chainx runtime module lib #[cfg(test)] -extern crate cxrml_system as cxsystem; -#[cfg(test)] extern crate cxrml_associations as associations; +extern crate cxrml_exchange_pendingorders as pendingorders; extern crate cxrml_support as cxsupport; +#[cfg(test)] +extern crate cxrml_system as cxsystem; extern crate cxrml_tokenbalances as tokenbalances; -extern crate cxrml_exchange_pendingorders as pendingorders; #[cfg(test)] mod tests; diff --git a/cxrml/exchange/matchorder/src/tests.rs b/cxrml/exchange/matchorder/src/tests.rs index a152facd1f962..99cadc31700e3 100644 --- a/cxrml/exchange/matchorder/src/tests.rs +++ b/cxrml/exchange/matchorder/src/tests.rs @@ -11,7 +11,7 @@ use runtime_primitives::BuildStorage; use super::*; use pendingorders::{Order, OrderPair, OrderStatus, OrderType}; use std::str; -use tokenbalances::{DescString, SymbolString, Token, ReservedType}; +use tokenbalances::{DescString, ReservedType, SymbolString, Token}; impl_outer_origin! { pub enum Origin for Test {} @@ -51,9 +51,9 @@ impl associations::Trait for Test { impl cxsupport::Trait for Test {} impl pendingorders::Trait for Test { - type Event = (); type Amount = u128; type Price = u128; + type Event = (); } // define tokenbalances module type @@ -82,7 +82,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { transfer_fee: 0, creation_fee: 0, reclaim_rebate: 0, - }.build_storage() + } + .build_storage() .unwrap(), ); @@ -91,7 +92,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { chainx_precision: 8, token_list: vec![], transfer_token_fee: 10, - }.build_storage() + } + .build_storage() .unwrap(), ); @@ -100,7 +102,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { order_fee: 10, pair_list: vec![], max_command_id: 0, - }.build_storage() + } + .build_storage() .unwrap(), ); @@ -163,18 +166,30 @@ fn test_match_part() { let buy = OrderType::Buy; let a_order = PendingOrders::put_order(Some(a).into(), p1.clone(), buy, 100, 5); assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 500); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 500 + ); //挂卖单 let sell = OrderType::Sell; let b_order = PendingOrders::put_order(Some(b).into(), p1.clone(), sell, 50, 5); assert_eq!(b_order, Ok(())); assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 950); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 50); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 50 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); print_bid(p1.clone(), OrderType::Sell); print_bid(p1.clone(), OrderType::Buy); @@ -183,17 +198,29 @@ fn test_match_part() { //1000+250 assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 1050); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); //1000-500 assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); //500-250 - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 250); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 250 + ); //1000-50 assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 950); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1250); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); print_bid(p1.clone(), OrderType::Sell); print_bid(p1.clone(), OrderType::Buy); @@ -233,18 +260,30 @@ fn test_match_all() { let buy = OrderType::Buy; let a_order = PendingOrders::put_order(Some(a).into(), p1.clone(), buy, 100, 5); assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 500); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 500 + ); //挂卖单 let sell = OrderType::Sell; let b_order = PendingOrders::put_order(Some(b).into(), p1.clone(), sell, 100, 5); assert_eq!(b_order, Ok(())); assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 900); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 100); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 100 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); print_bid(p1.clone(), OrderType::Sell); print_bid(p1.clone(), OrderType::Buy); @@ -253,17 +292,29 @@ fn test_match_all() { //1000+250 assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 1100); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); //1000-500 assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); //500-250 - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); //1000-50 assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 900); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1500); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); print_bid(p1.clone(), OrderType::Sell); print_bid(p1.clone(), OrderType::Buy); @@ -308,9 +359,15 @@ fn test_match_no() { let a_order = PendingOrders::put_order(Some(a).into(), p1.clone(), buy, 100, 7); assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 900); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 100); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 100 + ); assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 500); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 500 + ); //挂卖单 let sell = OrderType::Sell; @@ -321,18 +378,30 @@ fn test_match_no() { let b_order = PendingOrders::put_order(Some(b).into(), p1.clone(), sell, 50, 7); assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 900); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 100); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 100 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); //取消挂单 let cancel = PendingOrders::cancel_order(Some(b).into(), p1.clone(), 2); assert_eq!(Ok(()), cancel); assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 950); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 50); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 50 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); >::on_finalise(1); diff --git a/cxrml/exchange/pendingorders/src/lib.rs b/cxrml/exchange/pendingorders/src/lib.rs index 5e12d85af9376..5673860d54ca9 100644 --- a/cxrml/exchange/pendingorders/src/lib.rs +++ b/cxrml/exchange/pendingorders/src/lib.rs @@ -42,10 +42,10 @@ extern crate srml_system as system; // for chainx runtime module lib #[cfg(test)] -extern crate cxrml_system as cxsystem; -#[cfg(test)] extern crate cxrml_associations as associations; extern crate cxrml_support as cxsupport; +#[cfg(test)] +extern crate cxrml_system as cxsystem; extern crate cxrml_tokenbalances as tokenbalances; //extern crate cxrml_exchange_matchorder as matchorder; @@ -59,33 +59,33 @@ use runtime_primitives::traits::{As, Member, SimpleArithmetic, Zero}; use runtime_support::dispatch::Result; use runtime_support::{Parameter, StorageMap, StorageValue}; use system::ensure_signed; -use tokenbalances::{Symbol, ReservedType}; +use tokenbalances::{ReservedType, Symbol}; pub trait Trait: tokenbalances::Trait { type Amount: Parameter - + Member - + Codec - + SimpleArithmetic - + As - + As - + As - + As - + As - + Copy - + Zero - + Default; + + Member + + Codec + + SimpleArithmetic + + As + + As + + As + + As + + As + + Copy + + Zero + + Default; type Price: Parameter - + Member - + Codec - + SimpleArithmetic - + As - + As - + As - + As - + As - + Copy - + Zero - + Default; + + Member + + Codec + + SimpleArithmetic + + As + + As + + As + + As + + As + + Copy + + Zero + + Default; /// The overarching event type. type Event: From> + Into<::Event>; } @@ -188,10 +188,20 @@ impl Module { price: T::Price, ) -> Result { let transactor = ensure_signed(origin)?; - info!("put_order:{:?} {:?} {:?} {:?} {:?} ", transactor.clone(), pair.clone(), ordertype, amount, price); + info!( + "put_order:{:?} {:?} {:?} {:?} {:?} ", + transactor.clone(), + pair.clone(), + ordertype, + amount, + price + ); //判断交易对是否存在 if let Err(_) = Self::is_valid_pair(&pair) { - error!("put_order: not a existed pair in orderpair list {:?}", pair.clone()); + error!( + "put_order: not a existed pair in orderpair list {:?}", + pair.clone() + ); return Err("not a existed pair in orderpair list"); } //判定 数量和价格 @@ -215,24 +225,28 @@ impl Module { sender.clone(), pair.second.clone(), )) < sum - { - error!("put_order: transactor's free token balance too low, can't put buy order"); - return Err("transactor's free token balance too low, can't put buy order"); - } + { + error!("put_order: transactor's free token balance too low, can't put buy order"); + return Err("transactor's free token balance too low, can't put buy order"); + } // 锁定用户资产 - if let Err(msg) = >::reserve(sender, &pair.second, sum, ReservedType::Exchange) - { - error!("put_order: buy tokenbalance reserve:{:?}", msg); - return Err(msg); - } + if let Err(msg) = >::reserve( + sender, + &pair.second, + sum, + ReservedType::Exchange, + ) { + error!("put_order: buy tokenbalance reserve:{:?}", msg); + return Err(msg); + } } OrderType::Sell => { if >::free_token(&(sender.clone(), pair.first.clone())) < As::sa(amount.as_()) - { - error!("put_order: transactor's free token balance too low, can't put sell order"); - return Err("transactor's free token balance too low, can't put sell order"); - } + { + error!("put_order: transactor's free token balance too low, can't put sell order"); + return Err("transactor's free token balance too low, can't put sell order"); + } // 锁定用户资产 if let Err(msg) = >::reserve( sender, @@ -256,16 +270,21 @@ impl Module { index: new_last_index, class: ordertype, user: sender.clone(), - amount: amount, + amount, hasfill_amount: Zero::zero(), - price: price, + price, create_time: >::block_number(), lastupdate_time: >::block_number(), status: OrderStatus::FillNo, fill_index: Default::default(), }; Self::insert_order(new_last_index, &order); - info!("put_order: insert new order {:?} {:?} {}", sender.clone(), pair.clone(), new_last_index); + info!( + "put_order: insert new order {:?} {:?} {}", + sender.clone(), + pair.clone(), + new_last_index + ); // 记录日志 Self::deposit_event(RawEvent::PutOrder( sender.clone(), @@ -310,7 +329,12 @@ impl Module { } pub fn cancel_order(origin: T::Origin, pair: OrderPair, index: u64) -> Result { let transactor = ensure_signed(origin)?; - info!("cancel_order:{:?} {:?} {:?} ", transactor.clone(), pair.clone(), index); + info!( + "cancel_order:{:?} {:?} {:?} ", + transactor.clone(), + pair.clone(), + index + ); if let Some(mut order) = Self::order_of((transactor.clone(), pair.clone(), index)) { match order.status { @@ -323,7 +347,12 @@ impl Module { }; order.lastupdate_time = >::block_number(); Self::insert_order(index, &order); - info!("cancel_order:{:?} {} {:?}", transactor.clone(), index, order.status); + info!( + "cancel_order:{:?} {} {:?}", + transactor.clone(), + index, + order.status + ); //回退用户资产 let back_symbol: Symbol = match order.class { OrderType::Sell => pair.clone().first, @@ -331,9 +360,7 @@ impl Module { }; let back_amount: ::TokenBalance = match order.class { - OrderType::Sell => { - As::sa(order.amount.as_() - order.hasfill_amount.as_()) - } + OrderType::Sell => As::sa(order.amount.as_() - order.hasfill_amount.as_()), OrderType::Buy => As::sa( (order.amount.as_() - order.hasfill_amount.as_()) * order.price.as_(), ), @@ -397,51 +424,62 @@ impl Module { maker_fee: T::Amount, taker_fee: T::Amount, ) -> Result { - info!("fill_order:{:?} {:?} {:?} {:?} {:?} {:?} {:?} {:?} {:?}", pair.clone(), maker_user, taker_user, maker_user_order_index, taker_user_order_index, price, amount, maker_fee, taker_fee); + info!( + "fill_order:{:?} {:?} {:?} {:?} {:?} {:?} {:?} {:?} {:?}", + pair.clone(), + maker_user, + taker_user, + maker_user_order_index, + taker_user_order_index, + price, + amount, + maker_fee, + taker_fee + ); //逻辑校验 在调用方撮合模块中实现,此处只维护挂单、成交历史、资产转移 let new_last_fill_index = Self::last_fill_index_of_pair(&pair) + 1; //更新maker对应的订单 let maker_order = if let Some(mut maker_order) = - Self::order_of((maker_user.clone(), pair.clone(), maker_user_order_index)) - { - maker_order.fill_index.push(new_last_fill_index); - maker_order.hasfill_amount = maker_order.hasfill_amount + amount; - if maker_order.hasfill_amount == maker_order.amount { - maker_order.status = OrderStatus::FillAll; - } else if maker_order.hasfill_amount < maker_order.amount { - maker_order.status = OrderStatus::FillPart; - } else { - error!("fill_order: maker order has not enough amount"); - return Err(" maker order has not enough amount"); - } - - maker_order.lastupdate_time = >::block_number(); - maker_order + Self::order_of((maker_user.clone(), pair.clone(), maker_user_order_index)) + { + maker_order.fill_index.push(new_last_fill_index); + maker_order.hasfill_amount = maker_order.hasfill_amount + amount; + if maker_order.hasfill_amount == maker_order.amount { + maker_order.status = OrderStatus::FillAll; + } else if maker_order.hasfill_amount < maker_order.amount { + maker_order.status = OrderStatus::FillPart; } else { + error!("fill_order: maker order has not enough amount"); + return Err(" maker order has not enough amount"); + } + + maker_order.lastupdate_time = >::block_number(); + maker_order + } else { error!("fill_order: maker cann't find this maker order"); return Err("cann't find this maker order"); }; //更新taker对应的订单 let taker_order = if let Some(mut taker_order) = - Self::order_of((taker_user.clone(), pair.clone(), taker_user_order_index)) - { - taker_order.fill_index.push(new_last_fill_index); - taker_order.hasfill_amount = taker_order.hasfill_amount + amount; - if taker_order.hasfill_amount == taker_order.amount { - taker_order.status = OrderStatus::FillAll; - } else if taker_order.hasfill_amount < taker_order.amount { - taker_order.status = OrderStatus::FillPart; - } else { - error!("fill_order: taker order has not enough amount"); - return Err(" taker order has not enough amount"); - } - - taker_order.lastupdate_time = >::block_number(); - taker_order + Self::order_of((taker_user.clone(), pair.clone(), taker_user_order_index)) + { + taker_order.fill_index.push(new_last_fill_index); + taker_order.hasfill_amount = taker_order.hasfill_amount + amount; + if taker_order.hasfill_amount == taker_order.amount { + taker_order.status = OrderStatus::FillAll; + } else if taker_order.hasfill_amount < taker_order.amount { + taker_order.status = OrderStatus::FillPart; } else { + error!("fill_order: taker order has not enough amount"); + return Err(" taker order has not enough amount"); + } + + taker_order.lastupdate_time = >::block_number(); + taker_order + } else { error!("fill_order: taker cann't find this maker order"); return Err("cann't find this taker order"); }; @@ -454,10 +492,10 @@ impl Module { taker_user: taker_user.clone(), maker_user_order_index: maker_order.index, taker_user_order_index: taker_order.index, - price: price, - amount: amount, - maker_fee: maker_fee, - taker_fee: taker_fee, + price, + amount, + maker_fee, + taker_fee, time: >::block_number(), }; Self::insert_fill(&fill); @@ -563,7 +601,9 @@ impl Module { to: &T::AccountId, _fee_account: &T::AccountId, ) -> Result { - if let Err(msg) = >::unreserve(from, symbol, value, ReservedType::Exchange) { + if let Err(msg) = + >::unreserve(from, symbol, value, ReservedType::Exchange) + { return Err(msg); } //fee 外部算好了 @@ -627,9 +667,9 @@ pub struct OrderPair { impl OrderPair { pub fn new(first: Symbol, second: Symbol, precision: u32) -> Self { return OrderPair { - first: first, - second: second, - precision: precision, + first, + second, + precision, }; } } @@ -648,12 +688,12 @@ impl Default for OrderPair { #[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub struct Fill - where - Pair: Clone, - AccountId: Clone, - Amount: Copy, - Price: Copy, - BlockNumber: Copy, +where + Pair: Clone, + AccountId: Clone, + Amount: Copy, + Price: Copy, + BlockNumber: Copy, { pair: Pair, index: u128, @@ -669,12 +709,12 @@ pub struct Fill } impl Fill - where - Pair: Clone, - AccountId: Clone, - Amount: Copy, - Price: Copy, - BlockNumber: Copy, +where + Pair: Clone, + AccountId: Clone, + Amount: Copy, + Price: Copy, + BlockNumber: Copy, { pub fn pair(&self) -> Pair { self.pair.clone() @@ -724,12 +764,12 @@ pub type FillT = Fill< #[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub struct Order - where - Pair: Clone, - AccountId: Clone, - Amount: Copy, - Price: Copy, - BlockNumber: Copy, +where + Pair: Clone, + AccountId: Clone, + Amount: Copy, + Price: Copy, + BlockNumber: Copy, { pair: Pair, index: u64, @@ -745,12 +785,12 @@ pub struct Order } impl Order - where - Pair: Clone, - AccountId: Clone, - Amount: Copy, - Price: Copy, - BlockNumber: Copy, +where + Pair: Clone, + AccountId: Clone, + Amount: Copy, + Price: Copy, + BlockNumber: Copy, { pub fn new( pair: Pair, @@ -766,17 +806,17 @@ impl Order, ) -> Self { return Order { - pair: pair, - index: index, - class: class, - user: user, - amount: amount, - hasfill_amount: hasfill_amount, - price: price, - create_time: create_time, - lastupdate_time: lastupdate_time, - status: status, - fill_index: fill_index, + pair, + index, + class, + user, + amount, + hasfill_amount, + price, + create_time, + lastupdate_time, + status, + fill_index, }; } pub fn pair(&self) -> Pair { diff --git a/cxrml/exchange/pendingorders/src/tests.rs b/cxrml/exchange/pendingorders/src/tests.rs index 6e202a0146c35..bebbca173fab5 100644 --- a/cxrml/exchange/pendingorders/src/tests.rs +++ b/cxrml/exchange/pendingorders/src/tests.rs @@ -75,7 +75,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { transfer_fee: 0, creation_fee: 0, reclaim_rebate: 0, - }.build_storage() + } + .build_storage() .unwrap(), ); @@ -84,7 +85,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { order_fee: 10, pair_list: vec![], max_command_id: 0, - }.build_storage() + } + .build_storage() .unwrap(), ); r.into() @@ -192,7 +194,10 @@ fn test_order() { //500-200 assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 300); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 200); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 200 + ); //挂卖单 let sell = OrderType::Sell; @@ -204,7 +209,10 @@ fn test_order() { //500-100 assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 400); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 100); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 100 + ); let last_order_index_of_eos_eth = PendingOrders::last_order_index_of((a.clone(), p1.clone())).unwrap(); @@ -228,7 +236,10 @@ fn test_order() { assert_eq!(Ok(()), cancel); //500-200+200 assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); let cancel_order_1 = PendingOrders::order_of((a.clone(), p1.clone(), last_order_index_of_eos_eth - 1)) @@ -327,18 +338,30 @@ fn test_fill() { let buy = OrderType::Buy; let a_order = PendingOrders::put_order(Some(a).into(), p1.clone(), buy, 100, 5); assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 500); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 500 + ); //挂卖单 let sell = OrderType::Sell; let b_order = PendingOrders::put_order(Some(b).into(), p1.clone(), sell, 50, 5); assert_eq!(b_order, Ok(())); assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 950); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 50); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 50 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1000); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); print_order_list(a, p1.clone()); print_order_list(b, p1.clone()); @@ -348,17 +371,29 @@ fn test_fill() { //1000+250 assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 1050); - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); //1000-500 assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); //500-250 - assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), 250); + assert_eq!( + TokenBalances::reserved_token(&(a, t_sym_eth.clone(), ReservedType::Exchange)), + 250 + ); //1000-50 assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 950); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eos.clone(), ReservedType::Exchange)), + 0 + ); assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1250); - assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), 0); + assert_eq!( + TokenBalances::reserved_token(&(b, t_sym_eth.clone(), ReservedType::Exchange)), + 0 + ); assert_eq!(1, PendingOrders::last_fill_index_of_pair(&p1.clone())); let last_fill = PendingOrders::fill_of((p1.clone(), 1)).unwrap(); diff --git a/cxrml/funds/financialrecords/src/lib.rs b/cxrml/funds/financialrecords/src/lib.rs index 95ef8d48e2afc..73f07cb40edf9 100644 --- a/cxrml/funds/financialrecords/src/lib.rs +++ b/cxrml/funds/financialrecords/src/lib.rs @@ -33,15 +33,15 @@ extern crate sr_primitives as runtime_primitives; // Needed for type-safe access to storage DB. #[macro_use] extern crate srml_support as runtime_support; -extern crate srml_system as system; extern crate srml_balances as balances; +extern crate srml_system as system; // for chainx runtime module lib #[cfg(test)] -extern crate cxrml_system as cxsystem; -#[cfg(test)] extern crate cxrml_associations as associations; extern crate cxrml_support as cxsupport; +#[cfg(test)] +extern crate cxrml_system as cxsystem; extern crate cxrml_tokenbalances as tokenbalances; #[cfg(test)] @@ -50,14 +50,12 @@ mod tests; use codec::Codec; use rstd::prelude::*; use rstd::result::Result as StdResult; +use runtime_primitives::traits::OnFinalise; use runtime_support::dispatch::Result; use runtime_support::{StorageMap, StorageValue}; -use runtime_primitives::traits::OnFinalise; -pub use tokenbalances::{Symbol, ReservedType}; -use cxsupport::storage::linked_node::{ - Node, NodeT, LinkedNodeCollection, MultiNodeIndex, -}; +use cxsupport::storage::linked_node::{LinkedNodeCollection, MultiNodeIndex, Node, NodeT}; +pub use tokenbalances::{ReservedType, Symbol}; pub trait Trait: tokenbalances::Trait { /// The overarching event type. @@ -148,8 +146,11 @@ impl Default for Action { #[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct Record where - Symbol: Clone, TokenBalance: Copy, BlockNumber: Copy, +pub struct Record +where + Symbol: Clone, + TokenBalance: Copy, + BlockNumber: Copy, { action: Action, symbol: Symbol, @@ -159,51 +160,76 @@ pub struct Record where ext: Vec, } -type RecordT = Record::TokenBalance, ::BlockNumber>; +type RecordT = + Record::TokenBalance, ::BlockNumber>; -impl Record where - Symbol: Clone, TokenBalance: Copy, BlockNumber: Copy, +impl Record +where + Symbol: Clone, + TokenBalance: Copy, + BlockNumber: Copy, { - pub fn action(&self) -> Action { self.action } - pub fn mut_action(&mut self) -> &mut Action { &mut self.action } - pub fn symbol(&self) -> Symbol { self.symbol.clone() } - pub fn balance(&self) -> TokenBalance { self.balance } - pub fn addr(&self) -> Vec { self.addr.clone() } - pub fn ext(&self) -> Vec { self.ext.clone() } + pub fn action(&self) -> Action { + self.action + } + pub fn mut_action(&mut self) -> &mut Action { + &mut self.action + } + pub fn symbol(&self) -> Symbol { + self.symbol.clone() + } + pub fn balance(&self) -> TokenBalance { + self.balance + } + pub fn addr(&self) -> Vec { + self.addr.clone() + } + pub fn ext(&self) -> Vec { + self.ext.clone() + } /// block num for the record init time. - pub fn blocknum(&self) -> BlockNumber { self.init_blocknum } + pub fn blocknum(&self) -> BlockNumber { + self.init_blocknum + } } -impl Record where - Symbol: Clone, TokenBalance: Copy, BlockNumber: Copy, +impl Record +where + Symbol: Clone, + TokenBalance: Copy, + BlockNumber: Copy, { fn is_init(&self) -> bool { match self.action { Action::Deposit(ref state) => { - if let DepositState::Invalid = state { true } else { false } + if let DepositState::Invalid = state { + true + } else { + false + } } Action::Withdrawal(ref state) => { - if let WithdrawalState::Invalid = state { true } else { false } + if let WithdrawalState::Invalid = state { + true + } else { + false + } } } } fn is_finish(&self) -> bool { match self.action { - Action::Deposit(ref state) => { - match state { - DepositState::Success => true, - DepositState::Failed => true, - _ => false, - } - } - Action::Withdrawal(ref state) => { - match state { - WithdrawalState::Success => true, - WithdrawalState::Failed => true, - _ => false, - } - } + Action::Deposit(ref state) => match state { + DepositState::Success => true, + DepositState::Failed => true, + _ => false, + }, + Action::Withdrawal(ref state) => match state { + WithdrawalState::Success => true, + WithdrawalState::Failed => true, + _ => false, + }, } } } @@ -211,28 +237,37 @@ impl Record - where AccountId: Codec + Clone + Ord + Default, +where + AccountId: Codec + Clone + Ord + Default, { accountid: AccountId, index: u32, } impl NodeT for WithdrawLog - where AccountId: Codec + Clone + Ord + Default, +where + AccountId: Codec + Clone + Ord + Default, { type Index = (AccountId, u32); - fn index(&self) -> Self::Index { (self.accountid.clone(), self.index) } + fn index(&self) -> Self::Index { + (self.accountid.clone(), self.index) + } } impl WithdrawLog - where AccountId: Codec + Clone + Ord + Default, +where + AccountId: Codec + Clone + Ord + Default, { - pub fn accountid(&self) -> AccountId { self.accountid.clone() } - pub fn index(&self) -> u32 { self.index } + pub fn accountid(&self) -> AccountId { + self.accountid.clone() + } + pub fn index(&self) -> u32 { + self.index + } } -pub struct LinkedMultiKey (runtime_support::storage::generator::PhantomData); +pub struct LinkedMultiKey(runtime_support::storage::generator::PhantomData); impl LinkedNodeCollection for LinkedMultiKey { type Header = LogHeaderFor; @@ -263,7 +298,6 @@ decl_storage! { } } - impl Module { /// Deposit one of this module's events. fn deposit_event(event: Event) { @@ -294,17 +328,14 @@ impl Module { } } - pub fn last_deposit_of(who: &T::AccountId, sym: &Symbol) -> Option<(u32, RecordT)> { - Self::last_deposit_index_of((who.clone(), sym.clone())).and_then(|index| { - >::get(&(who.clone(), index)).map(|r| (index, r)) - }) + Self::last_deposit_index_of((who.clone(), sym.clone())) + .and_then(|index| >::get(&(who.clone(), index)).map(|r| (index, r))) } pub fn last_withdrawal_of(who: &T::AccountId, sym: &Symbol) -> Option<(u32, RecordT)> { - Self::last_withdrawal_index_of((who.clone(), sym.clone())).and_then(|index| { - >::get(&(who.clone(), index)).map(|r| (index, r)) - }) + Self::last_withdrawal_index_of((who.clone(), sym.clone())) + .and_then(|index| >::get(&(who.clone(), index)).map(|r| (index, r))) } /// deposit/withdrawal pre-process @@ -316,16 +347,17 @@ impl Module { let r = if is_withdrawal { match Self::last_deposit_of(who, sym) { None => return Err("the account has no deposit record for this token yet"), - Some((_, record)) => - { - if !record.is_finish() { - return Err("the account has no deposit record for this token yet"); - } + Some((_, record)) => { + if !record.is_finish() { + return Err("the account has no deposit record for this token yet"); } + } } Self::last_withdrawal_of(who, sym) - } else { Self::last_deposit_of(who, sym) }; + } else { + Self::last_deposit_of(who, sym) + }; if let Some((_, record)) = r { if !record.is_finish() { @@ -342,7 +374,7 @@ impl Module { } let len: u32 = Self::records_len_of(who); >::insert(&(who.clone(), len), record.clone()); - >::insert(who, len + 1); // len is more than 1 to max index + >::insert(who, len + 1); // len is more than 1 to max index let key = (who.clone(), record.symbol()); match record.action() { Action::Deposit(_) => >::insert(&key, len), @@ -360,16 +392,26 @@ impl Module { } /// withdrawal, notice this func has include withdrawal_init and withdrawal_locking - pub fn withdrawal(who: &T::AccountId, sym: &Symbol, balance: T::TokenBalance, addr: Vec, ext: Vec) -> Result { + pub fn withdrawal( + who: &T::AccountId, + sym: &Symbol, + balance: T::TokenBalance, + addr: Vec, + ext: Vec, + ) -> Result { let index = Self::withdrawal_with_index(who, sym, balance, addr, ext)?; // set to withdraw cache - let n = Node::new(WithdrawLog:: { accountid: who.clone(), index }); + let n = Node::new(WithdrawLog:: { + accountid: who.clone(), + index, + }); n.init_storage_withkey::, Symbol>(sym.clone()); if let Some(tail_index) = Self::log_tail_for(sym) { if let Some(mut tail_node) = Self::withdraw_log_cache(tail_index.index()) { - tail_node.add_option_node_after_withkey::, Symbol>(n, sym.clone())?; + tail_node + .add_option_node_after_withkey::, Symbol>(n, sym.clone())?; } } @@ -395,9 +437,13 @@ impl Module { } if let Some(next) = node.next() { index = next; - } else { return Err("not found this withdraw log in cache"); } + } else { + return Err("not found this withdraw log in cache"); + } } - } else { return Err("the withdraw log node header not exist for this symbol"); } + } else { + return Err("the withdraw log node header not exist for this symbol"); + } Self::withdrawal_finish_with_index(who, r.unwrap(), success).map(|_| ()) } @@ -435,33 +481,54 @@ impl Module { Self::deposit_finish_with_index(who, r.unwrap(), success).map(|_| ()) } -// /// withdrawal init, use for record a withdrawal start, should call withdrawal_locking after it -// fn withdrawal_init(who: &T::AccountId, sym: &Symbol, balance: T::TokenBalance) -> Result { -// Self::withdrawal_with_index(who, sym, balance).map(|_| ()) -// } -// /// change the free token to locking state -// fn withdrawal_locking(who: &T::AccountId, sym: &Symbol) -> Result { -// let r = Self::last_withdrawal_index_of(&(who.clone(), sym.clone())); -// if r.is_none() { -// return Err("have not executed withdrawal() or withdrawal_init() yet for this record"); -// } -// Self::withdrawal_locking_with_index(who, r.unwrap()).map(|_| ()) -// } + // /// withdrawal init, use for record a withdrawal start, should call withdrawal_locking after it + // fn withdrawal_init(who: &T::AccountId, sym: &Symbol, balance: T::TokenBalance) -> Result { + // Self::withdrawal_with_index(who, sym, balance).map(|_| ()) + // } + // /// change the free token to locking state + // fn withdrawal_locking(who: &T::AccountId, sym: &Symbol) -> Result { + // let r = Self::last_withdrawal_index_of(&(who.clone(), sym.clone())); + // if r.is_none() { + // return Err("have not executed withdrawal() or withdrawal_init() yet for this record"); + // } + // Self::withdrawal_locking_with_index(who, r.unwrap()).map(|_| ()) + // } /// deposit init, notice this func return index to show the index of records for this account - pub fn deposit_with_index(who: &T::AccountId, sym: &Symbol, balance: T::TokenBalance) -> StdResult { + pub fn deposit_with_index( + who: &T::AccountId, + sym: &Symbol, + balance: T::TokenBalance, + ) -> StdResult { Self::before(who, sym, false)?; >::is_valid_token(sym)?; - let r = Record { action: Action::Deposit(Default::default()), symbol: sym.clone(), balance: balance, init_blocknum: >::block_number(), addr: Vec::new(), ext: Vec::new() }; + let r = Record { + action: Action::Deposit(Default::default()), + symbol: sym.clone(), + balance, + init_blocknum: >::block_number(), + addr: Vec::new(), + ext: Vec::new(), + }; let index = Self::new_record(who, &r)?; - Self::deposit_event(RawEvent::DepositInit(who.clone(), index, r.symbol(), r.balance(), r.blocknum())); + Self::deposit_event(RawEvent::DepositInit( + who.clone(), + index, + r.symbol(), + r.balance(), + r.blocknum(), + )); Ok(index) } /// deposit finish, should use index to find the old deposit record, success flag mark the success - pub fn deposit_finish_with_index(who: &T::AccountId, index: u32, success: bool) -> StdResult { + pub fn deposit_finish_with_index( + who: &T::AccountId, + index: u32, + success: bool, + ) -> StdResult { let key = (who.clone(), index); if let Some(ref mut r) = >::get(&key) { if r.is_finish() { @@ -478,11 +545,23 @@ impl Module { // call tokenbalances to issue token for this accountid >::issue(who, &sym, bal)?; - Self::deposit_event(RawEvent::DepositSuccess(who.clone(), index, sym, bal, >::block_number())); + Self::deposit_event(RawEvent::DepositSuccess( + who.clone(), + index, + sym, + bal, + >::block_number(), + )); } else { *state = DepositState::Failed; - Self::deposit_event(RawEvent::DepositFailed(who.clone(), index, sym, bal, >::block_number())); + Self::deposit_event(RawEvent::DepositFailed( + who.clone(), + index, + sym, + bal, + >::block_number(), + )); } } _ => return Err("err action type in deposit_finish"), @@ -494,7 +573,13 @@ impl Module { } } /// withdrawal init, notice this func return index to show the index of records for this account - fn withdrawal_with_index(who: &T::AccountId, sym: &Symbol, balance: T::TokenBalance, addr: Vec, ext: Vec) -> StdResult { + fn withdrawal_with_index( + who: &T::AccountId, + sym: &Symbol, + balance: T::TokenBalance, + addr: Vec, + ext: Vec, + ) -> StdResult { Self::before(who, sym, true)?; >::is_valid_token_for(who, sym)?; @@ -503,13 +588,29 @@ impl Module { return Err("not enough free token to withdraw"); } - let r = Record { action: Action::Withdrawal(Default::default()), symbol: sym.clone(), balance: balance, init_blocknum: >::block_number(), addr, ext }; + let r = Record { + action: Action::Withdrawal(Default::default()), + symbol: sym.clone(), + balance, + init_blocknum: >::block_number(), + addr, + ext, + }; let index = Self::new_record(who, &r)?; - Self::deposit_event(RawEvent::WithdrawalInit(who.clone(), index, r.symbol(), r.balance(), r.blocknum())); + Self::deposit_event(RawEvent::WithdrawalInit( + who.clone(), + index, + r.symbol(), + r.balance(), + r.blocknum(), + )); Ok(index) } /// withdrawal lock, should use index to find out which record to change to locking state - fn withdrawal_locking_with_index(who: &T::AccountId, index: u32) -> StdResult { + fn withdrawal_locking_with_index( + who: &T::AccountId, + index: u32, + ) -> StdResult { let key = (who.clone(), index); if let Some(ref mut r) = >::get(&key) { if r.is_finish() { @@ -520,18 +621,22 @@ impl Module { let bal = r.balance(); // change state match r.mut_action() { - Action::Withdrawal(ref mut state) => { - match state { - WithdrawalState::Invalid => { - *state = WithdrawalState::Locking; - - >::reserve(who, &sym, bal, ReservedType::Funds)?; - - Self::deposit_event(RawEvent::WithdrawalLocking(who.clone(), index, sym, bal, >::block_number())); - } - _ => return Err("the withdrawal state must be Invalid."), + Action::Withdrawal(ref mut state) => match state { + WithdrawalState::Invalid => { + *state = WithdrawalState::Locking; + + >::reserve(who, &sym, bal, ReservedType::Funds)?; + + Self::deposit_event(RawEvent::WithdrawalLocking( + who.clone(), + index, + sym, + bal, + >::block_number(), + )); } - } + _ => return Err("the withdrawal state must be Invalid."), + }, _ => return Err("err action type in deposit_finish"), } >::insert(&key, r.clone()); @@ -542,7 +647,11 @@ impl Module { } } /// withdrawal finish, should use index to find out which record to changed to final, success flag mark success, if false, release the token to free - fn withdrawal_finish_with_index(who: &T::AccountId, index: u32, success: bool) -> StdResult { + fn withdrawal_finish_with_index( + who: &T::AccountId, + index: u32, + success: bool, + ) -> StdResult { let key = (who.clone(), index); if let Some(ref mut r) = >::get(&key) { if r.is_finish() { @@ -554,27 +663,47 @@ impl Module { // change state match r.mut_action() { - Action::Withdrawal(ref mut state) => { - match state { - WithdrawalState::Locking => { - if success { - *state = WithdrawalState::Success; - - >::destroy(who, &sym, bal, ReservedType::Funds)?; - - Self::deposit_event(RawEvent::WithdrawalSuccess(who.clone(), index, sym, bal, >::block_number())); - } else { - *state = WithdrawalState::Failed; - - >::unreserve(who, &sym, bal, ReservedType::Funds)?; - - Self::deposit_event(RawEvent::WithdrawalFailed(who.clone(), index, sym, bal, >::block_number())); - } + Action::Withdrawal(ref mut state) => match state { + WithdrawalState::Locking => { + if success { + *state = WithdrawalState::Success; + + >::destroy( + who, + &sym, + bal, + ReservedType::Funds, + )?; + + Self::deposit_event(RawEvent::WithdrawalSuccess( + who.clone(), + index, + sym, + bal, + >::block_number(), + )); + } else { + *state = WithdrawalState::Failed; + + >::unreserve( + who, + &sym, + bal, + ReservedType::Funds, + )?; + + Self::deposit_event(RawEvent::WithdrawalFailed( + who.clone(), + index, + sym, + bal, + >::block_number(), + )); } - _ => return Err("the withdrawal state must be Locking."), } - } - _ => return Err("err action type in deposit_finish") + _ => return Err("the withdrawal state must be Locking."), + }, + _ => return Err("err action type in deposit_finish"), } >::insert(&key, r.clone()); diff --git a/cxrml/funds/financialrecords/src/tests.rs b/cxrml/funds/financialrecords/src/tests.rs index a6493d77812df..a3e7a187aef3e 100644 --- a/cxrml/funds/financialrecords/src/tests.rs +++ b/cxrml/funds/financialrecords/src/tests.rs @@ -1,19 +1,19 @@ // Copyright 2018 Chainpool. -use substrate_primitives::{H256, Blake2Hasher}; +use substrate_primitives::{Blake2Hasher, H256}; -use runtime_primitives::BuildStorage; -use runtime_primitives::traits::BlakeTwo256; -use runtime_primitives::testing::{Digest, DigestItem, Header}; use runtime_io; use runtime_io::with_externalities; +use runtime_primitives::testing::{Digest, DigestItem, Header}; +use runtime_primitives::traits::BlakeTwo256; +use runtime_primitives::BuildStorage; use super::*; -use tokenbalances::{Token, SymbolString, DescString}; +use tokenbalances::{DescString, SymbolString, Token}; impl_outer_origin! { - pub enum Origin for Test {} - } + pub enum Origin for Test {} +} #[derive(Clone, Eq, PartialEq)] pub struct Test; @@ -61,64 +61,82 @@ impl tokenbalances::Trait for Test { // This function basically just builds a genesis storage key/value store according to // our desired mockup. pub fn new_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); // balance - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 500, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 500, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); // token balance let t: Token = Token::new(b"x-btc".to_vec(), b"btc token".to_vec(), 8); let t2: Token = Token::new(b"x-eth".to_vec(), b"eth token".to_vec(), 4); - r.extend(tokenbalances::GenesisConfig:: { - chainx_precision: 8, - token_list: vec![ - (t, vec![]), - (t2, vec![]), - ], - transfer_token_fee: 10, - }.build_storage().unwrap()); + r.extend( + tokenbalances::GenesisConfig:: { + chainx_precision: 8, + token_list: vec![(t, vec![]), (t2, vec![])], + transfer_token_fee: 10, + } + .build_storage() + .unwrap(), + ); // financialrecords - r.extend(GenesisConfig:: { - withdrawal_fee: 10, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { withdrawal_fee: 10 } + .build_storage() + .unwrap(), + ); r.into() } pub fn new_test_ext2() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); // balance - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 0, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 0, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); // token balance let t: Token = Token::new(b"x-btc".to_vec(), b"btc token".to_vec(), 8); let t2: Token = Token::new(b"x-eth".to_vec(), b"eth token".to_vec(), 4); - r.extend(tokenbalances::GenesisConfig:: { - chainx_precision: 8, - token_list: vec![ - (t, vec![]), - (t2, vec![]), - ], - transfer_token_fee: 10, - }.build_storage().unwrap()); + r.extend( + tokenbalances::GenesisConfig:: { + chainx_precision: 8, + token_list: vec![(t, vec![]), (t2, vec![])], + transfer_token_fee: 10, + } + .build_storage() + .unwrap(), + ); // financialrecords - r.extend(GenesisConfig:: { - withdrawal_fee: 10, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { withdrawal_fee: 10 } + .build_storage() + .unwrap(), + ); r.into() } @@ -141,10 +159,14 @@ fn test_normal() { assert_eq!(index, 0); FinancialRecords::deposit_finish_with_index(&a, index, true).unwrap(); // withdraw - let index = FinancialRecords::withdrawal_with_index(&a, &btc_symbol, 50, vec![], vec![]).unwrap(); + let index = + FinancialRecords::withdrawal_with_index(&a, &btc_symbol, 50, vec![], vec![]).unwrap(); assert_eq!(index, 1); FinancialRecords::withdrawal_locking_with_index(&a, index).unwrap(); - assert_eq!(FinancialRecords::withdrawal_finish_with_index(&a, index, true), Ok(1)); + assert_eq!( + FinancialRecords::withdrawal_finish_with_index(&a, index, true), + Ok(1) + ); }) } @@ -179,9 +201,15 @@ fn test_normal2() { let key2 = (a, eth_symbol.clone()); assert_eq!(FinancialRecords::last_deposit_index_of(&key1).unwrap(), 0); - assert_eq!(FinancialRecords::last_withdrawal_index_of(&key1).unwrap(), 2); + assert_eq!( + FinancialRecords::last_withdrawal_index_of(&key1).unwrap(), + 2 + ); assert_eq!(FinancialRecords::last_deposit_index_of(&key2).unwrap(), 1); - assert_eq!(FinancialRecords::last_withdrawal_index_of(&key2).unwrap(), 3); + assert_eq!( + FinancialRecords::last_withdrawal_index_of(&key2).unwrap(), + 3 + ); }) } @@ -191,32 +219,58 @@ fn test_last_not_finish() { let a: u64 = 1; // accountid let btc_symbol = b"x-btc".to_vec(); FinancialRecords::deposit_init(&a, &btc_symbol, 100).unwrap(); - assert_err!(FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), - "the account has no deposit record for this token yet"); + assert_err!( + FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), + "the account has no deposit record for this token yet" + ); // let deposit fail assert_ok!(FinancialRecords::deposit_finish(&a, &btc_symbol, false)); // 1. deposit failed assert_eq!(TokenBalances::total_token_of(&a, &btc_symbol), 0); - assert_err!(FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), "not a existed token in this account token list"); + assert_err!( + FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), + "not a existed token in this account token list" + ); assert_eq!(FinancialRecords::records_len_of(&a), 1); FinancialRecords::deposit_init(&a, &btc_symbol, 100).unwrap(); - assert_ok!(FinancialRecords::deposit_finish(&a, &btc_symbol, true)); // 2. deposit success + assert_ok!(FinancialRecords::deposit_finish(&a, &btc_symbol, true)); // 2. deposit success - assert_ok!(FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![])); + assert_ok!(FinancialRecords::withdrawal( + &a, + &btc_symbol, + 50, + vec![], + vec![] + )); - assert_ok!(FinancialRecords::deposit(&a, &btc_symbol, 50)); // 3. deposit success + assert_ok!(FinancialRecords::deposit(&a, &btc_symbol, 50)); // 3. deposit success assert_eq!(TokenBalances::total_token_of(&a, &btc_symbol), 150); - assert_eq!(TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), 100); + assert_eq!( + TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), + 100 + ); assert_ok!(FinancialRecords::withdrawal_finish(&a, &btc_symbol, false)); // 4. withdrawal failed - assert_eq!(TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), 150); - - assert_ok!(FinancialRecords::withdrawal(&a, &btc_symbol, 25, vec![], vec![])); - assert_ok!(FinancialRecords::withdrawal_finish(&a, &btc_symbol, true)); // destroy token here 5. withdrawal success + assert_eq!( + TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), + 150 + ); + + assert_ok!(FinancialRecords::withdrawal( + &a, + &btc_symbol, + 25, + vec![], + vec![] + )); + assert_ok!(FinancialRecords::withdrawal_finish(&a, &btc_symbol, true)); // destroy token here 5. withdrawal success assert_eq!(FinancialRecords::records_len_of(&a), 5); - assert_eq!(TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), 125); + assert_eq!( + TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), + 125 + ); assert_eq!(TokenBalances::total_token(&btc_symbol), 125); }) @@ -229,7 +283,10 @@ fn test_withdrawal_larger() { let btc_symbol = b"x-btc".to_vec(); assert_ok!(FinancialRecords::deposit(&a, &btc_symbol, 10)); - assert_err!(FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), "not enough free token to withdraw"); + assert_err!( + FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), + "not enough free token to withdraw" + ); assert_eq!(FinancialRecords::records_len_of(&a), 1); }) } @@ -239,7 +296,10 @@ fn test_withdrawal_first() { with_externalities(&mut new_test_ext(), || { let a: u64 = 1; // accountid let btc_symbol = b"x-btc".to_vec(); - assert_err!(FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), "the account has no deposit record for this token yet"); + assert_err!( + FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), + "the account has no deposit record for this token yet" + ); }) } @@ -252,12 +312,18 @@ fn test_multi_sym() { let key1 = (a, btc_symbol.clone()); let key2 = (a, eth_symbol.clone()); - assert_err!(FinancialRecords::withdrawal_finish(&a, &btc_symbol, true), "have not executed withdrawal() or withdrawal_init() yet for this record"); - assert_err!(FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), "the account has no deposit record for this token yet"); + assert_err!( + FinancialRecords::withdrawal_finish(&a, &btc_symbol, true), + "have not executed withdrawal() or withdrawal_init() yet for this record" + ); + assert_err!( + FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![]), + "the account has no deposit record for this token yet" + ); - assert_ok!(FinancialRecords::deposit(&a, &btc_symbol, 100)); // index = 0 - assert_ok!(FinancialRecords::deposit(&a, ð_symbol, 100)); // eth 100 index = 1 - assert_ok!(FinancialRecords::deposit(&a, &btc_symbol, 100)); // btc 200 index = 2 + assert_ok!(FinancialRecords::deposit(&a, &btc_symbol, 100)); // index = 0 + assert_ok!(FinancialRecords::deposit(&a, ð_symbol, 100)); // eth 100 index = 1 + assert_ok!(FinancialRecords::deposit(&a, &btc_symbol, 100)); // btc 200 index = 2 assert_eq!(FinancialRecords::last_deposit_index_of(&key1), Some(2)); assert_eq!(FinancialRecords::last_deposit_index_of(&key2), Some(1)); @@ -267,17 +333,38 @@ fn test_multi_sym() { assert_eq!(TokenBalances::total_token_of(&a, ð_symbol), 100); // withdraw - assert_ok!(FinancialRecords::withdrawal(&a, &btc_symbol, 50, vec![], vec![])); // index = 3 + assert_ok!(FinancialRecords::withdrawal( + &a, + &btc_symbol, + 50, + vec![], + vec![] + )); // index = 3 assert_err!(FinancialRecords::withdrawal(&a, &btc_symbol, 25, vec![], vec![]), "the last action have not finished yet! only if the last deposit/withdrawal have finished you can do a new action."); - assert_ok!(FinancialRecords::withdrawal(&a, ð_symbol, 50, vec![], vec![])); // parallel withdraw index = 4 - - assert_eq!(TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), 150); - assert_eq!(TokenBalances::free_token(&(a.clone(), eth_symbol.clone())), 50); - - assert_ok!(FinancialRecords::deposit(&a, ð_symbol, 50)); // deposit while withdraw index = 5 - - assert_eq!(TokenBalances::free_token(&(a.clone(), eth_symbol.clone())), 100); + assert_ok!(FinancialRecords::withdrawal( + &a, + ð_symbol, + 50, + vec![], + vec![] + )); // parallel withdraw index = 4 + + assert_eq!( + TokenBalances::free_token(&(a.clone(), btc_symbol.clone())), + 150 + ); + assert_eq!( + TokenBalances::free_token(&(a.clone(), eth_symbol.clone())), + 50 + ); + + assert_ok!(FinancialRecords::deposit(&a, ð_symbol, 50)); // deposit while withdraw index = 5 + + assert_eq!( + TokenBalances::free_token(&(a.clone(), eth_symbol.clone())), + 100 + ); assert_ok!(FinancialRecords::withdrawal_finish(&a, &btc_symbol, true)); assert_ok!(FinancialRecords::withdrawal_finish(&a, ð_symbol, false)); @@ -340,10 +427,14 @@ fn test_withdraw_log_cache() { v.push((node.data.accountid(), node.data.index())); if let Some(next) = node.next() { index = next; - } else { break; } + } else { + break; + } } assert_eq!(v.as_slice(), [(a, 2), (b, 2)]); - } else { panic!("unreachable!") } + } else { + panic!("unreachable!") + } // eth cache if let Some(eth_header) = FinancialRecords::log_header_for(ð_symbol) { let mut index = eth_header.index(); @@ -352,10 +443,14 @@ fn test_withdraw_log_cache() { v.push((node.data.accountid(), node.data.index())); if let Some(next) = node.next() { index = next; - } else { break; } + } else { + break; + } } assert_eq!(v.as_slice(), [(a, 3), (b, 3)]); - } else { panic!("unreachable!") } + } else { + panic!("unreachable!") + } // withdraw finish // loop linked node collection and find out @@ -372,10 +467,14 @@ fn test_withdraw_log_cache() { v.push((node.data.accountid(), node.data.index())); if let Some(next) = node.next() { index = next; - } else { break; } + } else { + break; + } } assert_eq!(v.as_slice(), [(a, 2)]); - } else { panic!("unreachable!") } + } else { + panic!("unreachable!") + } let log = FinancialRecords::withdraw_log_cache((a, 2)).unwrap(); assert_eq!(log.prev(), None); @@ -395,12 +494,16 @@ fn test_withdraw_log_cache() { v.push((node.data.accountid(), node.data.index())); if let Some(next) = node.next() { index = next; - } else { break; } + } else { + break; + } } assert_eq!(v.as_slice(), [(b, 3)]); - } else { panic!("unreachable!") } + } else { + panic!("unreachable!") + } assert_ok!(FinancialRecords::withdrawal_finish(&b, ð_symbol, true)); assert_eq!(FinancialRecords::log_header_for(&btc_symbol) == None, true); }) -} \ No newline at end of file +} diff --git a/cxrml/funds/withdrawal/src/lib.rs b/cxrml/funds/withdrawal/src/lib.rs index 321fa4527f195..24ffc9fb86215 100644 --- a/cxrml/funds/withdrawal/src/lib.rs +++ b/cxrml/funds/withdrawal/src/lib.rs @@ -30,21 +30,21 @@ extern crate sr_primitives as runtime_primitives; // Needed for type-safe access to storage DB. #[macro_use] extern crate srml_support as runtime_support; -extern crate srml_system as system; extern crate srml_balances as balances; #[cfg(test)] -extern crate srml_timestamp as timestamp; -#[cfg(test)] extern crate srml_consensus as consensus; +extern crate srml_system as system; +#[cfg(test)] +extern crate srml_timestamp as timestamp; // chainx runtime module #[cfg(test)] -extern crate cxrml_system as cxsystem; -#[cfg(test)] extern crate cxrml_associations as associations; +extern crate cxrml_funds_financialrecords as financialrecords; extern crate cxrml_support as cxsupport; +#[cfg(test)] +extern crate cxrml_system as cxsystem; extern crate cxrml_tokenbalances as tokenbalances; -extern crate cxrml_funds_financialrecords as financialrecords; // chainx runtime module bridge extern crate cxrml_bridge_btc as btc; @@ -56,16 +56,15 @@ mod tests; use rstd::prelude::*; //use rstd::result::Result as StdResult; +use runtime_primitives::traits::OnFinalise; use runtime_support::dispatch::Result; use runtime_support::StorageValue; -use runtime_primitives::traits::OnFinalise; use system::ensure_signed; use tokenbalances::{Symbol, TokenT}; - pub trait Trait: tokenbalances::Trait + financialrecords::Trait + btc::Trait { -// type Event: From> + Into<::Event>; + // type Event: From> + Into<::Event>; } //decl_event!( @@ -97,12 +96,18 @@ decl_storage! { impl Module { // event -// /// Deposit one of this module's events. -// fn deposit_event(event: Event) { -// >::deposit_event(::Event::from(event).into()); -// } - - fn withdraw(origin: T::Origin, sym: Symbol, value: T::TokenBalance, addr: Vec, ext: Vec) -> Result { + // /// Deposit one of this module's events. + // fn deposit_event(event: Event) { + // >::deposit_event(::Event::from(event).into()); + // } + + fn withdraw( + origin: T::Origin, + sym: Symbol, + value: T::TokenBalance, + addr: Vec, + ext: Vec, + ) -> Result { let who = ensure_signed(origin)?; cxsupport::Module::::handle_fee_before(&who, Self::withdrawal_fee(), true, || Ok(()))?; @@ -115,8 +120,8 @@ impl Module { fn verify_addr(sym: &Symbol, addr: &[u8], ext: &[u8]) -> Result { match sym.as_ref() { - btc::Module::::SYMBOL => { btc::Module::::check_addr(&addr, b"") } - _ => return Err("not found match token symbol addr checker") + btc::Module::::SYMBOL => btc::Module::::check_addr(&addr, b""), + _ => return Err("not found match token symbol addr checker"), } } @@ -124,5 +129,3 @@ impl Module { Self::verify_addr(&sym, &addr, &ext) } } - - diff --git a/cxrml/funds/withdrawal/src/tests.rs b/cxrml/funds/withdrawal/src/tests.rs index 2070608c7c1c0..cd1983c0cd576 100644 --- a/cxrml/funds/withdrawal/src/tests.rs +++ b/cxrml/funds/withdrawal/src/tests.rs @@ -1,19 +1,19 @@ -use substrate_primitives::{H256, Blake2Hasher}; +use substrate_primitives::{Blake2Hasher, H256}; -use runtime_primitives::BuildStorage; -use runtime_primitives::traits::BlakeTwo256; -use runtime_primitives::testing::{Digest, DigestItem, Header}; use runtime_io; use runtime_io::with_externalities; +use runtime_primitives::testing::{Digest, DigestItem, Header}; +use runtime_primitives::traits::BlakeTwo256; +use runtime_primitives::BuildStorage; use super::*; -use tokenbalances::{Token, SymbolString, DescString}; +use tokenbalances::{DescString, SymbolString, Token}; use base58::FromBase58; impl_outer_origin! { - pub enum Origin for Test {} - } + pub enum Origin for Test {} +} #[derive(Clone, Eq, PartialEq)] pub struct Test; @@ -60,7 +60,6 @@ impl timestamp::Trait for Test { type Moment = u64; } - // define tokenbalances module type pub type TokenBalance = u128; @@ -84,48 +83,77 @@ impl Trait for Test {} // This function basically just builds a genesis storage key/value store according to // our desired mockup. pub fn new_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); // balance - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 500, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 500, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); // token balance - let t: Token = Token::new(btc::Module::::SYMBOL.to_vec(), b"btc token".to_vec(), 8); - - r.extend(tokenbalances::GenesisConfig:: { - chainx_precision: 8, - token_list: vec![ - (t, vec![]), - ], - transfer_token_fee: 10, - }.build_storage().unwrap()); + let t: Token = Token::new( + btc::Module::::SYMBOL.to_vec(), + b"btc token".to_vec(), + 8, + ); + + r.extend( + tokenbalances::GenesisConfig:: { + chainx_precision: 8, + token_list: vec![(t, vec![])], + transfer_token_fee: 10, + } + .build_storage() + .unwrap(), + ); // financialrecords - r.extend(GenesisConfig:: { - withdrawal_fee: 10, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { withdrawal_fee: 10 } + .build_storage() + .unwrap(), + ); r.into() } - #[test] fn test_check_btc_addr() { with_externalities(&mut new_test_ext(), || { - assert_ok!(financialrecords::Module::::deposit(&1, &b"btc".to_vec(), 1000)); + assert_ok!(financialrecords::Module::::deposit( + &1, + &b"btc".to_vec(), + 1000 + )); let origin = system::RawOrigin::Signed(1).into(); - assert_err!(Module::::withdraw(origin, b"btc".to_vec(), 100, b"sdfds".to_vec(), b"".to_vec()), - "verify btc addr err"); + assert_err!( + Module::::withdraw( + origin, + b"btc".to_vec(), + 100, + b"sdfds".to_vec(), + b"".to_vec() + ), + "verify btc addr err" + ); let origin = system::RawOrigin::Signed(1).into(); - assert_ok!(Module::::withdraw(origin, b"btc".to_vec(), 100, - "mjKE11gjVN4JaC9U8qL6ZB5vuEBgmwik7b".from_base58().unwrap(), - b"".to_vec())); + assert_ok!(Module::::withdraw( + origin, + b"btc".to_vec(), + 100, + "mjKE11gjVN4JaC9U8qL6ZB5vuEBgmwik7b".from_base58().unwrap(), + b"".to_vec() + )); }) -} \ No newline at end of file +} diff --git a/cxrml/multisig/src/lib.rs b/cxrml/multisig/src/lib.rs index b3013720ae0ef..b23da70694b34 100644 --- a/cxrml/multisig/src/lib.rs +++ b/cxrml/multisig/src/lib.rs @@ -33,31 +33,31 @@ extern crate sr_primitives as runtime_primitives; // Needed for type-safe access to storage DB. #[macro_use] extern crate srml_support as runtime_support; -extern crate srml_system as system; extern crate srml_balances as balances; +extern crate srml_system as system; // for chainx runtime module lib #[cfg(test)] -extern crate cxrml_system as cxsystem; -#[cfg(test)] extern crate cxrml_associations as associations; extern crate cxrml_support as cxsupport; +#[cfg(test)] +extern crate cxrml_system as cxsystem; -mod transaction; #[cfg(test)] mod tests; +mod transaction; use codec::{Codec, Decode, Encode}; -use rstd::prelude::*; use rstd::marker::PhantomData; +use rstd::prelude::*; use rstd::result::Result as StdResult; +use runtime_primitives::traits::{Hash, OnFinalise}; use runtime_support::dispatch::Result; use runtime_support::{StorageMap, StorageValue}; -use runtime_primitives::traits::{OnFinalise, Hash}; use system::ensure_signed; -use transaction::{TransactionType, Transaction, TransferT}; +use transaction::{Transaction, TransactionType, TransferT}; pub trait MultiSigFor { /// generate multisig addr for a accountid @@ -194,13 +194,14 @@ decl_storage! { pub struct SimpleMultiSigIdFor(PhantomData); impl MultiSigFor for SimpleMultiSigIdFor - where T::AccountId: From +where + T::AccountId: From, { fn multi_sig_addr_for(who: &T::AccountId) -> T::AccountId { let mut buf = Vec::::new(); buf.extend_from_slice(&who.encode()); buf.extend_from_slice(&>::account_nonce(who).encode()); - buf.extend_from_slice(&>::multi_sig_list_len_for(who).encode()); // in case same nonce in genesis + buf.extend_from_slice(&>::multi_sig_list_len_for(who).encode()); // in case same nonce in genesis T::Hashing::hash(&buf[..]).into() } @@ -223,18 +224,21 @@ impl Module { } impl Module { -// fn remove_multi_sig_addr(multi_sig_addr: &T::AccountId) { -// >::remove_prefix(multi_sig_addr.clone()); -// >::remove_prefix(multi_sig_addr.clone()); -// >::remove(multi_sig_addr); -// >::remove(multi_sig_addr); -// } + // fn remove_multi_sig_addr(multi_sig_addr: &T::AccountId) { + // >::remove_prefix(multi_sig_addr.clone()); + // >::remove_prefix(multi_sig_addr.clone()); + // >::remove(multi_sig_addr); + // >::remove(multi_sig_addr); + // } fn remove_multi_sig_id(multi_sig_addr: &T::AccountId, multi_sig_id: T::Hash) { Self::remove_pending_for(multi_sig_addr, multi_sig_id); Self::remove_tx_for(multi_sig_addr, multi_sig_id); // event - Self::deposit_event(RawEvent::RemoveMultiSigIdFor(multi_sig_addr.clone(), multi_sig_id)); + Self::deposit_event(RawEvent::RemoveMultiSigIdFor( + multi_sig_addr.clone(), + multi_sig_id, + )); } fn remove_pending_for(multi_sig_addr: &T::AccountId, multi_sig_id: T::Hash) { @@ -246,7 +250,11 @@ impl Module { >::remove((multi_sig_addr.clone(), multi_sig_id)); } - fn is_owner(who: &T::AccountId, addr: &T::AccountId, required: bool) -> StdResult { + fn is_owner( + who: &T::AccountId, + addr: &T::AccountId, + required: bool, + ) -> StdResult { if let Some(list_owner) = Self::multi_sig_list_owner_for(addr) { for (index, (id, req)) in list_owner.iter().enumerate() { if id == who { @@ -263,7 +271,11 @@ impl Module { Err("it's not the owner") } - fn confirm_and_check(who: &T::AccountId, multi_sig_addr: &T::AccountId, multi_sig_id: T::Hash) -> StdResult { + fn confirm_and_check( + who: &T::AccountId, + multi_sig_addr: &T::AccountId, + multi_sig_id: T::Hash, + ) -> StdResult { let index = Self::is_owner(who, multi_sig_addr, false)?; let key = (multi_sig_addr.clone(), multi_sig_id); @@ -296,7 +308,14 @@ impl Module { >::insert((multi_sig_addr.clone(), multi_sig_id), pending); ret = false; } - Self::deposit_event(RawEvent::Confirm(who.clone(), multi_sig_addr.clone(), multi_sig_id, pending.yet_needed, pending.index, ret)); + Self::deposit_event(RawEvent::Confirm( + who.clone(), + multi_sig_addr.clone(), + multi_sig_id, + pending.yet_needed, + pending.index, + ret, + )); } else { return Err("this account has confirmed for this multi sig addr and id"); } @@ -304,10 +323,18 @@ impl Module { } // func alias - fn only_owner(who: &T::AccountId, addr: &T::AccountId, required: bool) -> StdResult { + fn only_owner( + who: &T::AccountId, + addr: &T::AccountId, + required: bool, + ) -> StdResult { Self::is_owner(who, addr, required) } - fn only_many_owner(who: &T::AccountId, multi_sig_addr: &T::AccountId, multi_sig_id: T::Hash) -> StdResult { + fn only_many_owner( + who: &T::AccountId, + multi_sig_addr: &T::AccountId, + multi_sig_id: T::Hash, + ) -> StdResult { Self::confirm_and_check(who, multi_sig_addr, multi_sig_id) } } @@ -315,14 +342,30 @@ impl Module { impl Module { // public call #[allow(unused)] - fn deploy(origin: T::Origin, owners: Vec<(T::AccountId, bool)>, required_num: u32, value: T::Balance) -> Result { + fn deploy( + origin: T::Origin, + owners: Vec<(T::AccountId, bool)>, + required_num: u32, + value: T::Balance, + ) -> Result { let from = ensure_signed(origin)?; Self::deploy_for(&from, owners, required_num, value) } - fn deploy_for(account_id: &T::AccountId, owners: Vec<(T::AccountId, bool)>, required_num: u32, value: T::Balance) -> Result { + fn deploy_for( + account_id: &T::AccountId, + owners: Vec<(T::AccountId, bool)>, + required_num: u32, + value: T::Balance, + ) -> Result { let mut owners = owners; - if let None = owners.iter().find(|(a, _)| { if *a == *account_id { return true; } else { return false; } }) { + if let None = owners.iter().find(|(a, _)| { + if *a == *account_id { + return true; + } else { + return false; + } + }) { owners.push((account_id.clone(), true)); } @@ -345,8 +388,8 @@ impl Module { // 1 let len = Self::multi_sig_list_len_for(account_id); >::insert((account_id.clone(), len), multi_addr.clone()); - >::insert(account_id.clone(), len + 1); // length inc - // 2 + >::insert(account_id.clone(), len + 1); // length inc + // 2 >::insert(multi_addr.clone(), account_id.clone()); // 3 >::insert(multi_addr.clone(), owners.clone()); @@ -354,7 +397,13 @@ impl Module { >::insert(multi_addr.clone(), required_num); >::insert(multi_addr.clone(), owners_len); // event - Self::deposit_event(RawEvent::DeployMultiSig(account_id.clone(), multi_addr.clone(), owners_len, required_num, value)); + Self::deposit_event(RawEvent::DeployMultiSig( + account_id.clone(), + multi_addr.clone(), + owners_len, + required_num, + value, + )); Ok(()) }) } @@ -364,7 +413,12 @@ impl Module { Self::is_owner(&from, &multi_sig_addr, false).map(|_| ()) } - fn execute(origin: T::Origin, multi_sig_addr: T::AccountId, tx_type: TransactionType, data: Vec) -> Result { + fn execute( + origin: T::Origin, + multi_sig_addr: T::AccountId, + tx_type: TransactionType, + data: Vec, + ) -> Result { let from: T::AccountId = ensure_signed(origin)?; Self::only_owner(&from, &multi_sig_addr, true)?; @@ -387,7 +441,12 @@ impl Module { let origin = system::RawOrigin::Signed(from.clone()).into(); Self::confirm(origin, multi_sig_addr.clone(), multi_sig_id)?; } - Self::deposit_event(RawEvent::ExecMultiSig(from.clone(), multi_sig_addr.clone(), multi_sig_id, tx_type)); + Self::deposit_event(RawEvent::ExecMultiSig( + from.clone(), + multi_sig_addr.clone(), + multi_sig_id, + tx_type, + )); Ok(()) })?; } else { @@ -417,13 +476,20 @@ impl Module { })?; } else { // log event - Self::deposit_event(RawEvent::ConfirmFinish(multi_sig_addr.clone(), multi_sig_id)); + Self::deposit_event(RawEvent::ConfirmFinish( + multi_sig_addr.clone(), + multi_sig_id, + )); } Ok(()) } - fn remove_multi_sig_for(origin: T::Origin, multi_sig_addr: T::AccountId, multi_sig_id: T::Hash) -> Result { + fn remove_multi_sig_for( + origin: T::Origin, + multi_sig_addr: T::AccountId, + multi_sig_id: T::Hash, + ) -> Result { let from: T::AccountId = ensure_signed(origin)?; Self::only_owner(&from, &multi_sig_addr, true)?; @@ -478,22 +544,20 @@ impl Module { } #[cfg(feature = "std")] -pub struct BalancesConfigCopy (balances::GenesisConfig); +pub struct BalancesConfigCopy(balances::GenesisConfig); #[cfg(feature = "std")] impl BalancesConfigCopy { pub fn create_from_src(config: &balances::GenesisConfig) -> BalancesConfigCopy { - BalancesConfigCopy( - balances::GenesisConfig:: { - balances: config.balances.clone(), - transaction_base_fee: config.transaction_base_fee.clone(), - transaction_byte_fee: config.transaction_byte_fee.clone(), - transfer_fee: config.transfer_fee.clone(), - creation_fee: config.creation_fee.clone(), - reclaim_rebate: config.reclaim_rebate.clone(), - existential_deposit: config.existential_deposit.clone(), - } - ) + BalancesConfigCopy(balances::GenesisConfig:: { + balances: config.balances.clone(), + transaction_base_fee: config.transaction_base_fee.clone(), + transaction_byte_fee: config.transaction_byte_fee.clone(), + transfer_fee: config.transfer_fee.clone(), + creation_fee: config.creation_fee.clone(), + reclaim_rebate: config.reclaim_rebate.clone(), + existential_deposit: config.existential_deposit.clone(), + }) } pub fn src(self) -> balances::GenesisConfig { self.0 diff --git a/cxrml/multisig/src/tests.rs b/cxrml/multisig/src/tests.rs index 275b5c4c0b512..43be4ffbb31ff 100644 --- a/cxrml/multisig/src/tests.rs +++ b/cxrml/multisig/src/tests.rs @@ -1,15 +1,15 @@ // Copyright 2018 Chainpool. -use substrate_primitives::{H256, Blake2Hasher}; +use substrate_primitives::{Blake2Hasher, H256}; -use runtime_primitives::BuildStorage; -use runtime_primitives::traits::BlakeTwo256; -use runtime_primitives::testing::{Digest, DigestItem, Header}; use runtime_io; use runtime_io::with_externalities; +use runtime_primitives::testing::{Digest, DigestItem, Header}; +use runtime_primitives::traits::BlakeTwo256; +use runtime_primitives::BuildStorage; -use super::*; use super::transaction::*; +use super::*; impl_outer_origin! { pub enum Origin for Test {} @@ -20,7 +20,6 @@ pub type AccountId = H256; #[derive(Clone, Eq, PartialEq)] pub struct Test; - impl system::Trait for Test { type Origin = Origin; type Index = u64; @@ -60,10 +59,19 @@ type Balances = balances::Module; type MultiSig = Module; pub fn new_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); let b_config = balances::GenesisConfig:: { - balances: vec![(1.into(), 10000), (2.into(), 510), (3.into(), 1000), (4.into(), 500), (5.into(), 100), (6.into(), 100)], + balances: vec![ + (1.into(), 10000), + (2.into(), 510), + (3.into(), 1000), + (4.into(), 500), + (5.into(), 100), + (6.into(), 100), + ], transaction_base_fee: 0, transaction_byte_fee: 0, existential_deposit: 0, // better set 0 @@ -76,24 +84,51 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { // balance r.extend(b_config.build_storage().unwrap()); // financialrecords - r.extend(GenesisConfig:: { - genesis_multi_sig: vec![ - (1.into(), vec![(1.into(), true), (2.into(), true), (3.into(), true), (4.into(), false), (5.into(), false)], 3, 1000), - (1.into(), vec![(2.into(), true), (3.into(), false)], 3, 300), - (2.into(), vec![(1.into(), true), (3.into(), false)], 2, 100), - (3.into(), vec![(1.into(), true), (3.into(), false)], 2, 100), - (4.into(), vec![(1.into(), true), (2.into(), true), (3.into(), false), (100.into(), false)], 1, 100), - ], - deploy_fee: 10, - exec_fee: 10, - confirm_fee: 10, - balances_config: b_config_copy, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { + genesis_multi_sig: vec![ + ( + 1.into(), + vec![ + (1.into(), true), + (2.into(), true), + (3.into(), true), + (4.into(), false), + (5.into(), false), + ], + 3, + 1000, + ), + (1.into(), vec![(2.into(), true), (3.into(), false)], 3, 300), + (2.into(), vec![(1.into(), true), (3.into(), false)], 2, 100), + (3.into(), vec![(1.into(), true), (3.into(), false)], 2, 100), + ( + 4.into(), + vec![ + (1.into(), true), + (2.into(), true), + (3.into(), false), + (100.into(), false), + ], + 1, + 100, + ), + ], + deploy_fee: 10, + exec_fee: 10, + confirm_fee: 10, + balances_config: b_config_copy, + } + .build_storage() + .unwrap(), + ); r.into() } pub fn err_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); let b_config = balances::GenesisConfig:: { balances: vec![(1.into(), 100)], @@ -109,20 +144,35 @@ pub fn err_test_ext() -> runtime_io::TestExternalities { // balance r.extend(b_config.build_storage().unwrap()); // financialrecords - r.extend(GenesisConfig:: { - genesis_multi_sig: vec![ - (1.into(), vec![(1.into(), true), (2.into(), true), (3.into(), true), (4.into(), false), (5.into(), false)], 3, 1000), - ], - deploy_fee: 10, - exec_fee: 10, - confirm_fee: 10, - balances_config: b_config_copy, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { + genesis_multi_sig: vec![( + 1.into(), + vec![ + (1.into(), true), + (2.into(), true), + (3.into(), true), + (4.into(), false), + (5.into(), false), + ], + 3, + 1000, + )], + deploy_fee: 10, + exec_fee: 10, + confirm_fee: 10, + balances_config: b_config_copy, + } + .build_storage() + .unwrap(), + ); r.into() } pub fn err_test_ext2() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); let b_config = balances::GenesisConfig:: { balances: vec![], @@ -138,15 +188,28 @@ pub fn err_test_ext2() -> runtime_io::TestExternalities { // balance r.extend(b_config.build_storage().unwrap()); // financialrecords - r.extend(GenesisConfig:: { - genesis_multi_sig: vec![ - (1.into(), vec![(1.into(), true), (2.into(), true), (3.into(), true), (4.into(), false), (5.into(), false)], 3, 1000), - ], - deploy_fee: 10, - exec_fee: 10, - confirm_fee: 10, - balances_config: b_config_copy, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { + genesis_multi_sig: vec![( + 1.into(), + vec![ + (1.into(), true), + (2.into(), true), + (3.into(), true), + (4.into(), false), + (5.into(), false), + ], + 3, + 1000, + )], + deploy_fee: 10, + exec_fee: 10, + confirm_fee: 10, + balances_config: b_config_copy, + } + .build_storage() + .unwrap(), + ); r.into() } @@ -166,8 +229,14 @@ fn test_genesis() { for i in 0..MultiSig::multi_sig_list_len_for(&1.into()) { let addr = MultiSig::multi_sig_list_item_for((a.clone(), i)).unwrap(); println!("{:?} {:} {:?}", a, i, addr); - assert_eq!(Balances::total_balance(&addr), if i == 0 { 1000 } else { 300 }); - assert_eq!(MultiSig::num_owner_for(&addr).unwrap(), if i == 0 { 5 } else { 3 }); + assert_eq!( + Balances::total_balance(&addr), + if i == 0 { 1000 } else { 300 } + ); + assert_eq!( + MultiSig::num_owner_for(&addr).unwrap(), + if i == 0 { 5 } else { 3 } + ); assert_eq!(MultiSig::required_num_for(&addr).unwrap(), 3); } // for 2 @@ -185,7 +254,10 @@ fn test_genesis() { assert_eq!(MultiSig::required_num_for(&addr).unwrap(), 2); let origin = system::RawOrigin::Signed(c.clone()).into(); assert_ok!(MultiSig::is_owner_for(origin, addr)); - assert_err!(MultiSig::is_owner(&c, &addr, true), "it's the owner but not required owner"); + assert_err!( + MultiSig::is_owner(&c, &addr, true), + "it's the owner but not required owner" + ); }) } @@ -215,18 +287,33 @@ fn test_multisig() { let origin = system::RawOrigin::Signed(a.clone()).into(); // transfer let t = TransferT:: { to: a, value: 100 }; - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t.encode() + )); assert_eq!(MultiSig::pending_list_len_for(addr), 1); let multi_sig_id = MultiSig::pending_list_item_for((addr.clone(), 0)).unwrap(); - assert_eq!(MultiSig::pending_state_for((addr.clone(), multi_sig_id)), PendingState { yet_needed: 2, owners_done: 1, index: 0 }); + assert_eq!( + MultiSig::pending_state_for((addr.clone(), multi_sig_id)), + PendingState { + yet_needed: 2, + owners_done: 1, + index: 0 + } + ); //b let origin = system::RawOrigin::Signed(b.clone()).into(); assert_ok!(MultiSig::confirm(origin, addr, multi_sig_id)); //a let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_err!(MultiSig::confirm(origin, addr, multi_sig_id), "this account has confirmed for this multi sig addr and id"); + assert_err!( + MultiSig::confirm(origin, addr, multi_sig_id), + "this account has confirmed for this multi sig addr and id" + ); //e let origin = system::RawOrigin::Signed(e.clone()).into(); assert_ok!(MultiSig::confirm(origin, addr, multi_sig_id)); @@ -236,14 +323,27 @@ fn test_multisig() { assert_eq!(Balances::total_balance(&a), 8660 - 10 + 100); // has delete - assert_eq!(MultiSig::transaction_for((addr.clone(), multi_sig_id)), None); + assert_eq!( + MultiSig::transaction_for((addr.clone(), multi_sig_id)), + None + ); assert_eq!(MultiSig::pending_list_item_for((addr.clone(), 0)), None); - assert_eq!(MultiSig::pending_state_for((addr.clone(), multi_sig_id)), PendingState { yet_needed: 0, owners_done: 0, index: 0 }); + assert_eq!( + MultiSig::pending_state_for((addr.clone(), multi_sig_id)), + PendingState { + yet_needed: 0, + owners_done: 0, + index: 0 + } + ); //d let origin = system::RawOrigin::Signed(d.clone()).into(); - assert_err!(MultiSig::confirm(origin, addr, multi_sig_id), "no pending tx for this addr and id or it has finished"); + assert_err!( + MultiSig::confirm(origin, addr, multi_sig_id), + "no pending tx for this addr and id or it has finished" + ); }) } @@ -257,18 +357,32 @@ fn test_not_required_owner() { let addr = MultiSig::multi_sig_list_item_for((c.clone(), 0)).unwrap(); let origin = system::RawOrigin::Signed(c.clone()).into(); assert_ok!(MultiSig::is_owner_for(origin, addr)); - assert_err!(MultiSig::is_owner(&c, &addr, true), "it's the owner but not required owner"); + assert_err!( + MultiSig::is_owner(&c, &addr, true), + "it's the owner but not required owner" + ); let origin = system::RawOrigin::Signed(c.clone()).into(); let t = TransferT:: { to: a, value: 10 }; - assert_err!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode()), "it's the owner but not required owner"); + assert_err!( + MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode()), + "it's the owner but not required owner" + ); let origin = system::RawOrigin::Signed(b.clone()).into(); - assert_err!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode()), "it's not the owner"); + assert_err!( + MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode()), + "it's not the owner" + ); // exec success let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t.encode() + )); // confirm success let multi_sig_id = MultiSig::pending_list_item_for((addr.clone(), 0)).unwrap(); @@ -284,19 +398,37 @@ fn test_not_exist() { let origin = system::RawOrigin::Signed(a.clone()).into(); let t = TransferT:: { to: a, value: 10 }; - assert_err!(MultiSig::execute(origin, 0.into(), TransactionType::TransferChainX, t.encode()), "the multi sig addr not exist"); + assert_err!( + MultiSig::execute( + origin, + 0.into(), + TransactionType::TransferChainX, + t.encode() + ), + "the multi sig addr not exist" + ); let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_err!(MultiSig::confirm(origin, 0.into(), 0.into()), "the multi sig addr not exist"); - + assert_err!( + MultiSig::confirm(origin, 0.into(), 0.into()), + "the multi sig addr not exist" + ); let addr = MultiSig::multi_sig_list_item_for((a.clone(), 0)).unwrap(); let origin = system::RawOrigin::Signed(a.clone()).into(); // transfer let t = TransferT:: { to: a, value: 100 }; - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t.encode() + )); let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_err!(MultiSig::confirm(origin, addr, 0.into()), "no pending tx for this addr and id or it has finished"); + assert_err!( + MultiSig::confirm(origin, addr, 0.into()), + "no pending tx for this addr and id or it has finished" + ); }) } @@ -313,7 +445,12 @@ fn test_remove() { // transfer // a let t = TransferT:: { to: a, value: 100 }; - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t.encode() + )); let multi_sig_id = MultiSig::pending_list_item_for((addr.clone(), 0)).unwrap(); // b @@ -321,24 +458,54 @@ fn test_remove() { assert_ok!(MultiSig::confirm(origin, addr, multi_sig_id)); // yet need 1 - assert_eq!(MultiSig::pending_state_for((addr.clone(), multi_sig_id)), PendingState { yet_needed: 1, owners_done: 3, index: 0 }); + assert_eq!( + MultiSig::pending_state_for((addr.clone(), multi_sig_id)), + PendingState { + yet_needed: 1, + owners_done: 3, + index: 0 + } + ); // remove the pending // e can't remove let origin = system::RawOrigin::Signed(e.clone()).into(); - assert_err!(MultiSig::remove_multi_sig_for(origin, addr, multi_sig_id), "it's the owner but not required owner"); - assert_eq!(MultiSig::pending_state_for((addr.clone(), multi_sig_id)), PendingState { yet_needed: 1, owners_done: 3, index: 0 }); + assert_err!( + MultiSig::remove_multi_sig_for(origin, addr, multi_sig_id), + "it's the owner but not required owner" + ); + assert_eq!( + MultiSig::pending_state_for((addr.clone(), multi_sig_id)), + PendingState { + yet_needed: 1, + owners_done: 3, + index: 0 + } + ); // c remove let origin = system::RawOrigin::Signed(c.clone()).into(); assert_ok!(MultiSig::remove_multi_sig_for(origin, addr, multi_sig_id)); // has del - assert_eq!(MultiSig::transaction_for((addr.clone(), multi_sig_id)), None); - assert_eq!(MultiSig::pending_state_for((addr.clone(), multi_sig_id)), PendingState { yet_needed: 0, owners_done: 0, index: 0 }); + assert_eq!( + MultiSig::transaction_for((addr.clone(), multi_sig_id)), + None + ); + assert_eq!( + MultiSig::pending_state_for((addr.clone(), multi_sig_id)), + PendingState { + yet_needed: 0, + owners_done: 0, + index: 0 + } + ); let origin = system::RawOrigin::Signed(b.clone()).into(); - assert_err!(MultiSig::confirm(origin, addr, multi_sig_id), "no pending tx for this addr and id or it has finished"); + assert_err!( + MultiSig::confirm(origin, addr, multi_sig_id), + "no pending tx for this addr and id or it has finished" + ); }) } @@ -354,14 +521,24 @@ fn test_conflict() { // a let t = TransferT:: { to: a, value: 250 }; let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t.encode() + )); let multi_sig_id = MultiSig::pending_list_item_for((addr.clone(), 0)).unwrap(); // transfer2 // a let t2 = TransferT:: { to: b, value: 250 }; let origin = system::RawOrigin::Signed(b.clone()).into(); - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t2.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t2.encode() + )); let multi_sig_id2 = MultiSig::pending_list_item_for((addr.clone(), 1)).unwrap(); // confirm b sign for id1 @@ -376,20 +553,42 @@ fn test_conflict() { let origin = system::RawOrigin::Signed(c.clone()).into(); assert_ok!(MultiSig::confirm(origin, addr, multi_sig_id2)); // has del - assert_eq!(MultiSig::transaction_for((addr.clone(), multi_sig_id2)), None); - assert_eq!(MultiSig::pending_state_for((addr.clone(), multi_sig_id2)), PendingState { yet_needed: 0, owners_done: 0, index: 0 }); - - - assert_eq!(Balances::total_balance(&addr), 300 - 250 - 10); // 300 - 250 - 10(fee) + assert_eq!( + MultiSig::transaction_for((addr.clone(), multi_sig_id2)), + None + ); + assert_eq!( + MultiSig::pending_state_for((addr.clone(), multi_sig_id2)), + PendingState { + yet_needed: 0, + owners_done: 0, + index: 0 + } + ); + + assert_eq!(Balances::total_balance(&addr), 300 - 250 - 10); // 300 - 250 - 10(fee) // confirm c sign for id1 let origin = system::RawOrigin::Signed(c.clone()).into(); - assert_err!(MultiSig::confirm(origin, addr, multi_sig_id), "balance too low to send value"); + assert_err!( + MultiSig::confirm(origin, addr, multi_sig_id), + "balance too low to send value" + ); // has del - assert_eq!(MultiSig::transaction_for((addr.clone(), multi_sig_id)), None); - assert_eq!(MultiSig::pending_state_for((addr.clone(), multi_sig_id)), PendingState { yet_needed: 0, owners_done: 0, index: 0 }); - - assert_eq!(Balances::total_balance(&addr), 300 - 250 - 10); // 300 - 250 - 10(fee) + assert_eq!( + MultiSig::transaction_for((addr.clone(), multi_sig_id)), + None + ); + assert_eq!( + MultiSig::pending_state_for((addr.clone(), multi_sig_id)), + PendingState { + yet_needed: 0, + owners_done: 0, + index: 0 + } + ); + + assert_eq!(Balances::total_balance(&addr), 300 - 250 - 10); // 300 - 250 - 10(fee) }) } @@ -401,24 +600,34 @@ fn test_parse_err() { let addr = MultiSig::multi_sig_list_item_for((a.clone(), 1)).unwrap(); // transfer1 // a - let t: Vec = vec![b't', b'e', b's', b't', ]; + let t: Vec = vec![b't', b'e', b's', b't']; let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_err!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t), "parse err for this tx data"); + assert_err!( + MultiSig::execute(origin, addr, TransactionType::TransferChainX, t), + "parse err for this tx data" + ); let mut t = (TransferT:: { to: a, value: 250 }).encode(); let e = t.len() - 1; t.remove(e); let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_err!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t), "parse err for this tx data"); + assert_err!( + MultiSig::execute(origin, addr, TransactionType::TransferChainX, t), + "parse err for this tx data" + ); let mut t = (TransferT:: { to: a, value: 250 }).encode(); t.push(b'1'); let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t)); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t + )); }) } - #[test] fn test_single() { with_externalities(&mut new_test_ext(), || { @@ -432,7 +641,12 @@ fn test_single() { // a let t = TransferT:: { to: a, value: 5 }; let origin = system::RawOrigin::Signed(a.clone()).into(); - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t.encode() + )); assert_eq!(Balances::total_balance(&addr), 100 - 5 - 10); assert_eq!(MultiSig::pending_list_item_for((addr.clone(), 0)), None); // no pending state @@ -440,7 +654,12 @@ fn test_single() { // b let t = TransferT:: { to: a, value: 5 }; let origin = system::RawOrigin::Signed(b.clone()).into(); - assert_ok!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode())); + assert_ok!(MultiSig::execute( + origin, + addr, + TransactionType::TransferChainX, + t.encode() + )); assert_eq!(Balances::total_balance(&addr), 100 - 5 - 10 - 5 - 10); assert_eq!(MultiSig::pending_list_item_for((addr.clone(), 0)), None); // no pending state @@ -448,7 +667,10 @@ fn test_single() { // c can't let t = TransferT:: { to: a, value: 5 }; let origin = system::RawOrigin::Signed(c.clone()).into(); - assert_err!(MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode()), "it's the owner but not required owner"); + assert_err!( + MultiSig::execute(origin, addr, TransactionType::TransferChainX, t.encode()), + "it's the owner but not required owner" + ); assert_eq!(Balances::total_balance(&addr), 100 - 5 - 10 - 5 - 10); assert_eq!(MultiSig::pending_list_item_for((addr.clone(), 0)), None); // no pending state diff --git a/cxrml/multisig/src/transaction.rs b/cxrml/multisig/src/transaction.rs index ba4cac67c302d..fb398221db225 100644 --- a/cxrml/multisig/src/transaction.rs +++ b/cxrml/multisig/src/transaction.rs @@ -1,8 +1,7 @@ // Copyright 2018 Chainpool. +use super::{balances, system, Codec}; use rstd::prelude::*; -use super::{Codec, system, balances}; - #[derive(PartialEq, Eq, Clone, Copy, Encode, Decode)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] @@ -40,11 +39,13 @@ impl Transaction { #[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub struct Transfer - where AccountId: Codec, Balance: Codec, +where + AccountId: Codec, + Balance: Codec, { pub to: AccountId, pub value: Balance, } #[allow(unused)] -pub type TransferT = Transfer<::AccountId, ::Balance>; \ No newline at end of file +pub type TransferT = Transfer<::AccountId, ::Balance>; diff --git a/cxrml/staking/src/lib.rs b/cxrml/staking/src/lib.rs index 3723761d2064e..8a62619db70ba 100644 --- a/cxrml/staking/src/lib.rs +++ b/cxrml/staking/src/lib.rs @@ -205,7 +205,10 @@ decl_event!( } ); -pub type Nominations = CodecBTreeMap<::AccountId, NominationRecord<::Balance, ::BlockNumber>>; +pub type Nominations = CodecBTreeMap< + ::AccountId, + NominationRecord<::Balance, ::BlockNumber>, +>; decl_storage! { trait Store for Module as Staking { @@ -298,19 +301,26 @@ impl Module { /// Nomination of a nominator to his some nominee pub fn nomination_of(nominator: &T::AccountId, nominee: &T::AccountId) -> T::Balance { if let Some(record) = >::get(nominator).0.get(nominee) { - return record.nomination + return record.nomination; } Zero::zero() } - pub fn nomination_record_of(nominator: &T::AccountId, nominee: &T::AccountId) -> NominationRecord { + pub fn nomination_record_of( + nominator: &T::AccountId, + nominee: &T::AccountId, + ) -> NominationRecord { if let Some(record) = >::get(nominator).0.get(nominee) { - return record.clone() + return record.clone(); } >::default() } - pub fn insert_nomination_record(nominator: &T::AccountId, nominee: &T::AccountId, record: NominationRecord) { + pub fn insert_nomination_record( + nominator: &T::AccountId, + nominee: &T::AccountId, + record: NominationRecord, + ) { let mut nominations = >::get(nominator); nominations.0.insert(nominee.clone(), record); >::insert(nominator, nominations); @@ -347,7 +357,8 @@ impl Module { /// Sum of all candidates' total vote weight pub fn candidates_weight() -> u64 { - >::get().candidates + >::get() + .candidates .into_iter() .map(|v| Self::total_vote_weight(&v)) .fold(0, |acc, x| acc + x) @@ -910,7 +921,8 @@ impl Module { let validators = >::validators(); if vals_reward > 0 { for v in validators.iter() { - let val_reward = T::Balance::sa(Self::total_vote_weight(v) * vals_reward / vals_weight); + let val_reward = + T::Balance::sa(Self::total_vote_weight(v) * vals_reward / vals_weight); >::insert(v, val_reward); total_minted += val_reward; Self::reward(v, val_reward); @@ -921,7 +933,8 @@ impl Module { let candidates = >::get().candidates; if cands_reward > 0 { for c in candidates.iter() { - let cand_reward = T::Balance::sa(Self::total_vote_weight(c) * cands_reward / cands_weight); + let cand_reward = + T::Balance::sa(Self::total_vote_weight(c) * cands_reward / cands_weight); >::insert(c, cand_reward); total_minted += cand_reward; Self::reward(c, cand_reward); @@ -972,7 +985,7 @@ impl Module { // Avoid reevaluate validator set if it would leave us with fewer than the minimum // needed validators if intentions.len() < Self::minimum_validator_count() as usize { - return + return; } intentions.sort_unstable_by(|&(ref b1, _), &(ref b2, _)| b2.cmp(&b1)); diff --git a/cxrml/staking/src/mock.rs b/cxrml/staking/src/mock.rs index 678a247be08a2..09045d29e1f2d 100644 --- a/cxrml/staking/src/mock.rs +++ b/cxrml/staking/src/mock.rs @@ -18,12 +18,12 @@ #![cfg(test)] -use primitives::BuildStorage; -use primitives::{Perbill, traits::Identity}; use primitives::testing::{Digest, DigestItem, Header}; -use substrate_primitives::{H256, Blake2Hasher}; +use primitives::BuildStorage; +use primitives::{traits::Identity, Perbill}; use runtime_io; -use {GenesisConfig, Module, Trait, consensus, session, system, timestamp, balances}; +use substrate_primitives::{Blake2Hasher, H256}; +use {balances, consensus, session, system, timestamp, GenesisConfig, Module, Trait}; impl_outer_origin!{ pub enum Origin for Test {} @@ -77,58 +77,107 @@ pub fn new_test_ext( sessions_per_era: u64, current_era: u64, monied: bool, - reward: u64 + reward: u64, ) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap(); - let balance_factor = if ext_deposit > 0 { - 256 - } else { - 1 - }; - t.extend(consensus::GenesisConfig::{ - code: vec![], - authorities: vec![], - }.build_storage().unwrap()); - t.extend(session::GenesisConfig::{ - session_length, - validators: vec![10, 20], - }.build_storage().unwrap()); - t.extend(balances::GenesisConfig::{ - balances: if monied { - if reward > 0 { - vec![(1, 10 * balance_factor), (2, 20 * balance_factor), (3, 30 * balance_factor), (4, 40 * balance_factor), (10, balance_factor), (20, balance_factor)] + let mut t = system::GenesisConfig::::default() + .build_storage() + .unwrap(); + let balance_factor = if ext_deposit > 0 { 256 } else { 1 }; + t.extend( + consensus::GenesisConfig:: { + code: vec![], + authorities: vec![], + } + .build_storage() + .unwrap(), + ); + t.extend( + session::GenesisConfig:: { + session_length, + validators: vec![10, 20], + } + .build_storage() + .unwrap(), + ); + t.extend( + balances::GenesisConfig:: { + balances: if monied { + if reward > 0 { + vec![ + (1, 10 * balance_factor), + (2, 20 * balance_factor), + (3, 30 * balance_factor), + (4, 40 * balance_factor), + (10, balance_factor), + (20, balance_factor), + ] + } else { + vec![ + (1, 10 * balance_factor), + (2, 20 * balance_factor), + (3, 30 * balance_factor), + (4, 40 * balance_factor), + ] + } } else { - vec![(1, 10 * balance_factor), (2, 20 * balance_factor), (3, 30 * balance_factor), (4, 40 * balance_factor)] - } - } else { - vec![(10, balance_factor), (20, balance_factor)] - }, - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: ext_deposit, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + vec![(10, balance_factor), (20, balance_factor)] + }, + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: ext_deposit, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); let initial_authorities = vec![10, 20]; - t.extend(GenesisConfig::{ - sessions_per_era, - current_era, - intentions: vec![10, 20], - intention_profiles: initial_authorities.clone().into_iter().map(|i| (i, initial_authorities.clone().iter().position(|&r| r == i).unwrap().to_string().into_bytes().to_vec(), b"chianx.org".to_vec())).collect(), - validator_count: 2, - reward_per_sec: 3, - minimum_validator_count: 0, - bonding_duration: sessions_per_era * session_length, - session_reward: Perbill::from_millionths((1000000 * reward / balance_factor) as u32), - offline_slash: if monied { Perbill::from_percent(40) } else { Perbill::zero() }, - current_session_reward: reward, - current_offline_slash: 20, - offline_slash_grace: 0, - }.build_storage().unwrap()); - t.extend(timestamp::GenesisConfig::{ - period: 5 - }.build_storage().unwrap()); + t.extend( + GenesisConfig:: { + sessions_per_era, + current_era, + intentions: vec![10, 20], + intention_profiles: initial_authorities + .clone() + .into_iter() + .map(|i| { + ( + i, + initial_authorities + .clone() + .iter() + .position(|&r| r == i) + .unwrap() + .to_string() + .into_bytes() + .to_vec(), + b"chianx.org".to_vec(), + ) + }) + .collect(), + validator_count: 2, + reward_per_sec: 3, + minimum_validator_count: 0, + bonding_duration: sessions_per_era * session_length, + session_reward: Perbill::from_millionths((1000000 * reward / balance_factor) as u32), + offline_slash: if monied { + Perbill::from_percent(40) + } else { + Perbill::zero() + }, + current_session_reward: reward, + current_offline_slash: 20, + offline_slash_grace: 0, + } + .build_storage() + .unwrap(), + ); + t.extend( + timestamp::GenesisConfig:: { period: 5 } + .build_storage() + .unwrap(), + ); runtime_io::TestExternalities::new(t) } diff --git a/cxrml/staking/src/tests.rs b/cxrml/staking/src/tests.rs index df573c4dafc3b..1be9be5333f58 100644 --- a/cxrml/staking/src/tests.rs +++ b/cxrml/staking/src/tests.rs @@ -20,9 +20,9 @@ use super::*; use consensus::OnOfflineValidator; -use runtime_io::with_externalities; #[allow(unused_imports)] -use mock::{Balances, Session, Staking, System, Timestamp, Test, new_test_ext, Origin}; +use mock::{new_test_ext, Balances, Origin, Session, Staking, System, Test, Timestamp}; +use runtime_io::with_externalities; /* #[test] @@ -104,193 +104,190 @@ fn note_offline_grace_should_work() { // #[test] // fn note_offline_force_unstake_session_change_should_work() { - // with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { - // Balances::set_free_balance(&10, 70); - // Balances::set_free_balance(&20, 70); - // assert_ok!(Staking::stake(Origin::signed(1))); - - // assert_eq!(Staking::slash_count(&10), 0); - // assert_eq!(Balances::free_balance(&10), 70); - // assert_eq!(Staking::intentions(), vec![10, 20, 1]); - // assert_eq!(Session::validators(), vec![10, 20]); - - // System::set_extrinsic_index(1); - // Staking::on_offline_validator(0); - // assert_eq!(Balances::free_balance(&10), 50); - // assert_eq!(Staking::slash_count(&10), 1); - // assert_eq!(Staking::intentions(), vec![10, 20, 1]); - - // System::set_extrinsic_index(1); - // Staking::on_offline_validator(0); - // assert_eq!(Staking::intentions(), vec![1, 20]); - // assert_eq!(Balances::free_balance(&10), 10); - // assert!(Staking::forcing_new_era().is_some()); - // }); +// with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { +// Balances::set_free_balance(&10, 70); +// Balances::set_free_balance(&20, 70); +// assert_ok!(Staking::stake(Origin::signed(1))); + +// assert_eq!(Staking::slash_count(&10), 0); +// assert_eq!(Balances::free_balance(&10), 70); +// assert_eq!(Staking::intentions(), vec![10, 20, 1]); +// assert_eq!(Session::validators(), vec![10, 20]); + +// System::set_extrinsic_index(1); +// Staking::on_offline_validator(0); +// assert_eq!(Balances::free_balance(&10), 50); +// assert_eq!(Staking::slash_count(&10), 1); +// assert_eq!(Staking::intentions(), vec![10, 20, 1]); + +// System::set_extrinsic_index(1); +// Staking::on_offline_validator(0); +// assert_eq!(Staking::intentions(), vec![1, 20]); +// assert_eq!(Balances::free_balance(&10), 10); +// assert!(Staking::forcing_new_era().is_some()); +// }); // } // #[test] // fn note_offline_auto_unstake_session_change_should_work() { - // with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { - // Balances::set_free_balance(&10, 7000); - // Balances::set_free_balance(&20, 7000); - // assert_ok!(Staking::register_preferences(Origin::signed(10), 0, ValidatorPrefs { unstake_threshold: 1, validator_payment: 0 })); - - // assert_eq!(Staking::intentions(), vec![10, 20]); - - // System::set_extrinsic_index(1); - // Staking::on_offline_validator(0); - // Staking::on_offline_validator(1); - // assert_eq!(Balances::free_balance(&10), 6980); - // assert_eq!(Balances::free_balance(&20), 6980); - // assert_eq!(Staking::intentions(), vec![10, 20]); - // assert!(Staking::forcing_new_era().is_none()); - - // System::set_extrinsic_index(1); - // Staking::on_offline_validator(0); - // Staking::on_offline_validator(1); - // assert_eq!(Balances::free_balance(&10), 6940); - // assert_eq!(Balances::free_balance(&20), 6940); - // assert_eq!(Staking::intentions(), vec![20]); - // assert!(Staking::forcing_new_era().is_some()); - - // System::set_extrinsic_index(1); - // Staking::on_offline_validator(1); - // assert_eq!(Balances::free_balance(&10), 6940); - // assert_eq!(Balances::free_balance(&20), 6860); - // assert_eq!(Staking::intentions(), vec![20]); - - // System::set_extrinsic_index(1); - // Staking::on_offline_validator(1); - // assert_eq!(Balances::free_balance(&10), 6940); - // assert_eq!(Balances::free_balance(&20), 6700); - // assert_eq!(Staking::intentions(), vec![0u64; 0]); - // }); +// with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { +// Balances::set_free_balance(&10, 7000); +// Balances::set_free_balance(&20, 7000); +// assert_ok!(Staking::register_preferences(Origin::signed(10), 0, ValidatorPrefs { unstake_threshold: 1, validator_payment: 0 })); + +// assert_eq!(Staking::intentions(), vec![10, 20]); + +// System::set_extrinsic_index(1); +// Staking::on_offline_validator(0); +// Staking::on_offline_validator(1); +// assert_eq!(Balances::free_balance(&10), 6980); +// assert_eq!(Balances::free_balance(&20), 6980); +// assert_eq!(Staking::intentions(), vec![10, 20]); +// assert!(Staking::forcing_new_era().is_none()); + +// System::set_extrinsic_index(1); +// Staking::on_offline_validator(0); +// Staking::on_offline_validator(1); +// assert_eq!(Balances::free_balance(&10), 6940); +// assert_eq!(Balances::free_balance(&20), 6940); +// assert_eq!(Staking::intentions(), vec![20]); +// assert!(Staking::forcing_new_era().is_some()); + +// System::set_extrinsic_index(1); +// Staking::on_offline_validator(1); +// assert_eq!(Balances::free_balance(&10), 6940); +// assert_eq!(Balances::free_balance(&20), 6860); +// assert_eq!(Staking::intentions(), vec![20]); + +// System::set_extrinsic_index(1); +// Staking::on_offline_validator(1); +// assert_eq!(Balances::free_balance(&10), 6940); +// assert_eq!(Balances::free_balance(&20), 6700); +// assert_eq!(Staking::intentions(), vec![0u64; 0]); +// }); // } - // #[test] // fn rewards_should_work() { - // with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { - // assert_eq!(Staking::era_length(), 9); - // assert_eq!(Staking::sessions_per_era(), 3); - // assert_eq!(Staking::last_era_length_change(), 0); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::current_index(), 0); - // assert_eq!(Balances::total_balance(&10), 1); - - // System::set_block_number(3); - // Timestamp::set_timestamp(15); // on time. - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::current_index(), 1); - // assert_eq!(Balances::total_balance(&10), 11); - // System::set_block_number(6); - // Timestamp::set_timestamp(31); // a little late - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::current_index(), 2); - // assert_eq!(Balances::total_balance(&10), 20); // less reward - // System::set_block_number(9); - // Timestamp::set_timestamp(50); // very late - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 1); - // assert_eq!(Session::current_index(), 3); - // assert_eq!(Balances::total_balance(&10), 27); // much less reward - // }); +// with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { +// assert_eq!(Staking::era_length(), 9); +// assert_eq!(Staking::sessions_per_era(), 3); +// assert_eq!(Staking::last_era_length_change(), 0); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::current_index(), 0); +// assert_eq!(Balances::total_balance(&10), 1); + +// System::set_block_number(3); +// Timestamp::set_timestamp(15); // on time. +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::current_index(), 1); +// assert_eq!(Balances::total_balance(&10), 11); +// System::set_block_number(6); +// Timestamp::set_timestamp(31); // a little late +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::current_index(), 2); +// assert_eq!(Balances::total_balance(&10), 20); // less reward +// System::set_block_number(9); +// Timestamp::set_timestamp(50); // very late +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 1); +// assert_eq!(Session::current_index(), 3); +// assert_eq!(Balances::total_balance(&10), 27); // much less reward +// }); // } // #[test] // fn slashing_should_work() { - // with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { - // assert_eq!(Staking::era_length(), 9); - // assert_eq!(Staking::sessions_per_era(), 3); - // assert_eq!(Staking::last_era_length_change(), 0); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::current_index(), 0); - // assert_eq!(Balances::total_balance(&10), 1); - - // System::set_block_number(3); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::current_index(), 1); - // assert_eq!(Balances::total_balance(&10), 11); - - // System::set_block_number(6); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::current_index(), 2); - // assert_eq!(Balances::total_balance(&10), 21); - - // System::set_block_number(7); - // System::set_extrinsic_index(1); - // Staking::on_offline_validator(0); - // Staking::on_offline_validator(1); - // assert_eq!(Balances::total_balance(&10), 1); - // }); +// with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { +// assert_eq!(Staking::era_length(), 9); +// assert_eq!(Staking::sessions_per_era(), 3); +// assert_eq!(Staking::last_era_length_change(), 0); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::current_index(), 0); +// assert_eq!(Balances::total_balance(&10), 1); + +// System::set_block_number(3); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::current_index(), 1); +// assert_eq!(Balances::total_balance(&10), 11); + +// System::set_block_number(6); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::current_index(), 2); +// assert_eq!(Balances::total_balance(&10), 21); + +// System::set_block_number(7); +// System::set_extrinsic_index(1); +// Staking::on_offline_validator(0); +// Staking::on_offline_validator(1); +// assert_eq!(Balances::total_balance(&10), 1); +// }); // } - - // #[test] // fn staking_should_work() { - // with_externalities(&mut new_test_ext(0, 1, 2, 0, true, 0), || { - - // assert_eq!(Staking::era_length(), 2); - // assert_eq!(Staking::validator_count(), 2); - // assert_eq!(Session::validators(), vec![10, 20]); - - // assert_ok!(Staking::set_bonding_duration(2)); - // assert_eq!(Staking::bonding_duration(), 2); - - // // Block 1: Add three validators. No obvious change. - // System::set_block_number(1); - // assert_ok!(Staking::stake(Origin::signed(1))); - // assert_ok!(Staking::stake(Origin::signed(2))); - // assert_ok!(Staking::stake(Origin::signed(4))); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::validators(), vec![10, 20]); - - // // Block 2: New validator set now. - // System::set_block_number(2); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 1); - // assert_eq!(Session::validators(), vec![4, 2]); - - // // Block 3: Unstake highest, introduce another staker. No change yet. - // System::set_block_number(3); - // assert_ok!(Staking::stake(Origin::signed(3))); - // assert_ok!(Staking::unstake(Origin::signed(4), Staking::intentions().iter().position(|&x| x == 4).unwrap() as u32)); - // assert_eq!(Staking::current_era(), 1); - // Session::check_rotate_session(System::block_number()); - - // // Block 4: New era - validators change. - // System::set_block_number(4); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 2); - // assert_eq!(Session::validators(), vec![3, 2]); - - // // Block 5: Transfer stake from highest to lowest. No change yet. - // System::set_block_number(5); - // assert_ok!(Balances::transfer(Origin::signed(4), 1.into(), 40)); - // Session::check_rotate_session(System::block_number()); - - // // Block 6: Lowest now validator. - // System::set_block_number(6); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::validators(), vec![1, 3]); - - // // Block 7: Unstake three. No change yet. - // System::set_block_number(7); - // assert_ok!(Staking::unstake(Origin::signed(3), Staking::intentions().iter().position(|&x| x == 3).unwrap() as u32)); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::validators(), vec![1, 3]); - - // // Block 8: Back to one and two. - // System::set_block_number(8); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::validators(), vec![1, 2]); - // }); +// with_externalities(&mut new_test_ext(0, 1, 2, 0, true, 0), || { + +// assert_eq!(Staking::era_length(), 2); +// assert_eq!(Staking::validator_count(), 2); +// assert_eq!(Session::validators(), vec![10, 20]); + +// assert_ok!(Staking::set_bonding_duration(2)); +// assert_eq!(Staking::bonding_duration(), 2); + +// // Block 1: Add three validators. No obvious change. +// System::set_block_number(1); +// assert_ok!(Staking::stake(Origin::signed(1))); +// assert_ok!(Staking::stake(Origin::signed(2))); +// assert_ok!(Staking::stake(Origin::signed(4))); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::validators(), vec![10, 20]); + +// // Block 2: New validator set now. +// System::set_block_number(2); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 1); +// assert_eq!(Session::validators(), vec![4, 2]); + +// // Block 3: Unstake highest, introduce another staker. No change yet. +// System::set_block_number(3); +// assert_ok!(Staking::stake(Origin::signed(3))); +// assert_ok!(Staking::unstake(Origin::signed(4), Staking::intentions().iter().position(|&x| x == 4).unwrap() as u32)); +// assert_eq!(Staking::current_era(), 1); +// Session::check_rotate_session(System::block_number()); + +// // Block 4: New era - validators change. +// System::set_block_number(4); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 2); +// assert_eq!(Session::validators(), vec![3, 2]); + +// // Block 5: Transfer stake from highest to lowest. No change yet. +// System::set_block_number(5); +// assert_ok!(Balances::transfer(Origin::signed(4), 1.into(), 40)); +// Session::check_rotate_session(System::block_number()); + +// // Block 6: Lowest now validator. +// System::set_block_number(6); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::validators(), vec![1, 3]); + +// // Block 7: Unstake three. No change yet. +// System::set_block_number(7); +// assert_ok!(Staking::unstake(Origin::signed(3), Staking::intentions().iter().position(|&x| x == 3).unwrap() as u32)); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::validators(), vec![1, 3]); + +// // Block 8: Back to one and two. +// System::set_block_number(8); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::validators(), vec![1, 2]); +// }); // } #[test] @@ -307,9 +304,24 @@ fn nominating_and_rewards_should_work() { System::set_block_number(1); - assert_ok!(Staking::stake(Origin::signed(1), String::from("1").into_bytes(), String::from("url").into_bytes(), 10)); - assert_ok!(Staking::stake(Origin::signed(2), String::from("2").into_bytes(), String::from("url").into_bytes(), 10)); - assert_ok!(Staking::stake(Origin::signed(3), String::from("3").into_bytes(), String::from("url").into_bytes(), 20)); + assert_ok!(Staking::stake( + Origin::signed(1), + String::from("1").into_bytes(), + String::from("url").into_bytes(), + 10 + )); + assert_ok!(Staking::stake( + Origin::signed(2), + String::from("2").into_bytes(), + String::from("url").into_bytes(), + 10 + )); + assert_ok!(Staking::stake( + Origin::signed(3), + String::from("3").into_bytes(), + String::from("url").into_bytes(), + 20 + )); System::set_block_number(2); assert_ok!(Staking::nominate(Origin::signed(4), 2.into(), 30)); @@ -378,77 +390,76 @@ fn nominating_and_rewards_should_work() { System::set_block_number(9); Session::check_rotate_session(System::block_number()); - }); } // TODO change to current // #[test] // fn nominating_and_rewards_should_work() { - // with_externalities(&mut new_test_ext(0, 1, 1, 0, true, 10), || { - // assert_eq!(Staking::era_length(), 1); - // assert_eq!(Staking::validator_count(), 2); - // assert_eq!(Staking::bonding_duration(), 3); - // assert_eq!(Session::validators(), vec![10, 20]); - - // //////// Old - // // session_reward 10 - - // System::set_block_number(1); - // assert_ok!(Staking::stake(Origin::signed(1))); - // assert_ok!(Staking::stake(Origin::signed(2))); - // assert_ok!(Staking::stake(Origin::signed(3))); - // assert_ok!(Staking::nominate(Origin::signed(4), 1.into())); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 1); - // assert_eq!(Session::validators(), vec![1, 3]); // 4 + 1, 3 - // // 1 + 10 - // assert_eq!(Balances::total_balance(&10), 11); - // assert_eq!(Balances::total_balance(&20), 11); - // assert_eq!(Balances::total_balance(&1), 10); - // assert_eq!(Balances::total_balance(&2), 20); - // assert_eq!(Balances::total_balance(&3), 30); - // assert_eq!(Balances::total_balance(&4), 40); - // // session reward (10+40+30+20)/3 - - // System::set_block_number(2); - // assert_ok!(Staking::unnominate(Origin::signed(4), 0)); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Staking::current_era(), 2); - // assert_eq!(Session::validators(), vec![3, 2]); - // assert_eq!(Balances::total_balance(&10), 11); - // assert_eq!(Balances::total_balance(&20), 11); - // // 10 + 10 + 10 + 20 + 30 + 40 = 120 - // // average_stake = 120 / 5 = 24 - // // validator 1: 10 * 10/(10 + 40) = 4 - // // 10 + 24 * 10/(10+40) = 14 - // assert_eq!(Balances::total_balance(&1), 14); - // assert_eq!(Balances::total_balance(&2), 20); - // // average_stake 24 - // // Perbill(1000000000) session_reward * average_stake - // // 30 + 24 - // assert_eq!(Balances::total_balance(&3), 54); - // // 24 * 40 / 50 = 19 - // assert_eq!(Balances::total_balance(&4), 59); - - // System::set_block_number(3); - // assert_ok!(Staking::stake(Origin::signed(4))); - // assert_ok!(Staking::unstake(Origin::signed(3), Staking::intentions().iter().position(|&x| x == 3).unwrap() as u32)); - // assert_ok!(Staking::nominate(Origin::signed(3), 1.into())); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::validators(), vec![1, 4]); - // assert_eq!(Balances::total_balance(&1), 14); - // assert_eq!(Balances::total_balance(&2), 42); - // assert_eq!(Balances::total_balance(&3), 76); - // assert_eq!(Balances::total_balance(&4), 59); - - // System::set_block_number(4); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Balances::total_balance(&1), 20); - // assert_eq!(Balances::total_balance(&2), 42); - // assert_eq!(Balances::total_balance(&3), 111); - // assert_eq!(Balances::total_balance(&4), 101); - // }); +// with_externalities(&mut new_test_ext(0, 1, 1, 0, true, 10), || { +// assert_eq!(Staking::era_length(), 1); +// assert_eq!(Staking::validator_count(), 2); +// assert_eq!(Staking::bonding_duration(), 3); +// assert_eq!(Session::validators(), vec![10, 20]); + +// //////// Old +// // session_reward 10 + +// System::set_block_number(1); +// assert_ok!(Staking::stake(Origin::signed(1))); +// assert_ok!(Staking::stake(Origin::signed(2))); +// assert_ok!(Staking::stake(Origin::signed(3))); +// assert_ok!(Staking::nominate(Origin::signed(4), 1.into())); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 1); +// assert_eq!(Session::validators(), vec![1, 3]); // 4 + 1, 3 +// // 1 + 10 +// assert_eq!(Balances::total_balance(&10), 11); +// assert_eq!(Balances::total_balance(&20), 11); +// assert_eq!(Balances::total_balance(&1), 10); +// assert_eq!(Balances::total_balance(&2), 20); +// assert_eq!(Balances::total_balance(&3), 30); +// assert_eq!(Balances::total_balance(&4), 40); +// // session reward (10+40+30+20)/3 + +// System::set_block_number(2); +// assert_ok!(Staking::unnominate(Origin::signed(4), 0)); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Staking::current_era(), 2); +// assert_eq!(Session::validators(), vec![3, 2]); +// assert_eq!(Balances::total_balance(&10), 11); +// assert_eq!(Balances::total_balance(&20), 11); +// // 10 + 10 + 10 + 20 + 30 + 40 = 120 +// // average_stake = 120 / 5 = 24 +// // validator 1: 10 * 10/(10 + 40) = 4 +// // 10 + 24 * 10/(10+40) = 14 +// assert_eq!(Balances::total_balance(&1), 14); +// assert_eq!(Balances::total_balance(&2), 20); +// // average_stake 24 +// // Perbill(1000000000) session_reward * average_stake +// // 30 + 24 +// assert_eq!(Balances::total_balance(&3), 54); +// // 24 * 40 / 50 = 19 +// assert_eq!(Balances::total_balance(&4), 59); + +// System::set_block_number(3); +// assert_ok!(Staking::stake(Origin::signed(4))); +// assert_ok!(Staking::unstake(Origin::signed(3), Staking::intentions().iter().position(|&x| x == 3).unwrap() as u32)); +// assert_ok!(Staking::nominate(Origin::signed(3), 1.into())); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::validators(), vec![1, 4]); +// assert_eq!(Balances::total_balance(&1), 14); +// assert_eq!(Balances::total_balance(&2), 42); +// assert_eq!(Balances::total_balance(&3), 76); +// assert_eq!(Balances::total_balance(&4), 59); + +// System::set_block_number(4); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Balances::total_balance(&1), 20); +// assert_eq!(Balances::total_balance(&2), 42); +// assert_eq!(Balances::total_balance(&3), 111); +// assert_eq!(Balances::total_balance(&4), 101); +// }); // } //#[test] @@ -513,101 +524,101 @@ fn nominating_and_rewards_should_work() { // #[test] // fn double_staking_should_fail() { - // with_externalities(&mut new_test_ext(0, 1, 2, 0, true, 0), || { - // System::set_block_number(1); - // assert_ok!(Staking::stake(Origin::signed(1))); - // assert_noop!(Staking::stake(Origin::signed(1)), "Cannot stake if already staked."); - // assert_noop!(Staking::nominate(Origin::signed(1), 1.into()), "Cannot nominate if already staked."); - // assert_ok!(Staking::nominate(Origin::signed(2), 1.into())); - // assert_noop!(Staking::stake(Origin::signed(2)), "Cannot stake if already nominating."); - // assert_noop!(Staking::nominate(Origin::signed(2), 1.into()), "Cannot nominate if already nominating."); - // }); +// with_externalities(&mut new_test_ext(0, 1, 2, 0, true, 0), || { +// System::set_block_number(1); +// assert_ok!(Staking::stake(Origin::signed(1))); +// assert_noop!(Staking::stake(Origin::signed(1)), "Cannot stake if already staked."); +// assert_noop!(Staking::nominate(Origin::signed(1), 1.into()), "Cannot nominate if already staked."); +// assert_ok!(Staking::nominate(Origin::signed(2), 1.into())); +// assert_noop!(Staking::stake(Origin::signed(2)), "Cannot stake if already nominating."); +// assert_noop!(Staking::nominate(Origin::signed(2), 1.into()), "Cannot nominate if already nominating."); +// }); // } // #[test] // fn staking_eras_work() { - // with_externalities(&mut new_test_ext(0, 1, 2, 0, true, 0), || { - // assert_eq!(Staking::era_length(), 2); - // assert_eq!(Staking::sessions_per_era(), 2); - // assert_eq!(Staking::last_era_length_change(), 0); - // assert_eq!(Staking::current_era(), 0); - // assert_eq!(Session::current_index(), 0); - - // // Block 1: No change. - // System::set_block_number(1); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::current_index(), 1); - // assert_eq!(Staking::sessions_per_era(), 2); - // assert_eq!(Staking::last_era_length_change(), 0); - // assert_eq!(Staking::current_era(), 0); - - // // Block 2: Simple era change. - // System::set_block_number(2); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::current_index(), 2); - // assert_eq!(Staking::sessions_per_era(), 2); - // assert_eq!(Staking::last_era_length_change(), 0); - // assert_eq!(Staking::current_era(), 1); - - // // Block 3: Schedule an era length change; no visible changes. - // System::set_block_number(3); - // assert_ok!(Staking::set_sessions_per_era(3)); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::current_index(), 3); - // assert_eq!(Staking::sessions_per_era(), 2); - // assert_eq!(Staking::last_era_length_change(), 0); - // assert_eq!(Staking::current_era(), 1); - - // // Block 4: Era change kicks in. - // System::set_block_number(4); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::current_index(), 4); - // assert_eq!(Staking::sessions_per_era(), 3); - // assert_eq!(Staking::last_era_length_change(), 4); - // assert_eq!(Staking::current_era(), 2); - - // // Block 5: No change. - // System::set_block_number(5); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::current_index(), 5); - // assert_eq!(Staking::sessions_per_era(), 3); - // assert_eq!(Staking::last_era_length_change(), 4); - // assert_eq!(Staking::current_era(), 2); - - // // Block 6: No change. - // System::set_block_number(6); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::current_index(), 6); - // assert_eq!(Staking::sessions_per_era(), 3); - // assert_eq!(Staking::last_era_length_change(), 4); - // assert_eq!(Staking::current_era(), 2); - - // // Block 7: Era increment. - // System::set_block_number(7); - // Session::check_rotate_session(System::block_number()); - // assert_eq!(Session::current_index(), 7); - // assert_eq!(Staking::sessions_per_era(), 3); - // assert_eq!(Staking::last_era_length_change(), 4); - // assert_eq!(Staking::current_era(), 3); - // }); +// with_externalities(&mut new_test_ext(0, 1, 2, 0, true, 0), || { +// assert_eq!(Staking::era_length(), 2); +// assert_eq!(Staking::sessions_per_era(), 2); +// assert_eq!(Staking::last_era_length_change(), 0); +// assert_eq!(Staking::current_era(), 0); +// assert_eq!(Session::current_index(), 0); + +// // Block 1: No change. +// System::set_block_number(1); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::current_index(), 1); +// assert_eq!(Staking::sessions_per_era(), 2); +// assert_eq!(Staking::last_era_length_change(), 0); +// assert_eq!(Staking::current_era(), 0); + +// // Block 2: Simple era change. +// System::set_block_number(2); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::current_index(), 2); +// assert_eq!(Staking::sessions_per_era(), 2); +// assert_eq!(Staking::last_era_length_change(), 0); +// assert_eq!(Staking::current_era(), 1); + +// // Block 3: Schedule an era length change; no visible changes. +// System::set_block_number(3); +// assert_ok!(Staking::set_sessions_per_era(3)); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::current_index(), 3); +// assert_eq!(Staking::sessions_per_era(), 2); +// assert_eq!(Staking::last_era_length_change(), 0); +// assert_eq!(Staking::current_era(), 1); + +// // Block 4: Era change kicks in. +// System::set_block_number(4); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::current_index(), 4); +// assert_eq!(Staking::sessions_per_era(), 3); +// assert_eq!(Staking::last_era_length_change(), 4); +// assert_eq!(Staking::current_era(), 2); + +// // Block 5: No change. +// System::set_block_number(5); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::current_index(), 5); +// assert_eq!(Staking::sessions_per_era(), 3); +// assert_eq!(Staking::last_era_length_change(), 4); +// assert_eq!(Staking::current_era(), 2); + +// // Block 6: No change. +// System::set_block_number(6); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::current_index(), 6); +// assert_eq!(Staking::sessions_per_era(), 3); +// assert_eq!(Staking::last_era_length_change(), 4); +// assert_eq!(Staking::current_era(), 2); + +// // Block 7: Era increment. +// System::set_block_number(7); +// Session::check_rotate_session(System::block_number()); +// assert_eq!(Session::current_index(), 7); +// assert_eq!(Staking::sessions_per_era(), 3); +// assert_eq!(Staking::last_era_length_change(), 4); +// assert_eq!(Staking::current_era(), 3); +// }); // } // #[test] // fn staking_balance_transfer_when_bonded_should_not_work() { - // with_externalities(&mut new_test_ext(0, 1, 3, 1, false, 0), || { - // Balances::set_free_balance(&1, 111); - // assert_ok!(Staking::stake(Origin::signed(1))); - // assert_noop!(Balances::transfer(Origin::signed(1), 2.into(), 69), "cannot transfer illiquid funds"); - // }); +// with_externalities(&mut new_test_ext(0, 1, 3, 1, false, 0), || { +// Balances::set_free_balance(&1, 111); +// assert_ok!(Staking::stake(Origin::signed(1))); +// assert_noop!(Balances::transfer(Origin::signed(1), 2.into(), 69), "cannot transfer illiquid funds"); +// }); // } // #[test] // fn deducting_balance_when_bonded_should_not_work() { - // with_externalities(&mut new_test_ext(0, 1, 3, 1, false, 0), || { - // Balances::set_free_balance(&1, 111); - // >::insert(1, 2); - // System::set_block_number(1); - // assert_eq!(Staking::unlock_block(&1), LockStatus::LockedUntil(2)); - // assert_noop!(Balances::reserve(&1, 69), "cannot transfer illiquid funds"); - // }); +// with_externalities(&mut new_test_ext(0, 1, 3, 1, false, 0), || { +// Balances::set_free_balance(&1, 111); +// >::insert(1, 2); +// System::set_block_number(1); +// assert_eq!(Staking::unlock_block(&1), LockStatus::LockedUntil(2)); +// assert_noop!(Balances::reserve(&1, 69), "cannot transfer illiquid funds"); +// }); // } diff --git a/cxrml/support/src/lib.rs b/cxrml/support/src/lib.rs index 96c330ba09f90..0268af63573c1 100644 --- a/cxrml/support/src/lib.rs +++ b/cxrml/support/src/lib.rs @@ -8,22 +8,22 @@ extern crate parity_codec_derive; #[cfg(feature = "std")] #[macro_use] extern crate serde_derive; -#[cfg(test)] -extern crate substrate_primitives; extern crate sr_io as runtime_io; extern crate sr_primitives as primitives; extern crate sr_std as rstd; extern crate srml_balances as balances; +#[cfg(test)] +extern crate substrate_primitives; #[macro_use] extern crate srml_support as runtime_support; extern crate srml_system as system; -extern crate cxrml_system as cxsystem; extern crate cxrml_associations as associations; +extern crate cxrml_system as cxsystem; // use balances::EnsureAccountLiquid; +use primitives::traits::{As, CheckedAdd, CheckedSub, OnFinalise, Zero}; use rstd::prelude::*; -use primitives::traits::{CheckedSub, CheckedAdd, OnFinalise, As, Zero}; use runtime_support::dispatch::Result; pub use storage::double_map::StorageDoubleMap; @@ -51,14 +51,20 @@ impl associations::OnCalcFee for Module { pub trait Trait: associations::Trait + cxsystem::Trait {} impl Module { - fn calc_fee_withaccount(who: &T::AccountId, fee: T::Balance, rate: &[(usize, T::AccountId)]) -> Result { + fn calc_fee_withaccount( + who: &T::AccountId, + fee: T::Balance, + rate: &[(usize, T::AccountId)], + ) -> Result { let from_balance = >::free_balance(who); let new_from_balance = match from_balance.checked_sub(&fee) { Some(b) => b, None => return Err("chainx balance too low to exec this option"), }; - if rate.len() < 1 { panic!("can't input a empty rate array") } + if rate.len() < 1 { + panic!("can't input a empty rate array") + } if rate.len() == 1 { let to_balance = >::free_balance(&rate[0].1); let new_to_balance = match to_balance.checked_add(&fee) { @@ -119,11 +125,16 @@ impl Module { Self::calc_fee_withaccount(from_who, fee, v.as_slice()) } - // util function /// handle the fee with the func, deduct fee before exec func, notice the fee have been deducted before func, so if the func return err, the balance already be deducted. - pub fn handle_fee_before(who: &T::AccountId, fee: T::Balance, check_after_open: bool, mut func: F) -> Result - where F: FnMut() -> Result + pub fn handle_fee_before( + who: &T::AccountId, + fee: T::Balance, + check_after_open: bool, + mut func: F, + ) -> Result + where + F: FnMut() -> Result, { let from_balance = >::free_balance(who); let new_from_balance = match from_balance.checked_sub(&fee) { @@ -132,7 +143,9 @@ impl Module { }; // ::EnsureAccountLiquid::ensure_account_liquid(who)?; if check_after_open && new_from_balance < >::existential_deposit() { - return Err("chainx balance is not enough after this tx, not allow to be killed at here"); + return Err( + "chainx balance is not enough after this tx, not allow to be killed at here", + ); } // deduct free @@ -141,10 +154,15 @@ impl Module { func() } - /// handle the fee with the func, deduct fee after exec func, notice the func can't do anything related with balance - pub fn handle_fee_after(who: &T::AccountId, fee: T::Balance, check_after_open: bool, mut func: F) -> Result - where F: FnMut() -> Result + pub fn handle_fee_after( + who: &T::AccountId, + fee: T::Balance, + check_after_open: bool, + mut func: F, + ) -> Result + where + F: FnMut() -> Result, { let from_balance = >::free_balance(who); let new_from_balance = match from_balance.checked_sub(&fee) { @@ -153,7 +171,9 @@ impl Module { }; // ::EnsureAccountLiquid::ensure_account_liquid(who)?; if check_after_open && new_from_balance < >::existential_deposit() { - return Err("chainx balance is not enough after this tx, not allow to be killed at here"); + return Err( + "chainx balance is not enough after this tx, not allow to be killed at here", + ); } func()?; diff --git a/cxrml/support/src/storage/btree_map.rs b/cxrml/support/src/storage/btree_map.rs index 84c5609827c1d..1f22bec960e92 100644 --- a/cxrml/support/src/storage/btree_map.rs +++ b/cxrml/support/src/storage/btree_map.rs @@ -1,4 +1,4 @@ -use codec::{Encode, Decode, Output, Input}; +use codec::{Decode, Encode, Input, Output}; use rstd::collections::btree_map::BTreeMap; #[derive(Default)] @@ -8,7 +8,10 @@ pub struct CodecBTreeMap(pub BTreeMap); impl Encode for CodecBTreeMap { fn encode_to(&self, dest: &mut W) { let len = self.0.len(); - assert!(len <= u32::max_value() as usize, "Attempted to serialize a collection with too many elements."); + assert!( + len <= u32::max_value() as usize, + "Attempted to serialize a collection with too many elements." + ); (len as u32).encode_to(dest); for i in self.0.iter() { i.encode_to(dest); @@ -19,7 +22,7 @@ impl Encode for CodecBTreeMap { impl Decode for CodecBTreeMap { fn decode(input: &mut I) -> Option { u32::decode(input).and_then(move |len| { - let mut r: BTreeMap = BTreeMap::new();// with_capacity(len as usize); + let mut r: BTreeMap = BTreeMap::new(); // with_capacity(len as usize); for _ in 0..len { let (key, v) = <(K, V)>::decode(input)?; r.insert(key, v); diff --git a/cxrml/support/src/storage/double_map.rs b/cxrml/support/src/storage/double_map.rs index ed7537bd71230..ecda527d841bc 100644 --- a/cxrml/support/src/storage/double_map.rs +++ b/cxrml/support/src/storage/double_map.rs @@ -18,10 +18,10 @@ //! //! This implementation is somewhat specialized to the tracking of the storage of accounts. -use rstd::prelude::*; use codec::{Codec, Encode}; -use runtime_support::storage::unhashed; +use rstd::prelude::*; use runtime_io::{blake2_256, twox_128}; +use runtime_support::storage::unhashed; /// Returns only a first part of the storage key. /// diff --git a/cxrml/support/src/storage/linked_node.rs b/cxrml/support/src/storage/linked_node.rs index ca62426f3088f..2da6a1b9f5bcb 100644 --- a/cxrml/support/src/storage/linked_node.rs +++ b/cxrml/support/src/storage/linked_node.rs @@ -1,7 +1,6 @@ use codec::Codec; -use runtime_support::{StorageMap, StorageValue}; use runtime_support::dispatch::Result; - +use runtime_support::{StorageMap, StorageValue}; pub trait NodeT { type Index: Codec + Clone + Eq + PartialEq + Default; @@ -59,7 +58,9 @@ pub struct NodeIndex { } impl NodeIndex { - pub fn index(&self) -> T::Index { self.index.clone() } + pub fn index(&self) -> T::Index { + self.index.clone() + } } pub trait NodeIndexT { @@ -69,7 +70,9 @@ pub trait NodeIndexT { impl NodeIndexT for NodeIndex { type IndexType = NodeIndex; - fn data(&self) -> &NodeIndex { self } + fn data(&self) -> &NodeIndex { + self + } } pub trait MultiNodeIndexT { @@ -81,25 +84,34 @@ pub trait MultiNodeIndexT { #[derive(Decode, Encode, Eq, PartialEq, Clone, Default)] pub struct MultiNodeIndex - where K: Codec + Clone + Eq + PartialEq + Default +where + K: Codec + Clone + Eq + PartialEq + Default, { multi_key: K, index: T::Index, } impl MultiNodeIndex - where K: Codec + Clone + Eq + PartialEq + Default +where + K: Codec + Clone + Eq + PartialEq + Default, { - pub fn index(&self) -> T::Index { self.index.clone() } + pub fn index(&self) -> T::Index { + self.index.clone() + } } impl MultiNodeIndexT for MultiNodeIndex - where K: Codec + Clone + Eq + PartialEq + Default +where + K: Codec + Clone + Eq + PartialEq + Default, { type KeyType = K; type IndexType = MultiNodeIndex; - fn data(&self) -> &MultiNodeIndex { self } - fn key(&self) -> K { self.multi_key.clone() } + fn data(&self) -> &MultiNodeIndex { + self + } + fn key(&self) -> K { + self.multi_key.clone() + } } pub trait OptionT { @@ -113,14 +125,14 @@ impl OptionT for Option> { fn data(&self) -> Option<&Node> { match self { None => None, - Some(ref i) => Some(i) + Some(ref i) => Some(i), } } fn mut_data(&mut self) -> Option<&mut Node> { match self { None => None, - Some(ref mut i) => Some(i) + Some(ref mut i) => Some(i), } } } @@ -130,33 +142,34 @@ impl OptionT for Option> { fn data(&self) -> Option<&NodeIndex> { match self { None => None, - Some(ref i) => Some(i) + Some(ref i) => Some(i), } } fn mut_data(&mut self) -> Option<&mut NodeIndex> { match self { None => None, - Some(ref mut i) => Some(i) + Some(ref mut i) => Some(i), } } } impl OptionT for Option> - where K: Codec + Clone + Eq + PartialEq + Default, +where + K: Codec + Clone + Eq + PartialEq + Default, { type OptionType = MultiNodeIndex; fn data(&self) -> Option<&MultiNodeIndex> { match self { None => None, - Some(ref i) => Some(i) + Some(ref i) => Some(i), } } fn mut_data(&mut self) -> Option<&mut MultiNodeIndex> { match self { None => None, - Some(ref mut i) => Some(i) + Some(ref mut i) => Some(i), } } } @@ -169,17 +182,24 @@ pub trait LinkedNodeCollection { impl Node { pub fn new(data: T) -> Node { - Node:: { data, prev: None, next: None } + Node:: { + data, + prev: None, + next: None, + } } pub fn add_option_node_before(&mut self, mut node: Node) -> Result - where - C::NodeMap: StorageMap>, - C::Header: StorageValue>, - ::Index, Node>>::Query: OptionT>, + where + C::NodeMap: StorageMap>, + C::Header: StorageValue>, + ::Index, Node>>::Query: + OptionT>, { let i = self.index(); - if i == node.index() { return Ok(()); } + if i == node.index() { + return Ok(()); + } match &self.prev { Some(p) => { C::NodeMap::mutate(p, |prev| { @@ -194,7 +214,9 @@ impl Node { None => { node.prev = None; node.next = Some(i); - C::Header::put(NodeIndex:: { index: node.index() }); + C::Header::put(NodeIndex:: { + index: node.index(), + }); } } if node.is_none() { @@ -210,13 +232,16 @@ impl Node { } pub fn add_option_node_after(&mut self, mut node: Node) -> Result - where - C::NodeMap: StorageMap>, - C::Tail: StorageValue>, - ::Index, Node>>::Query: OptionT>, + where + C::NodeMap: StorageMap>, + C::Tail: StorageValue>, + ::Index, Node>>::Query: + OptionT>, { let i = self.index(); - if i == node.index() { return Ok(()); } + if i == node.index() { + return Ok(()); + } match &self.next { Some(n) => { C::NodeMap::mutate(n, |next| { @@ -231,10 +256,14 @@ impl Node { None => { node.prev = Some(i); node.next = None; - C::Tail::put(NodeIndex:: { index: node.index() }); + C::Tail::put(NodeIndex:: { + index: node.index(), + }); } } - if node.is_none() { return Err("do add for a invalid node"); } + if node.is_none() { + return Err("do add for a invalid node"); + } self.next = Some(node.index()); C::NodeMap::insert(self.index(), self); let i = node.index(); @@ -243,23 +272,28 @@ impl Node { } pub fn remove_option_node(&mut self) -> Result - where - C::NodeMap: StorageMap>, - C::Header: StorageValue>, - C::Tail: StorageValue>, - ::Index, Node>>::Query: OptionT>, - >>::Query: OptionT>, - >>::Query: OptionT>, + where + C::NodeMap: StorageMap>, + C::Header: StorageValue>, + C::Tail: StorageValue>, + ::Index, Node>>::Query: + OptionT>, + >>::Query: OptionT>, + >>::Query: OptionT>, { if self.is_none() { let self_index = self.index(); C::NodeMap::remove(&self_index); if let Some(header) = C::Header::get().data() { - if self_index == header.index { C::Header::kill(); } + if self_index == header.index { + C::Header::kill(); + } } if let Some(tail) = C::Tail::get().data() { - if self_index == tail.index { C::Tail::kill(); } + if self_index == tail.index { + C::Tail::kill(); + } } return Ok(()); } @@ -271,7 +305,9 @@ impl Node { // TODO add Result when substrate update if let Some(next_node) = next.mut_data() { next_node.prev = None; - C::Header::put(NodeIndex:: { index: next_node.index() }); + C::Header::put(NodeIndex:: { + index: next_node.index(), + }); C::NodeMap::remove(self.index()); } }) @@ -288,7 +324,9 @@ impl Node { // TODO add Result when substrate update if let Some(prev_node) = prev.mut_data() { prev_node.next = None; - C::Tail::put(NodeIndex:: { index: prev_node.index() }); + C::Tail::put(NodeIndex:: { + index: prev_node.index(), + }); C::NodeMap::remove(self.index()); } }) @@ -322,27 +360,30 @@ impl Node { } pub fn add_node_before(&mut self, mut node: Node) -> Result - where - C::NodeMap: StorageMap>, - C::Header: StorageValue>, - ::Index, Node>>::Query: NormalNodeT>, + where + C::NodeMap: StorageMap>, + C::Header: StorageValue>, + ::Index, Node>>::Query: + NormalNodeT>, { let i = self.index(); - if i == node.index() { return Ok(()); } + if i == node.index() { + return Ok(()); + } match &self.prev { - Some(p) => { - C::NodeMap::mutate(p, |prev_node| { - if prev_node.data().is_none() == false { - node.prev = Some(prev_node.data().index()); - node.next = Some(i); - prev_node.mut_data().next = Some(node.index()); - } - }) - } + Some(p) => C::NodeMap::mutate(p, |prev_node| { + if prev_node.data().is_none() == false { + node.prev = Some(prev_node.data().index()); + node.next = Some(i); + prev_node.mut_data().next = Some(node.index()); + } + }), None => { node.prev = None; node.next = Some(i); - C::Header::put(NodeIndex:: { index: node.index() }); + C::Header::put(NodeIndex:: { + index: node.index(), + }); } } if node.is_none() { @@ -359,30 +400,35 @@ impl Node { } pub fn add_node_after(&mut self, mut node: Node) -> Result - where - C::NodeMap: StorageMap>, - C::Tail: StorageValue>, - ::Index, Node>>::Query: NormalNodeT>, + where + C::NodeMap: StorageMap>, + C::Tail: StorageValue>, + ::Index, Node>>::Query: + NormalNodeT>, { let i = self.index(); - if i == node.index() { return Ok(()); } + if i == node.index() { + return Ok(()); + } match &self.next { - Some(n) => { - C::NodeMap::mutate(n, |next_node| { - if next_node.data().is_none() == false { - node.prev = Some(i); - node.next = Some(next_node.data().index()); - next_node.mut_data().prev = Some(node.index()); - } - }) - } + Some(n) => C::NodeMap::mutate(n, |next_node| { + if next_node.data().is_none() == false { + node.prev = Some(i); + node.next = Some(next_node.data().index()); + next_node.mut_data().prev = Some(node.index()); + } + }), None => { node.prev = Some(i); node.next = None; - C::Tail::put(NodeIndex:: { index: node.index() }); + C::Tail::put(NodeIndex:: { + index: node.index(), + }); } } - if node.is_none() { return Err("do add for a invalid node"); } + if node.is_none() { + return Err("do add for a invalid node"); + } self.next = Some(node.index()); C::NodeMap::insert(self.index(), self); let i = node.index(); @@ -391,13 +437,14 @@ impl Node { } pub fn remove_node(&mut self) -> Result - where - C::NodeMap: StorageMap>, - C::Header: StorageValue>, - C::Tail: StorageValue>, - ::Index, Node>>::Query: NormalNodeT>, - >>::Query: NodeIndexT>, - >>::Query: NodeIndexT>, + where + C::NodeMap: StorageMap>, + C::Header: StorageValue>, + C::Tail: StorageValue>, + ::Index, Node>>::Query: + NormalNodeT>, + >>::Query: NodeIndexT>, + >>::Query: NodeIndexT>, { if self.is_none() { let self_index = self.index(); @@ -416,15 +463,15 @@ impl Node { if self.prev.is_none() { match &self.next { - Some(next) => { - C::NodeMap::mutate(next, |next_node| { - if next_node.data().is_none() == false { - next_node.mut_data().prev = None; - C::Header::put(NodeIndex:: { index: next_node.data().index() }); - C::NodeMap::remove(self.index()); - } - }) - } + Some(next) => C::NodeMap::mutate(next, |next_node| { + if next_node.data().is_none() == false { + next_node.mut_data().prev = None; + C::Header::put(NodeIndex:: { + index: next_node.data().index(), + }); + C::NodeMap::remove(self.index()); + } + }), None => { // something err return Err("prev is none, next should't be none"); @@ -432,15 +479,15 @@ impl Node { } } else if self.next.is_none() { match &self.prev { - Some(prev) => { - C::NodeMap::mutate(prev, |prev_node| { - if prev_node.data().is_none() == false { - prev_node.mut_data().next = None; - C::Tail::put(NodeIndex:: { index: prev_node.data().index() }); - C::NodeMap::remove(self.index()); - } - }) - } + Some(prev) => C::NodeMap::mutate(prev, |prev_node| { + if prev_node.data().is_none() == false { + prev_node.mut_data().next = None; + C::Tail::put(NodeIndex:: { + index: prev_node.data().index(), + }); + C::NodeMap::remove(self.index()); + } + }), None => { // something err return Err("next is none, prev should't be none"); @@ -462,7 +509,9 @@ impl Node { self.next = None; } }); - if self.is_none() { C::NodeMap::remove(self.index()); } else { + if self.is_none() { + C::NodeMap::remove(self.index()); + } else { // something err return Err("prev or next not exist in the storage yet, do not remove this node, but link maybe has been changed"); } @@ -471,16 +520,20 @@ impl Node { } pub fn init_storage(&self) - where - C::NodeMap: StorageMap>, - C::Header: StorageValue>, - C::Tail: StorageValue>, + where + C::NodeMap: StorageMap>, + C::Header: StorageValue>, + C::Tail: StorageValue>, { if C::Header::exists() == false { - C::Header::put(NodeIndex:: { index: self.index() }); + C::Header::put(NodeIndex:: { + index: self.index(), + }); } if C::Tail::exists() == false { - C::Tail::put(NodeIndex:: { index: self.index() }); + C::Tail::put(NodeIndex:: { + index: self.index(), + }); } C::NodeMap::insert(self.index(), self); } @@ -489,30 +542,52 @@ impl Node { // for multi index impl Node { pub fn init_storage_withkey(&self, key: K) - where - K: Codec + Clone + Eq + PartialEq + Default, - C::NodeMap: StorageMap>, - C::Header: StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, - C::Tail: StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, + where + K: Codec + Clone + Eq + PartialEq + Default, + C::NodeMap: StorageMap>, + C::Header: + StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, + C::Tail: + StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, { if C::Header::exists(&key) == false { - C::Header::insert(key.clone(), MultiNodeIndex:: { multi_key: key.clone(), index: self.index() }); + C::Header::insert( + key.clone(), + MultiNodeIndex:: { + multi_key: key.clone(), + index: self.index(), + }, + ); } if C::Tail::exists(&key) == false { - C::Tail::insert(key.clone(), MultiNodeIndex:: { multi_key: key.clone(), index: self.index() }); + C::Tail::insert( + key.clone(), + MultiNodeIndex:: { + multi_key: key.clone(), + index: self.index(), + }, + ); } C::NodeMap::insert(self.index(), self); } - pub fn add_option_node_before_withkey(&mut self, mut node: Node, key: K) -> Result - where - K: Codec + Clone + Eq + PartialEq + Default, - C::NodeMap: StorageMap>, - C::Header: StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, - ::Index, Node>>::Query: OptionT>, + pub fn add_option_node_before_withkey( + &mut self, + mut node: Node, + key: K, + ) -> Result + where + K: Codec + Clone + Eq + PartialEq + Default, + C::NodeMap: StorageMap>, + C::Header: + StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, + ::Index, Node>>::Query: + OptionT>, { let i = self.index(); - if i == node.index() { return Ok(()); } + if i == node.index() { + return Ok(()); + } match &self.prev { Some(p) => { C::NodeMap::mutate(p, |prev| { @@ -527,7 +602,13 @@ impl Node { None => { node.prev = None; node.next = Some(i); - C::Header::insert(key.clone(), MultiNodeIndex:: { multi_key: key, index: node.index() }); + C::Header::insert( + key.clone(), + MultiNodeIndex:: { + multi_key: key, + index: node.index(), + }, + ); } } if node.is_none() { @@ -542,16 +623,23 @@ impl Node { Ok(()) } - - pub fn add_option_node_after_withkey(&mut self, mut node: Node, key: K) -> Result - where - K: Codec + Clone + Eq + PartialEq + Default, - C::NodeMap: StorageMap>, - C::Tail: StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, - ::Index, Node>>::Query: OptionT>, + pub fn add_option_node_after_withkey( + &mut self, + mut node: Node, + key: K, + ) -> Result + where + K: Codec + Clone + Eq + PartialEq + Default, + C::NodeMap: StorageMap>, + C::Tail: + StorageMap< as MultiNodeIndexT>::KeyType, MultiNodeIndex>, + ::Index, Node>>::Query: + OptionT>, { let i = self.index(); - if i == node.index() { return Ok(()); } + if i == node.index() { + return Ok(()); + } match &self.next { Some(n) => { C::NodeMap::mutate(n, |next| { @@ -566,10 +654,18 @@ impl Node { None => { node.prev = Some(i); node.next = None; - C::Tail::insert(key.clone(), MultiNodeIndex:: { multi_key: key, index: node.index() }); + C::Tail::insert( + key.clone(), + MultiNodeIndex:: { + multi_key: key, + index: node.index(), + }, + ); } } - if node.is_none() { return Err("do add for a invalid node"); } + if node.is_none() { + return Err("do add for a invalid node"); + } self.next = Some(node.index()); C::NodeMap::insert(self.index(), self); let i = node.index(); @@ -578,24 +674,31 @@ impl Node { } pub fn remove_option_node_withkey(&mut self, key: K) -> Result - where - K: Codec + Clone + Eq + PartialEq + Default, - C::NodeMap: StorageMap>, - C::Header: StorageMap>, - C::Tail: StorageMap>, - ::Index, Node>>::Query: OptionT>, - >>::Query: OptionT>, - >>::Query: OptionT>, + where + K: Codec + Clone + Eq + PartialEq + Default, + C::NodeMap: StorageMap>, + C::Header: StorageMap>, + C::Tail: StorageMap>, + ::Index, Node>>::Query: + OptionT>, + >>::Query: + OptionT>, + >>::Query: + OptionT>, { if self.is_none() { let self_index = self.index(); C::NodeMap::remove(&self_index); if let Some(header) = C::Header::get(&key).data() { - if self_index == header.index { C::Header::remove(&key); } + if self_index == header.index { + C::Header::remove(&key); + } } if let Some(tail) = C::Tail::get(&key).data() { - if self_index == tail.index { C::Tail::remove(&key); } + if self_index == tail.index { + C::Tail::remove(&key); + } } return Ok(()); } @@ -607,7 +710,13 @@ impl Node { // TODO add Result when substrate update if let Some(next_node) = next.mut_data() { next_node.prev = None; - C::Header::insert(key.clone(), MultiNodeIndex:: { multi_key: key, index: next_node.index() }); + C::Header::insert( + key.clone(), + MultiNodeIndex:: { + multi_key: key, + index: next_node.index(), + }, + ); C::NodeMap::remove(self.index()); } }) @@ -624,7 +733,13 @@ impl Node { // TODO add Result when substrate update if let Some(prev_node) = prev.mut_data() { prev_node.next = None; - C::Tail::insert(key.clone(), MultiNodeIndex:: { multi_key: key, index: prev_node.index() }); + C::Tail::insert( + key.clone(), + MultiNodeIndex:: { + multi_key: key, + index: prev_node.index(), + }, + ); C::NodeMap::remove(self.index()); } }) diff --git a/cxrml/support/src/storage/mod.rs b/cxrml/support/src/storage/mod.rs index 17d85e29ef14d..2434adab417b1 100644 --- a/cxrml/support/src/storage/mod.rs +++ b/cxrml/support/src/storage/mod.rs @@ -1,5 +1,5 @@ // Copyright 2018 Chainpool. +pub mod btree_map; pub mod double_map; pub mod linked_node; -pub mod btree_map; \ No newline at end of file diff --git a/cxrml/support/src/tests.rs b/cxrml/support/src/tests.rs index 4d6e69da2e711..8324bf9df4452 100644 --- a/cxrml/support/src/tests.rs +++ b/cxrml/support/src/tests.rs @@ -1,17 +1,16 @@ -use substrate_primitives::{H256, Blake2Hasher}; +use substrate_primitives::{Blake2Hasher, H256}; -use primitives::BuildStorage; -use primitives::traits::BlakeTwo256; use primitives::testing::{Digest, DigestItem, Header}; +use primitives::traits::BlakeTwo256; +use primitives::BuildStorage; use runtime_io; use runtime_io::with_externalities; use super::*; - impl_outer_origin! { - pub enum Origin for Test {} - } + pub enum Origin for Test {} +} #[derive(Clone, Eq, PartialEq)] pub struct Test; @@ -51,21 +50,29 @@ type CXSystem = cxsystem::Module; type CXSupport = Module; pub fn new_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); // balances - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510), (3, 1000)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 0, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510), (3, 1000)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 0, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); // cxsystem - r.extend(cxsystem::GenesisConfig:: { - death_account: 100, - }.build_storage().unwrap()); + r.extend( + cxsystem::GenesisConfig:: { death_account: 100 } + .build_storage() + .unwrap(), + ); r.into() } diff --git a/cxrml/system/src/lib.rs b/cxrml/system/src/lib.rs index 9035607ad3a17..9b84979e675ad 100644 --- a/cxrml/system/src/lib.rs +++ b/cxrml/system/src/lib.rs @@ -36,16 +36,14 @@ extern crate srml_system as system; mod tests; use rstd::prelude::*; +use runtime_primitives::traits::OnFinalise; use runtime_support::dispatch::Result; use runtime_support::StorageValue; -use runtime_primitives::traits::OnFinalise; use system::ensure_inherent; - pub trait Trait: system::Trait {} - decl_module! { pub struct Module for enum Call where origin: T::Origin { fn set_block_producer(origin, producer: T::AccountId) -> Result; @@ -72,5 +70,3 @@ impl Module { Ok(()) } } - - diff --git a/cxrml/system/src/tests.rs b/cxrml/system/src/tests.rs index 2aedef47d4b16..2837a577fe20f 100644 --- a/cxrml/system/src/tests.rs +++ b/cxrml/system/src/tests.rs @@ -1,4 +1,4 @@ #[test] fn it_works() { assert_eq!(2 + 2, 4); -} \ No newline at end of file +} diff --git a/cxrml/tokenbalances/src/lib.rs b/cxrml/tokenbalances/src/lib.rs index e130e5baa714c..f26d891f90f45 100644 --- a/cxrml/tokenbalances/src/lib.rs +++ b/cxrml/tokenbalances/src/lib.rs @@ -26,32 +26,32 @@ extern crate sr_primitives as primitives; // for substrate runtime module lib #[macro_use] extern crate srml_support as runtime_support; -extern crate srml_system as system; extern crate srml_balances as balances; +extern crate srml_system as system; // for chainx runtime module lib #[cfg(test)] -extern crate cxrml_system as cxsystem; -#[cfg(test)] extern crate cxrml_associations as associations; extern crate cxrml_support as cxsupport; +#[cfg(test)] +extern crate cxrml_system as cxsystem; #[cfg(test)] mod mock; #[cfg(test)] mod tests; +use codec::Codec; +use primitives::traits::{As, CheckedAdd, CheckedSub, Member, OnFinalise, SimpleArithmetic}; use rstd::prelude::*; -use rstd::slice::Iter; pub use rstd::result::Result as StdResult; -use codec::Codec; -use runtime_support::{StorageValue, StorageMap, Parameter}; +use rstd::slice::Iter; use runtime_support::dispatch::Result; -use primitives::traits::{SimpleArithmetic, As, Member, CheckedAdd, CheckedSub, OnFinalise}; +use runtime_support::{Parameter, StorageMap, StorageValue}; // substrate mod -use system::ensure_signed; use balances::address::Address; +use system::ensure_signed; // use balances::EnsureAccountLiquid; pub type SymbolString = &'static [u8]; @@ -62,7 +62,17 @@ pub trait Trait: balances::Trait + cxsupport::Trait { const CHAINX_SYMBOL: SymbolString; const CHAINX_TOKEN_DESC: DescString; /// The token balance. - type TokenBalance: Parameter + Member + Codec + SimpleArithmetic + As + As + As + As + As + Copy + Default; + type TokenBalance: Parameter + + Member + + Codec + + SimpleArithmetic + + As + + As + + As + + As + + As + + Copy + + Default; /// Event type Event: From> + Into<::Event>; } @@ -86,8 +96,11 @@ pub fn is_valid_symbol(v: &[u8]) -> Result { || (*c == 0x2D) // - || (*c == 0x2E) // . || (*c == 0x7C) // | - || (*c == 0x7E) // ~ - { continue; } else { + || (*c == 0x7E) + // ~ + { + continue; + } else { return Err("not a valid symbol char for number, capital/small letter or '-', '.', '|', '~'"); } } @@ -96,11 +109,14 @@ pub fn is_valid_symbol(v: &[u8]) -> Result { } pub fn is_valid_token_desc(v: &[u8]) -> Result { - if v.len() > MAX_TOKENDESC_LEN { Err("token desc length too long") } else { + if v.len() > MAX_TOKENDESC_LEN { + Err("token desc length too long") + } else { for c in v.iter() { // ascii visible char - if *c >= 20 && *c <= 0x7E - { continue; } else { + if *c >= 20 && *c <= 0x7E { + continue; + } else { return Err("not a valid ascii visible char"); } } @@ -127,7 +143,11 @@ pub struct Token { impl Token { pub fn new(symbol: Symbol, token_desc: TokenDesc, precision: Precision) -> Self { - Token { symbol, token_desc, precision } + Token { + symbol, + token_desc, + precision, + } } pub fn symbol(&self) -> Symbol { @@ -164,7 +184,11 @@ pub enum ReservedType { impl ReservedType { pub fn iterator() -> Iter<'static, ReservedType> { - static TYPES: [ReservedType; 3] = [ReservedType::Others, ReservedType::Funds, ReservedType::Exchange]; + static TYPES: [ReservedType; 3] = [ + ReservedType::Others, + ReservedType::Funds, + ReservedType::Exchange, + ]; TYPES.into_iter() } } @@ -329,13 +353,21 @@ impl Module { // token symol // public call /// register a token into token list ans init - pub fn register_token(token: Token, free: T::TokenBalance, reserved: T::TokenBalance) -> Result { + pub fn register_token( + token: Token, + free: T::TokenBalance, + reserved: T::TokenBalance, + ) -> Result { token.is_valid()?; let sym = token.symbol(); Self::add_token(&sym, free, reserved)?; >::insert(&sym, (token.clone(), true)); - Self::deposit_event(RawEvent::RegisterToken(token.symbol(), token.token_desc(), token.precision())); + Self::deposit_event(RawEvent::RegisterToken( + token.symbol(), + token.token_desc(), + token.precision(), + )); Ok(()) } /// cancel a token from token list but not remove it @@ -358,11 +390,14 @@ impl Module { } pub fn valid_token_list() -> Vec { - Self::token_list().into_iter() + Self::token_list() + .into_iter() .filter(|s| { if let Some(t) = TokenInfo::::get(s) { t.1 - } else { false } + } else { + false + } }) .collect() } @@ -464,7 +499,12 @@ impl Module { Ok(()) } - pub fn destroy(who: &T::AccountId, symbol: &Symbol, value: T::TokenBalance, t: ReservedType) -> Result { + pub fn destroy( + who: &T::AccountId, + symbol: &Symbol, + value: T::TokenBalance, + t: ReservedType, + ) -> Result { if symbol.as_slice() == T::CHAINX_SYMBOL { return Err("can't destroy chainx token"); } @@ -493,7 +533,12 @@ impl Module { Ok(()) } - pub fn reserve(who: &T::AccountId, symbol: &Symbol, value: T::TokenBalance, t: ReservedType) -> Result { + pub fn reserve( + who: &T::AccountId, + symbol: &Symbol, + value: T::TokenBalance, + t: ReservedType, + ) -> Result { Self::is_valid_token_for(who, symbol)?; // ::EnsureAccountLiquid::ensure_account_liquid(who)?; //TODO validator @@ -524,7 +569,11 @@ impl Module { ReservedToken::::insert(reserved_key, new_reserved_token); TotalReservedToken::::insert(symbol, new_total_reserved_token); - Self::deposit_event(RawEvent::ReverseToken(who.clone(), T::CHAINX_SYMBOL.to_vec(), val)); + Self::deposit_event(RawEvent::ReverseToken( + who.clone(), + T::CHAINX_SYMBOL.to_vec(), + val, + )); return Ok(()); } @@ -561,7 +610,12 @@ impl Module { Ok(()) } - pub fn unreserve(who: &T::AccountId, symbol: &Symbol, value: T::TokenBalance, t: ReservedType) -> Result { + pub fn unreserve( + who: &T::AccountId, + symbol: &Symbol, + value: T::TokenBalance, + t: ReservedType, + ) -> Result { Self::is_valid_token_for(who, symbol)?; // ::EnsureAccountLiquid::ensure_account_liquid(who)?; //TODO validator @@ -592,7 +646,11 @@ impl Module { ReservedToken::::insert(reserved_key, new_reserved_token); TotalReservedToken::::insert(symbol, new_total_reserved_token); - Self::deposit_event(RawEvent::UnreverseToken(who.clone(), T::CHAINX_SYMBOL.to_vec(), val)); + Self::deposit_event(RawEvent::UnreverseToken( + who.clone(), + T::CHAINX_SYMBOL.to_vec(), + val, + )); return Ok(()); } @@ -629,7 +687,12 @@ impl Module { Ok(()) } - pub fn move_free_token(from: &T::AccountId, to: &T::AccountId, symbol: &Symbol, value: T::TokenBalance) -> StdResult<(), TokenErr> { + pub fn move_free_token( + from: &T::AccountId, + to: &T::AccountId, + symbol: &Symbol, + value: T::TokenBalance, + ) -> StdResult<(), TokenErr> { Self::is_valid_token_for(from, symbol).map_err(|_| TokenErr::InvalidToken)?; // ::EnsureAccountLiquid::ensure_account_liquid(from).map_err(|_| TokenErr::InvalidAccount)?; //TODO validator` @@ -650,7 +713,12 @@ impl Module { }; balances::FreeBalance::::insert(from, new_from_token); balances::FreeBalance::::insert(to, new_to_token); - Self::deposit_event(RawEvent::MoveFreeToken(from.clone(), to.clone(), symbol.clone(), As::sa(value.as_()))); + Self::deposit_event(RawEvent::MoveFreeToken( + from.clone(), + to.clone(), + symbol.clone(), + As::sa(value.as_()), + )); return Ok(()); } @@ -671,7 +739,12 @@ impl Module { }; FreeToken::::insert(key_from, new_from_token); FreeToken::::insert(key_to, new_to_token); - Self::deposit_event(RawEvent::MoveFreeToken(from.clone(), to.clone(), symbol.clone(), value)); + Self::deposit_event(RawEvent::MoveFreeToken( + from.clone(), + to.clone(), + symbol.clone(), + value, + )); Ok(()) } } @@ -699,7 +772,12 @@ impl TokenErr { impl Module { // public call /// transfer token between accountid, notice the fee is chainx - pub fn transfer_token(origin: T::Origin, dest: balances::Address, sym: Symbol, value: T::TokenBalance) -> Result { + pub fn transfer_token( + origin: T::Origin, + dest: balances::Address, + sym: Symbol, + value: T::TokenBalance, + ) -> Result { if sym.as_slice() == T::CHAINX_SYMBOL { return Err("not allow to transfer chainx use transfer_token"); } @@ -732,7 +810,13 @@ impl Module { // set to storage FreeToken::::insert(&key_from, new_from_token); FreeToken::::insert(&key_to, new_to_token); - Self::deposit_event(RawEvent::TransferToken(sender.clone(), receiver.clone(), sym.clone(), value, fee)); + Self::deposit_event(RawEvent::TransferToken( + sender.clone(), + receiver.clone(), + sym.clone(), + value, + fee, + )); } Ok(()) })?; diff --git a/cxrml/tokenbalances/src/mock.rs b/cxrml/tokenbalances/src/mock.rs index f06750d0e96c5..3863f2bae6c1d 100644 --- a/cxrml/tokenbalances/src/mock.rs +++ b/cxrml/tokenbalances/src/mock.rs @@ -1,10 +1,10 @@ // Copyright 2018 Chainpool. -use substrate_primitives::{H256, Blake2Hasher}; +use substrate_primitives::{Blake2Hasher, H256}; -use primitives::BuildStorage; -use primitives::traits::BlakeTwo256; use primitives::testing::{Digest, DigestItem, Header}; +use primitives::traits::BlakeTwo256; +use primitives::BuildStorage; use runtime_io; use super::*; @@ -62,82 +62,103 @@ pub type Balances = balances::Module; // This function basically just builds a genesis storage key/value store according to // our desired mockup. pub fn new_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); // balance - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510), (3, 1000)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 500, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510), (3, 1000)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 500, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); // token let t: Token = Token::new(b"x-btc".to_vec(), b"btc token".to_vec(), 8); let t2: Token = Token::new(b"x-eth".to_vec(), b"eth token".to_vec(), 4); - r.extend(GenesisConfig:: { - chainx_precision: 8, - token_list: vec![ - (t, [(3, 100)].to_vec()), - (t2, [(3, 100)].to_vec()), - ], - transfer_token_fee: 10, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { + chainx_precision: 8, + token_list: vec![(t, [(3, 100)].to_vec()), (t2, [(3, 100)].to_vec())], + transfer_token_fee: 10, + } + .build_storage() + .unwrap(), + ); r.into() } pub fn err_test_ext() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); // balance - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510), (3, 1000)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 500, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510), (3, 1000)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 500, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); // token let t: Token = Token::new(b"x-btc?...".to_vec(), b"btc token".to_vec(), 8); let t2: Token = Token::new(b"x-eth".to_vec(), b"eth token".to_vec(), 4); - r.extend(GenesisConfig:: { - chainx_precision: 8, - token_list: vec![ - (t, [(3, 100)].to_vec()), - (t2, [(3, 100)].to_vec()), - ], - transfer_token_fee: 10, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { + chainx_precision: 8, + token_list: vec![(t, [(3, 100)].to_vec()), (t2, [(3, 100)].to_vec())], + transfer_token_fee: 10, + } + .build_storage() + .unwrap(), + ); r.into() } pub fn new_test_ext2() -> runtime_io::TestExternalities { - let mut r = system::GenesisConfig::::default().build_storage().unwrap(); + let mut r = system::GenesisConfig::::default() + .build_storage() + .unwrap(); // balance - r.extend(balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 510), (3, 1000)], - transaction_base_fee: 0, - transaction_byte_fee: 0, - existential_deposit: 0, - transfer_fee: 0, - creation_fee: 0, - reclaim_rebate: 0, - }.build_storage().unwrap()); + r.extend( + balances::GenesisConfig:: { + balances: vec![(1, 1000), (2, 510), (3, 1000)], + transaction_base_fee: 0, + transaction_byte_fee: 0, + existential_deposit: 0, + transfer_fee: 0, + creation_fee: 0, + reclaim_rebate: 0, + } + .build_storage() + .unwrap(), + ); // token let t: Token = Token::new(b"x-btc".to_vec(), b"btc token".to_vec(), 8); let t2: Token = Token::new(b"x-eth".to_vec(), b"eth token".to_vec(), 4); - r.extend(GenesisConfig:: { - chainx_precision: 8, - token_list: vec![ - (t, [(3, 100)].to_vec()), - (t2, [(3, 100)].to_vec()), - ], - transfer_token_fee: 10, - }.build_storage().unwrap()); + r.extend( + GenesisConfig:: { + chainx_precision: 8, + token_list: vec![(t, [(3, 100)].to_vec()), (t2, [(3, 100)].to_vec())], + transfer_token_fee: 10, + } + .build_storage() + .unwrap(), + ); r.into() -} \ No newline at end of file +} diff --git a/cxrml/tokenbalances/src/tests.rs b/cxrml/tokenbalances/src/tests.rs index 17e4f5a87dd94..5632466771e0d 100644 --- a/cxrml/tokenbalances/src/tests.rs +++ b/cxrml/tokenbalances/src/tests.rs @@ -1,8 +1,8 @@ // Copyright 2018 Chainpool. -use runtime_io::with_externalities; -use mock::*; use super::*; +use mock::*; +use runtime_io::with_externalities; #[test] fn test_genesis() { @@ -12,20 +12,38 @@ fn test_genesis() { let btc_symbol = b"x-btc".to_vec(); let eth_symbol = b"x-eth".to_vec(); - assert_eq!(TokenBalances::token_list(), vec![ - Test::CHAINX_SYMBOL.to_vec(), - btc_symbol.clone(), - eth_symbol.clone(), - ]); - - assert_eq!(TokenBalances::token_info(btc_symbol.clone()).unwrap().0.precision(), 8); - assert_eq!(TokenBalances::token_info(eth_symbol.clone()).unwrap().0.precision(), 4); + assert_eq!( + TokenBalances::token_list(), + vec![ + Test::CHAINX_SYMBOL.to_vec(), + btc_symbol.clone(), + eth_symbol.clone(), + ] + ); + + assert_eq!( + TokenBalances::token_info(btc_symbol.clone()) + .unwrap() + .0 + .precision(), + 8 + ); + assert_eq!( + TokenBalances::token_info(eth_symbol.clone()) + .unwrap() + .0 + .precision(), + 4 + ); assert_eq!(TokenBalances::total_free_token(btc_symbol.clone()), 100); assert_eq!(TokenBalances::total_reserved_token(btc_symbol.clone()), 0); // chainx symbol for every user - assert_eq!(TokenBalances::token_list_of(&0), [Test::CHAINX_SYMBOL.to_vec()].to_vec()); + assert_eq!( + TokenBalances::token_list_of(&0), + [Test::CHAINX_SYMBOL.to_vec()].to_vec() + ); }); } @@ -34,11 +52,17 @@ fn test_genesis_token_issue() { with_externalities(&mut new_test_ext(), || { let btc_symbol = b"x-btc".to_vec(); let eth_symbol = b"x-eth".to_vec(); - assert_eq!(TokenBalances::free_token(&(3, Test::CHAINX_SYMBOL.to_vec())), 1000); + assert_eq!( + TokenBalances::free_token(&(3, Test::CHAINX_SYMBOL.to_vec())), + 1000 + ); assert_eq!(TokenBalances::free_token(&(3, btc_symbol.clone())), 100); assert_eq!(TokenBalances::free_token(&(3, eth_symbol.clone())), 100); - assert_eq!(TokenBalances::token_list_of(&3), [Test::CHAINX_SYMBOL.to_vec(), btc_symbol, eth_symbol]); + assert_eq!( + TokenBalances::token_list_of(&3), + [Test::CHAINX_SYMBOL.to_vec(), btc_symbol, eth_symbol] + ); }) } @@ -62,19 +86,31 @@ fn test_register() { let btc_symbol = b"x-btc".to_vec(); //b"x-btc".to_vec(); let eth_symbol = b"x-eth".to_vec(); //slice_to_u8_8(b"x-eth"); - assert_eq!(TokenBalances::token_list(), vec![ - Test::CHAINX_SYMBOL.to_vec(), - btc_symbol.clone(), - eth_symbol.clone(), - t_sym.clone(), - ]); + assert_eq!( + TokenBalances::token_list(), + vec![ + Test::CHAINX_SYMBOL.to_vec(), + btc_symbol.clone(), + eth_symbol.clone(), + t_sym.clone(), + ] + ); assert_eq!(TokenBalances::total_free_token(t_sym.clone()), 0); - assert_eq!(TokenBalances::token_info(t_sym.clone()).unwrap().0.precision(), 4); + assert_eq!( + TokenBalances::token_info(t_sym.clone()) + .unwrap() + .0 + .precision(), + 4 + ); // test err branch let btc_t = Token::new(btc_symbol.clone(), b"btc token".to_vec(), 4); - assert_noop!(TokenBalances::register_token(btc_t, 0, 0), "already has this token symbol"); + assert_noop!( + TokenBalances::register_token(btc_t, 0, 0), + "already has this token symbol" + ); assert_eq!(TokenBalances::token_list_len(), 4); assert_eq!(TokenBalances::token_list_map(4), b"".to_vec()); }) @@ -97,11 +133,20 @@ fn test_remove() { assert_eq!(TokenBalances::token_list_len(), 4); // length not modify // re-register, but must be failed - assert_noop!(TokenBalances::register_token(t.clone(), 0, 0), "already has this token symbol"); + assert_noop!( + TokenBalances::register_token(t.clone(), 0, 0), + "already has this token symbol" + ); // create new token symbol - let t_new: Token = Token { symbol: b"x-eos2".to_vec(), ..t }; - assert_noop!(TokenBalances::cancel_token(&t_new.symbol), "this token symbol dose not register yet or is invalid"); + let t_new: Token = Token { + symbol: b"x-eos2".to_vec(), + ..t + }; + assert_noop!( + TokenBalances::cancel_token(&t_new.symbol), + "this token symbol dose not register yet or is invalid" + ); assert_eq!(TokenBalances::register_token(t_new.clone(), 0, 0), Ok(())); assert_eq!(TokenBalances::token_list_map(3), t_sym.clone()); assert_eq!(TokenBalances::token_list_map(4), t_new.symbol); @@ -192,7 +237,6 @@ fn test_unlock_issue_and_destroy2() { assert_eq!(TokenBalances::total_token_of(&a, &btc_symbol.clone()), 50); assert_eq!(TokenBalances::total_token(&btc_symbol.clone()), 150); - // reserve TokenBalances::reserve(&a, &btc_symbol.clone(), 25, Default::default()).unwrap(); assert_eq!(TokenBalances::reserved_token(&reserved_key), 25); @@ -220,14 +264,30 @@ fn test_error_issue_and_destroy1() { assert_eq!(TokenBalances::total_token(&btc_symbol.clone()), 150); // destroy first // destroy - assert_err!(TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default()), "reserved token too low to destroy"); + assert_err!( + TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default()), + "reserved token too low to destroy" + ); // reserve assert_eq!(TokenBalances::total_free_token(&btc_symbol.clone()), 150); - assert_err!(TokenBalances::reserve(&a, &btc_symbol.clone(), 100, Default::default()), "free token too low to reserve"); + assert_err!( + TokenBalances::reserve(&a, &btc_symbol.clone(), 100, Default::default()), + "free token too low to reserve" + ); // lock first - assert_ok!(TokenBalances::reserve(&a, &btc_symbol.clone(), 25, Default::default())); + assert_ok!(TokenBalances::reserve( + &a, + &btc_symbol.clone(), + 25, + Default::default() + )); // destroy - assert_ok!(TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default())); + assert_ok!(TokenBalances::destroy( + &a, + &btc_symbol.clone(), + 25, + Default::default() + )); }) } @@ -242,8 +302,19 @@ fn test_error_issue_and_destroy2() { assert_eq!(TokenBalances::total_token(&btc_symbol.clone()), 150); // overflow let i: i32 = -1; - assert_err!(TokenBalances::reserve(&a, &btc_symbol.clone(), i as TokenBalance, Default::default()), "free token too low to reserve"); - assert_err!(TokenBalances::issue(&a, &btc_symbol.clone(), i as TokenBalance), "free token too high to issue"); + assert_err!( + TokenBalances::reserve( + &a, + &btc_symbol.clone(), + i as TokenBalance, + Default::default() + ), + "free token too low to reserve" + ); + assert_err!( + TokenBalances::issue(&a, &btc_symbol.clone(), i as TokenBalance), + "free token too high to issue" + ); }) } @@ -253,15 +324,37 @@ fn test_error_issue_and_destroy3() { let a: u64 = 1; // accountid let btc_symbol = b"x-btc".to_vec(); // lock or destroy without init - assert_err!(TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default()), "not a existed token in this account token list"); - assert_err!(TokenBalances::reserve(&a, &btc_symbol.clone(), 25, Default::default()), "not a existed token in this account token list"); + assert_err!( + TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default()), + "not a existed token in this account token list" + ); + assert_err!( + TokenBalances::reserve(&a, &btc_symbol.clone(), 25, Default::default()), + "not a existed token in this account token list" + ); TokenBalances::issue(&a, &btc_symbol.clone(), 0).unwrap(); - assert_err!(TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default()), "reserved token too low to destroy"); - assert_err!(TokenBalances::reserve(&a, &btc_symbol.clone(), 25, Default::default()), "free token too low to reserve"); + assert_err!( + TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default()), + "reserved token too low to destroy" + ); + assert_err!( + TokenBalances::reserve(&a, &btc_symbol.clone(), 25, Default::default()), + "free token too low to reserve" + ); TokenBalances::issue(&a, &btc_symbol.clone(), 100).unwrap(); - assert_ok!(TokenBalances::reserve(&a, &btc_symbol.clone(), 25, Default::default())); - assert_ok!(TokenBalances::destroy(&a, &btc_symbol.clone(), 25, Default::default())); + assert_ok!(TokenBalances::reserve( + &a, + &btc_symbol.clone(), + 25, + Default::default() + )); + assert_ok!(TokenBalances::destroy( + &a, + &btc_symbol.clone(), + 25, + Default::default() + )); }) } @@ -274,14 +367,18 @@ fn test_transfer() { // issue 50 to account 1 TokenBalances::issue(&a, &btc_symbol.clone(), 50).unwrap(); // transfer - TokenBalances::transfer_token(Some(a).into(), b.into(), btc_symbol.clone().clone(), 25).unwrap(); + TokenBalances::transfer_token(Some(a).into(), b.into(), btc_symbol.clone().clone(), 25) + .unwrap(); // sum not change assert_eq!(TokenBalances::total_free_token(&btc_symbol.clone()), 150); assert_eq!(TokenBalances::total_token_of(&a, &btc_symbol.clone()), 25); assert_eq!(TokenBalances::free_token(&(b, btc_symbol.clone())), 25); assert_eq!(Balances::free_balance(&a), 990); - assert_err!(TokenBalances::transfer_token(Some(a).into(), b.into(), btc_symbol.clone().clone(), 50), "free token too low to send value") + assert_err!( + TokenBalances::transfer_token(Some(a).into(), b.into(), btc_symbol.clone().clone(), 50), + "free token too low to send value" + ) }) } @@ -293,7 +390,8 @@ fn test_transfer_to_self() { // issue 50 to account 1 TokenBalances::issue(&a, &btc_symbol.clone(), 50).unwrap(); // transfer - TokenBalances::transfer_token(Some(a).into(), a.into(), btc_symbol.clone().clone(), 25).unwrap(); + TokenBalances::transfer_token(Some(a).into(), a.into(), btc_symbol.clone().clone(), 25) + .unwrap(); // sum not change assert_eq!(TokenBalances::total_free_token(&btc_symbol.clone()), 150); assert_eq!(TokenBalances::total_token_of(&a, &btc_symbol.clone()), 50); @@ -310,15 +408,18 @@ fn test_transfer_err() { // issue 50 to account 2 TokenBalances::issue(&b, &btc_symbol.clone(), 50).unwrap(); // transfer - TokenBalances::transfer_token(Some(b).into(), a.into(), btc_symbol.clone().clone(), 25).unwrap(); + TokenBalances::transfer_token(Some(b).into(), a.into(), btc_symbol.clone().clone(), 25) + .unwrap(); // sum not change assert_eq!(TokenBalances::total_free_token(&btc_symbol.clone()), 150); assert_eq!(TokenBalances::free_token(&(b, btc_symbol.clone())), 25); assert_eq!(TokenBalances::total_token_of(&a, &btc_symbol.clone()), 25); assert_eq!(Balances::free_balance(&b), 500); - assert_err!(TokenBalances::transfer_token(Some(b).into(), a.into(), btc_symbol.clone(), 1), - "chainx balance is not enough after this tx, not allow to be killed at here"); + assert_err!( + TokenBalances::transfer_token(Some(b).into(), a.into(), btc_symbol.clone(), 1), + "chainx balance is not enough after this tx, not allow to be killed at here" + ); assert_eq!(Balances::free_balance(&b), 500); }) } @@ -329,20 +430,35 @@ fn test_char_valid() { let to: balances::Address = balances::address::Address::Id(2); let origin = system::RawOrigin::Signed(1).into(); let sym = b"".to_vec(); - assert_err!(TokenBalances::transfer_token(origin, to.clone(), sym, 10), "symbol length too long or zero"); + assert_err!( + TokenBalances::transfer_token(origin, to.clone(), sym, 10), + "symbol length too long or zero" + ); let origin = system::RawOrigin::Signed(1).into(); let sym = b"dfasdlfjkalsdjfklasjdflkasjdfklasjklfasjfkdlsajf".to_vec(); - assert_err!(TokenBalances::transfer_token(origin, to.clone(), sym, 10), "symbol length too long or zero"); + assert_err!( + TokenBalances::transfer_token(origin, to.clone(), sym, 10), + "symbol length too long or zero" + ); let origin = system::RawOrigin::Signed(1).into(); let sym = b"23jfkldae(".to_vec(); - assert_err!(TokenBalances::transfer_token(origin, to.clone(), sym, 10), "not a valid symbol char for number, capital/small letter or '-', '.', '|', '~'"); + assert_err!( + TokenBalances::transfer_token(origin, to.clone(), sym, 10), + "not a valid symbol char for number, capital/small letter or '-', '.', '|', '~'" + ); let t: Token = Token::new(b"x-btc2".to_vec(), b"btc token fdsfsdfasfasdfasdfasdfasdfasdfasdfjaskldfjalskdjflk;asjdfklasjkldfjalksdjfklasjflkdasjflkjkladsjfkrtewtewrtwertrjhjwretywertwertwerrtwerrtwerrtwertwelasjdfklsajdflkaj".to_vec(), 8); - assert_err!(TokenBalances::register_token(t, 0, 0), "token desc length too long"); + assert_err!( + TokenBalances::register_token(t, 0, 0), + "token desc length too long" + ); let t: Token = Token::new(b"x-btc?".to_vec(), b"btc token".to_vec(), 8); - assert_err!(TokenBalances::register_token(t, 0, 0), "not a valid symbol char for number, capital/small letter or '-', '.', '|', '~'") + assert_err!( + TokenBalances::register_token(t, 0, 0), + "not a valid symbol char for number, capital/small letter or '-', '.', '|', '~'" + ) }) } @@ -352,20 +468,35 @@ fn test_chainx() { let a: u64 = 1; // accountid let b: u64 = 2; // accountid let sym = Test::CHAINX_SYMBOL.to_vec(); - assert_err!(TokenBalances::issue(&a, &sym, 100), "can't issue chainx token"); + assert_err!( + TokenBalances::issue(&a, &sym, 100), + "can't issue chainx token" + ); assert_ok!(TokenBalances::reserve(&a, &sym, 100, Default::default())); assert_eq!(Balances::free_balance(&a), 900); assert_eq!(Balances::reserved_balance(&a), 100); - assert_eq!(TokenBalances::reserved_token(&(a, sym.clone(), Default::default())), 100); + assert_eq!( + TokenBalances::reserved_token(&(a, sym.clone(), Default::default())), + 100 + ); assert_ok!(TokenBalances::unreserve(&a, &sym, 50, Default::default())); assert_eq!(Balances::free_balance(&a), 950); - assert_eq!(TokenBalances::reserved_token(&(a, sym.clone(), Default::default())), 50); + assert_eq!( + TokenBalances::reserved_token(&(a, sym.clone(), Default::default())), + 50 + ); assert_eq!(Balances::reserved_balance(&a), 50); - assert_err!(TokenBalances::destroy(&a, &sym, 50, Default::default()), "can't destroy chainx token"); - - assert_err!(TokenBalances::transfer_token(Some(b).into(), a.into(), sym.clone(), 1), "not allow to transfer chainx use transfer_token"); + assert_err!( + TokenBalances::destroy(&a, &sym, 50, Default::default()), + "can't destroy chainx token" + ); + + assert_err!( + TokenBalances::transfer_token(Some(b).into(), a.into(), sym.clone(), 1), + "not allow to transfer chainx use transfer_token" + ); }) } @@ -375,8 +506,14 @@ fn test_chainx_err() { let a: u64 = 1; // accountid let sym = Test::CHAINX_SYMBOL.to_vec(); - assert_err!(TokenBalances::reserve(&a, &sym, 2000, Default::default()), "chainx free token too low to reserve"); - assert_err!(TokenBalances::unreserve(&a, &sym, 10, Default::default()), "chainx reserved token too low to unreserve"); + assert_err!( + TokenBalances::reserve(&a, &sym, 2000, Default::default()), + "chainx free token too low to reserve" + ); + assert_err!( + TokenBalances::unreserve(&a, &sym, 10, Default::default()), + "chainx reserved token too low to unreserve" + ); let i: i32 = -1; let larger_balance: TokenBalance = (i as u64) as u128 + 2; @@ -384,13 +521,21 @@ fn test_chainx_err() { assert_eq!(larger_balance, 18446744073709551617); assert_eq!(larger_balance as u64, 1); - assert_ok!(TokenBalances::reserve(&a, &sym, larger_balance, Default::default())); + assert_ok!(TokenBalances::reserve( + &a, + &sym, + larger_balance, + Default::default() + )); assert_eq!(Balances::free_balance(&a), 999); let i: i32 = -1; let max_balance: TokenBalance = i as u128; assert_eq!(max_balance as u64, 18446744073709551615); - assert_err!(TokenBalances::reserve(&a, &sym, max_balance, Default::default()), "chainx free token too low to reserve"); + assert_err!( + TokenBalances::reserve(&a, &sym, max_balance, Default::default()), + "chainx free token too low to reserve" + ); }) } @@ -401,18 +546,27 @@ fn test_move() { let b: u64 = 2; // accountid let sym = Test::CHAINX_SYMBOL.to_vec(); assert_ok!(TokenBalances::move_free_token(&a, &b, &sym, 100)); - assert_err!(TokenBalances::move_free_token(&a, &b, &sym, 1000), TokenErr::NotEnough); + assert_err!( + TokenBalances::move_free_token(&a, &b, &sym, 1000), + TokenErr::NotEnough + ); assert_eq!(Balances::free_balance(&a), 900); assert_eq!(Balances::free_balance(&b), 510 + 100); let sym = b"x-btc".to_vec(); - assert_err!(TokenBalances::move_free_token(&a, &b, &sym, 100), TokenErr::InvalidToken); + assert_err!( + TokenBalances::move_free_token(&a, &b, &sym, 100), + TokenErr::InvalidToken + ); TokenBalances::issue(&a, &sym, 100).unwrap(); assert_ok!(TokenBalances::move_free_token(&a, &b, &sym, 100)); - assert_err!(TokenBalances::move_free_token(&a, &b, &sym, 1000), TokenErr::NotEnough); + assert_err!( + TokenBalances::move_free_token(&a, &b, &sym, 1000), + TokenErr::NotEnough + ); assert_eq!(TokenBalances::free_token(&(a.clone(), sym.clone())), 0); assert_eq!(TokenBalances::free_token(&(b.clone(), sym.clone())), 100); }) -} \ No newline at end of file +} diff --git a/network/src/consensus.rs b/network/src/consensus.rs index c5634d8c8a402..d8904f2950a86 100644 --- a/network/src/consensus.rs +++ b/network/src/consensus.rs @@ -5,22 +5,22 @@ //! each time consensus begins on a new chain head. use bft; -use substrate_primitives::ed25519; -use substrate_network::{self as net, generic_message as msg}; -use substrate_network::consensus_gossip::ConsensusMessage; use rhododendron; +use substrate_network::consensus_gossip::ConsensusMessage; +use substrate_network::{self as net, generic_message as msg}; +use substrate_primitives::ed25519; -use chainx_primitives::{Block, Hash, SessionKey}; use chainx_api::ChainXApi; use chainx_consensus::Network; +use chainx_primitives::{Block, Hash, SessionKey}; use futures::prelude::*; use futures::sync::mpsc; use std::sync::Arc; -use tokio::runtime::TaskExecutor; use tokio::executor::Executor; +use tokio::runtime::TaskExecutor; use super::NetworkService; @@ -36,29 +36,40 @@ impl Sink for BftSink { // TODO: replace this with the ! type when that's stabilized type SinkError = E; - fn start_send(&mut self, message: bft::Communication) - -> ::futures::StartSend, E> - { + fn start_send( + &mut self, + message: bft::Communication, + ) -> ::futures::StartSend, E> { let network_message = net::LocalizedBftMessage { message: match message { rhododendron::Communication::Consensus(c) => msg::BftMessage::Consensus(match c { - rhododendron::LocalizedMessage::Propose(proposal) => msg::SignedConsensusMessage::Propose(msg::SignedConsensusProposal { - round_number: proposal.round_number as u32, - proposal: proposal.proposal, - digest: proposal.digest, - sender: proposal.sender, - digest_signature: proposal.digest_signature.signature, - full_signature: proposal.full_signature.signature, - }), - rhododendron::LocalizedMessage::Vote(vote) => msg::SignedConsensusMessage::Vote(msg::SignedConsensusVote { - sender: vote.sender, - signature: vote.signature.signature, - vote: match vote.vote { - rhododendron::Vote::Prepare(r, h) => msg::ConsensusVote::Prepare(r as u32, h), - rhododendron::Vote::Commit(r, h) => msg::ConsensusVote::Commit(r as u32, h), - rhododendron::Vote::AdvanceRound(r) => msg::ConsensusVote::AdvanceRound(r as u32), - }, - }), + rhododendron::LocalizedMessage::Propose(proposal) => { + msg::SignedConsensusMessage::Propose(msg::SignedConsensusProposal { + round_number: proposal.round_number as u32, + proposal: proposal.proposal, + digest: proposal.digest, + sender: proposal.sender, + digest_signature: proposal.digest_signature.signature, + full_signature: proposal.full_signature.signature, + }) + } + rhododendron::LocalizedMessage::Vote(vote) => { + msg::SignedConsensusMessage::Vote(msg::SignedConsensusVote { + sender: vote.sender, + signature: vote.signature.signature, + vote: match vote.vote { + rhododendron::Vote::Prepare(r, h) => { + msg::ConsensusVote::Prepare(r as u32, h) + } + rhododendron::Vote::Commit(r, h) => { + msg::ConsensusVote::Commit(r as u32, h) + } + rhododendron::Vote::AdvanceRound(r) => { + msg::ConsensusVote::AdvanceRound(r as u32) + } + }, + }) + } }), rhododendron::Communication::Auxiliary(justification) => { let unchecked: bft::UncheckedJustification<_> = justification.uncheck().into(); @@ -67,9 +78,10 @@ impl Sink for BftSink { }, parent_hash: self.parent_hash, }; - self.network.with_spec( - move |spec, ctx| spec.consensus_gossip.multicast_bft_message(ctx, network_message) - ); + self.network.with_spec(move |spec, ctx| { + spec.consensus_gossip + .multicast_bft_message(ctx, network_message) + }); Ok(::futures::AsyncSink::Ready) } @@ -83,33 +95,38 @@ fn process_bft_message( msg: msg::LocalizedBftMessage, local_id: &SessionKey, authorities: &[SessionKey], -) -> Result>, bft::Error> -{ +) -> Result>, bft::Error> { Ok(Some(match msg.message { msg::BftMessage::Consensus(c) => rhododendron::Communication::Consensus(match c { - msg::SignedConsensusMessage::Propose(proposal) => rhododendron::LocalizedMessage::Propose({ - if &proposal.sender == local_id { return Ok(None); } - let proposal = rhododendron::LocalizedProposal { - round_number: proposal.round_number as usize, - proposal: proposal.proposal, - digest: proposal.digest, - sender: proposal.sender, - digest_signature: ed25519::LocalizedSignature { - signature: proposal.digest_signature, - signer: ed25519::Public(proposal.sender.into()), - }, - full_signature: ed25519::LocalizedSignature { - signature: proposal.full_signature, - signer: ed25519::Public(proposal.sender.into()), - }, - }; - bft::check_proposal(authorities, &msg.parent_hash, &proposal)?; + msg::SignedConsensusMessage::Propose(proposal) => { + rhododendron::LocalizedMessage::Propose({ + if &proposal.sender == local_id { + return Ok(None); + } + let proposal = rhododendron::LocalizedProposal { + round_number: proposal.round_number as usize, + proposal: proposal.proposal, + digest: proposal.digest, + sender: proposal.sender, + digest_signature: ed25519::LocalizedSignature { + signature: proposal.digest_signature, + signer: ed25519::Public(proposal.sender.into()), + }, + full_signature: ed25519::LocalizedSignature { + signature: proposal.full_signature, + signer: ed25519::Public(proposal.sender.into()), + }, + }; + bft::check_proposal(authorities, &msg.parent_hash, &proposal)?; - trace!(target: "bft", "importing proposal message for round {} from {}", proposal.round_number, Hash::from(proposal.sender.0)); - proposal - }), + trace!(target: "bft", "importing proposal message for round {} from {}", proposal.round_number, Hash::from(proposal.sender.0)); + proposal + }) + } msg::SignedConsensusMessage::Vote(vote) => rhododendron::LocalizedMessage::Vote({ - if &vote.sender == local_id { return Ok(None); } + if &vote.sender == local_id { + return Ok(None); + } let vote = rhododendron::LocalizedVote { sender: vote.sender, signature: ed25519::LocalizedSignature { @@ -117,9 +134,15 @@ fn process_bft_message( signer: ed25519::Public(vote.sender.0), }, vote: match vote.vote { - msg::ConsensusVote::Prepare(r, h) => rhododendron::Vote::Prepare(r as usize, h), - msg::ConsensusVote::Commit(r, h) => rhododendron::Vote::Commit(r as usize, h), - msg::ConsensusVote::AdvanceRound(r) => rhododendron::Vote::AdvanceRound(r as usize), + msg::ConsensusVote::Prepare(r, h) => { + rhododendron::Vote::Prepare(r as usize, h) + } + msg::ConsensusVote::Commit(r, h) => { + rhododendron::Vote::Commit(r as usize, h) + } + msg::ConsensusVote::AdvanceRound(r) => { + rhododendron::Vote::AdvanceRound(r as usize) + } }, }; bft::check_vote::(authorities, &msg.parent_hash, &vote)?; @@ -131,8 +154,12 @@ fn process_bft_message( msg::BftMessage::Auxiliary(a) => { let justification = bft::UncheckedJustification::from(a); // TODO: get proper error - let justification: Result<_, bft::Error> = bft::check_prepare_justification::(authorities, msg.parent_hash, justification) - .map_err(|_| bft::ErrorKind::InvalidJustification.into()); + let justification: Result<_, bft::Error> = bft::check_prepare_justification::( + authorities, + msg.parent_hash, + justification, + ) + .map_err(|_| bft::ErrorKind::InvalidJustification.into()); rhododendron::Communication::Auxiliary(justification?) } })) @@ -182,9 +209,11 @@ impl Future for MessageProcessTask { fn poll(&mut self) -> Poll<(), ()> { loop { match self.inner_stream.poll() { - Ok(Async::Ready(Some(val))) => if let Some(async) = self.process_message(val) { - return Ok(async); - }, + Ok(Async::Ready(Some(val))) => { + if let Some(async) = self.process_message(val) { + return Ok(async); + } + } Ok(Async::Ready(None)) => return Ok(Async::Ready(())), Ok(Async::NotReady) => return Ok(Async::NotReady), Err(e) => { @@ -208,7 +237,7 @@ impl Stream for InputAdapter { fn poll(&mut self) -> Poll, Self::Error> { match self.input.poll() { Err(_) | Ok(Async::Ready(None)) => Err(bft::InputStreamConcluded.into()), - Ok(x) => Ok(x) + Ok(x) => Ok(x), } } } @@ -245,12 +274,12 @@ impl Network for ConsensusNetwork

{ /// Get input and output streams of BFT messages. fn communication_for( - &self, validators: &[SessionKey], + &self, + validators: &[SessionKey], local_id: SessionKey, parent_hash: Hash, mut task_executor: TaskExecutor, - ) -> (Self::Input, Self::Output) - { + ) -> (Self::Input, Self::Output) { let sink = BftSink { network: self.network.clone(), parent_hash, diff --git a/network/src/lib.rs b/network/src/lib.rs index 757a2163e7a2a..0a17c6ebbc039 100644 --- a/network/src/lib.rs +++ b/network/src/lib.rs @@ -5,19 +5,17 @@ //! This manages gossip of consensus messages for BFT, communication between validators //! and more. - - extern crate substrate_bft as bft; extern crate substrate_network; extern crate substrate_primitives; -extern crate chainx_primitives; -extern crate chainx_consensus; extern crate chainx_api; +extern crate chainx_consensus; +extern crate chainx_primitives; extern crate futures; -extern crate tokio; extern crate rhododendron; +extern crate tokio; #[macro_use] extern crate log; @@ -25,11 +23,11 @@ extern crate log; pub mod consensus; use chainx_primitives::{Block, Hash, Header}; -use substrate_network::{NodeIndex, Context, Severity}; use substrate_network::consensus_gossip::ConsensusGossip; -use substrate_network::{message, generic_message}; use substrate_network::specialization::Specialization; use substrate_network::StatusMessage as GenericFullStatus; +use substrate_network::{generic_message, message}; +use substrate_network::{Context, NodeIndex, Severity}; type FullStatus = GenericFullStatus; @@ -75,7 +73,12 @@ impl Specialization for ChainXProtocol { self.consensus_gossip.peer_disconnected(ctx, who); } - fn on_message(&mut self, ctx: &mut Context, who: NodeIndex, message: message::Message) { + fn on_message( + &mut self, + ctx: &mut Context, + who: NodeIndex, + message: message::Message, + ) { match message { generic_message::Message::BftMessage(msg) => { trace!(target: "p_net", "ChainX BFT message from {}: {:?}", who, msg); diff --git a/pool/src/error.rs b/pool/src/error.rs index 7eedfde30e561..e4c7ca57ac5e5 100644 --- a/pool/src/error.rs +++ b/pool/src/error.rs @@ -1,51 +1,50 @@ -use chainx_runtime::{Address, UncheckedExtrinsic}; +use chainx_api; use chainx_primitives::Hash; +use chainx_runtime::{Address, UncheckedExtrinsic}; use extrinsic_pool; -use chainx_api; - error_chain! { - links { - Pool(extrinsic_pool::Error, extrinsic_pool::ErrorKind); - Api(chainx_api::Error, chainx_api::ErrorKind); - } - errors { - /// Unexpected extrinsic format submitted - InvalidExtrinsicFormat { - description("Invalid extrinsic format."), - display("Invalid extrinsic format."), - } - /// Attempted to queue an inherent transaction. - IsInherent(xt: UncheckedExtrinsic) { - description("Inherent transactions cannot be queued."), - display("Inherent transactions cannot be queued."), - } - /// Attempted to queue a transaction with bad signature. - BadSignature(e: &'static str) { - description("Transaction had bad signature."), - display("Transaction had bad signature: {}", e), - } - /// Attempted to queue a transaction that is already in the pool. - AlreadyImported(hash: Hash) { - description("Transaction is already in the pool."), - display("Transaction {:?} is already in the pool.", hash), - } - /// Import error. - Import(err: Box<::std::error::Error + Send>) { - description("Error importing transaction"), - display("Error importing transaction: {}", err.description()), - } - /// Runtime failure. - UnrecognisedAddress(who: Address) { - description("Unrecognised address in extrinsic"), - display("Unrecognised address in extrinsic: {}", who), - } - /// Extrinsic too large - TooLarge(got: usize, max: usize) { - description("Extrinsic too large"), - display("Extrinsic is too large ({} > {})", got, max), - } - } + links { + Pool(extrinsic_pool::Error, extrinsic_pool::ErrorKind); + Api(chainx_api::Error, chainx_api::ErrorKind); + } + errors { + /// Unexpected extrinsic format submitted + InvalidExtrinsicFormat { + description("Invalid extrinsic format."), + display("Invalid extrinsic format."), + } + /// Attempted to queue an inherent transaction. + IsInherent(xt: UncheckedExtrinsic) { + description("Inherent transactions cannot be queued."), + display("Inherent transactions cannot be queued."), + } + /// Attempted to queue a transaction with bad signature. + BadSignature(e: &'static str) { + description("Transaction had bad signature."), + display("Transaction had bad signature: {}", e), + } + /// Attempted to queue a transaction that is already in the pool. + AlreadyImported(hash: Hash) { + description("Transaction is already in the pool."), + display("Transaction {:?} is already in the pool.", hash), + } + /// Import error. + Import(err: Box<::std::error::Error + Send>) { + description("Error importing transaction"), + display("Error importing transaction: {}", err.description()), + } + /// Runtime failure. + UnrecognisedAddress(who: Address) { + description("Unrecognised address in extrinsic"), + display("Unrecognised address in extrinsic: {}", who), + } + /// Extrinsic too large + TooLarge(got: usize, max: usize) { + description("Extrinsic too large"), + display("Extrinsic is too large ({} > {})", got, max), + } + } } impl extrinsic_pool::IntoPoolError for Error { diff --git a/pool/src/lib.rs b/pool/src/lib.rs index cc11f4be67c50..651ca72ab2389 100644 --- a/pool/src/lib.rs +++ b/pool/src/lib.rs @@ -1,27 +1,26 @@ // Copyright 2018 Chainpool. -extern crate sr_primitives as runtime_primitives; -extern crate substrate_primitives as substrate_primitives; -extern crate substrate_transaction_pool as extrinsic_pool; +extern crate chainx_api; +extern crate chainx_executor; +extern crate chainx_primitives; +extern crate chainx_runtime; extern crate parity_codec as codec; +extern crate sr_primitives as runtime_primitives; +extern crate substrate_client; extern crate substrate_client_db; extern crate substrate_executor; extern crate substrate_network; -extern crate substrate_client; -extern crate chainx_primitives; -extern crate chainx_executor; -extern crate chainx_runtime; -extern crate chainx_api; +extern crate substrate_primitives as substrate_primitives; +extern crate substrate_transaction_pool as extrinsic_pool; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; -mod pool; mod error; +mod pool; -pub use pool::TransactionPool; pub use extrinsic_pool::Pool; pub use pool::PoolApi; - +pub use pool::TransactionPool; diff --git a/pool/src/pool.rs b/pool/src/pool.rs index 40366439dfb2e..fea44c4564b9e 100644 --- a/pool/src/pool.rs +++ b/pool/src/pool.rs @@ -1,23 +1,28 @@ // Copyright 2018 Chainpool. -use extrinsic_pool::{Pool, ChainApi, VerifiedFor, ExtrinsicFor, scoring, - Readiness, VerifiedTransaction, Transaction, Options, scoring::Choice}; -use runtime_primitives::traits::{Hash as HashT, Bounded, Checkable, BlakeTwo256, Lookup, CurrentHeight, BlockNumberToHash}; +use chainx_api::ChainXApi; +use chainx_executor; +use chainx_primitives::{AccountId, Block, BlockId, BlockNumber, Hash, Index}; +use chainx_runtime::{Address, UncheckedExtrinsic}; +use codec::{Decode, Encode}; +use error::{Error, ErrorKind, Result}; +use extrinsic_pool; +use extrinsic_pool::IntoPoolError; +use extrinsic_pool::{ + scoring, scoring::Choice, ChainApi, ExtrinsicFor, Options, Pool, Readiness, Transaction, + VerifiedFor, VerifiedTransaction, +}; +use runtime_primitives::traits::{ + BlakeTwo256, BlockNumberToHash, Bounded, Checkable, CurrentHeight, Hash as HashT, Lookup, +}; use std::{cmp::Ordering, collections::HashMap, sync::Arc}; -use chainx_primitives::{Block, Hash, BlockId, AccountId, Index, BlockNumber}; -use chainx_runtime::{UncheckedExtrinsic, Address}; -use substrate_executor::NativeExecutor; use substrate_client::{self, Client}; -use extrinsic_pool::IntoPoolError; -use codec::{Encode, Decode}; -use chainx_api::ChainXApi; use substrate_client_db; +use substrate_executor::NativeExecutor; use substrate_network; -use chainx_executor; -use extrinsic_pool; -use error::{Error, ErrorKind, Result}; -type Executor = substrate_client::LocalCallExecutor>; +type Executor = + substrate_client::LocalCallExecutor>; type Backend = substrate_client_db::Backend; const MAX_TRANSACTION_SIZE: usize = 4 * 1024 * 1024; @@ -58,13 +63,13 @@ impl VerifiedTransaction for VerifiedExtrinsic { &self.hash } - fn sender(&self) -> &Self::Sender { - &self.sender - } - fn mem_usage(&self) -> usize { self.encoded_size } + + fn sender(&self) -> &Self::Sender { + &self.sender + } } pub struct LocalContext<'a, A: 'a>(&'a Arc); @@ -85,45 +90,44 @@ impl<'a, A: 'a + ChainXApi> Lookup for LocalContext<'a, A> { type Source = Address; type Target = AccountId; fn lookup(&self, a: Address) -> ::std::result::Result { - self.0.lookup(&BlockId::number(self.current_height()), a).unwrap_or(None).ok_or("error with lookup") + self.0 + .lookup(&BlockId::number(self.current_height()), a) + .unwrap_or(None) + .ok_or("error with lookup") } } -pub struct PoolApi{ - api:Arc, +pub struct PoolApi { + api: Arc, } -impl PoolApi where +impl PoolApi +where A: ChainXApi, { /// Create a new instance. pub fn new(api: Arc) -> Self { - PoolApi { - api, - } + PoolApi { api } } } -impl ChainApi for PoolApi where +impl ChainApi for PoolApi +where A: ChainXApi + Send + Sync, { - type Ready = HashMap; + type Block = Block; + type Hash = Hash; type Sender = AccountId; type VEx = VerifiedExtrinsic; - type Block = Block; + type Ready = HashMap; type Error = Error; - type Hash = Hash; type Score = u64; type Event = (); - fn verify_transaction( - &self, - _at: &BlockId, - xt: &ExtrinsicFor, - ) -> Result { - + fn verify_transaction(&self, _at: &BlockId, xt: &ExtrinsicFor) -> Result { let encoded = xt.encode(); - let uxt = UncheckedExtrinsic::decode(&mut encoded.as_slice()).ok_or_else(|| ErrorKind::InvalidExtrinsicFormat)?; + let uxt = UncheckedExtrinsic::decode(&mut encoded.as_slice()) + .ok_or_else(|| ErrorKind::InvalidExtrinsicFormat)?; if !uxt.is_signed() { bail!(ErrorKind::IsInherent(uxt)) @@ -134,9 +138,11 @@ impl ChainApi for PoolApi where bail!(ErrorKind::TooLarge(encoded_size, MAX_TRANSACTION_SIZE)); } - debug!(target: "transaction-pool", "Transaction submitted: {}", ::substrate_primitives::hexdisplay::HexDisplay::from(&encoded)); + debug!(target: "transaction-pool", "Transaction submitted: {}", ::substrate_primitives::hexdisplay::HexDisplay::from(&encoded)); let checked = uxt.clone().check(&LocalContext(&self.api))?; - let (sender, index) = checked.signed.expect("function previously bailed unless uxt.is_signed(); qed"); + let (sender, index) = checked + .signed + .expect("function previously bailed unless uxt.is_signed(); qed"); if encoded_size < 1024 { debug!(target: "transaction-pool", "Transaction verified: {} => {:?}", hash, uxt); @@ -168,8 +174,11 @@ impl ChainApi for PoolApi where // TODO: find a way to handle index error properly -- will need changes to // transaction-pool trait. let api = &self.api; - let next_index = known_nonces.entry(sender) - .or_insert_with(|| api.index(at, sender).ok().unwrap_or_else(Bounded::max_value)); + let next_index = known_nonces.entry(sender).or_insert_with(|| { + api.index(at, sender) + .ok() + .unwrap_or_else(Bounded::max_value) + }); let result = match xt.verified.index.cmp(&next_index) { Ordering::Greater => Readiness::Future, @@ -200,7 +209,7 @@ impl ChainApi for PoolApi where _change: scoring::Change<()>, ) { for i in 0..xts.len() { - scores[i] = 1; + scores[i] = 1; } } @@ -209,18 +218,22 @@ impl ChainApi for PoolApi where } fn latest_hash(&self) -> Hash { - self.api.block_number_to_hash(self.api.current_height()).expect("Latest block number always has a hash; qed") + self.api + .block_number_to_hash(self.api.current_height()) + .expect("Latest block number always has a hash; qed") } } -pub struct TransactionPool where +pub struct TransactionPool +where A: ChainXApi + Send + Sync, { inner: Arc>>, client: Arc>, } -impl TransactionPool where +impl TransactionPool +where A: ChainXApi + Send + Sync, { /// Create a new transaction pool. @@ -247,7 +260,8 @@ impl TransactionPool where } } -impl substrate_network::TransactionPool for TransactionPool where +impl substrate_network::TransactionPool for TransactionPool +where A: ChainXApi + Send + Sync, { fn transactions(&self) -> Vec<(Hash, ExtrinsicFor>)> { @@ -260,7 +274,7 @@ impl substrate_network::TransactionPool for TransactionPool w pending .map(|t| { let hash = t.hash().clone(); - let ex:ExtrinsicFor> = t.original.clone(); + let ex: ExtrinsicFor> = t.original.clone(); (hash, ex) }) .collect() @@ -279,19 +293,21 @@ impl substrate_network::TransactionPool for TransactionPool w Ok(xt) => Some(*xt.hash()), Err(e) => match e.into_pool_error() { Ok(e) => match e.kind() { - extrinsic_pool::ErrorKind::AlreadyImported(hash) => - Some(::std::str::FromStr::from_str(&hash).map_err(|_| {}) - .expect("Hash string is always valid")), + extrinsic_pool::ErrorKind::AlreadyImported(hash) => Some( + ::std::str::FromStr::from_str(&hash) + .map_err(|_| {}) + .expect("Hash string is always valid"), + ), _ => { debug!("Error adding transaction to the pool: {:?}", e); None - }, + } }, Err(e) => { debug!("Error converting pool error: {:?}", e); None } - } + }, } } else { debug!("Error decoding transaction"); diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index b07e4d46adab1..a5e922c287e4e 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -5,9 +5,9 @@ #![cfg_attr(not(feature = "std"), feature(alloc))] extern crate parity_codec as codec; -extern crate substrate_primitives as primitives; extern crate sr_primitives as runtime_primitives; extern crate sr_std as rstd; +extern crate substrate_primitives as primitives; #[cfg(test)] extern crate substrate_serializer; @@ -24,8 +24,8 @@ extern crate parity_codec_derive; use primitives::bytes; use rstd::prelude::*; -use runtime_primitives::traits::BlakeTwo256; use runtime_primitives::generic; +use runtime_primitives::traits::BlakeTwo256; /// Signature on candidate's block data by a collator. pub type CandidateSignature = ::runtime_primitives::Ed25519Signature; @@ -64,7 +64,6 @@ pub type AccountId = primitives::H256; /// never know... pub type AccountIndex = u64; - /// Indentifier for a chain. 32-bit should be plenty. pub type ChainId = u32; @@ -126,7 +125,10 @@ impl CandidateReceipt { pub fn check_signature(&self) -> Result<(), ()> { use runtime_primitives::traits::Verify; - if self.signature.verify(&self.block_data_hash.0[..], &self.collator) { + if self + .signature + .verify(&self.block_data_hash.0[..], &self.collator) + { Ok(()) } else { Err(()) diff --git a/rpc/src/chainext/error.rs b/rpc/src/chainext/error.rs index b7b8704597573..e60fcb02a9c71 100644 --- a/rpc/src/chainext/error.rs +++ b/rpc/src/chainext/error.rs @@ -19,16 +19,16 @@ pub fn internal(e: E) -> rpccore::Error { } error_chain! { - links { - Client(client::error::Error, client::error::ErrorKind) #[doc = "Client error"]; - } - errors { - /// Not implemented yet - Unimplemented { - description("not yet implemented"), - display("Method Not Implemented"), - } - } + links { + Client(client::error::Error, client::error::ErrorKind) #[doc = "Client error"]; + } + errors { + /// Not implemented yet + Unimplemented { + description("not yet implemented"), + display("Method Not Implemented"), + } + } } impl From for rpccore::Error { diff --git a/rpc/src/chainext/mod.rs b/rpc/src/chainext/mod.rs index d1daf18702fc7..23d9f22c1b26f 100644 --- a/rpc/src/chainext/mod.rs +++ b/rpc/src/chainext/mod.rs @@ -12,11 +12,11 @@ mod error; use self::error::Result; build_rpc_trait! { - pub trait ChainApiExt { + pub trait ChainApiExt { - #[rpc(name = "chainext_getBlockByNumber")] - fn block_info(&self, Trailing) -> Result>>; - } + #[rpc(name = "chainext_getBlockByNumber")] + fn block_info(&self, Trailing) -> Result>>; + } } pub struct ChainExt { @@ -30,11 +30,11 @@ impl ChainExt { } impl ChainApiExt, Block::Extrinsic> -for ChainExt - where - Block: BlockT + 'static, - B: client::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, + for ChainExt +where + Block: BlockT + 'static, + B: client::backend::Backend + Send + Sync + 'static, + E: client::CallExecutor + Send + Sync + 'static, { fn block_info( &self, diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 4865343488698..bd3bdd68ff41a 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -10,12 +10,12 @@ extern crate jsonrpc_http_server as http; extern crate jsonrpc_pubsub as pubsub; extern crate jsonrpc_ws_server as ws; extern crate serde; +extern crate sr_primitives as runtime_primitives; extern crate substrate_client as client; extern crate substrate_primitives as primitives; extern crate substrate_rpc; pub extern crate substrate_rpc as apis; extern crate substrate_rpc_servers as rpc_server; -extern crate sr_primitives as runtime_primitives; extern crate tokio; #[macro_use] extern crate error_chain; @@ -66,8 +66,8 @@ pub fn maybe_start_server( address: Option, start: F, ) -> Result, io::Error> - where - F: Fn(&SocketAddr) -> Result, +where + F: Fn(&SocketAddr) -> Result, { Ok(match address { Some(mut address) => Some(start(&address).or_else(|e| match e.kind() { diff --git a/rpc/src/servers.rs b/rpc/src/servers.rs index fe525227b436e..e3269a1dcafa5 100644 --- a/rpc/src/servers.rs +++ b/rpc/src/servers.rs @@ -25,25 +25,31 @@ pub fn rpc_handler( author: A, system: Y, ) -> RpcHandler - where - Block: BlockT + 'static, - ExHash: Send +where + Block: BlockT + 'static, + ExHash: Send + Sync + 'static + runtime_primitives::Serialize + runtime_primitives::DeserializeOwned, - PendingExtrinsics: serde::Serialize + serde::de::DeserializeOwned + Send + Sync + 'static, - S: apis::state::StateApi, - C: apis::chain::ChainApi< - Block::Hash, - Block::Header, - NumberFor, - Block::Extrinsic, - Metadata=Metadata, - >, - CE: chainext::ChainApiExt, Block::Extrinsic>, - A: apis::author::AuthorApi, - Y: apis::system::SystemApi, + PendingExtrinsics: serde::Serialize + serde::de::DeserializeOwned + Send + Sync + 'static, + S: apis::state::StateApi, + C: apis::chain::ChainApi< + Block::Hash, + Block::Header, + NumberFor, + Block::Extrinsic, + Metadata = Metadata, + >, + CE: chainext::ChainApiExt, Block::Extrinsic>, + A: apis::author::AuthorApi< + ExHash, + Block::Hash, + Block::Extrinsic, + PendingExtrinsics, + Metadata = Metadata, + >, + Y: apis::system::SystemApi, { let mut io = pubsub::PubSubHandler::default(); io.extend_with(state.to_delegate()); @@ -67,13 +73,14 @@ pub fn start_http(addr: &std::net::SocketAddr, io: RpcHandler) -> io::Result io::Result { ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| { Metadata::new(context.sender()) - }).start(addr) - .map_err(|err| match err { - ws::Error(ws::ErrorKind::Io(io), _) => io, - ws::Error(ws::ErrorKind::ConnectionClosed, _) => io::ErrorKind::BrokenPipe.into(), - ws::Error(e, _) => { - error!("{}", e); - io::ErrorKind::Other.into() - } - }) + }) + .start(addr) + .map_err(|err| match err { + ws::Error(ws::ErrorKind::Io(io), _) => io, + ws::Error(ws::ErrorKind::ConnectionClosed, _) => io::ErrorKind::BrokenPipe.into(), + ws::Error(e, _) => { + error!("{}", e); + io::ErrorKind::Other.into() + } + }) } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index acab4a154ba44..93e0ed781a9fa 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -23,7 +23,6 @@ srml-democracy = { git = "https://github.com/paritytech/substrate" } srml-executive = { git = "https://github.com/paritytech/substrate" } sr-primitives = { git = "https://github.com/paritytech/substrate" } srml-session = { git = "https://github.com/paritytech/substrate" } - srml-system = { git = "https://github.com/paritytech/substrate" } srml-timestamp = { git = "https://github.com/paritytech/substrate" } srml-treasury = { git = "https://github.com/paritytech/substrate" } diff --git a/runtime/src/checked_block.rs b/runtime/src/checked_block.rs index 54c7e874274e5..e9b66bd46fb4a 100644 --- a/runtime/src/checked_block.rs +++ b/runtime/src/checked_block.rs @@ -2,7 +2,9 @@ //! Typesafe block interaction. -use super::{Call, Block, AccountId, TIMESTAMP_SET_POSITION, NOTE_OFFLINE_POSITION, BLOCK_PRODUCER_POSITION}; +use super::{ + AccountId, Block, Call, BLOCK_PRODUCER_POSITION, NOTE_OFFLINE_POSITION, TIMESTAMP_SET_POSITION, +}; use timestamp::Call as TimestampCall; //use session::Call as SessionCall; use cxsystem::Call as CXSystemCall; @@ -20,8 +22,8 @@ impl CheckedBlock { .extrinsics .get(TIMESTAMP_SET_POSITION as usize) .map_or(false, |xt| { - !xt.is_signed() && - match xt.function { + !xt.is_signed() + && match xt.function { Call::Timestamp(TimestampCall::set(_)) => true, _ => false, } @@ -48,7 +50,8 @@ impl CheckedBlock { /// Extract the timestamp from the block. pub fn timestamp(&self) -> ::chainx_primitives::Timestamp { - let x = self.inner + let x = self + .inner .extrinsics .get(TIMESTAMP_SET_POSITION as usize) .and_then(|xt| match xt.function { @@ -102,7 +105,7 @@ impl ::std::ops::Deref for CheckedBlock { /// in case it isn't. #[macro_export] macro_rules! assert_chainx_block { - ($block: expr) => { - $crate::CheckedBlock::new_unchecked($block, file!(), line!()) - } + ($block: expr) => { + $crate::CheckedBlock::new_unchecked($block, file!(), line!()) + }; } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 29ae01227cc31..4c9227ef2396a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -3,7 +3,6 @@ //! The ChainX runtime. This can be compiled with ``#[no_std]`, ready for Wasm. #![cfg_attr(not(feature = "std"), no_std)] - // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] @@ -22,12 +21,11 @@ extern crate sr_primitives as runtime_primitives; extern crate parity_codec as codec; #[macro_use] extern crate parity_codec_derive; -extern crate substrate_primitives; #[cfg_attr(not(feature = "std"), macro_use)] extern crate sr_std as rstd; +extern crate srml_balances as balances; extern crate srml_consensus as consensus; extern crate srml_contract as contract; -extern crate srml_balances as balances; extern crate srml_council as council; extern crate srml_democracy as democracy; extern crate srml_executive as executive; @@ -35,22 +33,22 @@ extern crate srml_session as session; extern crate srml_system as system; extern crate srml_timestamp as timestamp; extern crate srml_treasury as treasury; +extern crate substrate_primitives; // cx runtime module -extern crate cxrml_system as cxsystem; -extern crate cxrml_support as cxsupport; +extern crate cxrml_associations as associations; +extern crate cxrml_multisig as multisig; extern crate cxrml_staking as staking; +extern crate cxrml_support as cxsupport; +extern crate cxrml_system as cxsystem; extern crate cxrml_tokenbalances as tokenbalances; -extern crate cxrml_multisig as multisig; -extern crate cxrml_associations as associations; // chainx runtime bridge extern crate cxrml_bridge_btc as bridge_btc; // funds extern crate cxrml_funds_financialrecords as financialrecords; extern crate cxrml_funds_withdrawal as withdrawal; // exchange -extern crate cxrml_exchange_pendingorders as pendingorders; extern crate cxrml_exchange_matchorder as matchorder; - +extern crate cxrml_exchange_pendingorders as pendingorders; #[macro_use] extern crate sr_version as version; @@ -62,44 +60,46 @@ mod checked_block; pub use balances::address::Address as RawAddress; #[cfg(feature = "std")] pub use checked_block::CheckedBlock; -pub use runtime_primitives::{Permill, Perbill}; +pub use runtime_primitives::{Perbill, Permill}; pub use tokenbalances::Token; -use rstd::prelude::*; -use substrate_primitives::u32_trait::{_2, _4}; -use chainx_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature}; -use timestamp::Call as TimestampCall; +use chainx_primitives::InherentData; +use chainx_primitives::{ + AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature, +}; pub use consensus::Call as ConsensusCall; +use council::{motions as council_motions, voting as council_voting}; use cxsystem::Call as CXSystemCall; -use chainx_primitives::InherentData; +use rstd::prelude::*; use runtime_primitives::generic; -use runtime_primitives::traits::{Convert, BlakeTwo256, DigestItem}; -use council::{motions as council_motions, voting as council_voting}; -use version::{RuntimeVersion, ApiId}; +use runtime_primitives::traits::{BlakeTwo256, Convert, DigestItem}; +use substrate_primitives::u32_trait::{_2, _4}; +use timestamp::Call as TimestampCall; #[cfg(any(feature = "std", test))] use version::NativeVersion; +use version::{ApiId, RuntimeVersion}; // for set consensus period -pub use timestamp::BlockPeriod; pub use srml_support::StorageValue; +pub use timestamp::BlockPeriod; -#[cfg(feature = "std")] -pub use multisig::BalancesConfigCopy; #[cfg(feature = "std")] pub use bridge_btc::Params; +#[cfg(feature = "std")] +pub use multisig::BalancesConfigCopy; pub fn inherent_extrinsics(data: InherentData) -> Vec { let mut inherent = vec![generic::UncheckedMortalExtrinsic::new_unsigned( - Call::Timestamp(TimestampCall::set(data.timestamp)) + Call::Timestamp(TimestampCall::set(data.timestamp)), )]; inherent.push(generic::UncheckedMortalExtrinsic::new_unsigned( - Call::CXSystem(CXSystemCall::set_block_producer(data.block_producer)) + Call::CXSystem(CXSystemCall::set_block_producer(data.block_producer)), )); if !data.offline_indices.is_empty() { inherent.push(generic::UncheckedMortalExtrinsic::new_unsigned( - Call::Consensus(ConsensusCall::note_offline(data.offline_indices)) + Call::Consensus(ConsensusCall::note_offline(data.offline_indices)), )); } @@ -261,16 +261,15 @@ impl withdrawal::Trait for Runtime {} // exchange impl pendingorders::Trait for Runtime { - type Event = Event; type Amount = TokenBalance; type Price = TokenBalance; + type Event = Event; } impl matchorder::Trait for Runtime { type Event = Event; } - impl DigestItem for Log { type Hash = Hash; type AuthorityId = SessionKey; @@ -337,7 +336,8 @@ pub type UncheckedExtrinsic = generic::UncheckedMortalExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = executive::Executive, Balances, AllModules>; +pub type Executive = + executive::Executive, Balances, AllModules>; // define tokenbalances module type pub type TokenBalance = u128; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/cli.rs b/src/cli.rs index ae8087a5e7966..c66122bc4d0e9 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,6 @@ // Copyright 2018 chainpool -use clap::{Arg, App, SubCommand, ArgMatches}; +use clap::{App, Arg, ArgMatches, SubCommand}; use std::net::SocketAddr; #[derive(Clone, Debug)] @@ -125,13 +125,15 @@ pub fn parse_address( port_param: &str, matches: &ArgMatches, ) -> Result { - let mut address: SocketAddr = default.parse().ok().ok_or_else(|| { - format!("Invalid address specified for --{}.", port_param) - })?; + let mut address: SocketAddr = default + .parse() + .ok() + .ok_or_else(|| format!("Invalid address specified for --{}.", port_param))?; if let Some(port) = matches.value_of(port_param) { - let port: u16 = port.parse().ok().ok_or_else(|| { - format!("Invalid port for --{} specified.", port_param) - })?; + let port: u16 = port + .parse() + .ok() + .ok_or_else(|| format!("Invalid port for --{} specified.", port_param))?; address.set_port(port); } diff --git a/src/client.rs b/src/client.rs index f0dbd93e47661..92e50a7dc9184 100644 --- a/src/client.rs +++ b/src/client.rs @@ -3,14 +3,14 @@ use std::path::PathBuf; use Arc; -use substrate_client; use client_db; use state_db; +use substrate_client; -pub use chainx_api::{TBackend, TExecutor, TClient, TClientBlockBuilder}; -use state_machine::ExecutionStrategy; +pub use chainx_api::{TBackend, TClient, TClientBlockBuilder, TExecutor}; use chainx_executor::NativeExecutor; use cli::ChainSpec; +use state_machine::ExecutionStrategy; const FINALIZATION_WINDOW: u64 = 32; @@ -23,14 +23,14 @@ pub fn build_client(db_path: &str, chainspec: ChainSpec) -> Arc { pruning: state_db::PruningMode::default(), }, FINALIZATION_WINDOW, - ).unwrap(), + ) + .unwrap(), ); let executor = substrate_client::LocalCallExecutor::new(backend.clone(), NativeExecutor::new()); let genesis_config = super::genesis_config::testnet_genesis(chainspec); - Arc::new( TClient::new( backend.clone(), @@ -38,6 +38,7 @@ pub fn build_client(db_path: &str, chainspec: ChainSpec) -> Arc { genesis_config, ExecutionStrategy::NativeWhenPossible, ExecutionStrategy::NativeWhenPossible, - ).unwrap(), + ) + .unwrap(), ) } diff --git a/src/genesis_config.rs b/src/genesis_config.rs index c3f9c8d56c070..7d073121b1fd4 100644 --- a/src/genesis_config.rs +++ b/src/genesis_config.rs @@ -1,32 +1,29 @@ // Copyright 2018 chainpool -extern crate primitives as btc_primitives; -extern crate chain as btc_chain; extern crate base58; +extern crate chain as btc_chain; extern crate cxrml_exchange_pendingorders; extern crate cxrml_tokenbalances; extern crate keys; +extern crate primitives as btc_primitives; -use self::cxrml_exchange_pendingorders::OrderPair; use self::base58::FromBase58; -use chainx_runtime::{GenesisConfig, ConsensusConfig, CouncilVotingConfig, DemocracyConfig, - SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig, - ContractConfig, Permill, Perbill, - CXSystemConfig, - TokenBalancesConfig, Token, - MultiSigConfig, BalancesConfigCopy, - AssociationsConfig, - WithdrawalConfig, - BridgeOfBTCConfig, Params, BridgeOfBTC, - PendingOrdersConfig, MatchOrderConfig}; +use self::cxrml_exchange_pendingorders::OrderPair; +use chainx_runtime::{ + AssociationsConfig, BalancesConfig, BalancesConfigCopy, BridgeOfBTC, BridgeOfBTCConfig, + CXSystemConfig, ConsensusConfig, ContractConfig, CouncilVotingConfig, DemocracyConfig, + GenesisConfig, MatchOrderConfig, MultiSigConfig, Params, PendingOrdersConfig, Perbill, Permill, + SessionConfig, StakingConfig, TimestampConfig, Token, TokenBalancesConfig, TreasuryConfig, + WithdrawalConfig, +}; use super::cli::ChainSpec; -use keyring::Keyring; use ed25519; +use keyring::Keyring; -use self::btc_primitives::{hash::H256, compact::Compact}; use self::btc_chain::BlockHeader; -use self::keys::DisplayLayout; +use self::btc_primitives::{compact::Compact, hash::H256}; use self::cxrml_tokenbalances::TokenT; +use self::keys::DisplayLayout; pub fn testnet_genesis(chainspec: ChainSpec) -> GenesisConfig { let alice = ed25519::Pair::from_seed(b"Alice ").public(); @@ -46,10 +43,9 @@ pub fn testnet_genesis(chainspec: ChainSpec) -> GenesisConfig { ChainSpec::Multi => vec![auth1, auth2, auth3, auth4], }; - -// const MILLICENTS: u128 = 1_000_000_000; -// const CENTS: u128 = 1_000 * MILLICENTS; // assume this is worth about a cent. -// const DOLLARS: u128 = 100 * CENTS; + // const MILLICENTS: u128 = 1_000_000_000; + // const CENTS: u128 = 1_000 * MILLICENTS; // assume this is worth about a cent. + // const DOLLARS: u128 = 100 * CENTS; const SECS_PER_BLOCK: u64 = 3; const MINUTES: u64 = 60 / SECS_PER_BLOCK; diff --git a/src/main.rs b/src/main.rs index 65f68fea72b55..48934eb2765c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,46 +23,44 @@ extern crate chainx_primitives; extern crate chainx_rpc; extern crate chainx_runtime; - +extern crate ansi_term; extern crate clap; extern crate ctrlc; extern crate env_logger; extern crate exit_future; extern crate hex_literal; -extern crate parity_codec as codec; extern crate jsonrpc_http_server; extern crate jsonrpc_ws_server; +extern crate names; +extern crate parity_codec as codec; extern crate rhododendron; -extern crate ansi_term; extern crate sysinfo; -extern crate names; extern crate tokio; #[macro_use] extern crate slog; #[macro_use] extern crate log; +mod cli; +mod client; mod genesis_config; -mod telemetry; mod network; -mod client; mod rpc; -mod cli; +mod telemetry; use substrate_client::BlockchainEvents; use substrate_primitives::{ed25519, ed25519::Pair, storage::StorageKey, twox_128}; -use chainx_network::consensus::ConsensusNetwork; -use chainx_pool::{PoolApi, TransactionPool, Pool}; -use chainx_primitives::{Block, Hash, BlockId, Timestamp}; use chainx_api::TClient; -use chainx_runtime::{BlockPeriod, StorageValue, Runtime as ChainXRuntime}; +use chainx_network::consensus::ConsensusNetwork; +use chainx_pool::{Pool, PoolApi, TransactionPool}; +use chainx_primitives::{Block, BlockId, Hash, Timestamp}; +use chainx_runtime::{BlockPeriod, Runtime as ChainXRuntime, StorageValue}; use cli::ChainSpec; - use codec::Decode; -use std::sync::Arc; use names::{Generator, Name}; +use std::sync::Arc; use tokio::prelude::Future; use tokio::prelude::Stream; use tokio::runtime::Runtime; @@ -134,10 +132,13 @@ fn main() { .import_notification_stream() .for_each(move |notification| { network.on_block_imported(notification.hash, ¬ification.header); - txpool.inner().cull(&BlockId::hash(notification.hash)) + txpool + .inner() + .cull(&BlockId::hash(notification.hash)) .map_err(|e| warn!("Error removing extrinsics: {:?}", e))?; Ok(()) - }).select(exit.clone()) + }) + .select(exit.clone()) .then(|_| Ok(())); task_executor.spawn(events); } @@ -146,7 +147,9 @@ fn main() { // extrinsic notifications let network = network.clone(); let txpool = extrinsic_pool.clone(); - let events = txpool.inner().import_notification_stream() + let events = txpool + .inner() + .import_notification_stream() // TODO [ToDr] Consider throttling? .for_each(move |_| { network.trigger_repropagate(); @@ -164,40 +167,40 @@ fn main() { .unwrap() .value_of("auth") .unwrap_or("alice") - { - "alice" => { - info!("Auth is alice"); - ed25519::Pair::from_seed(b"Alice ") - } - "bob" => { - info!("Auth is bob"); - ed25519::Pair::from_seed(b"Bob ") - } - "gavin" => { - info!("Auth is gavin"); - ed25519::Pair::from_seed(b"Gavin ") - } - "charlie" => { - info!("Auth is charlie"); - ed25519::Pair::from_seed(b"Charlie ") - } - "dave" => { - info!("Auth is dave"); - ed25519::Pair::from_seed(b"Dave ") - } - "eve" => { - info!("Auth is eve"); - ed25519::Pair::from_seed(b"Eve ") - } - "ferdie" => { - info!("Auth is ferdie"); - ed25519::Pair::from_seed(b"Ferdie ") - } - "satoshi" | _ => { - info!("Auth is satoshi"); - ed25519::Pair::from_seed(b"Satoshi ") - } - }; + { + "alice" => { + info!("Auth is alice"); + ed25519::Pair::from_seed(b"Alice ") + } + "bob" => { + info!("Auth is bob"); + ed25519::Pair::from_seed(b"Bob ") + } + "gavin" => { + info!("Auth is gavin"); + ed25519::Pair::from_seed(b"Gavin ") + } + "charlie" => { + info!("Auth is charlie"); + ed25519::Pair::from_seed(b"Charlie ") + } + "dave" => { + info!("Auth is dave"); + ed25519::Pair::from_seed(b"Dave ") + } + "eve" => { + info!("Auth is eve"); + ed25519::Pair::from_seed(b"Eve ") + } + "ferdie" => { + info!("Auth is ferdie"); + ed25519::Pair::from_seed(b"Ferdie ") + } + "satoshi" | _ => { + info!("Auth is satoshi"); + ed25519::Pair::from_seed(b"Satoshi ") + } + }; if let Some(seed) = matches.value_of("key") { let generate_from_seed = |seed: &str| -> Pair { @@ -211,7 +214,12 @@ fn main() { let block_id = BlockId::number(client.info().unwrap().chain.best_number); // TODO: this needs to be dynamically adjustable - let block_delay = client.storage(&block_id, &StorageKey(twox_128(BlockPeriod::::key()).to_vec())).unwrap() + let block_delay = client + .storage( + &block_id, + &StorageKey(twox_128(BlockPeriod::::key()).to_vec()), + ) + .unwrap() .and_then(|data| Timestamp::decode(&mut data.0.as_slice())) .unwrap_or_else(|| { warn!("Block period is missing in the storage."); diff --git a/src/network.rs b/src/network.rs index efb85f8b6eefe..3380327aa6265 100644 --- a/src/network.rs +++ b/src/network.rs @@ -1,14 +1,14 @@ // Copyright 2018 chainpool -use std::net::Ipv4Addr; -use std::iter; use clap; +use std::iter; +use std::net::Ipv4Addr; use Arc; -use substrate_network::{Params, TransactionPool, Roles}; -use substrate_network_libp2p::Protocol; -use substrate_network_libp2p; use substrate_network; +use substrate_network::{Params, Roles, TransactionPool}; +use substrate_network_libp2p; +use substrate_network_libp2p::Protocol; use chainx_network::{ChainXProtocol, NetworkService, CHAINX_PROTOCOL_ID}; @@ -26,15 +26,16 @@ pub fn build_network( let mut net_conf = substrate_network_libp2p::NetworkConfiguration::new(); net_conf.listen_addresses = vec![]; for addr in multi_address { - let addr = addr.parse().map_err(|_| "Invalid listen multiaddress").unwrap(); + let addr = addr + .parse() + .map_err(|_| "Invalid listen multiaddress") + .unwrap(); net_conf.listen_addresses.push(addr); } if net_conf.listen_addresses.is_empty() { - net_conf.listen_addresses = vec![ - iter::once(Protocol::Ip4(Ipv4Addr::new(0, 0, 0, 0))) - .chain(iter::once(Protocol::Tcp(port))) - .collect(), - ]; + net_conf.listen_addresses = vec![iter::once(Protocol::Ip4(Ipv4Addr::new(0, 0, 0, 0))) + .chain(iter::once(Protocol::Tcp(port))) + .collect()]; } net_conf.boot_nodes = boot_nodes; net_conf.net_config_path = Some(net_config_path.to_string()); @@ -43,7 +44,7 @@ pub fn build_network( config.roles = Roles::AUTHORITY; } let param = NetworkParam { - config: config, + config, network_config: net_conf, chain: client, on_demand: None, diff --git a/src/rpc.rs b/src/rpc.rs index f05bb735046f9..e02188b8c3759 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -1,18 +1,18 @@ // Copyright 2018 chainpool -use jsonrpc_http_server::Server as HttpServer; -use jsonrpc_ws_server::Server as WsServer; -use chainx_pool::TransactionPool; -use tokio::runtime::TaskExecutor; use chainx_api::ChainXApi; use chainx_api::TClient; +use chainx_pool::TransactionPool; use chainx_primitives; use chainx_rpc; +use clap; +use cli; +use jsonrpc_http_server::Server as HttpServer; +use jsonrpc_ws_server::Server as WsServer; use rpc_server; use std::io; +use tokio::runtime::TaskExecutor; use Arc; -use clap; -use cli; pub fn start( client: &Arc, @@ -22,7 +22,8 @@ pub fn start( ) -> ( Result, io::Error>, Result, io::Error>, -) where +) +where A: ChainXApi + Send + Sync + 'static, { let handler = || { @@ -36,7 +37,16 @@ pub fn start( extrinsic_pool.inner().clone(), subscriptions.clone(), ); - chainx_rpc::servers::rpc_handler::( + chainx_rpc::servers::rpc_handler::< + chainx_primitives::Block, + chainx_primitives::Hash, + _, + _, + _, + _, + _, + _, + >( state, chain, chain_ext, @@ -44,8 +54,16 @@ pub fn start( chainx_rpc::default_rpc_config(), ) }; - let rpc_interface: &str = if matches.is_present("rpc-external") { "0.0.0.0" } else { "127.0.0.1" }; - let ws_interface: &str = if matches.is_present("ws-external") { "0.0.0.0" } else { "127.0.0.1" }; + let rpc_interface: &str = if matches.is_present("rpc-external") { + "0.0.0.0" + } else { + "127.0.0.1" + }; + let ws_interface: &str = if matches.is_present("ws-external") { + "0.0.0.0" + } else { + "127.0.0.1" + }; let rpc_http_addr = Some( cli::parse_address(&format!("{}:{}", rpc_interface, 8081), "rpc-port", &matches).unwrap(), ); diff --git a/src/telemetry.rs b/src/telemetry.rs index f067176d12378..2d679cee9e122 100644 --- a/src/telemetry.rs +++ b/src/telemetry.rs @@ -1,18 +1,18 @@ // Copyright 2018 chainpool -use substrate_network::{SyncState, SyncProvider}; -use sr_primitives::traits::{Header, As}; +use sr_primitives::traits::{As, Header}; use substrate_client::BlockchainEvents; -use ::{PoolApi, Pool}; -use ::TClient; +use substrate_network::{SyncProvider, SyncState}; use tel; +use TClient; +use {Pool, PoolApi}; -use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; +use ansi_term::Colour; use std::time::{Duration, Instant}; -use tokio::runtime::TaskExecutor; +use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use tokio::prelude::{Future, Stream}; +use tokio::runtime::TaskExecutor; use tokio::timer::Interval; -use ansi_term::Colour; const TIMER_INTERVAL_MS: u64 = 5000; @@ -22,11 +22,10 @@ pub fn build_telemetry( name: String, ) -> Option { let telemetry = match telemetry_url { - Some(url) => { - Some(tel::init_telemetry(tel::TelemetryConfig { - url: url, - on_connect: Box::new(move || { - telemetry!("system.connected"; + Some(url) => Some(tel::init_telemetry(tel::TelemetryConfig { + url, + on_connect: Box::new(move || { + telemetry!("system.connected"; "name" => name.clone(), "implementation" => "chainx", "version" => "0.1", @@ -34,9 +33,8 @@ pub fn build_telemetry( "chain" => "ChainX", "authority" => is_authority ); - }), - })) - } + }), + })), None => None, }; telemetry @@ -55,23 +53,28 @@ pub fn run_telemetry( let self_pid = get_current_pid(); let client1 = client.clone(); let txpool1 = txpool.clone(); - let display_notifications = interval.map_err(|e| debug!("Timer error: {:?}", e)).for_each(move |_| { - let sync_status = network.status(); - if let Ok(best_block) = client1.best_block_header() { - let hash = best_block.hash(); - let num_peers = sync_status.num_peers; - let best_number: u64 = best_block.number().as_(); - let speed = move || speed(best_number, last_number); - let (status, target) = - match (sync_status.sync.state, sync_status.sync.best_seen_block) { - (SyncState::Idle, _) => ("Idle".into(), "".into()), - (SyncState::Downloading, None) => (format!("Syncing{}", speed()), "".into()), - (SyncState::Downloading, Some(n)) => - (format!("Syncing{}", speed()), format!(", target=#{}", n)), - }; - last_number = Some(best_number); - let txpool_status = txpool1.light_status(); - info!( + let display_notifications = interval + .map_err(|e| debug!("Timer error: {:?}", e)) + .for_each(move |_| { + let sync_status = network.status(); + if let Ok(best_block) = client1.best_block_header() { + let hash = best_block.hash(); + let num_peers = sync_status.num_peers; + let best_number: u64 = best_block.number().as_(); + let speed = move || speed(best_number, last_number); + let (status, target) = + match (sync_status.sync.state, sync_status.sync.best_seen_block) { + (SyncState::Idle, _) => ("Idle".into(), "".into()), + (SyncState::Downloading, None) => { + (format!("Syncing{}", speed()), "".into()) + } + (SyncState::Downloading, Some(n)) => { + (format!("Syncing{}", speed()), format!(", target=#{}", n)) + } + }; + last_number = Some(best_number); + let txpool_status = txpool1.light_status(); + info!( target: "substrate", "{}{} ({} peers), best: #{} ({})", Colour::White.bold().paint(&status), @@ -81,12 +84,16 @@ pub fn run_telemetry( hash ); - // get cpu usage and memory usage of this process - let (cpu_usage, memory) = if sys.refresh_process(self_pid) { - let proc = sys.get_process(self_pid).expect("Above refresh_process succeeds, this should be Some(), qed"); - (proc.cpu_usage(), proc.memory()) - } else { (0.0, 0) }; - telemetry!( + // get cpu usage and memory usage of this process + let (cpu_usage, memory) = if sys.refresh_process(self_pid) { + let proc = sys + .get_process(self_pid) + .expect("Above refresh_process succeeds, this should be Some(), qed"); + (proc.cpu_usage(), proc.memory()) + } else { + (0.0, 0) + }; + telemetry!( "system.interval"; "status" => format!("{}{}", status, target), "peers" => num_peers, @@ -96,11 +103,11 @@ pub fn run_telemetry( "cpu" => cpu_usage, "memory" => memory ); - } else { - warn!("Error getting best block information"); - } - Ok(()) - }); + } else { + warn!("Error getting best block information"); + } + Ok(()) + }); let display_block_import = client.import_notification_stream().for_each(|n| { info!(target: "substrate", "Imported #{} ({})", n.header.number(), n.hash);