From 6aaf90e60fdde0612a18dd04ca5a915ed01d35e2 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 18 Feb 2018 15:07:36 +0100 Subject: [PATCH] fixed broken logs --- ethcore/src/blockchain/block_info.rs | 4 +- ethcore/src/blockchain/blockchain.rs | 91 +++++++++++++++++++++----- ethcore/src/blockchain/generator.rs | 5 ++ ethcore/src/blooms/bloom_group.rs | 8 +++ ethcore/src/snapshot/consensus/work.rs | 4 +- util/bloomchain/src/group/group.rs | 2 +- 6 files changed, 93 insertions(+), 21 deletions(-) diff --git a/ethcore/src/blockchain/block_info.rs b/ethcore/src/blockchain/block_info.rs index ade08c7d233..ee8a50d09d9 100644 --- a/ethcore/src/blockchain/block_info.rs +++ b/ethcore/src/blockchain/block_info.rs @@ -31,7 +31,7 @@ pub struct BlockInfo { } /// Describes location of newly inserted block. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum BlockLocation { /// It's part of the canon chain. CanonChain, @@ -43,7 +43,7 @@ pub enum BlockLocation { BranchBecomingCanonChain(BranchBecomingCanonChainData), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct BranchBecomingCanonChainData { /// Hash of the newest common ancestor with old canon chain. pub ancestor: H256, diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index feedf1247c6..421a8a13d4a 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -16,7 +16,7 @@ //! Blockchain database. -use std::collections::{HashMap, HashSet}; +use std::collections::{HashMap, HashSet, hash_map}; use std::sync::Arc; use std::mem; use itertools::Itertools; @@ -714,6 +714,7 @@ impl BlockChain { /// This is used by snapshot restoration and when downloading missing blocks for the chain gap. /// `is_best` forces the best block to be updated to this block. /// `is_ancient` forces the best block of the first block sequence to be updated to this block. + /// `parent_td` is a parent total diffuculty /// Supply a dummy parent total difficulty when the parent block may not be in the chain. /// Returns true if the block is disconnected. pub fn insert_unordered_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec, parent_td: Option, is_best: bool, is_ancient: bool) -> bool { @@ -1005,29 +1006,50 @@ impl BlockChain { batch.extend_with_cache(db::COL_EXTRA, &mut *write_receipts, update.block_receipts, CacheUpdatePolicy::Remove); } - { - let mut write_blocks_blooms = self.blocks_blooms.write(); - batch.extend_with_cache(db::COL_EXTRA, &mut *write_blocks_blooms, update.blocks_blooms, CacheUpdatePolicy::Remove); - } - // These cached values must be updated last with all four locks taken to avoid // cache decoherence { let mut best_block = self.pending_best_block.write(); + let mut write_blocks_blooms = self.blocks_blooms.write(); // update best block match update.info.location { BlockLocation::Branch => (), - _ => if is_best { - batch.put(db::COL_EXTRA, b"best", &update.info.hash); - *best_block = Some(BestBlock { - hash: update.info.hash, - number: update.info.number, - total_difficulty: update.info.total_difficulty, - timestamp: update.timestamp, - block: update.block.to_vec(), - }); + BlockLocation::BranchBecomingCanonChain(_) => { + // clear all existing blooms, cause they may be created for block + // number higher than current best block + *write_blocks_blooms = update.blocks_blooms; + for (key, value) in write_blocks_blooms.iter() { + batch.write(db::COL_EXTRA, key, value); + } + }, + BlockLocation::CanonChain => { + // update all existing blooms groups + for (key, value) in update.blocks_blooms { + match write_blocks_blooms.entry(key) { + hash_map::Entry::Occupied(mut entry) => { + entry.get_mut().accrue_bloom_group(&value); + batch.write(db::COL_EXTRA, entry.key(), entry.get()); + }, + hash_map::Entry::Vacant(entry) => { + batch.write(db::COL_EXTRA, entry.key(), &value); + entry.insert(value); + }, + } + } }, } + + if is_best && update.info.location != BlockLocation::Branch { + batch.put(db::COL_EXTRA, b"best", &update.info.hash); + *best_block = Some(BestBlock { + hash: update.info.hash, + number: update.info.number, + total_difficulty: update.info.total_difficulty, + timestamp: update.timestamp, + block: update.block.to_vec(), + }); + } + let mut write_hashes = self.pending_block_hashes.write(); let mut write_details = self.pending_block_details.write(); let mut write_txs = self.pending_transaction_addresses.write(); @@ -2098,6 +2120,45 @@ mod tests { assert_eq!(blocks_ba, vec![3]); } + #[test] + fn test_insert_unordered() { + let bloom_b1: Bloom = "00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000".into(); + + let bloom_b2: Bloom = "00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(); + + let bloom_b3: Bloom = "00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(); + + let genesis = BlockBuilder::genesis(); + let b1 = genesis.add_block_with_bloom(bloom_b1); + let b2 = b1.add_block_with_bloom(bloom_b2); + let b3 = b2.add_block_with_bloom(bloom_b3); + let b1_total_difficulty = genesis.last().difficulty() + b1.last().difficulty(); + + let db = new_db(); + let bc = new_chain(&genesis.last().encoded(), db.clone()); + let mut batch = db.transaction(); + bc.insert_unordered_block(&mut batch, &b2.last().encoded(), vec![], Some(b1_total_difficulty), false, false); + bc.commit(); + bc.insert_unordered_block(&mut batch, &b3.last().encoded(), vec![], None, true, false); + bc.commit(); + bc.insert_unordered_block(&mut batch, &b1.last().encoded(), vec![], None, false, false); + bc.commit(); + db.write(batch).unwrap(); + + assert_eq!(bc.best_block_hash(), b3.last().hash()); + assert_eq!(bc.block_hash(1).unwrap(), b1.last().hash()); + assert_eq!(bc.block_hash(2).unwrap(), b2.last().hash()); + assert_eq!(bc.block_hash(3).unwrap(), b3.last().hash()); + + let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 3); + let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 3); + let blocks_b3 = bc.blocks_with_bloom(&bloom_b3, 0, 3); + + assert_eq!(blocks_b1, vec![1]); + assert_eq!(blocks_b2, vec![2]); + assert_eq!(blocks_b3, vec![3]); + } + #[test] fn test_best_block_update() { let genesis = BlockBuilder::genesis(); diff --git a/ethcore/src/blockchain/generator.rs b/ethcore/src/blockchain/generator.rs index 5c9068721c8..5f990a4d980 100644 --- a/ethcore/src/blockchain/generator.rs +++ b/ethcore/src/blockchain/generator.rs @@ -53,6 +53,11 @@ impl Block { pub fn encoded(&self) -> Bytes { encode(self).into_vec() } + + #[inline] + pub fn difficulty(&self) -> U256 { + *self.header.difficulty() + } } #[derive(Debug)] diff --git a/ethcore/src/blooms/bloom_group.rs b/ethcore/src/blooms/bloom_group.rs index 4cd891686cb..4d57c9b2622 100644 --- a/ethcore/src/blooms/bloom_group.rs +++ b/ethcore/src/blooms/bloom_group.rs @@ -24,6 +24,14 @@ pub struct BloomGroup { blooms: Vec, } +impl BloomGroup { + pub fn accrue_bloom_group(&mut self, group: &BloomGroup) { + for (bloom, other) in self.blooms.iter_mut().zip(group.blooms.iter()) { + bloom.accrue_bloom(other); + } + } +} + impl From for BloomGroup { fn from(group: bc::BloomGroup) -> Self { let blooms = group.blooms diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index bfb213091e5..5b4ff488893 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -248,9 +248,7 @@ impl Rebuilder for PowRebuilder { let abridged_rlp = pair.at(0)?.as_raw().to_owned(); let abridged_block = AbridgedBlock::from_raw(abridged_rlp); let receipts: Vec<::receipt::Receipt> = pair.list_at(1)?; - let receipts_root = ordered_trie_root( - pair.at(1)?.iter().map(|r| r.as_raw()) - ); + let receipts_root = ordered_trie_root(pair.at(1)?.iter().map(|r| r.as_raw())); let block = abridged_block.to_block(parent_hash, cur_number, receipts_root)?; let block_bytes = block.rlp_bytes(Seal::With); diff --git a/util/bloomchain/src/group/group.rs b/util/bloomchain/src/group/group.rs index 16dbea65e3d..084c8f8e48e 100644 --- a/util/bloomchain/src/group/group.rs +++ b/util/bloomchain/src/group/group.rs @@ -1,7 +1,7 @@ use bloom::Bloom; /// Group of blooms that are in the same index. -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct BloomGroup { pub blooms: Vec, }