Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

block cleanup #9117

Merged
merged 14 commits into from
Jul 30, 2018
Next Next commit
blockchain insert expects owned block instead of block reference
debris committed Jul 13, 2018
commit a0610a7b32661772bddb05b34427d4b64aa3d629
228 changes: 114 additions & 114 deletions ethcore/src/blockchain/blockchain.rs

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions ethcore/src/blockchain/generator.rs
Original file line number Diff line number Diff line change
@@ -19,11 +19,11 @@
use std::collections::VecDeque;
use ethereum_types::{U256, H256, Bloom};

use bytes::Bytes;
use header::Header;
use rlp::encode;
use transaction::SignedTransaction;
use views::BlockView;
use encoded;

/// Helper structure, used for encoding blocks.
#[derive(Default, Clone, RlpEncodable)]
@@ -41,7 +41,7 @@ impl Block {

#[inline]
pub fn hash(&self) -> H256 {
view!(BlockView, &self.encoded()).header_view().hash()
view!(BlockView, &self.encoded().raw()).header_view().hash()
}

#[inline]
@@ -50,8 +50,8 @@ impl Block {
}

#[inline]
pub fn encoded(&self) -> Bytes {
encode(self).into_vec()
pub fn encoded(&self) -> encoded::Block {
encoded::Block::new(encode(self).into_vec())
}

#[inline]
5 changes: 3 additions & 2 deletions ethcore/src/blockchain/update.rs
Original file line number Diff line number Diff line change
@@ -19,13 +19,14 @@ use ethereum_types::{H256, Bloom};
use header::BlockNumber;
use blockchain::block_info::BlockInfo;
use blockchain::extras::{BlockDetails, BlockReceipts, TransactionAddress};
use encoded::Block;

/// Block extras update info.
pub struct ExtrasUpdate<'a> {
pub struct ExtrasUpdate {
/// Block info.
pub info: BlockInfo,
/// Current block uncompressed rlp bytes
pub block: &'a [u8],
pub block: Block,
/// Modified block hashes.
pub block_hashes: HashMap<BlockNumber, H256>,
/// Modified block details.
29 changes: 14 additions & 15 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
@@ -75,7 +75,6 @@ use types::ancestry_action::AncestryAction;
use verification;
use verification::{PreverifiedBlock, Verifier};
use verification::queue::BlockQueue;
use views::BlockView;
use parity_machine::{Finalizable, WithMetadata};

// re-export
@@ -212,7 +211,7 @@ pub struct Client {
/// Queued ancient blocks, make sure they are imported in order.
queued_ancient_blocks: Arc<RwLock<(
HashSet<H256>,
VecDeque<(Header, Bytes, Bytes)>
VecDeque<(Header, encoded::Block, Bytes)>
)>>,
ancient_blocks_import_lock: Arc<Mutex<()>>,
/// Consensus messages import queue
@@ -299,7 +298,7 @@ impl Importer {

let transactions_len = closed_block.transactions().len();

let route = self.commit_block(closed_block, &header, &bytes, client);
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), client);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in future, I'd like this function (and blockchain.rs functions) to take as argument some MetaBlock that contains both plain block and it's encoded version. Currently we are encoding and then decoding stuff that we just encoded. That's not efficient

import_results.push(route);

client.report.write().accrue_block(&header, transactions_len);
@@ -433,9 +432,8 @@ impl Importer {
///
/// The block is guaranteed to be the next best blocks in the
/// first block sequence. Does no sealing or transaction validation.
fn import_old_block(&self, header: &Header, block_bytes: &[u8], receipts_bytes: &[u8], db: &KeyValueDB, chain: &BlockChain) -> Result<H256, ::error::Error> {
fn import_old_block(&self, header: &Header, block: encoded::Block, receipts_bytes: &[u8], db: &KeyValueDB, chain: &BlockChain) -> Result<(), ::error::Error> {
let receipts = ::rlp::decode_list(receipts_bytes);
let hash = header.hash();
let _import_lock = self.import_lock.lock();

{
@@ -446,20 +444,20 @@ impl Importer {

// Commit results
let mut batch = DBTransaction::new();
chain.insert_unordered_block(&mut batch, block_bytes, receipts, None, false, true);
chain.insert_unordered_block(&mut batch, block, receipts, None, false, true);
// Final commit to the DB
db.write_buffered(batch);
chain.commit();
}
db.flush().expect("DB flush failed.");
Ok(hash)
Ok(())
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this value was never used, therefore not needed

}

// NOTE: the header of the block passed here is not necessarily sealed, as
// it is for reconstructing the state transition.
//
// The header passed is from the original block data and is sealed.
fn commit_block<B>(&self, block: B, header: &Header, block_data: &[u8], client: &Client) -> ImportRoute where B: IsBlock + Drain {
fn commit_block<B>(&self, block: B, header: &Header, block_data: encoded::Block, client: &Client) -> ImportRoute where B: IsBlock + Drain {
let hash = &header.hash();
let number = header.number();
let parent = header.parent_hash();
@@ -469,7 +467,7 @@ impl Importer {
let receipts = block.receipts().to_owned();
let traces = block.traces().clone().drain();

assert_eq!(header.hash(), view!(BlockView, block_data).header_view().hash());
debug_assert_eq!(header.hash(), block_data.header_view().hash());

//let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));

@@ -522,7 +520,7 @@ impl Importer {
// state.
self.check_epoch_end_signal(
&header,
block_data,
block_data.raw(),
&receipts,
&state,
&chain,
@@ -1331,7 +1329,7 @@ impl ChainInfo for Client {
}

impl BlockInfo for Client {
fn block_header(&self, id: BlockId) -> Option<::encoded::Header> {
fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
let chain = self.chain.read();

Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash))
@@ -2055,7 +2053,7 @@ impl IoClient for Client {
{
let mut queued = self.queued_ancient_blocks.write();
queued.0.insert(hash);
queued.1.push_back((header, block_bytes, receipts_bytes));
queued.1.push_back((header, encoded::Block::new(block_bytes), receipts_bytes));
}

let queued = self.queued_ancient_blocks.clone();
@@ -2071,7 +2069,7 @@ impl IoClient for Client {
let hash = header.hash();
let result = client.importer.import_old_block(
&header,
&block_bytes,
block_bytes,
&receipts_bytes,
&**client.db.read().key_value(),
&*client.chain.read(),
@@ -2196,7 +2194,7 @@ impl ImportSealedBlock for Client {
let block_data = block.rlp_bytes();
let header = block.header().clone();

let route = self.importer.commit_block(block, &header, &block_data, self);
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
trace!(target: "client", "Imported sealed block #{} ({})", number, h);
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
route
@@ -2375,6 +2373,7 @@ mod tests {
use std::sync::atomic::{AtomicBool, Ordering};
use kvdb::DBTransaction;
use blockchain::ExtrasInsert;
use encoded;

let client = generate_dummy_client(0);
let genesis = client.chain_info().best_block_hash;
@@ -2387,7 +2386,7 @@ mod tests {
let another_client = client.clone();
thread::spawn(move || {
let mut batch = DBTransaction::new();
another_client.chain.read().insert_block(&mut batch, &new_block, Vec::new(), ExtrasInsert {
another_client.chain.read().insert_block(&mut batch, encoded::Block::new(new_block), Vec::new(), ExtrasInsert {
fork_choice: ::engines::ForkChoice::New,
is_finalized: false,
metadata: None,
5 changes: 5 additions & 0 deletions ethcore/src/encoded.rs
Original file line number Diff line number Diff line change
@@ -222,6 +222,11 @@ impl Block {

/// Consume the view and return the raw bytes.
pub fn into_inner(self) -> Vec<u8> { self.0 }

/// Returns the reference to slice of bytes
pub fn raw(&self) -> &[u8] {
&self.0
}
}

// forwarders to borrowed header view.
3 changes: 2 additions & 1 deletion ethcore/src/snapshot/consensus/authority.rs
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ use rlp::{RlpStream, Rlp};
use ethereum_types::{H256, U256};
use kvdb::KeyValueDB;
use bytes::Bytes;
use encoded;


/// Snapshot creation and restoration for PoA chains.
@@ -339,7 +340,7 @@ impl Rebuilder for ChunkRebuilder {
let parent_td: U256 = last_rlp.val_at(4)?;

let mut batch = self.db.transaction();
self.chain.insert_unordered_block(&mut batch, &block_data, receipts, Some(parent_td), true, false);
self.chain.insert_unordered_block(&mut batch, encoded::Block::new(block_data), receipts, Some(parent_td), true, false);
self.db.write_buffered(batch);

self.warp_target = Some(block.header);
10 changes: 5 additions & 5 deletions ethcore/src/snapshot/consensus/work.rs
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@ use kvdb::KeyValueDB;
use bytes::Bytes;
use rlp::{RlpStream, Rlp};
use rand::OsRng;
use encoded;

/// Snapshot creation and restoration for PoW chains.
/// This includes blocks from the head of the chain as a
@@ -220,7 +221,6 @@ impl Rebuilder for PowRebuilder {
/// Feed the rebuilder an uncompressed block chunk.
/// Returns the number of blocks fed or any errors.
fn feed(&mut self, chunk: &[u8], engine: &EthEngine, abort_flag: &AtomicBool) -> Result<(), ::error::Error> {
use views::BlockView;
use snapshot::verify_old_block;
use ethereum_types::U256;
use triehash::ordered_trie_root;
@@ -250,7 +250,7 @@ impl Rebuilder for PowRebuilder {
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();
let block_bytes = encoded::Block::new(block.rlp_bytes());
let is_best = cur_number == self.best_number;

if is_best {
@@ -275,16 +275,16 @@ impl Rebuilder for PowRebuilder {

// special-case the first block in each chunk.
if idx == 3 {
if self.chain.insert_unordered_block(&mut batch, &block_bytes, receipts, Some(parent_total_difficulty), is_best, false) {
if self.chain.insert_unordered_block(&mut batch, block_bytes, receipts, Some(parent_total_difficulty), is_best, false) {
self.disconnected.push((cur_number, block.header.hash()));
}
} else {
self.chain.insert_unordered_block(&mut batch, &block_bytes, receipts, None, is_best, false);
self.chain.insert_unordered_block(&mut batch, block_bytes, receipts, None, is_best, false);
}
self.db.write_buffered(batch);
self.chain.commit();

parent_hash = view!(BlockView, &block_bytes).hash();
parent_hash = block.header.hash();
cur_number += 1;
}

10 changes: 5 additions & 5 deletions ethcore/src/snapshot/tests/proof_of_work.rs
Original file line number Diff line number Diff line change
@@ -43,12 +43,12 @@ fn chunk_and_restore(amount: u64) {
let snapshot_path = tempdir.path().join("SNAP");

let old_db = test_helpers::new_db();
let bc = BlockChain::new(Default::default(), &genesis.encoded(), old_db.clone());
let bc = BlockChain::new(Default::default(), genesis.encoded().raw(), old_db.clone());

// build the blockchain.
let mut batch = DBTransaction::new();
for block in generator {
bc.insert_block(&mut batch, &block.encoded(), vec![], ExtrasInsert {
bc.insert_block(&mut batch, block.encoded(), vec![], ExtrasInsert {
fork_choice: ::engines::ForkChoice::New,
is_finalized: false,
metadata: None,
@@ -83,7 +83,7 @@ fn chunk_and_restore(amount: u64) {

// restore it.
let new_db = test_helpers::new_db();
let new_chain = BlockChain::new(Default::default(), &genesis.encoded(), new_db.clone());
let new_chain = BlockChain::new(Default::default(), genesis.encoded().raw(), new_db.clone());
let mut rebuilder = SNAPSHOT_MODE.rebuilder(new_chain, new_db.clone(), &manifest).unwrap();

let reader = PackedReader::new(&snapshot_path).unwrap().unwrap();
@@ -98,7 +98,7 @@ fn chunk_and_restore(amount: u64) {
drop(rebuilder);

// and test it.
let new_chain = BlockChain::new(Default::default(), &genesis.encoded(), new_db);
let new_chain = BlockChain::new(Default::default(), genesis.encoded().raw(), new_db);
assert_eq!(new_chain.best_block_hash(), best_hash);
}

@@ -130,7 +130,7 @@ fn checks_flag() {

let db = test_helpers::new_db();
let engine = ::spec::Spec::new_test().engine;
let chain = BlockChain::new(Default::default(), &genesis.last().encoded(), db.clone());
let chain = BlockChain::new(Default::default(), genesis.last().encoded().raw(), db.clone());

let manifest = ::snapshot::ManifestData {
version: 2,
5 changes: 3 additions & 2 deletions ethcore/src/test_helpers.rs
Original file line number Diff line number Diff line change
@@ -43,6 +43,7 @@ use blooms_db;
use kvdb::KeyValueDB;
use kvdb_rocksdb;
use tempdir::TempDir;
use encoded;

/// Creates test block with corresponding header
pub fn create_test_block(header: &Header) -> Bytes {
@@ -354,7 +355,7 @@ pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain {
let mut batch = db.key_value().transaction();
for block_order in 1..block_number {
// Total difficulty is always 0 here.
bc.insert_block(&mut batch, &create_unverifiable_block(block_order, bc.best_block_hash()), vec![], ExtrasInsert {
bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block(block_order, bc.best_block_hash())), vec![], ExtrasInsert {
fork_choice: ::engines::ForkChoice::New,
is_finalized: false,
metadata: None,
@@ -373,7 +374,7 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> BlockChain {
let mut batch = db.key_value().transaction();
for block_order in 1..block_number {
// Total difficulty is always 0 here.
bc.insert_block(&mut batch, &create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![], ExtrasInsert {
bc.insert_block(&mut batch, encoded::Block::new(create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None)), vec![], ExtrasInsert {
fork_choice: ::engines::ForkChoice::New,
is_finalized: false,
metadata: None,