From c54beba932e5effb46fd317b0fa2ce6aaafb73e0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 30 Jul 2018 11:45:10 +0200 Subject: [PATCH] block cleanup (#9117) * blockchain insert expects owned block instead of block reference * reduce a number of times a block is deserialized * removed cached uncle_bytes from block * removed is_finalized from OpenBlock * removed unused parity_machine::WithMetadata trait * removed commented out code * remove unused metadata from block * remove unused metadata from block * BlockDetails extras may have at most 5 elements --- ethcore/src/block.rs | 55 +--- ethcore/src/blockchain/blockchain.rs | 268 +++++++++----------- ethcore/src/blockchain/extras.rs | 16 +- ethcore/src/blockchain/generator.rs | 8 +- ethcore/src/blockchain/update.rs | 7 +- ethcore/src/client/client.rs | 39 ++- ethcore/src/encoded.rs | 5 + ethcore/src/header.rs | 6 - ethcore/src/snapshot/consensus/authority.rs | 3 +- ethcore/src/snapshot/consensus/work.rs | 10 +- ethcore/src/snapshot/tests/proof_of_work.rs | 11 +- ethcore/src/test_helpers.rs | 7 +- ethcore/src/verification/verification.rs | 1 - machine/src/lib.rs | 16 -- 14 files changed, 179 insertions(+), 273 deletions(-) diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 2cd2fef70..6f1ba7a2f 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -116,10 +116,6 @@ pub struct ExecutedBlock { pub traces: Tracing, /// Hashes of last 256 blocks. pub last_hashes: Arc, - /// Finalization flag. - pub is_finalized: bool, - /// Block metadata. - pub metadata: Option>, } impl ExecutedBlock { @@ -138,8 +134,6 @@ impl ExecutedBlock { Tracing::Disabled }, last_hashes: last_hashes, - is_finalized: false, - metadata: None, } } @@ -228,26 +222,6 @@ impl ::parity_machine::Transactions for ExecutedBlock { } } -impl ::parity_machine::Finalizable for ExecutedBlock { - fn is_finalized(&self) -> bool { - self.is_finalized - } - - fn mark_finalized(&mut self) { - self.is_finalized = true; - } -} - -impl ::parity_machine::WithMetadata for ExecutedBlock { - fn metadata(&self) -> Option<&[u8]> { - self.metadata.as_ref().map(|v| v.as_ref()) - } - - fn set_metadata(&mut self, value: Option>) { - self.metadata = value; - } -} - /// Block that is ready for transactions to be added. /// /// It's a bit like a Vec, except that whenever a transaction is pushed, we execute it and @@ -264,10 +238,7 @@ pub struct OpenBlock<'x> { #[derive(Clone)] pub struct ClosedBlock { block: ExecutedBlock, - uncle_bytes: Bytes, unclosed_state: State, - unclosed_finalization_state: bool, - unclosed_metadata: Option>, } /// Just like `ClosedBlock` except that we can't reopen it and it's faster. @@ -276,7 +247,6 @@ pub struct ClosedBlock { #[derive(Clone)] pub struct LockedBlock { block: ExecutedBlock, - uncle_bytes: Bytes, } /// A block that has a valid seal. @@ -284,7 +254,6 @@ pub struct LockedBlock { /// The block's header has valid seal arguments. The block cannot be reversed into a `ClosedBlock` or `OpenBlock`. pub struct SealedBlock { block: ExecutedBlock, - uncle_bytes: Bytes, } impl<'x> OpenBlock<'x> { @@ -432,14 +401,12 @@ impl<'x> OpenBlock<'x> { let mut s = self; let unclosed_state = s.block.state.clone(); - let unclosed_metadata = s.block.metadata.clone(); - let unclosed_finalization_state = s.block.is_finalized; s.engine.on_close_block(&mut s.block)?; s.block.state.commit()?; s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes()))); - let uncle_bytes = encode_list(&s.block.uncles).into_vec(); + let uncle_bytes = encode_list(&s.block.uncles); s.block.header.set_uncles_hash(keccak(&uncle_bytes)); s.block.header.set_state_root(s.block.state.root().clone()); s.block.header.set_receipts_root(ordered_trie_root(s.block.receipts.iter().map(|r| r.rlp_bytes()))); @@ -451,10 +418,7 @@ impl<'x> OpenBlock<'x> { Ok(ClosedBlock { block: s.block, - uncle_bytes, unclosed_state, - unclosed_metadata, - unclosed_finalization_state, }) } @@ -468,8 +432,8 @@ impl<'x> OpenBlock<'x> { if s.block.header.transactions_root().is_zero() || s.block.header.transactions_root() == &KECCAK_NULL_RLP { s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes()))); } - let uncle_bytes = encode_list(&s.block.uncles).into_vec(); if s.block.header.uncles_hash().is_zero() || s.block.header.uncles_hash() == &KECCAK_EMPTY_LIST_RLP { + let uncle_bytes = encode_list(&s.block.uncles); s.block.header.set_uncles_hash(keccak(&uncle_bytes)); } if s.block.header.receipts_root().is_zero() || s.block.header.receipts_root() == &KECCAK_NULL_RLP { @@ -485,7 +449,6 @@ impl<'x> OpenBlock<'x> { Ok(LockedBlock { block: s.block, - uncle_bytes, }) } @@ -514,7 +477,6 @@ impl ClosedBlock { pub fn lock(self) -> LockedBlock { LockedBlock { block: self.block, - uncle_bytes: self.uncle_bytes, } } @@ -523,8 +485,6 @@ impl ClosedBlock { // revert rewards (i.e. set state back at last transaction's state). let mut block = self.block; block.state = self.unclosed_state; - block.metadata = self.unclosed_metadata; - block.is_finalized = self.unclosed_finalization_state; OpenBlock { block: block, engine: engine, @@ -533,7 +493,6 @@ impl ClosedBlock { } impl LockedBlock { - /// Removes outcomes from receipts and updates the receipt root. /// /// This is done after the block is enacted for historical reasons. @@ -566,7 +525,9 @@ impl LockedBlock { } s.block.header.set_seal(seal); s.block.header.compute_hash(); - Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes }) + Ok(SealedBlock { + block: s.block + }) } /// Provide a valid seal in order to turn this into a `SealedBlock`. @@ -584,7 +545,9 @@ impl LockedBlock { // TODO: passing state context to avoid engines owning it? match engine.verify_local_seal(&s.block.header) { Err(e) => Err((e, s)), - _ => Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes }), + _ => Ok(SealedBlock { + block: s.block + }), } } } @@ -601,7 +564,7 @@ impl SealedBlock { let mut block_rlp = RlpStream::new_list(3); block_rlp.append(&self.block.header); block_rlp.append_list(&self.block.transactions); - block_rlp.append_raw(&self.uncle_bytes, 1); + block_rlp.append_list(&self.block.uncles); block_rlp.out() } } diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 5977a0a81..01becd182 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -450,9 +450,7 @@ impl<'a> Iterator for AncestryWithMetadataIter<'a> { Some(ExtendedHeader { parent_total_difficulty: details.total_difficulty - *header.difficulty(), is_finalized: details.is_finalized, - metadata: details.metadata, - - header: header, + header, }) }, _ => { @@ -555,7 +553,6 @@ impl BlockChain { parent: header.parent_hash(), children: vec![], is_finalized: false, - metadata: None, }; let mut batch = DBTransaction::new(); @@ -759,10 +756,11 @@ impl BlockChain { /// `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 { - let block = view!(BlockView, bytes); - let header = block.header_view(); - let hash = header.hash(); + pub fn insert_unordered_block(&self, batch: &mut DBTransaction, block: encoded::Block, receipts: Vec, parent_td: Option, is_best: bool, is_ancient: bool) -> bool { + let block_number = block.header_view().number(); + let block_parent_hash = block.header_view().parent_hash(); + let block_difficulty = block.header_view().difficulty(); + let hash = block.header_view().hash(); if self.is_known(&hash) { return false; @@ -770,45 +768,45 @@ impl BlockChain { assert!(self.pending_best_block.read().is_none()); - let compressed_header = compress(block.header_rlp().as_raw(), blocks_swapper()); - let compressed_body = compress(&Self::block_to_body(bytes), blocks_swapper()); + let compressed_header = compress(block.header_view().rlp().as_raw(), blocks_swapper()); + let compressed_body = compress(&Self::block_to_body(block.raw()), blocks_swapper()); // store block in db batch.put(db::COL_HEADERS, &hash, &compressed_header); batch.put(db::COL_BODIES, &hash, &compressed_body); - let maybe_parent = self.block_details(&header.parent_hash()); + let maybe_parent = self.block_details(&block_parent_hash); if let Some(parent_details) = maybe_parent { // parent known to be in chain. let info = BlockInfo { hash: hash, - number: header.number(), - total_difficulty: parent_details.total_difficulty + header.difficulty(), + number: block_number, + total_difficulty: parent_details.total_difficulty + block_difficulty, location: BlockLocation::CanonChain, }; self.prepare_update(batch, ExtrasUpdate { - block_hashes: self.prepare_block_hashes_update(bytes, &info), - block_details: self.prepare_block_details_update(bytes, &info, false, None), + block_hashes: self.prepare_block_hashes_update(&info), + block_details: self.prepare_block_details_update(block_parent_hash, &info, false), block_receipts: self.prepare_block_receipts_update(receipts, &info), - blocks_blooms: self.prepare_block_blooms_update(bytes, &info), - transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info), + blocks_blooms: self.prepare_block_blooms_update(block.header_view().log_bloom(), &info), + transactions_addresses: self.prepare_transaction_addresses_update(block.view().transaction_hashes(), &info), info: info, - block: bytes + block, }, is_best); if is_ancient { let mut best_ancient_block = self.best_ancient_block.write(); let ancient_number = best_ancient_block.as_ref().map_or(0, |b| b.number); - if self.block_hash(header.number() + 1).is_some() { + if self.block_hash(block_number + 1).is_some() { batch.delete(db::COL_EXTRA, b"ancient"); *best_ancient_block = None; - } else if header.number() > ancient_number { + } else if block_number > ancient_number { batch.put(db::COL_EXTRA, b"ancient", &hash); *best_ancient_block = Some(BestAncientBlock { hash: hash, - number: header.number(), + number: block_number, }); } } @@ -821,32 +819,31 @@ impl BlockChain { let info = BlockInfo { hash: hash, - number: header.number(), - total_difficulty: d + header.difficulty(), + number: block_number, + total_difficulty: d + block_difficulty, location: BlockLocation::CanonChain, }; // TODO [sorpaas] support warp sync insertion of finalization and metadata. let block_details = BlockDetails { - number: header.number(), + number: block_number, total_difficulty: info.total_difficulty, - parent: header.parent_hash(), + parent: block_parent_hash, children: Vec::new(), is_finalized: false, - metadata: None, }; let mut update = HashMap::new(); update.insert(hash, block_details); self.prepare_update(batch, ExtrasUpdate { - block_hashes: self.prepare_block_hashes_update(bytes, &info), + block_hashes: self.prepare_block_hashes_update(&info), block_details: update, block_receipts: self.prepare_block_receipts_update(receipts, &info), - blocks_blooms: self.prepare_block_blooms_update(bytes, &info), - transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info), + blocks_blooms: self.prepare_block_blooms_update(block.header_view().log_bloom(), &info), + transactions_addresses: self.prepare_transaction_addresses_update(block.view().transaction_hashes(), &info), info: info, - block: bytes, + block, }, is_best); true } @@ -958,41 +955,36 @@ impl BlockChain { /// Inserts the block into backing cache database. /// Expects the block to be valid and already verified. /// If the block is already known, does nothing. - pub fn insert_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec, extras: ExtrasInsert) -> ImportRoute { - let block = view!(BlockView, bytes); - let header = block.header_view(); - - let parent_hash = header.parent_hash(); + pub fn insert_block(&self, batch: &mut DBTransaction, block: encoded::Block, receipts: Vec, extras: ExtrasInsert) -> ImportRoute { + let parent_hash = block.header_view().parent_hash(); let best_hash = self.best_block_hash(); let route = self.tree_route(best_hash, parent_hash).expect("forks are only kept when it has common ancestors; tree route from best to prospective's parent always exists; qed"); - self.insert_block_with_route(batch, bytes, receipts, route, extras) + self.insert_block_with_route(batch, block, receipts, route, extras) } /// Inserts the block into backing cache database with already generated route information. /// Expects the block to be valid and already verified and route is tree route information from current best block to new block's parent. /// If the block is already known, does nothing. - pub fn insert_block_with_route(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec, route: TreeRoute, extras: ExtrasInsert) -> ImportRoute { - // create views onto rlp - let block = view!(BlockView, bytes); - let header = block.header_view(); - let hash = header.hash(); + pub fn insert_block_with_route(&self, batch: &mut DBTransaction, block: encoded::Block, receipts: Vec, route: TreeRoute, extras: ExtrasInsert) -> ImportRoute { + let hash = block.header_view().hash(); + let parent_hash = block.header_view().parent_hash(); - if self.is_known_child(&header.parent_hash(), &hash) { + if self.is_known_child(&parent_hash, &hash) { return ImportRoute::none(); } assert!(self.pending_best_block.read().is_none()); - let compressed_header = compress(block.header_rlp().as_raw(), blocks_swapper()); - let compressed_body = compress(&Self::block_to_body(bytes), blocks_swapper()); + let compressed_header = compress(block.header_view().rlp().as_raw(), blocks_swapper()); + let compressed_body = compress(&Self::block_to_body(block.raw()), blocks_swapper()); // store block in db batch.put(db::COL_HEADERS, &hash, &compressed_header); batch.put(db::COL_BODIES, &hash, &compressed_body); - let info = self.block_info(&header, route, &extras); + let info = self.block_info(&block.header_view(), route, &extras); if let BlockLocation::BranchBecomingCanonChain(ref d) = info.location { info!(target: "reorg", "Reorg to {} ({} {} {})", @@ -1004,13 +996,13 @@ impl BlockChain { } self.prepare_update(batch, ExtrasUpdate { - block_hashes: self.prepare_block_hashes_update(bytes, &info), - block_details: self.prepare_block_details_update(bytes, &info, extras.is_finalized, extras.metadata), + block_hashes: self.prepare_block_hashes_update(&info), + block_details: self.prepare_block_details_update(parent_hash, &info, extras.is_finalized), block_receipts: self.prepare_block_receipts_update(receipts, &info), - blocks_blooms: self.prepare_block_blooms_update(bytes, &info), - transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info), + blocks_blooms: self.prepare_block_blooms_update(block.header_view().log_bloom(), &info), + transactions_addresses: self.prepare_transaction_addresses_update(block.view().transaction_hashes(), &info), info: info.clone(), - block: bytes, + block, }, true); ImportRoute::from(info) @@ -1090,11 +1082,10 @@ impl BlockChain { let mut best_block = self.pending_best_block.write(); if is_best && update.info.location != BlockLocation::Branch { batch.put(db::COL_EXTRA, b"best", &update.info.hash); - let block = encoded::Block::new(update.block.to_vec()); *best_block = Some(BestBlock { total_difficulty: update.info.total_difficulty, - header: block.decode_header(), - block, + header: update.block.decode_header(), + block: update.block, }); } @@ -1214,16 +1205,13 @@ impl BlockChain { } /// This function returns modified block hashes. - fn prepare_block_hashes_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap { + fn prepare_block_hashes_update(&self, info: &BlockInfo) -> HashMap { let mut block_hashes = HashMap::new(); - let block = view!(BlockView, block_bytes); - let header = block.header_view(); - let number = header.number(); match info.location { BlockLocation::Branch => (), BlockLocation::CanonChain => { - block_hashes.insert(number, info.hash); + block_hashes.insert(info.number, info.hash); }, BlockLocation::BranchBecomingCanonChain(ref data) => { let ancestor_number = self.block_number(&data.ancestor).expect("Block number of ancestor is always in DB"); @@ -1233,7 +1221,7 @@ impl BlockChain { block_hashes.insert(start_number + index as BlockNumber, hash); } - block_hashes.insert(number, info.hash); + block_hashes.insert(info.number, info.hash); } } @@ -1242,23 +1230,18 @@ impl BlockChain { /// This function returns modified block details. /// Uses the given parent details or attempts to load them from the database. - fn prepare_block_details_update(&self, block_bytes: &[u8], info: &BlockInfo, is_finalized: bool, metadata: Option>) -> HashMap { - let block = view!(BlockView, block_bytes); - let header = block.header_view(); - let parent_hash = header.parent_hash(); - + fn prepare_block_details_update(&self, parent_hash: H256, info: &BlockInfo, is_finalized: bool) -> HashMap { // update parent let mut parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash)); parent_details.children.push(info.hash); // create current block details. let details = BlockDetails { - number: header.number(), + number: info.number, total_difficulty: info.total_difficulty, parent: parent_hash, children: vec![], is_finalized: is_finalized, - metadata: metadata, }; // write to batch @@ -1276,10 +1259,7 @@ impl BlockChain { } /// This function returns modified transaction addresses. - fn prepare_transaction_addresses_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap> { - let block = view!(BlockView, block_bytes); - let transaction_hashes = block.transaction_hashes(); - + fn prepare_transaction_addresses_update(&self, transaction_hashes: Vec, info: &BlockInfo) -> HashMap> { match info.location { BlockLocation::CanonChain => { transaction_hashes.into_iter() @@ -1344,14 +1324,10 @@ impl BlockChain { /// Later, BloomIndexer is used to map bloom location on filter layer (BloomIndex) /// to bloom location in database (BlocksBloomLocation). /// - fn prepare_block_blooms_update(&self, block_bytes: &[u8], info: &BlockInfo) -> Option<(u64, Vec)> { - let block = view!(BlockView, block_bytes); - let header = block.header_view(); - + fn prepare_block_blooms_update(&self, log_bloom: Bloom, info: &BlockInfo) -> Option<(u64, Vec)> { match info.location { BlockLocation::Branch => None, BlockLocation::CanonChain => { - let log_bloom = header.log_bloom(); if log_bloom.is_zero() { None } else { @@ -1369,7 +1345,7 @@ impl BlockChain { .map(|h| h.log_bloom()) .collect(); - blooms.push(header.log_bloom()); + blooms.push(log_bloom); Some((start_number, blooms)) } } @@ -1505,18 +1481,19 @@ mod tests { use log_entry::{LogEntry, LocalizedLogEntry}; use ethkey::Secret; use test_helpers::new_db; + use encoded; - fn new_chain(genesis: &[u8], db: Arc) -> BlockChain { - BlockChain::new(Config::default(), genesis, db) + fn new_chain(genesis: encoded::Block, db: Arc) -> BlockChain { + BlockChain::new(Config::default(), genesis.raw(), db) } - fn insert_block(db: &Arc, bc: &BlockChain, bytes: &[u8], receipts: Vec) -> ImportRoute { - insert_block_commit(db, bc, bytes, receipts, true) + fn insert_block(db: &Arc, bc: &BlockChain, block: encoded::Block, receipts: Vec) -> ImportRoute { + insert_block_commit(db, bc, block, receipts, true) } - fn insert_block_commit(db: &Arc, bc: &BlockChain, bytes: &[u8], receipts: Vec, commit: bool) -> ImportRoute { + fn insert_block_commit(db: &Arc, bc: &BlockChain, block: encoded::Block, receipts: Vec, commit: bool) -> ImportRoute { let mut batch = db.key_value().transaction(); - let res = insert_block_batch(&mut batch, bc, bytes, receipts); + let res = insert_block_batch(&mut batch, bc, block, receipts); db.key_value().write(batch).unwrap(); if commit { bc.commit(); @@ -1524,25 +1501,24 @@ mod tests { res } - fn insert_block_batch(batch: &mut DBTransaction, bc: &BlockChain, bytes: &[u8], receipts: Vec) -> ImportRoute { - use views::BlockView; + fn insert_block_batch(batch: &mut DBTransaction, bc: &BlockChain, block: encoded::Block, receipts: Vec) -> ImportRoute { use blockchain::ExtrasInsert; - let block = view!(BlockView, bytes); - let header = block.header_view(); - let parent_hash = header.parent_hash(); - let parent_details = bc.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash)); - let block_total_difficulty = parent_details.total_difficulty + header.difficulty(); - let fork_choice = if block_total_difficulty > bc.best_block_total_difficulty() { - ::engines::ForkChoice::New - } else { - ::engines::ForkChoice::Old + let fork_choice = { + let header = block.header_view(); + let parent_hash = header.parent_hash(); + let parent_details = bc.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash)); + let block_total_difficulty = parent_details.total_difficulty + header.difficulty(); + if block_total_difficulty > bc.best_block_total_difficulty() { + ::engines::ForkChoice::New + } else { + ::engines::ForkChoice::Old + } }; - bc.insert_block(batch, bytes, receipts, ExtrasInsert { + bc.insert_block(batch, block, receipts, ExtrasInsert { fork_choice: fork_choice, is_finalized: false, - metadata: None }) } @@ -1553,11 +1529,11 @@ mod tests { let first = genesis.add_block(); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); assert_eq!(bc.best_block_number(), 0); // when - insert_block_commit(&db, &bc, &first.last().encoded(), vec![], false); + insert_block_commit(&db, &bc, first.last().encoded(), vec![], false); assert_eq!(bc.best_block_number(), 0); bc.commit(); // NOTE no db.write here (we want to check if best block is cached) @@ -1578,7 +1554,7 @@ mod tests { let first_hash = first.hash(); let db = new_db(); - let bc = new_chain(&genesis.encoded(), db.clone()); + let bc = new_chain(genesis.encoded(), db.clone()); assert_eq!(bc.genesis_hash(), genesis_hash); assert_eq!(bc.best_block_hash(), genesis_hash); @@ -1587,7 +1563,7 @@ mod tests { assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![]); let mut batch = db.key_value().transaction(); - insert_block_batch(&mut batch, &bc, &first.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, first.encoded(), vec![]); db.key_value().write(batch).unwrap(); bc.commit(); @@ -1607,13 +1583,13 @@ mod tests { let generator = BlockGenerator::new(vec![first_10]); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut block_hashes = vec![genesis.last().hash()]; let mut batch = db.key_value().transaction(); for block in generator { block_hashes.push(block.hash()); - insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, block.encoded(), vec![]); bc.commit(); } db.key_value().write(batch).unwrap(); @@ -1651,10 +1627,10 @@ mod tests { ); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); for b in generator { - insert_block(&db, &bc, &b.encoded(), vec![]); + insert_block(&db, &bc, b.encoded(), vec![]); } assert_eq!(uncle_headers, bc.find_uncle_headers(&b4a_hash, 3).unwrap()); @@ -1687,12 +1663,12 @@ mod tests { let b2_hash = b2.last().hash(); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut batch = db.key_value().transaction(); - let _ = insert_block_batch(&mut batch, &bc, &b1a.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, b1a.last().encoded(), vec![]); bc.commit(); - let _ = insert_block_batch(&mut batch, &bc, &b1b.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, b1b.last().encoded(), vec![]); bc.commit(); db.key_value().write(batch).unwrap(); @@ -1704,7 +1680,7 @@ mod tests { // now let's make forked chain the canon chain let mut batch = db.key_value().transaction(); - let _ = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, b2.last().encoded(), vec![]); bc.commit(); db.key_value().write(batch).unwrap(); @@ -1762,12 +1738,12 @@ mod tests { let t3_hash = t3.hash(); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut batch = db.key_value().transaction(); - let _ = insert_block_batch(&mut batch, &bc, &b1a.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, b1a.last().encoded(), vec![]); bc.commit(); - let _ = insert_block_batch(&mut batch, &bc, &b1b.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, b1b.last().encoded(), vec![]); bc.commit(); db.key_value().write(batch).unwrap(); @@ -1783,7 +1759,7 @@ mod tests { // now let's make forked chain the canon chain let mut batch = db.key_value().transaction(); - let _ = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]); + let _ = insert_block_batch(&mut batch, &bc, b2.last().encoded(), vec![]); bc.commit(); db.key_value().write(batch).unwrap(); @@ -1820,19 +1796,19 @@ mod tests { let best_block_hash = b3a_hash; let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut batch = db.key_value().transaction(); - let ir1 = insert_block_batch(&mut batch, &bc, &b1.last().encoded(), vec![]); + let ir1 = insert_block_batch(&mut batch, &bc, b1.last().encoded(), vec![]); bc.commit(); - let ir2 = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]); + let ir2 = insert_block_batch(&mut batch, &bc, b2.last().encoded(), vec![]); bc.commit(); - let ir3b = insert_block_batch(&mut batch, &bc, &b3b.last().encoded(), vec![]); + let ir3b = insert_block_batch(&mut batch, &bc, b3b.last().encoded(), vec![]); bc.commit(); db.key_value().write(batch).unwrap(); assert_eq!(bc.block_hash(3).unwrap(), b3b_hash); let mut batch = db.key_value().transaction(); - let ir3a = insert_block_batch(&mut batch, &bc, &b3a.last().encoded(), vec![]); + let ir3a = insert_block_batch(&mut batch, &bc, b3a.last().encoded(), vec![]); bc.commit(); db.key_value().write(batch).unwrap(); @@ -1934,17 +1910,17 @@ mod tests { let db = new_db(); { - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); assert_eq!(bc.best_block_hash(), genesis_hash); let mut batch = db.key_value().transaction(); - insert_block_batch(&mut batch, &bc, &first.last().encoded(), vec![]); + insert_block_batch(&mut batch, &bc, first.last().encoded(), vec![]); db.key_value().write(batch).unwrap(); bc.commit(); assert_eq!(bc.best_block_hash(), first_hash); } { - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); assert_eq!(bc.best_block_hash(), first_hash); } @@ -1994,9 +1970,9 @@ mod tests { let b1_hash: H256 = "f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3".into(); let db = new_db(); - let bc = new_chain(&genesis, db.clone()); + let bc = new_chain(encoded::Block::new(genesis), db.clone()); let mut batch = db.key_value().transaction(); - insert_block_batch(&mut batch, &bc, &b1, vec![]); + insert_block_batch(&mut batch, &bc, encoded::Block::new(b1), vec![]); db.key_value().write(batch).unwrap(); bc.commit(); @@ -2062,8 +2038,8 @@ mod tests { let b3_number = b3.last().number(); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); - insert_block(&db, &bc, &b1.last().encoded(), vec![Receipt { + let bc = new_chain(genesis.last().encoded(), db.clone()); + insert_block(&db, &bc, b1.last().encoded(), vec![Receipt { outcome: TransactionOutcome::StateRoot(H256::default()), gas_used: 10_000.into(), log_bloom: Default::default(), @@ -2080,7 +2056,7 @@ mod tests { LogEntry { address: Default::default(), topics: vec![], data: vec![3], }, ], }]); - insert_block(&db, &bc, &b2.last().encoded(), vec![ + insert_block(&db, &bc, b2.last().encoded(), vec![ Receipt { outcome: TransactionOutcome::StateRoot(H256::default()), gas_used: 10_000.into(), @@ -2090,7 +2066,7 @@ mod tests { ], } ]); - insert_block(&db, &bc, &b3.last().encoded(), vec![ + insert_block(&db, &bc, b3.last().encoded(), vec![ Receipt { outcome: TransactionOutcome::StateRoot(H256::default()), gas_used: 10_000.into(), @@ -2190,27 +2166,27 @@ mod tests { let b2a = b1a.add_block_with_bloom(bloom_ba); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let blocks_b1 = bc.blocks_with_bloom(Some(&bloom_b1), 0, 5); let blocks_b2 = bc.blocks_with_bloom(Some(&bloom_b2), 0, 5); assert!(blocks_b1.is_empty()); assert!(blocks_b2.is_empty()); - insert_block(&db, &bc, &b1.last().encoded(), vec![]); + insert_block(&db, &bc, b1.last().encoded(), vec![]); let blocks_b1 = bc.blocks_with_bloom(Some(&bloom_b1), 0, 5); let blocks_b2 = bc.blocks_with_bloom(Some(&bloom_b2), 0, 5); assert_eq!(blocks_b1, vec![1]); assert!(blocks_b2.is_empty()); - insert_block(&db, &bc, &b2.last().encoded(), vec![]); + insert_block(&db, &bc, b2.last().encoded(), vec![]); let blocks_b1 = bc.blocks_with_bloom(Some(&bloom_b1), 0, 5); let blocks_b2 = bc.blocks_with_bloom(Some(&bloom_b2), 0, 5); assert_eq!(blocks_b1, vec![1]); assert_eq!(blocks_b2, vec![2]); // hasn't been forked yet - insert_block(&db, &bc, &b1a.last().encoded(), vec![]); + insert_block(&db, &bc, b1a.last().encoded(), vec![]); let blocks_b1 = bc.blocks_with_bloom(Some(&bloom_b1), 0, 5); let blocks_b2 = bc.blocks_with_bloom(Some(&bloom_b2), 0, 5); let blocks_ba = bc.blocks_with_bloom(Some(&bloom_ba), 0, 5); @@ -2219,7 +2195,7 @@ mod tests { assert!(blocks_ba.is_empty()); // fork has happend - insert_block(&db, &bc, &b2a.last().encoded(), vec![]); + insert_block(&db, &bc, b2a.last().encoded(), vec![]); let blocks_b1 = bc.blocks_with_bloom(Some(&bloom_b1), 0, 5); let blocks_b2 = bc.blocks_with_bloom(Some(&bloom_b2), 0, 5); let blocks_ba = bc.blocks_with_bloom(Some(&bloom_ba), 0, 5); @@ -2228,7 +2204,7 @@ mod tests { assert_eq!(blocks_ba, vec![1, 2]); // fork back - insert_block(&db, &bc, &b3.last().encoded(), vec![]); + insert_block(&db, &bc, b3.last().encoded(), vec![]); let blocks_b1 = bc.blocks_with_bloom(Some(&bloom_b1), 0, 5); let blocks_b2 = bc.blocks_with_bloom(Some(&bloom_b2), 0, 5); let blocks_ba = bc.blocks_with_bloom(Some(&bloom_ba), 0, 5); @@ -2252,13 +2228,13 @@ mod tests { let b1_total_difficulty = genesis.last().difficulty() + b1.last().difficulty(); let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut batch = db.key_value().transaction(); - bc.insert_unordered_block(&mut batch, &b2.last().encoded(), vec![], Some(b1_total_difficulty), false, false); + 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.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.insert_unordered_block(&mut batch, b1.last().encoded(), vec![], None, false, false); bc.commit(); db.key_value().write(batch).unwrap(); @@ -2285,23 +2261,23 @@ mod tests { let db = new_db(); { - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut batch = db.key_value().transaction(); // create a longer fork for block in generator { - insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, block.encoded(), vec![]); bc.commit(); } assert_eq!(bc.best_block_number(), 5); - insert_block_batch(&mut batch, &bc, &uncle.last().encoded(), vec![]); + insert_block_batch(&mut batch, &bc, uncle.last().encoded(), vec![]); db.key_value().write(batch).unwrap(); bc.commit(); } // re-loading the blockchain should load the correct best block. - let bc = new_chain(&genesis.last().encoded(), db); + let bc = new_chain(genesis.last().encoded(), db); assert_eq!(bc.best_block_number(), 5); } @@ -2316,13 +2292,13 @@ mod tests { let db = new_db(); { - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut batch = db.key_value().transaction(); // create a longer fork for (i, block) in generator.into_iter().enumerate() { - insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]); + insert_block_batch(&mut batch, &bc, block.encoded(), vec![]); bc.insert_epoch_transition(&mut batch, i as u64, EpochTransition { block_hash: block.hash(), block_number: i as u64 + 1, @@ -2333,7 +2309,7 @@ mod tests { assert_eq!(bc.best_block_number(), 5); - insert_block_batch(&mut batch, &bc, &uncle.last().encoded(), vec![]); + insert_block_batch(&mut batch, &bc, uncle.last().encoded(), vec![]); bc.insert_epoch_transition(&mut batch, 999, EpochTransition { block_hash: uncle.last().hash(), block_number: 1, @@ -2348,7 +2324,7 @@ mod tests { } // re-loading the blockchain should load the correct best block. - let bc = new_chain(&genesis.last().encoded(), db); + let bc = new_chain(genesis.last().encoded(), db); assert_eq!(bc.best_block_number(), 5); assert_eq!(bc.epoch_transitions().map(|(i, _)| i).collect::>(), vec![0, 1, 2, 3, 4]); @@ -2369,7 +2345,7 @@ mod tests { let db = new_db(); - let bc = new_chain(&genesis.last().encoded(), db.clone()); + let bc = new_chain(genesis.last().encoded(), db.clone()); let mut batch = db.key_value().transaction(); bc.insert_epoch_transition(&mut batch, 0, EpochTransition { @@ -2383,7 +2359,7 @@ mod tests { // and a non-canonical fork of 8 from genesis. let fork_hash = { for block in fork_generator { - insert_block(&db, &bc, &block.encoded(), vec![]); + insert_block(&db, &bc, block.encoded(), vec![]); } assert_eq!(bc.best_block_number(), 7); @@ -2391,7 +2367,7 @@ mod tests { }; for block in next_generator { - insert_block(&db, &bc, &block.encoded(), vec![]); + insert_block(&db, &bc, block.encoded(), vec![]); } assert_eq!(bc.best_block_number(), 10); diff --git a/ethcore/src/blockchain/extras.rs b/ethcore/src/blockchain/extras.rs index bbf67374a..1dd51b7c7 100644 --- a/ethcore/src/blockchain/extras.rs +++ b/ethcore/src/blockchain/extras.rs @@ -152,17 +152,15 @@ pub struct BlockDetails { pub children: Vec, /// Whether the block is considered finalized pub is_finalized: bool, - /// Additional block metadata - pub metadata: Option>, } impl rlp::Encodable for BlockDetails { fn rlp_append(&self, stream: &mut rlp::RlpStream) { - let use_short_version = self.metadata.is_none() && !self.is_finalized; + let use_short_version = !self.is_finalized; match use_short_version { true => { stream.begin_list(4); }, - false => { stream.begin_list(6); }, + false => { stream.begin_list(5); }, } stream.append(&self.number); @@ -171,7 +169,6 @@ impl rlp::Encodable for BlockDetails { stream.append_list(&self.children); if !use_short_version { stream.append(&self.is_finalized); - stream.append(&self.metadata); } } } @@ -180,7 +177,7 @@ impl rlp::Decodable for BlockDetails { fn decode(rlp: &rlp::Rlp) -> Result { let use_short_version = match rlp.item_count()? { 4 => true, - 6 => false, + 5 => false, _ => return Err(rlp::DecoderError::RlpIncorrectListLen), }; @@ -194,11 +191,6 @@ impl rlp::Decodable for BlockDetails { } else { rlp.val_at(4)? }, - metadata: if use_short_version { - None - } else { - rlp.val_at(5)? - }, }) } } @@ -252,7 +244,7 @@ pub struct EpochTransitions { #[cfg(test)] mod tests { use rlp::*; - + use super::BlockReceipts; #[test] diff --git a/ethcore/src/blockchain/generator.rs b/ethcore/src/blockchain/generator.rs index 5a97f37f9..44d4e038c 100644 --- a/ethcore/src/blockchain/generator.rs +++ b/ethcore/src/blockchain/generator.rs @@ -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] diff --git a/ethcore/src/blockchain/update.rs b/ethcore/src/blockchain/update.rs index 0a2d0e774..897abb59b 100644 --- a/ethcore/src/blockchain/update.rs +++ b/ethcore/src/blockchain/update.rs @@ -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, /// Modified block details. @@ -44,6 +45,4 @@ pub struct ExtrasInsert { pub fork_choice: ::engines::ForkChoice, /// Is the inserted block considered finalized. pub is_finalized: bool, - /// New block local metadata. - pub metadata: Option>, } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 8278b2ca8..47974356f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -74,7 +74,6 @@ use types::filter::Filter; use types::ancestry_action::AncestryAction; use verification; use verification::{PreverifiedBlock, Verifier, BlockQueue}; -use views::BlockView; // re-export pub use types::blockchain_info::BlockChainInfo; @@ -210,7 +209,7 @@ pub struct Client { /// Queued ancient blocks, make sure they are imported in order. queued_ancient_blocks: Arc, - VecDeque<(Header, Bytes, Bytes)> + VecDeque<(Header, encoded::Block, Bytes)> )>>, ancient_blocks_import_lock: Arc>, /// Consensus messages import queue @@ -297,7 +296,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); import_results.push(route); client.report.write().accrue_block(&header, transactions_len); @@ -430,9 +429,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 { + 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(); { @@ -443,28 +441,29 @@ 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(()) } // 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(&self, block: B, header: &Header, block_data: &[u8], client: &Client) -> ImportRoute where B: Drain { + fn commit_block(&self, block: B, header: &Header, block_data: encoded::Block, client: &Client) -> ImportRoute where B: Drain { let hash = &header.hash(); let number = header.number(); let parent = header.parent_hash(); let chain = client.chain.read(); + let is_finalized = false; // Commit results let block = block.drain(); - assert_eq!(header.hash(), view!(BlockView, block_data).header_view().hash()); + debug_assert_eq!(header.hash(), block_data.header_view().hash()); let mut batch = DBTransaction::new(); @@ -476,8 +475,7 @@ impl Importer { let new = ExtendedHeader { header: header.clone(), - is_finalized: block.is_finalized, - metadata: block.metadata, + is_finalized, parent_total_difficulty: chain.block_details(&parent).expect("Parent block is in the database; qed").total_difficulty }; @@ -493,8 +491,6 @@ impl Importer { ExtendedHeader { parent_total_difficulty: details.total_difficulty - *header.difficulty(), is_finalized: details.is_finalized, - metadata: details.metadata, - header: header, } }; @@ -515,7 +511,7 @@ impl Importer { // state. self.check_epoch_end_signal( &header, - block_data, + block_data.raw(), &receipts, &state, &chain, @@ -532,8 +528,7 @@ impl Importer { let route = chain.insert_block(&mut batch, block_data, receipts.clone(), ExtrasInsert { fork_choice: fork_choice, - is_finalized: block.is_finalized, - metadata: new.metadata, + is_finalized, }); client.tracedb.read().import(&mut batch, TraceImportRequest { @@ -1327,7 +1322,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 { let chain = self.chain.read(); Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash)) @@ -2053,7 +2048,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(); @@ -2069,7 +2064,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(), @@ -2194,7 +2189,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 @@ -2380,6 +2375,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; @@ -2392,10 +2388,9 @@ 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, }); go_thread.store(true, Ordering::SeqCst); }); diff --git a/ethcore/src/encoded.rs b/ethcore/src/encoded.rs index 5bd723f0e..9573bb5d1 100644 --- a/ethcore/src/encoded.rs +++ b/ethcore/src/encoded.rs @@ -222,6 +222,11 @@ impl Block { /// Consume the view and return the raw bytes. pub fn into_inner(self) -> Vec { self.0 } + + /// Returns the reference to slice of bytes + pub fn raw(&self) -> &[u8] { + &self.0 + } } // forwarders to borrowed header view. diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 5aa4be323..7896282fc 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -43,8 +43,6 @@ pub struct ExtendedHeader { pub is_finalized: bool, /// The parent block difficulty. pub parent_total_difficulty: U256, - /// The block metadata information. - pub metadata: Option>, } /// A block header. @@ -418,10 +416,6 @@ impl ::parity_machine::FinalizableHeader for ExtendedHeader { fn is_finalized(&self) -> bool { self.is_finalized } } -impl ::parity_machine::WithMetadataHeader for ExtendedHeader { - fn metadata(&self) -> Option<&[u8]> { self.metadata.as_ref().map(|v| v.as_ref()) } -} - #[cfg(test)] mod tests { use rustc_hex::FromHex; diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index 8ae4cc33c..72d828643 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -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); diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index 963a96a7f..ded004fe8 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -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; } diff --git a/ethcore/src/snapshot/tests/proof_of_work.rs b/ethcore/src/snapshot/tests/proof_of_work.rs index 40733c328..257269968 100644 --- a/ethcore/src/snapshot/tests/proof_of_work.rs +++ b/ethcore/src/snapshot/tests/proof_of_work.rs @@ -43,15 +43,14 @@ 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, }); bc.commit(); } @@ -83,7 +82,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 +97,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 +129,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, diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 443e0418b..408714571 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -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,10 +355,9 @@ 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, }); bc.commit(); } @@ -373,10 +373,9 @@ 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, }); bc.commit(); } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index a02101354..a0ecf9634 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -467,7 +467,6 @@ mod tests { parent: header.parent_hash().clone(), children: Vec::new(), is_finalized: false, - metadata: None, } }) } diff --git a/machine/src/lib.rs b/machine/src/lib.rs index 6d152851d..a3f640fe5 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -95,22 +95,6 @@ pub trait Transactions: LiveBlock { fn transactions(&self) -> &[Self::Transaction]; } -/// Trait for blocks which have finalized information. -pub trait Finalizable: LiveBlock { - /// Get whether the block is finalized. - fn is_finalized(&self) -> bool; - /// Mark the block as finalized. - fn mark_finalized(&mut self); -} - -/// A state machine with block metadata. -pub trait WithMetadata: LiveBlock { - /// Get the current live block metadata. - fn metadata(&self) -> Option<&[u8]>; - /// Set the current live block metadata. - fn set_metadata(&mut self, value: Option>); -} - /// Generalization of types surrounding blockchain-suitable state machines. pub trait Machine: for<'a> LocalizedMachine<'a> { /// The block header type.