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
This commit is contained in:
committed by
André Silva
parent
a809621f63
commit
c54beba932
@@ -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<Receipt>, parent_td: Option<U256>, 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<Receipt>, parent_td: Option<U256>, 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<Receipt>, 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<Receipt>, 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<Receipt>, 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<Receipt>, 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<BlockNumber, H256> {
|
||||
fn prepare_block_hashes_update(&self, info: &BlockInfo) -> HashMap<BlockNumber, H256> {
|
||||
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<Vec<u8>>) -> HashMap<H256, BlockDetails> {
|
||||
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<H256, BlockDetails> {
|
||||
// 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<H256, Option<TransactionAddress>> {
|
||||
let block = view!(BlockView, block_bytes);
|
||||
let transaction_hashes = block.transaction_hashes();
|
||||
|
||||
fn prepare_transaction_addresses_update(&self, transaction_hashes: Vec<H256>, info: &BlockInfo) -> HashMap<H256, Option<TransactionAddress>> {
|
||||
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<Bloom>)> {
|
||||
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<Bloom>)> {
|
||||
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<BlockChainDB>) -> BlockChain {
|
||||
BlockChain::new(Config::default(), genesis, db)
|
||||
fn new_chain(genesis: encoded::Block, db: Arc<BlockChainDB>) -> BlockChain {
|
||||
BlockChain::new(Config::default(), genesis.raw(), db)
|
||||
}
|
||||
|
||||
fn insert_block(db: &Arc<BlockChainDB>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
|
||||
insert_block_commit(db, bc, bytes, receipts, true)
|
||||
fn insert_block(db: &Arc<BlockChainDB>, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>) -> ImportRoute {
|
||||
insert_block_commit(db, bc, block, receipts, true)
|
||||
}
|
||||
|
||||
fn insert_block_commit(db: &Arc<BlockChainDB>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>, commit: bool) -> ImportRoute {
|
||||
fn insert_block_commit(db: &Arc<BlockChainDB>, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>, 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<Receipt>) -> ImportRoute {
|
||||
use views::BlockView;
|
||||
fn insert_block_batch(batch: &mut DBTransaction, bc: &BlockChain, block: encoded::Block, receipts: Vec<Receipt>) -> 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<_>>(), 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);
|
||||
|
||||
@@ -152,17 +152,15 @@ pub struct BlockDetails {
|
||||
pub children: Vec<H256>,
|
||||
/// Whether the block is considered finalized
|
||||
pub is_finalized: bool,
|
||||
/// Additional block metadata
|
||||
pub metadata: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
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<Self, rlp::DecoderError> {
|
||||
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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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.
|
||||
@@ -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<Vec<u8>>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user