Skip to content

Commit

Permalink
Merge pull request paritytech#156 from chainpool/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
gguoss authored Dec 17, 2018
2 parents 83bce65 + 25b3c71 commit cf42ab2
Show file tree
Hide file tree
Showing 27 changed files with 176 additions and 53 deletions.
3 changes: 3 additions & 0 deletions .github/delete-merged-branch-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exclude:
- master
- develop
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ language: rust
sudo: required

rust:
- stable
- beta
- nightly

env:
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ $ brew install cmake pkg-config openssl git
$ git clone https://github.com/chainx-org/ChainX ~/ChainX
$ cd ~/ChainX

$ cargo build --release
# Note: build ChainX with nightly
$ cargo +nightly build --release
```

## Testnet
Expand All @@ -105,12 +106,12 @@ $ RUST_LOG=info ./chainx --chainspec=dev --telemetry --bootnodes=/ip4/47.93.16.1

## Development

When you succeed to build the project with `cargo build`, the `chainx` binary should be present in `target/debug/chainx`.
When you succeed to build the project with `cargo build`, the `chainx` binary should be present in `target/release/chainx`.

We assume `chainx` is in your `$PATH` in the following sections. Run this command so that `chainx` could be found in `$PATH`:

```bash
$ export PATH=$(pwd)/target/debug:$PATH
$ export PATH=$(pwd)/target/release:$PATH
```

### Run a local testnet
Expand Down
9 changes: 6 additions & 3 deletions cxrml/associations/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! this module is for bch-bridge
// Copyright 2018 Chainpool.

//! this module is for associations
#![cfg_attr(not(feature = "std"), no_std)]
// for encode/decode
Expand All @@ -22,8 +24,7 @@ extern crate substrate_primitives;
// for substrate runtime
// map!, vec! marco.
extern crate sr_std as rstd;
// Needed for tests (`with_externalities`).
#[cfg(feature = "std")]

extern crate sr_io as runtime_io;
extern crate sr_primitives as runtime_primitives;
// for substrate runtime module lib
Expand Down Expand Up @@ -122,6 +123,7 @@ impl<T: Trait> Module<T> {

impl<T: Trait> Module<T> {
pub fn init_account(origin: T::Origin, who: T::AccountId) -> Result {
runtime_io::print("[associations] init_account");
let from = ensure_signed(origin)?;
// deduct fee first
T::OnCalcFee::on_calc_fee(&from, Self::init_fee())?;
Expand Down Expand Up @@ -150,6 +152,7 @@ impl<T: Trait> Module<T> {
}

pub fn init_exchange_relationship(origin: T::Origin, who: T::AccountId) -> Result {
runtime_io::print("[associations] init_exchange_relationship");
let from = ensure_signed(origin)?;
// deduct fee first
T::OnCalcFee::on_calc_fee(&from, Self::init_fee())?;
Expand Down
78 changes: 63 additions & 15 deletions cxrml/bridge/btc/src/blockchain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright 2018 Chainpool.

use codec::Encode;
use rstd::marker::PhantomData;
use rstd::prelude::*;
use rstd::result::Result;
use runtime_io;
use runtime_primitives::traits::As;
use runtime_support::{StorageMap, StorageValue};
use {BtcFee, IrrBlock};
Expand Down Expand Up @@ -73,12 +77,12 @@ impl ChainErr {
match *self {
ChainErr::CannotCanonize => "Cannot canonize block",
ChainErr::UnknownParent => "Block parent is unknown",
ChainErr::NotFound => "not to find orphaned side chain in header collection; qed",
ChainErr::NotFound => "Not to find orphaned side chain in header collection; qed",
ChainErr::AncientFork => "Fork is too long to proceed",
ChainErr::Unreachable => "should not occur",
ChainErr::Unreachable => "Should not occur",
ChainErr::CanonizeMustZero => "[canonize] must be zero in this case",
ChainErr::DecanonizeMustZero => "[decanonize] must be zero in this case",
ChainErr::ForkErr => "the hash should same",
ChainErr::ForkErr => "The hash should same",
ChainErr::OtherErr(s) => s,
}
}
Expand All @@ -96,16 +100,21 @@ impl<T: Trait> Chain<T> {
// case 1: block has been added to the main branch
BlockOrigin::CanonChain { .. } => {
Self::canonize(&header.hash())?;
runtime_io::print("[Main] block has been added to the main branch");
Ok(())
}
// case 2: block has been added to the side branch with reorganization to this branch
BlockOrigin::SideChainBecomingCanonChain(origin) => {
Self::fork(origin.clone())?;
Self::canonize(&header.hash())?;
runtime_io::print("[Switch to Main] block has been added to the side branch with reorganization to this branch");
Ok(())
}
// case 3: block has been added to the side branch without reorganization to this branch
BlockOrigin::SideChain(_origin) => Ok(()),
BlockOrigin::SideChain(_origin) => {
runtime_io::print("[Side] block has been added to the side branch without reorganization to this branch");
Ok(())
}
}
}

Expand All @@ -114,9 +123,13 @@ impl<T: Trait> Chain<T> {
let best_hash = best_index.hash;
let best_bumber = best_index.number;

//todo change unwrap
let (best_header, _, _): (BlockHeader, T::AccountId, T::BlockNumber) =
<BlockHeaderFor<T>>::get(&best_hash).unwrap();
let best_header: BlockHeader =
if let Some((header, _, _)) = <BlockHeaderFor<T>>::get(&best_hash) {
header
} else {
return Err(ChainErr::OtherErr("not found blockheader for this hash"));
};

let new_best_header = BestHeader {
hash: best_header.previous_header_hash.clone(),
number: if best_bumber > 0 {
Expand Down Expand Up @@ -145,9 +158,12 @@ impl<T: Trait> Chain<T> {
let best_hash = best_index.hash;
let best_number = best_index.number;

//todo change unwrap
let (header, _, _): (BlockHeader, T::AccountId, T::BlockNumber) =
<BlockHeaderFor<T>>::get(hash).unwrap();
let header: BlockHeader = if let Some((header, _, _)) = <BlockHeaderFor<T>>::get(hash) {
header
} else {
return Err(ChainErr::OtherErr("not found blockheader for this hash"));
};

if best_hash != header.previous_header_hash {
return Err(ChainErr::CannotCanonize);
}
Expand All @@ -171,19 +187,26 @@ impl<T: Trait> Chain<T> {
v.push(h);
}
});
runtime_io::print("best header");
runtime_io::print(new_best_header.number as u64);
// best chain choose finish
<BestIndex<T>>::put(new_best_header.clone());
<BestIndex<T>>::put(&new_best_header);

// deposit/withdraw handle start
let symbol: Symbol = Module::<T>::SYMBOL.to_vec();
let irr_block = <IrrBlock<T>>::get();
// Deposit
if let Some(vec) = <DepositCache<T>>::take() {
runtime_io::print("deposit start ---accountid---amount---tx_hash---blocknum");
let mut uncomplete_cache: Vec<(T::AccountId, u64, H256, H256)> = Vec::new();
for (account_id, amount, tx_hash, block_hash) in vec {
match <NumberForHash<T>>::get(block_hash.clone()) {
Some(height) => {
if new_best_header.number >= height + irr_block {
runtime_io::print(account_id.encode().as_slice());
runtime_io::print(amount);
runtime_io::print(&tx_hash[..]);
runtime_io::print(height as u64);
// TODO handle err
let _ = <financial_records::Module<T>>::deposit(
&account_id,
Expand All @@ -192,10 +215,14 @@ impl<T: Trait> Chain<T> {
Some(tx_hash.as_ref().to_vec()),
);
} else {
runtime_io::print("not reach irr_block --best --height");
runtime_io::print(new_best_header.number as u64);
runtime_io::print(height as u64);
uncomplete_cache.push((account_id, amount, tx_hash, block_hash));
}
}
None => {
// TODO 遇到分叉,需要从deposit cache剔除相应的交易
uncomplete_cache.push((account_id, amount, tx_hash, block_hash));
} // Optmise
}
Expand All @@ -210,11 +237,16 @@ impl<T: Trait> Chain<T> {
let mut candidate = Module::<T>::tx_proposal(len - 1).unwrap();
// candidate: CandidateTx
if candidate.confirmed == false {
runtime_io::print("withdraw start ---accountid---tx_hash---blocknum");
match <NumberForHash<T>>::get(&candidate.block_hash) {
Some(height) => {
if new_best_header.number >= height + irr_block {
let txid = candidate.tx.hash();
for (account_id, _) in candidate.outs.clone() {
runtime_io::print(account_id.encode().as_slice());
runtime_io::print(&txid[..]);
runtime_io::print(height as u64);

// TODO handle err
let _ = <financial_records::Module<T>>::withdrawal_finish(
&account_id,
Expand All @@ -225,9 +257,15 @@ impl<T: Trait> Chain<T> {
candidate.confirmed = true;
// mark this tx withdraw finish!
TxProposal::<T>::insert(len - 1, candidate);
} else {
runtime_io::print("not reach irr_block --best --height");
runtime_io::print(new_best_header.number as u64);
runtime_io::print(height as u64);
}
}
None => {}
None => {
// todo 处理分叉问题
}
}
}
}
Expand All @@ -238,6 +276,7 @@ impl<T: Trait> Chain<T> {
// 标记该链上这笔proposal由于BTC 托管人没有按着正常逻辑签名广播, 该proposal可能永远不会confirmed.
// 所以开始重新创建proposal.
if len == 0 {
runtime_io::print("crate_proposal case 1");
// no withdraw cache would return None
if let Some(indexs) = financial_records::Module::<T>::withdrawal_cache_indexs(&symbol) {
let btc_fee = <BtcFee<T>>::get();
Expand All @@ -249,6 +288,9 @@ impl<T: Trait> Chain<T> {
if len > 0 {
let candidate = Module::<T>::tx_proposal(len - 1).unwrap();
if candidate.confirmed || candidate.unexpect {
runtime_io::print("crate_proposal case 2,3 ---confirmed---unexpect");
runtime_io::print(candidate.confirmed.encode().as_slice());
runtime_io::print(candidate.unexpect.encode().as_slice());
// no withdraw cache would return None
if let Some(indexs) =
financial_records::Module::<T>::withdrawal_cache_indexs(&symbol)
Expand All @@ -263,6 +305,7 @@ impl<T: Trait> Chain<T> {

// SendCert
if let Some(cert_info) = <CertCache<T>>::take() {
runtime_io::print("send cert start");
if let Err(e) = <staking::Module<T>>::issue(cert_info.0, cert_info.1, cert_info.2) {
return Err(ChainErr::OtherErr(e));
}
Expand Down Expand Up @@ -294,9 +337,14 @@ impl<T: Trait> Chain<T> {

fn block_origin(header: &BlockHeader) -> Result<BlockOrigin, ChainErr> {
let best_index: BestHeader = <BestIndex<T>>::get();
// TODO change unwrap
let (best_header, _, _): (BlockHeader, T::AccountId, T::BlockNumber) =
<BlockHeaderFor<T>>::get(&best_index.hash).unwrap();

let best_header: BlockHeader =
if let Some((header, _, _)) = <BlockHeaderFor<T>>::get(&best_index.hash) {
header
} else {
return Err(ChainErr::OtherErr("not found blockheader for this hash"));
};

if <NumberForHash<T>>::exists(header.hash()) {
return Ok(BlockOrigin::KnownBlock);
}
Expand Down
10 changes: 8 additions & 2 deletions cxrml/bridge/btc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2018 Chainpool.

//! this module is for btc-bridge
#![cfg_attr(not(feature = "std"), no_std)]
Expand Down Expand Up @@ -26,7 +28,7 @@ extern crate substrate_primitives;
// for substrate runtime
// map!, vec! marco.
extern crate sr_std as rstd;
// Needed for tests (`with_externalities`).

extern crate sr_io as runtime_io;
extern crate sr_primitives as runtime_primitives;
// for substrate runtime module lib
Expand Down Expand Up @@ -332,6 +334,7 @@ impl<T: Trait> Module<T> {
impl<T: Trait> Module<T> {
// public call
pub fn push_header(origin: T::Origin, header: Vec<u8>) -> Result {
runtime_io::print("[bridge_btc] push btc header");
let from = ensure_signed(origin)?;
// parse header
let header: BlockHeader =
Expand All @@ -341,13 +344,15 @@ impl<T: Trait> Module<T> {
}

pub fn push_transaction(origin: T::Origin, tx: Vec<u8>) -> Result {
runtime_io::print("[bridge_btc] push btc tx");
let from = ensure_signed(origin)?;
let tx: RelayTx = Decode::decode(&mut tx.as_slice()).ok_or("parse RelayTx err")?;
Self::process_tx(tx, &from)?;
Ok(())
}

pub fn propose_transaction(origin: T::Origin, tx: Vec<u8>) -> Result {
runtime_io::print("[bridge_btc] propose btc tx");
let from = ensure_signed(origin)?;

let tx: BTCTransaction =
Expand Down Expand Up @@ -375,6 +380,7 @@ impl<T: Trait> Module<T> {
}
// check
{
runtime_io::print("check header");
let c = verify_header::HeaderVerifier::new::<T>(&header).map_err(|e| e.info())?;
c.check::<T>()?;
}
Expand Down Expand Up @@ -404,7 +410,7 @@ impl<T: Trait> Module<T> {
} else {
return Err("should set CERT_address first");
};
let tx_type = validate_transaction::<T>(&tx, (&receive_address, &cert_address)).unwrap();
let tx_type = validate_transaction::<T>(&tx, (&receive_address, &cert_address))?;
match tx_type {
TxType::Withdraw => {
handle_input::<T>(&tx.raw, &tx.block_hash, &who, &receive_address);
Expand Down
2 changes: 2 additions & 0 deletions cxrml/bridge/btc/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2018 Chainpool.

extern crate srml_consensus as consensus;
extern crate srml_session as session;

Expand Down
13 changes: 6 additions & 7 deletions cxrml/bridge/btc/src/tx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,12 @@ pub fn validate_transaction<T: Trait>(
if previous_txid != tx.raw.inputs[0].previous_output.hash {
return Err("previous tx id not right");
}

// detect cert
for input in tx.raw.inputs.iter() {
let outpoint = input.previous_output.clone();
let send_address = inspect_address::<T>(&tx.previous_raw, outpoint).unwrap();
if send_address.hash == address.1.hash {
return Ok(TxType::SendCert);
}
let outpoint = tx.raw.inputs[0].previous_output.clone();
let send_address = inspect_address::<T>(&tx.previous_raw, outpoint).unwrap();
if send_address.hash == address.1.hash {
return Ok(TxType::SendCert);
}

// detect withdraw: To do: All inputs relay
Expand Down Expand Up @@ -376,7 +375,7 @@ pub fn handle_input<T: Trait>(
<TxProposal<T>>::insert(len - 1, candidate);
}
} else {
// To do: handle_input error not expect
// Todo: handle_input error not expect
runtime_io::print("-----------handle_input error not expect");
}
}
Expand Down
2 changes: 2 additions & 0 deletions cxrml/bridge/btc/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2018 Chainpool.

use rstd::prelude::Vec;

pub fn vec_to_u32(date: Vec<u8>) -> Option<u32> {
Expand Down
2 changes: 1 addition & 1 deletion cxrml/bridge/btc/src/verify_header.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//#![cfg_attr(not(feature = "std"), no_std)]
// Copyright 2018 Chainpool.

use rstd::cmp;
use rstd::result::Result as StdResult;
Expand Down
Loading

0 comments on commit cf42ab2

Please sign in to comment.