From 9de944fc95400d40b60bec5457abd773964fab2b Mon Sep 17 00:00:00 2001 From: toxotguo Date: Sat, 10 Nov 2018 17:44:39 +0800 Subject: [PATCH] optimization match (#89) --- Cargo.lock | 22 +- cxrml/matchorder/src/lib.rs | 494 +++++++++++++++++-------------- cxrml/matchorder/src/tests.rs | 135 +++++++-- cxrml/pendingorders/src/tests.rs | 10 +- runtime/wasm/Cargo.lock | 115 ++++++- 5 files changed, 511 insertions(+), 265 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80d812794e295..0c4b915e3bece 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,11 @@ source = "git+https://github.com/chainx-org/bit-vec.git#ced2a13de722307d5c966aa8 [[package]] name = "bitcrypto" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#b5778f689a0845c3133f86131e61ff68a7dba398" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "primitives 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "siphasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0 (git+https://github.com/chainx-org/sr-std)", ] @@ -246,7 +248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chain" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#b5778f689a0845c3133f86131e61ff68a7dba398" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "bitcrypto 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2027,12 +2029,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-rocksdb-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-rocksdb-sys 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-rocksdb-sys" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2130,7 +2132,7 @@ dependencies = [ [[package]] name = "primitives" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#b5778f689a0845c3133f86131e61ff68a7dba398" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2386,6 +2388,11 @@ name = "rustc-hex" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc_version" version = "0.2.3" @@ -2523,7 +2530,7 @@ dependencies = [ [[package]] name = "serialization" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#b5778f689a0845c3133f86131e61ff68a7dba398" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", @@ -4101,7 +4108,7 @@ dependencies = [ "checksum parity-codec 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "63c4b16ee2b7d6aace13b09bb0d16ade6b90ef19b7ca1c6cec9b8d08b9f59ecb" "checksum parity-codec-derive 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "693976dd8dd73d0c06ea8f339046903684e9d6a66e915ec0186b7baad43e7945" "checksum parity-rocksdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd55d2d6d6000ec99f021cf52c9acc7d2a402e14f95ced4c5de230696fabe00b" -"checksum parity-rocksdb-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ae07d4bfb2759541957c19f471996b807fc09ef3a5bdce14409b57f038de49f" +"checksum parity-rocksdb-sys 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0e59eda423021494a6cf1be74f6989add403f53157409993f794e17b123cab51" "checksum parity-snappy-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c2086caac40c79289cb70d7e1c64f5888e1c53f5d38399d3e95101493739f423" "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" "checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" @@ -4143,6 +4150,7 @@ dependencies = [ "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rw-stream-sink 0.1.0 (git+https://github.com/tomaka/libp2p-rs?rev=8111062f0177fd7423626f2db9560273644a4c4d)" = "" "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" diff --git a/cxrml/matchorder/src/lib.rs b/cxrml/matchorder/src/lib.rs index 257d10325dd5b..7bd949752b313 100644 --- a/cxrml/matchorder/src/lib.rs +++ b/cxrml/matchorder/src/lib.rs @@ -50,6 +50,8 @@ mod tests; use rstd::prelude::*; //use runtime_primitives::traits::OnFinalise; +use codec::Codec; +use cxsupport::storage::linked_node::{LinkedNodeCollection, MultiNodeIndex, Node, NodeT}; use pendingorders::{CommandType, OrderPair, OrderType}; use runtime_primitives::traits::OnFinalise; use runtime_primitives::traits::{As, Zero}; @@ -88,31 +90,62 @@ decl_storage! { trait Store for Module as MatchOrder { pub MatchFee get(match_fee) config(): T::Balance; - /// bidid=>{id,pair,type,user,order_index,price,amount,time} - /// pair+type=>[{price,sum,[bidid,bidid]},{price,sum,[bidid]}] - pub BidList get( bid_list) : map (OrderPair,OrderType) => Vec>;// 维护有序,价格优先,时间优先 - pub BidOf get(bid_of):map BidId => Option>; + // 维护有序,价格优先,时间优先 + pub BidListHeaderFor get(bidlist_header_for): map (OrderPair,OrderType) => Option>>; + pub BidListTailFor get(bidlist_tail_for): map (OrderPair,OrderType) => Option>>; + pub BidListCache get(bidlist_cache): map u128 => Option>>; + NodeId get(nodeid):u128; + pub BidOf get(bid_of):map BidId => Option>; pub LastBidIndexOf get(last_bid_index_of): BidId; pub BidOfUserOrder get( bid_of_user_order) : map (T::AccountId,OrderPair,u64) => BidId; //索引 accountid+orderindex=>bidid } } +pub struct LinkedMultiKey(runtime_support::storage::generator::PhantomData); +impl LinkedNodeCollection for LinkedMultiKey { + type Header = BidListHeaderFor; + type NodeMap = BidListCache; + type Tail = BidListTailFor; +} + +/// 盘口 记录 聚合 +#[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +pub struct Bid +where + Amount: Copy, + Price: Copy, +{ + nodeid: u128, + price: Price, + sum: Amount, + list: Vec, +} + +pub type BidT = Bid<::Amount, ::Price>; + +impl NodeT for Bid +where + Price: Codec + Clone + Eq + PartialEq + Default + Copy, + Amount: Copy, +{ + type Index = u128; + + fn index(&self) -> Self::Index { + self.nodeid + } +} + impl OnFinalise for Module { fn on_finalise(time: T::BlockNumber) { //先读取pendingorders模块的所有新挂单 let max_command_id: u64 = >::max_command_id(); - info!( - "on_finalise:max_command_id {:?}", - max_command_id - ); + info!("on_finalise:max_command_id {:?}", max_command_id); for command_id in 1..(max_command_id + 1) { - info!( - "handle_match: command id {:?}", - command_id - ); + info!("on_finalise: command id {:?}", command_id); if let Some(command) = >::command_of(command_id) { if let Some(order) = >::order_of(( command.0.clone(), @@ -188,14 +221,20 @@ impl Module { Self::deposit_event(RawEvent::SetMatchFee(val)); Ok(()) } - + fn new_nodeid() -> u128 { + let mut last_nodeid: u128 = >::get(); + last_nodeid = match last_nodeid.checked_add(1_u128) { + Some(b) => b, + None => 0, + }; + >::put(last_nodeid); + + last_nodeid + } //处理 撮合 fn handle_match(_time: T::BlockNumber) { let max_command_id: u64 = >::max_command_id(); - info!( - "handle_match:max_command_id {:?}", - max_command_id - ); + info!("handle_match:max_command_id {:?}", max_command_id); //遍历每个bid for command_id in 1..(max_command_id + 1) { if let Some(command) = >::command_of(command_id) { @@ -215,9 +254,7 @@ impl Module { //自身是买单,找卖单 match command.3 { CommandType::Match => { - let mut wait_bid_list: Vec> = - Self::bid_list((in_bid_detail.pair.clone(), find_type)); - Self::do_match(find_type, &mut wait_bid_list, &mut in_bid_detail); + Self::do_match(find_type, &mut in_bid_detail); if in_bid_detail.amount == Zero::zero() { //已被匹配完毕,则删除 @@ -237,160 +274,167 @@ impl Module { } } - fn do_match( - find_type: OrderType, - wait_bid_list: &mut Vec>, - in_bid_detail: &mut BidDetailT, - ) { + fn do_match(find_type: OrderType, in_bid_detail: &mut BidDetailT) { //wait_bid_list 是价格有序 时间有序 let mut need_fill: T::Amount = in_bid_detail.amount; let mut remove_from_wait_bid_list: Vec> = Vec::new(); info!("do_match:{:?}", in_bid_detail); - let mut find_match = false; - for j in 0..wait_bid_list.len() { - match in_bid_detail.order_type { - OrderType::Sell => { - if (need_fill != Zero::zero()) - && (in_bid_detail.price <= wait_bid_list[j].price) - { + if let Some(header) = Self::bidlist_header_for((in_bid_detail.pair.clone(), find_type)) { + let mut index = header.index(); + + let mut find_match = false; + while let Some(mut node) = Self::bidlist_cache(&index) { + info!("do_match:index={:?} {:?}", index, find_match); + match in_bid_detail.order_type { + OrderType::Sell => { + if (need_fill != Zero::zero()) && (in_bid_detail.price <= node.data.price) { find_match = true; } - } - OrderType::Buy => { - if (need_fill != Zero::zero()) - && (in_bid_detail.price >= wait_bid_list[j].price) - { + } + OrderType::Buy => { + if (need_fill != Zero::zero()) && (in_bid_detail.price >= node.data.price) { find_match = true; } + } } - } - if find_match == true { - //找到匹配的 计算手续费 构建fill order - let mut fill_num: T::Amount; - if need_fill < wait_bid_list[j].sum { - fill_num = need_fill; - } else { - fill_num = wait_bid_list[j].sum; - remove_from_wait_bid_list.push(wait_bid_list[j].clone()); //计入删除 - } - need_fill = need_fill - fill_num; - in_bid_detail.amount = in_bid_detail.amount - fill_num; - wait_bid_list[j].sum = wait_bid_list[j].sum - fill_num; - // 一个个填充 - let mut remove_from_list: Vec = Vec::new(); - - for kk in 0..wait_bid_list[j].list.len() { - if let Some(mut match_bid) = Self::bid_of(wait_bid_list[j].list[kk]) { - let maker_user = match_bid.user.clone(); - let taker_user = in_bid_detail.user.clone(); - let maker_user_order_index = match_bid.order_index; - let taker_user_order_index = in_bid_detail.order_index; - let order_price = match_bid.price; - let mut amount: T::Amount; - let maker_fee: T::Amount = As::sa(0); //默认先0 手续费 - let taker_fee: T::Amount = As::sa(0); //默认先0 手续费 - - if fill_num >= match_bid.amount { - amount = match_bid.amount; - //被撮合完了,删除 - >::remove(match_bid.id); - remove_from_list.push(match_bid.id); - } else { - amount = fill_num; - match_bid.amount = match_bid.amount - amount; - >::insert(match_bid.id, match_bid.clone()); - } + //info!("do_match:index={:?} {:?}", index,find_match); + if find_match == true { + //找到匹配的 计算手续费 构建fill order + let mut fill_num: T::Amount; + if need_fill < node.data.sum { + fill_num = need_fill; + } else { + fill_num = node.data.sum; + remove_from_wait_bid_list.push(node.data.clone()); //计入删除 + } + need_fill = need_fill - fill_num; + in_bid_detail.amount = in_bid_detail.amount - fill_num; + node.data.sum = node.data.sum - fill_num; + // 一个个填充 + let mut remove_from_list: Vec = Vec::new(); + + for kk in 0..node.data.list.len() { + if let Some(mut match_bid) = Self::bid_of(node.data.list[kk]) { + let maker_user = match_bid.user.clone(); + let taker_user = in_bid_detail.user.clone(); + let maker_user_order_index = match_bid.order_index; + let taker_user_order_index = in_bid_detail.order_index; + let order_price = match_bid.price; + let mut amount: T::Amount; + let maker_fee: T::Amount = As::sa(0); //默认先0 手续费 + let taker_fee: T::Amount = As::sa(0); //默认先0 手续费 + + if fill_num >= match_bid.amount { + amount = match_bid.amount; + //被撮合完了,删除 + >::remove(match_bid.id); + remove_from_list.push(match_bid.id); + } else { + amount = fill_num; + match_bid.amount = match_bid.amount - amount; + >::insert(match_bid.id, match_bid.clone()); + } - fill_num = fill_num - amount; - //成交 - if let Err(msg) = >::fill_order( - in_bid_detail.pair.clone(), - maker_user.clone(), - taker_user.clone(), - maker_user_order_index, - taker_user_order_index, - order_price, - amount, - maker_fee, - taker_fee, - ) { - error!("do_match: match fail {:?}", msg); - Self::deposit_event(RawEvent::MatchFail( - match_bid.id, + fill_num = fill_num - amount; + //成交 + if let Err(msg) = >::fill_order( in_bid_detail.pair.clone(), - maker_user, - taker_user, + maker_user.clone(), + taker_user.clone(), maker_user_order_index, taker_user_order_index, order_price, amount, maker_fee, taker_fee, - >::block_number(), - )); - } + ) { + error!("do_match: match fail {:?}", msg); + Self::deposit_event(RawEvent::MatchFail( + match_bid.id, + in_bid_detail.pair.clone(), + maker_user, + taker_user, + maker_user_order_index, + taker_user_order_index, + order_price, + amount, + maker_fee, + taker_fee, + >::block_number(), + )); + } - if fill_num == Zero::zero() { - break; + if fill_num == Zero::zero() { + break; + } } } - } - Self::remove_from_bid_list(&mut wait_bid_list[j], &remove_from_list); - } else { - break; + Self::remove_from_bid_list(&mut node, &remove_from_list); + + if let Some(next) = node.next() { + index = next; + } else { + break; + } + } else { + break; + } } } // 删掉已经被撮合完的 - Self::remove_from_bid( - &in_bid_detail.pair, - find_type, - wait_bid_list, - &remove_from_wait_bid_list, - ); + Self::remove_from_bid(&in_bid_detail.pair, find_type, &remove_from_wait_bid_list); } - fn remove_from_bid_list(bid_list: &mut BidT, remove_id: &Vec) { + fn remove_from_bid_list( + node: &mut Node< + Bid<::Amount, ::Price>, + >, + remove_id: &Vec, + ) { let mut new_list: Vec = Vec::new(); - for mm in 0..bid_list.list.len() { + for mm in 0..node.data.list.len() { let mut remove = false; for nn in 0..remove_id.len() { - if bid_list.list[mm] == remove_id[nn] { + if node.data.list[mm] == remove_id[nn] { remove = true; >::remove(remove_id[nn]); info!("remove_from_bid_list:{:?}", remove_id[nn]); } } if remove == false { - new_list.push(bid_list.list[mm]); + new_list.push(node.data.list[mm]); } } - bid_list.list = new_list; + node.data.list = new_list; + >::insert(node.index(), node); + //更新node } - fn remove_from_bid( - pair: &OrderPair, - order_type: OrderType, - old_bid_list: &mut Vec>, - remove_bid: &Vec>, - ) { - let mut new_bid_list: Vec> = Vec::new(); - for mm in 0..old_bid_list.len() { - let mut remove = false; - for nn in 0..remove_bid.len() { - if old_bid_list[mm].price == remove_bid[nn].price { - remove = true; - info!("remove_from_bid:{:?}", remove_bid[nn].price); + fn remove_from_bid(pair: &OrderPair, order_type: OrderType, remove_bid: &Vec>) { + for nn in 0..remove_bid.len() { + if let Some(header) = Self::bidlist_header_for((pair.clone(), order_type)) { + let mut index = header.index(); + + while let Some(mut node) = Self::bidlist_cache(&index) { + if node.data.price == remove_bid[nn].price { + info!("remove_from_bid:{:?}", remove_bid[nn].price); + + let _=node.remove_option_node_withkey::, (OrderPair,OrderType)>((pair.clone(),order_type)); + break; + } + + if let Some(next) = node.next() { + index = next; + } else { + break; + } } } - if remove == false { - new_bid_list.push(old_bid_list[mm].clone()); - } } - >::insert((pair.clone(), order_type), new_bid_list); } fn insert_bid_list(in_bid_detail: &BidDetailT) { @@ -398,73 +442,96 @@ impl Module { >::insert(in_bid_detail.id, in_bid_detail.clone()); - //插入对应位置到 sell bid list - let mut bid_list: Vec> = - Self::bid_list((in_bid_detail.pair.clone(), in_bid_detail.order_type)); let mut finish = false; - for k in 0..bid_list.len() { - if in_bid_detail.price == bid_list[k].price { - //累加 - bid_list[k].sum += in_bid_detail.amount; - bid_list[k].list.push(in_bid_detail.id); - >::insert( - (in_bid_detail.pair.clone(), in_bid_detail.order_type), - bid_list.clone(), - ); - info!("insert_bid_list: insert add"); - finish = true; - break; - } - let mut insert_head = false; + if let Some(header) = + Self::bidlist_header_for((in_bid_detail.pair.clone(), in_bid_detail.order_type)) + { + let mut index = header.index(); + + while let Some(mut node) = Self::bidlist_cache(&index) { + if in_bid_detail.price == node.data.price { + //累加 + node.data.sum += in_bid_detail.amount; + node.data.list.push(in_bid_detail.id); + + >::insert(node.index(), node); + + info!("insert_bid_list: insert add"); + finish = true; + break; + } + let mut insert_head = false; - match in_bid_detail.order_type { - OrderType::Sell => { - if in_bid_detail.price < bid_list[k].price { - //插入当前的 前面 - insert_head = true; + match in_bid_detail.order_type { + OrderType::Sell => { + if in_bid_detail.price < node.data.price { + //插入当前的 前面 + insert_head = true; + } } - } - OrderType::Buy => { - if in_bid_detail.price > bid_list[k].price { - insert_head = true; + OrderType::Buy => { + if in_bid_detail.price > node.data.price { + insert_head = true; + } } } - } - if insert_head == true { - let mut new_bid_list: Vec> = Vec::new(); - for m in 0..k { - new_bid_list.push(bid_list[m].clone()); + if insert_head == true { + let new_nodeid = Self::new_nodeid(); + let new_bid = Bid { + nodeid: new_nodeid, + price: in_bid_detail.price, + sum: in_bid_detail.amount, + list: vec![in_bid_detail.id], + }; + + let n = Node::new(new_bid); + n.init_storage_withkey::, (OrderPair, OrderType)>(( + in_bid_detail.pair.clone(), + in_bid_detail.order_type, + )); + + let _=node.add_option_node_before_withkey::, (OrderPair,OrderType)>(n,(in_bid_detail.pair.clone(),in_bid_detail.order_type)); + + info!("insert_bid_list: insert head"); + finish = true; + break; } - new_bid_list.push(Bid { - price: in_bid_detail.price, - sum: in_bid_detail.amount, - list: vec![in_bid_detail.id], - }); - - for n in k..bid_list.len() { - new_bid_list.push(bid_list[n].clone()); + + if let Some(next) = node.next() { + index = next; + } else { + break; } - >::insert( - (in_bid_detail.pair.clone(), in_bid_detail.order_type), - new_bid_list, - ); - info!("insert_bid_list: insert head"); - finish = true; - break; } } if finish == false { //追加在最后 - bid_list.push(Bid { + let new_nodeid = Self::new_nodeid(); + let new_bid = Bid { + nodeid: new_nodeid, price: in_bid_detail.price, sum: in_bid_detail.amount, list: vec![in_bid_detail.id], - }); - >::insert( - (in_bid_detail.pair.clone(), in_bid_detail.order_type), - bid_list.clone(), - ); + }; + let n = Node::new(new_bid); + n.init_storage_withkey::, (OrderPair, OrderType)>(( + in_bid_detail.pair.clone(), + in_bid_detail.order_type, + )); + + if let Some(tail_index) = + Self::bidlist_tail_for((in_bid_detail.pair.clone(), in_bid_detail.order_type)) + { + if let Some(mut tail_node) = Self::bidlist_cache(tail_index.index()) { + let _ = tail_node + .add_option_node_after_withkey::, (OrderPair, OrderType)>( + n, + (in_bid_detail.pair.clone(), in_bid_detail.order_type), + ); + } + } + info!("insert_bid_list: insert tail"); } } @@ -474,29 +541,37 @@ impl Module { info!("cancel_bid:{:?}", in_bid_detail); let mut remove_from_wait_bid_list: Vec> = Vec::new(); - let mut wait_bid_list: Vec> = - Self::bid_list((in_bid_detail.pair.clone(), in_bid_detail.order_type)); - for kk in 0..wait_bid_list.len() { - if wait_bid_list[kk].price == in_bid_detail.price { - wait_bid_list[kk].sum = wait_bid_list[kk].sum - in_bid_detail.amount; - if wait_bid_list[kk].sum == Zero::zero() { - remove_from_wait_bid_list.push(wait_bid_list[kk].clone()); //标记删除 - } - for mm in 0..wait_bid_list[kk].list.len() { - if in_bid_detail.id == wait_bid_list[kk].list[mm] { - Self::remove_from_bid_list(&mut wait_bid_list[kk], &vec![in_bid_detail.id]); - break; + if let Some(header) = + Self::bidlist_header_for((in_bid_detail.pair.clone(), in_bid_detail.order_type)) + { + let mut index = header.index(); + + while let Some(mut node) = Self::bidlist_cache(&index) { + if node.data.price == in_bid_detail.price { + node.data.sum = node.data.sum - in_bid_detail.amount; + if node.data.sum == Zero::zero() { + remove_from_wait_bid_list.push(node.data.clone()); //标记删除 + } + for mm in 0..node.data.list.len() { + if in_bid_detail.id == node.data.list[mm] { + Self::remove_from_bid_list(&mut node, &vec![in_bid_detail.id]); + break; + } } - } - break; + break; + } + if let Some(next) = node.next() { + index = next; + } else { + break; + } } } Self::remove_from_bid( &in_bid_detail.pair, in_bid_detail.order_type, - &mut wait_bid_list, &remove_from_wait_bid_list, ); //最后更新 } @@ -508,12 +583,12 @@ pub type BidId = u128; #[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub struct BidDetail - where - Pair: Clone, - AccountId: Clone, - Amount: Copy, - Price: Copy, - BlockNumber: Copy, +where + Pair: Clone, + AccountId: Clone, + Amount: Copy, + Price: Copy, + BlockNumber: Copy, { id: BidId, pair: Pair, @@ -525,19 +600,6 @@ pub struct BidDetail time: BlockNumber, } -/// 盘口 记录 聚合 -#[derive(PartialEq, Eq, Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct Bid - where - Amount: Copy, - Price: Copy, -{ - price: Price, - sum: Amount, - list: Vec, -} - pub type BidDetailT = BidDetail< OrderPair, ::AccountId, @@ -545,5 +607,3 @@ pub type BidDetailT = BidDetail< ::Price, ::BlockNumber, >; - -pub type BidT = Bid<::Amount, ::Price>; diff --git a/cxrml/matchorder/src/tests.rs b/cxrml/matchorder/src/tests.rs index 9908ec4d1b17f..0218be6dbcd52 100644 --- a/cxrml/matchorder/src/tests.rs +++ b/cxrml/matchorder/src/tests.rs @@ -76,18 +76,16 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { transfer_fee: 0, creation_fee: 0, reclaim_rebate: 0, - } - .build_storage() - .unwrap(), + }.build_storage() + .unwrap(), ); r.extend( tokenbalances::GenesisConfig:: { token_list: vec![], transfer_token_fee: 10, - } - .build_storage() - .unwrap(), + }.build_storage() + .unwrap(), ); r.extend( @@ -95,9 +93,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { order_fee: 10, pair_list: vec![], max_command_id: 0, - } - .build_storage() - .unwrap(), + }.build_storage() + .unwrap(), ); r.extend( @@ -196,6 +193,76 @@ fn test_match_part() { }) } +#[test] +fn test_match_all() { + with_externalities(&mut new_test_ext(), || { + let t_sym_eos = b"x-eos".to_vec(); + let t_desc_eos = b"eos token".to_vec(); + let precision = 4; + let t_eos: Token = Token::new(t_sym_eos.clone(), t_desc_eos.clone(), precision); + assert_eq!(TokenBalances::register_token(t_eos, 0, 0), Ok(())); + + let t_sym_eth = b"x-eth".to_vec(); + let t_desc_eth = b"eth token".to_vec(); + let precision = 4; + let t_eth: Token = Token::new(t_sym_eth.clone(), t_desc_eth.clone(), precision); + assert_eq!(TokenBalances::register_token(t_eth, 0, 0), Ok(())); + + let p1 = OrderPair::new(t_sym_eos.clone(), t_sym_eth.clone(), 0); + + // 增加交易对 + PendingOrders::add_pair(p1.clone()).unwrap(); + + let a: u64 = 1; // accountid + let b: u64 = 2; + + // 发放 + TokenBalances::issue(&a, &t_sym_eos.clone(), 1000).unwrap(); + TokenBalances::issue(&a, &t_sym_eth.clone(), 1000).unwrap(); + TokenBalances::issue(&b, &t_sym_eos.clone(), 1000).unwrap(); + TokenBalances::issue(&b, &t_sym_eth.clone(), 1000).unwrap(); + + //挂买单 + 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())), 0); + assert_eq!(TokenBalances::free_token(&(a, t_sym_eth.clone())), 500); + assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eth.clone())), 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())), 100); + assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1000); + assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone())), 0); + + print_bid(p1.clone(), OrderType::Sell); + print_bid(p1.clone(), OrderType::Buy); + + >::on_finalise(1); + + //1000+250 + assert_eq!(TokenBalances::free_token(&(a, t_sym_eos.clone())), 1100); + assert_eq!(TokenBalances::reserved_token(&(a, t_sym_eos.clone())), 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())), 0); + + //1000-50 + assert_eq!(TokenBalances::free_token(&(b, t_sym_eos.clone())), 900); + assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eos.clone())), 0); + assert_eq!(TokenBalances::free_token(&(b, t_sym_eth.clone())), 1500); + assert_eq!(TokenBalances::reserved_token(&(b, t_sym_eth.clone())), 0); + + print_bid(p1.clone(), OrderType::Sell); + print_bid(p1.clone(), OrderType::Buy); + }) +} + #[test] fn test_match_no() { with_externalities(&mut new_test_ext(), || { @@ -272,28 +339,34 @@ fn print_bid(pair: OrderPair, order_type: OrderType) { "-------------------{:?} {:?} -----------------", pair, order_type ); - let bids: Vec< - Bid< - ::Amount, - ::Price, - >, - > = MatchOrder::bid_list((pair, order_type)); - for i in 0..bids.len() { - println!("---{}---", i); - println!("price:{:?}", bids[i].price); - println!("sum:{:?}", bids[i].sum); - println!("list:{:?}", bids[i].list.len()); - for j in 0..bids[i].list.len() { - println!(" [{:?}] {:?}", j, bids[i].list[j]); - let bid_detail = MatchOrder::bid_of(bids[i].list[j]).unwrap(); - println!(" id:{:?}", bid_detail.id); - println!(" pair:{:?}", bid_detail.pair); - println!(" order_type:{:?}", bid_detail.order_type); - println!(" user:{:?}", bid_detail.user); - println!(" order_index:{:?}", bid_detail.order_index); - println!(" price:{:?}", bid_detail.price); - println!(" amount:{:?}", bid_detail.amount); - println!(" time:{:?}", bid_detail.time); + + if let Some(header) = MatchOrder::bidlist_header_for((pair, order_type)) { + let mut index = header.index(); + + while let Some(mut node) = MatchOrder::bidlist_cache(&index) { + println!("---{}---", index); + println!("price:{:?}", node.data.price); + println!("sum:{:?}", node.data.sum); + println!("list:{:?}", node.data.list.len()); + for j in 0..node.data.list.len() { + println!(" [{:?}] {:?}", j, node.data.list[j]); + let bid_detail = MatchOrder::bid_of(node.data.list[j]).unwrap(); + println!(" id:{:?}", bid_detail.id); + println!(" pair:{:?}", bid_detail.pair); + println!(" order_type:{:?}", bid_detail.order_type); + println!(" user:{:?}", bid_detail.user); + println!(" order_index:{:?}", bid_detail.order_index); + println!(" price:{:?}", bid_detail.price); + println!(" amount:{:?}", bid_detail.amount); + println!(" time:{:?}", bid_detail.time); + } + if let Some(next) = node.next() { + index = next; + } else { + break; + } } + } else { + println!("-------------------end -----------------"); } } diff --git a/cxrml/pendingorders/src/tests.rs b/cxrml/pendingorders/src/tests.rs index b85822f0571d5..a4dba25294941 100644 --- a/cxrml/pendingorders/src/tests.rs +++ b/cxrml/pendingorders/src/tests.rs @@ -69,9 +69,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { transfer_fee: 0, creation_fee: 0, reclaim_rebate: 0, - } - .build_storage() - .unwrap(), + }.build_storage() + .unwrap(), ); r.extend( @@ -79,9 +78,8 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { order_fee: 10, pair_list: vec![], max_command_id: 0, - } - .build_storage() - .unwrap(), + }.build_storage() + .unwrap(), ); r.into() } diff --git a/runtime/wasm/Cargo.lock b/runtime/wasm/Cargo.lock index 5d1b76cf01976..72e1c2bbc9e91 100644 --- a/runtime/wasm/Cargo.lock +++ b/runtime/wasm/Cargo.lock @@ -19,9 +19,11 @@ source = "git+https://github.com/chainx-org/bit-vec.git#ced2a13de722307d5c966aa8 [[package]] name = "bitcrypto" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#279298c7235a6bb66dfd47be0dec9c04f2ea3ae8" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "primitives 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "siphasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0 (git+https://github.com/chainx-org/sr-std)", ] @@ -45,6 +47,11 @@ name = "byteorder" version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cc" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cfg-if" version = "0.1.5" @@ -53,7 +60,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chain" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#279298c7235a6bb66dfd47be0dec9c04f2ea3ae8" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "bitcrypto 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -112,6 +119,14 @@ dependencies = [ "substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)", ] +[[package]] +name = "clippy" +version = "0.0.302" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -165,14 +180,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "cxrml-bridge-btc" version = "0.1.0" dependencies = [ + "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit-vec 0.5.0 (git+https://github.com/chainx-org/bit-vec.git)", "bitcrypto 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", "chain 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "cxrml-financialrecords 0.1.0", + "cxrml-support 0.1.0", + "cxrml-tokenbalances 0.1.0", "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keys 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", "merkle 0.1.0 (git+https://github.com/chainx-org/merkle.git)", "parity-codec 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "script 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serialization 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", @@ -298,6 +320,20 @@ name = "environmental" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "eth-secp256k1" +version = "0.5.7" +source = "git+https://github.com/chainx-org/rust-secp256k1#2f384b06bea56344e778b565c683c66b2fb3e4d0" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.302 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (git+https://github.com/rust-lang/libc)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 0.1.0 (git+https://github.com/chainx-org/sr-std)", +] + [[package]] name = "fixed-hash" version = "0.2.2" @@ -371,6 +407,26 @@ name = "integer-sqrt" version = "0.1.0" source = "git+https://github.com/paritytech/integer-sqrt-rs.git#886e9cb983c46498003878afe965d55caa762025" +[[package]] +name = "keys" +version = "0.1.0" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" +dependencies = [ + "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitcrypto 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "eth-secp256k1 0.5.7 (git+https://github.com/chainx-org/rust-secp256k1)", + "parity-codec 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "primitives 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_bytes 0.10.4 (git+https://github.com/serde-rs/bytes)", + "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serialization 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "sr-std 0.1.0 (git+https://github.com/chainx-org/sr-std)", +] + [[package]] name = "lazy_static" version = "0.2.11" @@ -384,6 +440,11 @@ dependencies = [ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "libc" +version = "0.2.43" +source = "git+https://github.com/rust-lang/libc#9c5e70ae306463a23ec02179ac2c9fe05c3fb44e" + [[package]] name = "libc" version = "0.2.43" @@ -535,7 +596,7 @@ dependencies = [ [[package]] name = "primitives" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#279298c7235a6bb66dfd47be0dec9c04f2ea3ae8" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -586,6 +647,16 @@ dependencies = [ "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.4.3" @@ -662,6 +733,11 @@ name = "rustc-hex" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc_version" version = "0.2.3" @@ -683,6 +759,19 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "script" +version = "0.1.0" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" +dependencies = [ + "bitcrypto 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "chain 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "keys 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "primitives 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "serialization 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", + "sr-std 0.1.0 (git+https://github.com/chainx-org/sr-std)", +] + [[package]] name = "semver" version = "0.9.0" @@ -722,7 +811,7 @@ dependencies = [ [[package]] name = "serialization" version = "0.1.0" -source = "git+https://github.com/chainx-org/bitcoin-rust#279298c7235a6bb66dfd47be0dec9c04f2ea3ae8" +source = "git+https://github.com/chainx-org/bitcoin-rust#753a7cb5cb9f77fccf612c14ed477cb47a8fbcd9" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)", @@ -1124,6 +1213,15 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "term" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "trie-db" version = "0.9.0" @@ -1227,8 +1325,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" +"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" "checksum chain 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)" = "" +"checksum clippy 0.0.302 (registry+https://github.com/rust-lang/crates.io-index)" = "d911ee15579a3f50880d8c1d59ef6e79f9533127a3bd342462f5d584f5e8c294" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" @@ -1237,6 +1337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" "checksum environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db746025e3ea695bfa0ae744dbacd5fcfc8db51b9760cf8bd0ab69708bb93c49" +"checksum eth-secp256k1 0.5.7 (git+https://github.com/chainx-org/rust-secp256k1)" = "" "checksum fixed-hash 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d5ec8112f00ea8a483e04748a85522184418fd1cf02890b626d8fc28683f7de" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" @@ -1247,8 +1348,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95" "checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a" "checksum integer-sqrt 0.1.0 (git+https://github.com/paritytech/integer-sqrt-rs.git)" = "" +"checksum keys 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)" = "" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" +"checksum libc 0.2.43 (git+https://github.com/rust-lang/libc)" = "" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" @@ -1274,6 +1377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" "checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" @@ -1283,9 +1387,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum script 0.1.0 (git+https://github.com/chainx-org/bitcoin-rust)" = "" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" @@ -1319,6 +1425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum substrate-trie 0.4.0 (git+https://github.com/paritytech/substrate)" = "" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b10ee269228fb723234fce98e9aac0eaed2bd5f1ad2f6930e8d5b93f04445a1a" +"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum trie-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum trie-root 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f85be565a110ed72ed7048cf56570db04ce0a592c98aa59b7dacde3e5718750"