From 0bedcde8adb06632bbcdd1b07a7454c37732784d Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Sat, 11 May 2019 14:35:03 +0800 Subject: [PATCH] refactor: improve core type fmt debug --- chain/src/chain.rs | 25 ++++++----- core/src/cell.rs | 55 ++++++++++++++++------- core/src/transaction.rs | 25 ++++------- shared/src/cell_set.rs | 8 ++-- shared/src/chain_state.rs | 4 +- shared/src/tx_pool/orphan.rs | 4 +- shared/src/tx_pool/staging.rs | 84 +++++++++++++++++------------------ store/src/store.rs | 2 +- util/src/lib.rs | 13 ++++++ 9 files changed, 125 insertions(+), 95 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 46a01ba590..12c99532b5 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -302,22 +302,21 @@ impl ChainService { } new_best_block = true; - total_difficulty = cannon_total_difficulty; + total_difficulty = cannon_total_difficulty.clone(); } else { batch.insert_block_ext(&block.header().hash(), &ext)?; } batch.commit()?; - let tip_header = block.header(); - let tip_number = tip_header.number(); - let tip_hash = tip_header.hash(); - let txs_cnt = block.transactions().len(); - if new_best_block { info!( target: "chain", - "block: {}, hash: {:#x}, diff: {:#x}, txs: {}", - tip_number, tip_hash, total_difficulty, txs_cnt); + "block: {}, hash: {:#x}, total_diff: {:#x}, txs: {}", + block.header().number(), + block.header().hash(), + total_difficulty, + block.transactions().len() + ); let tip_header = block.header().to_owned(); // finalize proposal_id table change // then, update tx_pool @@ -339,8 +338,12 @@ impl ChainService { } else { info!( target: "chain", - "uncle: {}, hash: {:#x}, diff: {:#x}, txs: {}", - tip_number, tip_hash, total_difficulty, txs_cnt); + "uncle: {}, hash: {:#x}, total_diff: {:#x}, txs: {}", + block.header().number(), + block.header().hash(), + cannon_total_difficulty, + block.transactions().len() + ); self.notify.notify_new_uncle(block); } @@ -653,7 +656,7 @@ impl ChainService { let hash = self.shared.block_hash(number).unwrap_or_else(|| { panic!(format!("invaild block number({}), tip={}", number, tip)) }); - debug!(target: "chain", " {} => {}", number, hash); + debug!(target: "chain", " {} => {:x}", number, hash); } debug!(target: "chain", "}}"); diff --git a/core/src/cell.rs b/core/src/cell.rs index 7930ccf119..1ba0242d85 100644 --- a/core/src/cell.rs +++ b/core/src/cell.rs @@ -2,11 +2,13 @@ use crate::block::Block; use crate::header::Header; use crate::transaction::{CellOutPoint, CellOutput, OutPoint, Transaction}; use crate::Capacity; +use ckb_util::LowerHexOption; use fnv::{FnvHashMap, FnvHashSet}; use numext_fixed_hash::H256; use serde_derive::{Deserialize, Serialize}; +use std::fmt; -#[derive(Clone, Eq, PartialEq, Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Eq, PartialEq, Default, Deserialize, Serialize)] pub struct CellMeta { #[serde(skip)] pub cell_output: Option, @@ -27,6 +29,22 @@ impl From<&CellOutput> for CellMeta { } } +impl fmt::Debug for CellMeta { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("CellMeta") + .field("cell_output", &self.cell_output) + .field("out_point", &self.out_point) + .field("block_number", &self.block_number) + .field("cellbase", &self.cellbase) + .field("capacity", &self.capacity) + .field( + "data_hash", + &format_args!("{:#x}", LowerHexOption(self.data_hash.as_ref())), + ) + .finish() + } +} + impl CellMeta { pub fn is_cellbase(&self) -> bool { self.cellbase @@ -353,11 +371,11 @@ pub fn resolve_transaction<'a, CP: CellProvider, HP: HeaderProvider>( // skip resolve input of cellbase if !transaction.is_cellbase() { - for out_point in transaction.input_pts() { - let (cell_status, header_status) = if seen_inputs.insert(out_point.clone()) { + for out_point in transaction.input_pts_iter() { + let (cell_status, header_status) = if seen_inputs.insert(out_point.to_owned()) { ( - cell_provider.cell(&out_point), - header_provider.header(&out_point), + cell_provider.cell(out_point), + header_provider.header(out_point), ) } else { (CellStatus::Dead, HeaderStatus::Unknown) @@ -365,24 +383,27 @@ pub fn resolve_transaction<'a, CP: CellProvider, HP: HeaderProvider>( match (cell_status, header_status) { (CellStatus::Dead, _) => { - return Err(UnresolvableError::Dead(out_point.clone())); + return Err(UnresolvableError::Dead(out_point.to_owned())); } (CellStatus::Unknown, _) => { - unknown_out_points.push(out_point.clone()); + unknown_out_points.push(out_point.to_owned()); } // Input cell must exist (CellStatus::Unspecified, _) => { - return Err(UnresolvableError::UnspecifiedInputCell(out_point.clone())); + return Err(UnresolvableError::UnspecifiedInputCell( + out_point.to_owned(), + )); } (_, HeaderStatus::Unknown) => { // TODO: should we change transaction pool so transactions // with unknown header can be included as orphans, waiting // for the correct block header to enable it? - return Err(UnresolvableError::InvalidHeader(out_point.clone())); + return Err(UnresolvableError::InvalidHeader(out_point.to_owned())); } (_, HeaderStatus::InclusionFaliure) => { - return Err(UnresolvableError::InvalidHeader(out_point.clone())); + return Err(UnresolvableError::InvalidHeader(out_point.to_owned())); } + (CellStatus::Live(cell_meta), HeaderStatus::Live(header)) => { resolved_inputs.push(ResolvedOutPoint::cell_and_header(*cell_meta, *header)); } @@ -393,25 +414,25 @@ pub fn resolve_transaction<'a, CP: CellProvider, HP: HeaderProvider>( } } - for out_point in transaction.dep_pts() { - let cell_status = cell_provider.cell(&out_point); - let header_status = header_provider.header(&out_point); + for out_point in transaction.deps_iter() { + let cell_status = cell_provider.cell(out_point); + let header_status = header_provider.header(out_point); match (cell_status, header_status) { (CellStatus::Dead, _) => { - return Err(UnresolvableError::Dead(out_point.clone())); + return Err(UnresolvableError::Dead(out_point.to_owned())); } (CellStatus::Unknown, _) => { - unknown_out_points.push(out_point.clone()); + unknown_out_points.push(out_point.to_owned()); } (_, HeaderStatus::Unknown) => { // TODO: should we change transaction pool so transactions // with unknown header can be included as orphans, waiting // for the correct block header to enable it? - return Err(UnresolvableError::InvalidHeader(out_point.clone())); + return Err(UnresolvableError::InvalidHeader(out_point.to_owned())); } (_, HeaderStatus::InclusionFaliure) => { - return Err(UnresolvableError::InvalidHeader(out_point.clone())); + return Err(UnresolvableError::InvalidHeader(out_point.to_owned())); } (CellStatus::Live(cell_meta), HeaderStatus::Live(header)) => { resolved_deps.push(ResolvedOutPoint::cell_and_header(*cell_meta, *header)); diff --git a/core/src/transaction.rs b/core/src/transaction.rs index 6d9793b6d2..967e3ee434 100644 --- a/core/src/transaction.rs +++ b/core/src/transaction.rs @@ -5,6 +5,7 @@ pub use crate::Capacity; use crate::{BlockNumber, Version}; use bincode::{deserialize, serialize}; use bytes::Bytes; +use ckb_util::LowerHexOption; use faster_hex::hex_string; use hash::blake2b_256; use numext_fixed_hash::H256; @@ -64,7 +65,10 @@ impl fmt::Debug for OutPoint { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("OutPoint") .field("cell", &self.cell) - .field("block_hash", &self.block_hash) + .field( + "block_hash", + &format_args!("{:#x}", LowerHexOption(self.block_hash.as_ref())), + ) .finish() } } @@ -492,14 +496,6 @@ impl Transaction { &self.witness_hash } - pub fn out_points_iter(&self) -> impl Iterator { - self.deps.iter().chain( - self.inputs - .iter() - .map(|input: &CellInput| &input.previous_output), - ) - } - pub fn output_pts(&self) -> Vec { let h = self.hash(); (0..self.outputs.len()) @@ -507,15 +503,12 @@ impl Transaction { .collect() } - pub fn input_pts(&self) -> Vec { - self.inputs - .iter() - .map(|x| x.previous_output.clone()) - .collect() + pub fn input_pts_iter(&self) -> impl Iterator { + self.inputs.iter().map(|x| &x.previous_output) } - pub fn dep_pts(&self) -> Vec { - self.deps.clone() + pub fn deps_iter(&self) -> impl Iterator { + self.deps.iter() } pub fn is_empty(&self) -> bool { diff --git a/shared/src/cell_set.rs b/shared/src/cell_set.rs index 2b4a145a22..2845f0e9c6 100644 --- a/shared/src/cell_set.rs +++ b/shared/src/cell_set.rs @@ -16,10 +16,10 @@ pub struct CellSetDiff { impl CellSetDiff { pub fn push_new(&mut self, block: &Block) { for tx in block.transactions() { - let input_pts = tx.input_pts(); + let input_iter = tx.input_pts_iter(); let tx_hash = tx.hash(); let output_len = tx.outputs().len(); - self.new_inputs.extend(input_pts); + self.new_inputs.extend(input_iter.cloned()); self.new_outputs.insert( tx_hash.to_owned(), (block.header().number(), tx.is_cellbase(), output_len), @@ -29,10 +29,10 @@ impl CellSetDiff { pub fn push_old(&mut self, block: &Block) { for tx in block.transactions() { - let input_pts = tx.input_pts(); + let input_iter = tx.input_pts_iter(); let tx_hash = tx.hash(); - self.old_inputs.extend(input_pts); + self.old_inputs.extend(input_iter.cloned()); self.old_outputs.insert(tx_hash.to_owned()); } } diff --git a/shared/src/chain_state.rs b/shared/src/chain_state.rs index 0c65a4e014..f04b14ff78 100644 --- a/shared/src/chain_state.rs +++ b/shared/src/chain_state.rs @@ -146,11 +146,11 @@ impl ChainState { for n in 0..=number { let hash = store.get_block_hash(n).unwrap(); for tx in store.get_block_body(&hash).unwrap() { - let inputs = tx.input_pts(); + let inputs = tx.input_pts_iter(); let output_len = tx.outputs().len(); for o in inputs { - cell_set.mark_dead(&o); + cell_set.mark_dead(o); } cell_set.insert(tx.hash().to_owned(), n, tx.is_cellbase(), output_len); diff --git a/shared/src/tx_pool/orphan.rs b/shared/src/tx_pool/orphan.rs index e63a76b4d7..476cdf152e 100644 --- a/shared/src/tx_pool/orphan.rs +++ b/shared/src/tx_pool/orphan.rs @@ -102,10 +102,10 @@ impl OrphanPool { } pub(crate) fn remove_conflict(&mut self, tx: &Transaction) { - let inputs = tx.input_pts(); + let inputs = tx.input_pts_iter(); for input in inputs { - if let Some(ids) = self.edges.remove(&input) { + if let Some(ids) = self.edges.remove(input) { for cid in ids { self.recursion_remove(&cid); } diff --git a/shared/src/tx_pool/staging.rs b/shared/src/tx_pool/staging.rs index e1439461e7..66105012f9 100644 --- a/shared/src/tx_pool/staging.rs +++ b/shared/src/tx_pool/staging.rs @@ -5,6 +5,7 @@ use ckb_core::cell::{CellMeta, CellProvider, CellStatus}; use ckb_core::transaction::{CellOutput, OutPoint, ProposalShortId, Transaction}; use ckb_core::Cycle; use ckb_util::{FnvHashMap, FnvHashSet, LinkedFnvHashMap}; +use std::collections::VecDeque; use std::hash::Hash; #[derive(Default, Debug, Clone)] @@ -152,43 +153,48 @@ impl StagingPool { }) } - pub fn remove_vertex(&mut self, id: &ProposalShortId, rtxs: &mut Vec) { - if let Some(x) = self.vertices.remove(id) { - let tx = &x.transaction; - let inputs = tx.input_pts(); - let outputs = tx.output_pts(); - let deps = tx.dep_pts(); + pub fn remove_vertex(&mut self, id: &ProposalShortId) -> Vec { + let mut entries = Vec::new(); + let mut queue = VecDeque::new(); - rtxs.push(x); + queue.push_back(id.to_owned()); - for i in inputs { - if self.edges.inner.remove(&i).is_none() { - self.edges.outer.remove(&i); + while let Some(id) = queue.pop_front() { + if let Some(entry) = self.vertices.remove(&id) { + let tx = &entry.transaction; + let inputs = tx.input_pts_iter(); + let outputs = tx.output_pts(); + let deps = tx.deps_iter(); + for i in inputs { + if self.edges.inner.remove(i).is_none() { + self.edges.outer.remove(i); + } } - } - for d in deps { - self.edges.delete_value_in_deps(&d, id); - } - - for o in outputs { - if let Some(cid) = self.edges.remove_inner(&o) { - self.remove_vertex(&cid, rtxs); + for d in deps { + self.edges.delete_value_in_deps(d, &id); } - if let Some(ids) = self.edges.remove_deps(&o) { - for cid in ids { - self.remove_vertex(&cid, rtxs); + for o in outputs { + if let Some(cid) = self.edges.remove_inner(&o) { + queue.push_back(cid); + } + + if let Some(ids) = self.edges.remove_deps(&o) { + for cid in ids { + queue.push_back(cid); + } } } + + entries.push(entry); } } + entries } pub fn remove(&mut self, id: &ProposalShortId) -> Option> { - let mut rtxs = Vec::new(); - - self.remove_vertex(id, &mut rtxs); + let rtxs = self.remove_vertex(id); if rtxs.is_empty() { None @@ -198,9 +204,9 @@ impl StagingPool { } pub fn add_tx(&mut self, cycles: Cycle, tx: Transaction) { - let inputs = tx.input_pts(); + let inputs = tx.input_pts_iter(); let outputs = tx.output_pts(); - let deps = tx.dep_pts(); + let deps = tx.deps_iter(); let id = tx.proposal_short_id(); @@ -208,22 +214,22 @@ impl StagingPool { for i in inputs { let mut flag = true; - if let Some(x) = self.edges.get_inner_mut(&i) { + if let Some(x) = self.edges.get_inner_mut(i) { *x = Some(id); count += 1; flag = false; } if flag { - self.edges.insert_outer(i, id); + self.edges.insert_outer(i.to_owned(), id); } } for d in deps { - if self.edges.contains_key(&d) { + if self.edges.contains_key(d) { count += 1; } - self.edges.insert_deps(d, id); + self.edges.insert_deps(d.to_owned(), id); } for o in outputs { @@ -236,8 +242,8 @@ impl StagingPool { pub fn remove_committed_tx(&mut self, tx: &Transaction) { let outputs = tx.output_pts(); - let inputs = tx.input_pts(); - let deps = tx.dep_pts(); + let inputs = tx.input_pts_iter(); + let deps = tx.deps_iter(); let id = tx.proposal_short_id(); if self.vertices.remove(&id).is_some() { @@ -255,11 +261,11 @@ impl StagingPool { } for i in inputs { - self.edges.remove_outer(&i); + self.edges.remove_outer(i); } for d in deps { - self.edges.delete_value_in_deps(&d, &id) + self.edges.delete_value_in_deps(d, &id) } } else { self.resolve_conflict(tx); @@ -267,10 +273,10 @@ impl StagingPool { } pub fn resolve_conflict(&mut self, tx: &Transaction) { - let inputs = tx.input_pts(); + let inputs = tx.input_pts_iter(); for i in inputs { - if let Some(id) = self.edges.remove_outer(&i) { + if let Some(id) = self.edges.remove_outer(i) { self.remove(&id); } @@ -295,12 +301,6 @@ impl StagingPool { self.vertices.values() } - // pub fn inc_ref(&mut self, id: &ProposalShortId) { - // if let Some(x) = self.vertices.get_mut(&id) { - // x.refs_count += 1; - // } - // } - pub fn dec_ref(&mut self, id: &ProposalShortId) { if let Some(x) = self.vertices.get_mut(&id) { x.refs_count -= 1; diff --git a/store/src/store.rs b/store/src/store.rs index 523e0d45e6..3126aa7149 100644 --- a/store/src/store.rs +++ b/store/src/store.rs @@ -200,7 +200,7 @@ impl ChainStore for ChainKVStore { let ins = if tx.is_cellbase() { Vec::new() } else { - tx.input_pts() + tx.input_pts_iter().cloned().collect() }; let outs = tx.output_pts(); diff --git a/util/src/lib.rs b/util/src/lib.rs index 6b1f4683af..621e1ca826 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -1,5 +1,7 @@ mod linked_hash_set; +use std::fmt; + pub use fnv::{FnvBuildHasher, FnvHashMap, FnvHashSet}; pub use linked_hash_map::{Entries as LinkedHashMapEntries, LinkedHashMap}; pub use linked_hash_set::LinkedHashSet; @@ -44,3 +46,14 @@ macro_rules! try_option { } }; } + +pub struct LowerHexOption(pub Option); + +impl fmt::LowerHex for LowerHexOption { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.0 { + Some(ref v) => write!(f, "Some({:x})", v), + None => write!(f, "None"), + } + } +}