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

Fork choice and metadata framework for Engine #8401

Merged
merged 73 commits into from
May 16, 2018
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
b07ad5f
Add light client TODO item
sorpaas Apr 13, 2018
3c891b9
Move existing total-difficulty-based fork choice check to Engine
sorpaas Apr 13, 2018
d272376
Abstract total difficulty and block provider as Machine::BlockMetadat…
sorpaas Apr 14, 2018
c4d349c
Decouple "generate_metadata" logic to Engine
sorpaas Apr 14, 2018
e1c0252
Merge branch 'master' into fork-choice-no-metadata
sorpaas Apr 14, 2018
1d8149a
Use fixed BlockMetadata and BlockProvider type for null and instantseal
sorpaas Apr 14, 2018
d3ef877
Extend blockdetails with metadatas and finalized info
sorpaas Apr 16, 2018
f325298
Extra data update: mark_finalized and update_metadatas
sorpaas Apr 16, 2018
6756cef
Check finalized block in Blockchain
sorpaas Apr 16, 2018
7c958b4
Fix a test constructor in verification mod
sorpaas Apr 16, 2018
e491abf
Add total difficulty trait
sorpaas Apr 16, 2018
5459695
Fix type import
sorpaas Apr 16, 2018
7fe0d79
Db migration to V13 with metadata column
sorpaas Apr 16, 2018
ce105c6
Address grumbles
sorpaas Apr 16, 2018
45b8ce7
metadatas -> metadata
sorpaas Apr 16, 2018
f86d4cf
Use generic type for update_metadata to avoid passing HashMap all around
sorpaas Apr 16, 2018
24b6316
Merge branch 'finalize' into fork-choice-no-metadata
sorpaas Apr 17, 2018
e797462
Merge branch 'master' of https://github.com/paritytech/parity into fo…
sorpaas Apr 17, 2018
c6dd811
Remove metadata in blockdetails
sorpaas Apr 17, 2018
fb1cc21
[WIP] Implement a generic metadata architecture
sorpaas Apr 17, 2018
5cb6813
[WIP] Metadata insertion logic in BlockChain
sorpaas Apr 17, 2018
f972609
typo: Value -> Self::Value
sorpaas Apr 17, 2018
493e6f0
[WIP] Temporarily remove Engine::is_new_best interface
sorpaas Apr 17, 2018
cb5bfcf
[WIP] Fix more type errors
sorpaas Apr 17, 2018
fc809c7
[WIP] ExtendedHeader::PartialEq
sorpaas Apr 17, 2018
d517ba3
[WIP] Change metadata type Option<Vec<u8>> to Vec<u8>
sorpaas Apr 17, 2018
ac37c31
[WIP] Remove Metadata Error
sorpaas Apr 17, 2018
0f36e50
[WIP] Clean up error conversion
sorpaas Apr 17, 2018
ef3aa63
[WIP] finalized -> is_finalized
sorpaas Apr 17, 2018
3957c49
[WIP] Mark all fields in ExtrasInsert as pub
sorpaas Apr 17, 2018
bc9cc87
[WIP] Remove unused import
sorpaas Apr 17, 2018
4983b68
[WIP] Keep only local metadata info
sorpaas Apr 17, 2018
6009dfa
Mark metadata as optional
sorpaas Apr 17, 2018
13b1b5b
[WIP] Revert metadata db change in BlockChain
sorpaas Apr 17, 2018
723e8a9
[WIP] Put finalization in unclosed state
sorpaas Apr 17, 2018
cf34f0d
Use metadata interface in BlockDetail
sorpaas Apr 17, 2018
5861acb
[WIP] Fix current build failures
sorpaas Apr 17, 2018
6d68222
[WIP] Remove unused blockmetadata struct
sorpaas Apr 17, 2018
a492830
Remove DB migration info
sorpaas Apr 17, 2018
8a06c4e
[WIP] Typo
sorpaas Apr 17, 2018
e673a98
Use ExtendedHeader to implement fork choice check
sorpaas Apr 17, 2018
700779e
Implement is_new_best using Ancestry iterator
sorpaas Apr 17, 2018
143277f
Use expect instead of panic
sorpaas Apr 17, 2018
1dd2ea1
[WIP] Add ancestry Engine support via on_new_block
sorpaas Apr 18, 2018
5d4bd67
Fix tests
sorpaas Apr 18, 2018
704e697
Emission of ancestry actions
sorpaas Apr 18, 2018
fdadd42
use_short_version should take account of metadata
sorpaas Apr 18, 2018
60a7a17
Engine::is_new_best -> Engine::fork_choice
sorpaas Apr 18, 2018
78569a0
Use proper expect format as defined in #1026
sorpaas Apr 18, 2018
8d6629b
panic -> expect
sorpaas Apr 18, 2018
fda5e75
ancestry_header -> ancestry_with_metadata
sorpaas Apr 18, 2018
45f144d
Boxed iterator -> &mut iterator
sorpaas Apr 18, 2018
86d1ef2
Fix tests
sorpaas Apr 18, 2018
7281726
is_new_best -> primitive_fork_choice
sorpaas Apr 18, 2018
d86a056
Document how fork_choice works
sorpaas Apr 18, 2018
e7a83f4
Engine::fork_choice -> Engine::primitive_fork_choice
sorpaas Apr 18, 2018
6b6b042
comment: clarify types of finalization where Engine::primitive_fork_c…
sorpaas Apr 19, 2018
d36e41f
Merge branch 'master' of https://github.com/paritytech/parity into fo…
sorpaas Apr 19, 2018
c593e17
Expose FinalizationInfo to Engine
sorpaas Apr 21, 2018
4900e86
Merge branch 'master' of https://github.com/paritytech/parity into fo…
sorpaas Apr 21, 2018
0b8e55d
Fix tests due to merging
sorpaas Apr 21, 2018
4512b09
Merge branch 'master' into fork-choice-no-metadata
sorpaas Apr 27, 2018
69cc856
Remove TotalDifficulty trait
sorpaas May 1, 2018
4df05f0
Merge branch 'master' of https://github.com/paritytech/parity into fo…
sorpaas May 8, 2018
60b6def
Do not pass FinalizationInfo to Engine
sorpaas May 8, 2018
fca4ca1
Merge branch 'master' of https://github.com/paritytech/parity into fo…
sorpaas May 9, 2018
15a967b
Fix compile
sorpaas May 9, 2018
8d1d98b
Fix unused import
sorpaas May 9, 2018
63a3f54
Remove is_to_route_finalized
sorpaas May 11, 2018
7b0cd66
Address format grumbles
sorpaas May 11, 2018
2c17071
Fix docs: mark_finalized returns None if block hash is not found
sorpaas May 11, 2018
819b3d8
Fix inaccurate tree_route None expect description
sorpaas May 11, 2018
58756e4
Merge branch 'master' of https://github.com/paritytech/parity into fo…
sorpaas May 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions ethcore/light/src/client/header_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ impl HeaderChain {
let raw = header.encoded().into_inner();
transaction.put_vec(self.col, &hash[..], raw);

// TODO: For engines when required, use cryptoeconomic guarantees.
let (best_num, is_new_best) = {
let cur_best = self.best_block.read();
if cur_best.total_difficulty < total_difficulty {
Expand Down
103 changes: 54 additions & 49 deletions ethcore/src/blockchain/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ 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>) -> ImportRoute {
pub fn insert_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec<Receipt>, metadata: U256, is_new_best: bool) -> ImportRoute {
// create views onto rlp
let block = BlockView::new(bytes);
let header = block.header_view();
Expand All @@ -915,7 +915,7 @@ impl BlockChain {
batch.put(db::COL_HEADERS, &hash, &compressed_header);
batch.put(db::COL_BODIES, &hash, &compressed_body);

let info = self.block_info(&header);
let info = self.block_info(&header, metadata, is_new_best);

if let BlockLocation::BranchBecomingCanonChain(ref d) = info.location {
info!(target: "reorg", "Reorg to {} ({} {} {})",
Expand All @@ -940,17 +940,16 @@ impl BlockChain {
}

/// Get inserted block info which is critical to prepare extras updates.
fn block_info(&self, header: &HeaderView) -> BlockInfo {
fn block_info(&self, header: &HeaderView, metadata: U256, is_new_best: bool) -> BlockInfo {
let hash = header.hash();
let number = header.number();
let parent_hash = header.parent_hash();
let parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash));
let is_new_best = parent_details.total_difficulty + header.difficulty() > self.best_block_total_difficulty();

BlockInfo {
hash: hash,
number: number,
total_difficulty: parent_details.total_difficulty + header.difficulty(),
total_difficulty: metadata,
location: if is_new_best {
// on new best block we need to make sure that all ancestors
// are moved to "canon chain"
Expand Down Expand Up @@ -1416,7 +1415,7 @@ mod tests {
use std::sync::Arc;
use rustc_hex::FromHex;
use hash::keccak;
use kvdb::KeyValueDB;
use kvdb::{KeyValueDB, DBTransaction};
use kvdb_memorydb;
use ethereum_types::*;
use receipt::{Receipt, TransactionOutcome};
Expand All @@ -1439,6 +1438,33 @@ mod tests {
BlockChain::new(Config::default(), genesis, db)
}

fn insert_block(db: &Arc<KeyValueDB>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
insert_block_commit(db, bc, bytes, receipts, true)
}

fn insert_block_commit(db: &Arc<KeyValueDB>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>, commit: bool) -> ImportRoute {
let mut batch = db.transaction();
let res = insert_block_batch(&mut batch, bc, bytes, receipts);
db.write(batch).unwrap();
if commit {
bc.commit();
}
res
}

fn insert_block_batch(batch: &mut DBTransaction, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
use views::BlockView;

let block = BlockView::new(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 is_new_best = block_total_difficulty > bc.best_block_total_difficulty();

bc.insert_block(batch, bytes, receipts, block_total_difficulty, is_new_best)
}

#[test]
fn should_cache_best_block() {
// given
Expand All @@ -1450,8 +1476,7 @@ mod tests {
assert_eq!(bc.best_block_number(), 0);

// when
let mut batch = db.transaction();
bc.insert_block(&mut batch, &first.last().encoded(), vec![]);
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)
Expand Down Expand Up @@ -1481,7 +1506,7 @@ mod tests {
assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![]);

let mut batch = db.transaction();
bc.insert_block(&mut batch, &first.encoded(), vec![]);
insert_block_batch(&mut batch, &bc, &first.encoded(), vec![]);
db.write(batch).unwrap();
bc.commit();

Expand All @@ -1507,7 +1532,7 @@ mod tests {
let mut batch = db.transaction();
for block in generator {
block_hashes.push(block.hash());
bc.insert_block(&mut batch, &block.encoded(), vec![]);
insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]);
bc.commit();
}
db.write(batch).unwrap();
Expand Down Expand Up @@ -1547,14 +1572,10 @@ mod tests {
let db = new_db();
let bc = new_chain(&genesis.last().encoded(), db.clone());

let mut batch = db.transaction();
for b in generator {
bc.insert_block(&mut batch, &b.encoded(), vec![]);
bc.commit();
insert_block(&db, &bc, &b.encoded(), vec![]);
}

db.write(batch).unwrap();

assert_eq!(uncle_headers, bc.find_uncle_headers(&b4a_hash, 3).unwrap());
// TODO: insert block that already includes one of them as an uncle to check it's not allowed.
}
Expand Down Expand Up @@ -1588,9 +1609,9 @@ mod tests {
let bc = new_chain(&genesis.last().encoded(), db.clone());

let mut batch = db.transaction();
let _ = bc.insert_block(&mut batch, &b1a.last().encoded(), vec![]);
let _ = insert_block_batch(&mut batch, &bc, &b1a.last().encoded(), vec![]);
bc.commit();
let _ = bc.insert_block(&mut batch, &b1b.last().encoded(), vec![]);
let _ = insert_block_batch(&mut batch, &bc, &b1b.last().encoded(), vec![]);
bc.commit();
db.write(batch).unwrap();

Expand All @@ -1602,7 +1623,7 @@ mod tests {

// now let's make forked chain the canon chain
let mut batch = db.transaction();
let _ = bc.insert_block(&mut batch, &b2.last().encoded(), vec![]);
let _ = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]);
bc.commit();
db.write(batch).unwrap();

Expand Down Expand Up @@ -1663,9 +1684,9 @@ mod tests {
let bc = new_chain(&genesis.last().encoded(), db.clone());

let mut batch = db.transaction();
let _ = bc.insert_block(&mut batch, &b1a.last().encoded(), vec![]);
let _ = insert_block_batch(&mut batch, &bc, &b1a.last().encoded(), vec![]);
bc.commit();
let _ = bc.insert_block(&mut batch, &b1b.last().encoded(), vec![]);
let _ = insert_block_batch(&mut batch, &bc, &b1b.last().encoded(), vec![]);
bc.commit();
db.write(batch).unwrap();

Expand All @@ -1681,7 +1702,7 @@ mod tests {

// now let's make forked chain the canon chain
let mut batch = db.transaction();
let _ = bc.insert_block(&mut batch, &b2.last().encoded(), vec![]);
let _ = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]);
bc.commit();
db.write(batch).unwrap();

Expand Down Expand Up @@ -1721,16 +1742,16 @@ mod tests {
let bc = new_chain(&genesis.last().encoded(), db.clone());

let mut batch = db.transaction();
let ir1 = bc.insert_block(&mut batch, &b1.last().encoded(), vec![]);
let ir1 = insert_block_batch(&mut batch, &bc, &b1.last().encoded(), vec![]);
bc.commit();
let ir2 = bc.insert_block(&mut batch, &b2.last().encoded(), vec![]);
let ir2 = insert_block_batch(&mut batch, &bc, &b2.last().encoded(), vec![]);
bc.commit();
let ir3b = bc.insert_block(&mut batch, &b3b.last().encoded(), vec![]);
let ir3b = insert_block_batch(&mut batch, &bc, &b3b.last().encoded(), vec![]);
bc.commit();
db.write(batch).unwrap();
assert_eq!(bc.block_hash(3).unwrap(), b3b_hash);
let mut batch = db.transaction();
let ir3a = bc.insert_block(&mut batch, &b3a.last().encoded(), vec![]);
let ir3a = insert_block_batch(&mut batch, &bc, &b3a.last().encoded(), vec![]);
bc.commit();
db.write(batch).unwrap();

Expand Down Expand Up @@ -1835,7 +1856,7 @@ mod tests {
let bc = new_chain(&genesis.last().encoded(), db.clone());
assert_eq!(bc.best_block_hash(), genesis_hash);
let mut batch = db.transaction();
bc.insert_block(&mut batch, &first.last().encoded(), vec![]);
insert_block_batch(&mut batch, &bc, &first.last().encoded(), vec![]);
db.write(batch).unwrap();
bc.commit();
assert_eq!(bc.best_block_hash(), first_hash);
Expand Down Expand Up @@ -1894,7 +1915,7 @@ mod tests {
let db = new_db();
let bc = new_chain(&genesis, db.clone());
let mut batch =db.transaction();
bc.insert_block(&mut batch, &b1, vec![]);
insert_block_batch(&mut batch, &bc, &b1, vec![]);
db.write(batch).unwrap();
bc.commit();

Expand All @@ -1905,14 +1926,6 @@ mod tests {
}
}

fn insert_block(db: &Arc<KeyValueDB>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
let mut batch = db.transaction();
let res = bc.insert_block(&mut batch, bytes, receipts);
db.write(batch).unwrap();
bc.commit();
res
}

#[test]
fn test_logs() {
let t1 = Transaction {
Expand Down Expand Up @@ -2158,12 +2171,12 @@ mod tests {
let mut batch = db.transaction();
// create a longer fork
for block in generator {
bc.insert_block(&mut batch, &block.encoded(), vec![]);
insert_block_batch(&mut batch, &bc, &block.encoded(), vec![]);
bc.commit();
}

assert_eq!(bc.best_block_number(), 5);
bc.insert_block(&mut batch, &uncle.last().encoded(), vec![]);
insert_block_batch(&mut batch, &bc, &uncle.last().encoded(), vec![]);
db.write(batch).unwrap();
bc.commit();
}
Expand All @@ -2190,7 +2203,7 @@ mod tests {
// create a longer fork
for (i, block) in generator.into_iter().enumerate() {

bc.insert_block(&mut batch, &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,
Expand All @@ -2201,7 +2214,7 @@ mod tests {

assert_eq!(bc.best_block_number(), 5);

bc.insert_block(&mut batch, &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,
Expand Down Expand Up @@ -2251,23 +2264,15 @@ mod tests {
// and a non-canonical fork of 8 from genesis.
let fork_hash = {
for block in fork_generator {
let mut batch = db.transaction();

bc.insert_block(&mut batch, &block.encoded(), vec![]);
bc.commit();
db.write(batch).unwrap();
insert_block(&db, &bc, &block.encoded(), vec![]);
}

assert_eq!(bc.best_block_number(), 7);
bc.chain_info().best_block_hash
};

for block in next_generator {
let mut batch = db.transaction();
bc.insert_block(&mut batch, &block.encoded(), vec![]);
bc.commit();

db.write(batch).unwrap();
insert_block(&db, &bc, &block.encoded(), vec![]);
}

assert_eq!(bc.best_block_number(), 10);
Expand Down
9 changes: 7 additions & 2 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@ impl Importer {
//
// 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 {
use std::ops::Deref;

let hash = &header.hash();
let number = header.number();
let parent = header.parent_hash();
Expand Down Expand Up @@ -538,7 +540,9 @@ impl Importer {
);

state.journal_under(&mut batch, number, hash).expect("DB commit failed");
let route = chain.insert_block(&mut batch, block_data, receipts.clone());
let block_metadata = client.engine.generate_metadata(block_data, chain.deref().deref());
let is_new_best = client.engine.is_new_best(block_data, &block_metadata, &chain.best_block_total_difficulty(), chain.deref().deref());
let route = chain.insert_block(&mut batch, block_data, receipts.clone(), block_metadata, is_new_best);

client.tracedb.read().import(&mut batch, TraceImportRequest {
traces: traces.into(),
Expand Down Expand Up @@ -2253,6 +2257,7 @@ mod tests {
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use kvdb::DBTransaction;
use ethereum_types::U256;

let client = generate_dummy_client(0);
let genesis = client.chain_info().best_block_hash;
Expand All @@ -2265,7 +2270,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());
another_client.chain.read().insert_block(&mut batch, &new_block, Vec::new(), U256::zero(), true);
go_thread.store(true, Ordering::SeqCst);
});
go
Expand Down
8 changes: 8 additions & 0 deletions ethcore/src/engines/authority_round/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,14 @@ impl Engine<EthereumMachine> for AuthorityRound {
Some(Box::new(::snapshot::PoaSnapshot))
}
}

fn generate_metadata(&self, bytes: &[u8], provider: &<EthereumMachine as ::parity_machine::Machine>::BlockProvider) -> <EthereumMachine as ::parity_machine::Machine>::BlockMetadata {
super::total_difficulty_generate_metadata(bytes, provider)
}

fn is_new_best(&self, bytes: &[u8], block_metadata: &<EthereumMachine as ::parity_machine::Machine>::BlockMetadata, best_block_metadata: &<EthereumMachine as ::parity_machine::Machine>::BlockMetadata, provider: &<EthereumMachine as ::parity_machine::Machine>::BlockProvider) -> bool {
super::total_difficulty_is_new_best(bytes, *block_metadata, *best_block_metadata, provider)
}
}

#[cfg(test)]
Expand Down
8 changes: 8 additions & 0 deletions ethcore/src/engines/basic_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ impl Engine<EthereumMachine> for BasicAuthority {
fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> {
None
}

fn generate_metadata(&self, bytes: &[u8], provider: &<EthereumMachine as ::parity_machine::Machine>::BlockProvider) -> <EthereumMachine as ::parity_machine::Machine>::BlockMetadata {
super::total_difficulty_generate_metadata(bytes, provider)
}

fn is_new_best(&self, bytes: &[u8], block_metadata: &<EthereumMachine as ::parity_machine::Machine>::BlockMetadata, best_block_metadata: &<EthereumMachine as ::parity_machine::Machine>::BlockMetadata, provider: &<EthereumMachine as ::parity_machine::Machine>::BlockProvider) -> bool {
super::total_difficulty_is_new_best(bytes, *block_metadata, *best_block_metadata, provider)
}
}

#[cfg(test)]
Expand Down
10 changes: 9 additions & 1 deletion ethcore/src/engines/instant_seal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl<M> InstantSeal<M> {
}
}

impl<M: Machine> Engine<M> for InstantSeal<M>
impl<M: Machine<BlockMetadata=::ethereum_types::U256, BlockProvider=::blockchain::BlockProvider>> Engine<M> for InstantSeal<M>
where M::LiveBlock: Transactions
{
fn name(&self) -> &str {
Expand Down Expand Up @@ -61,6 +61,14 @@ impl<M: Machine> Engine<M> for InstantSeal<M>
fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool {
header_timestamp >= parent_timestamp
}

fn generate_metadata(&self, bytes: &[u8], provider: &<::machine::EthereumMachine as ::parity_machine::Machine>::BlockProvider) -> <::machine::EthereumMachine as ::parity_machine::Machine>::BlockMetadata {
super::total_difficulty_generate_metadata(bytes, provider)
}

fn is_new_best(&self, bytes: &[u8], block_metadata: &<::machine::EthereumMachine as ::parity_machine::Machine>::BlockMetadata, best_block_metadata: &<::machine::EthereumMachine as ::parity_machine::Machine>::BlockMetadata, provider: &<::machine::EthereumMachine as ::parity_machine::Machine>::BlockProvider) -> bool {
super::total_difficulty_is_new_best(bytes, *block_metadata, *best_block_metadata, provider)
}
}

#[cfg(test)]
Expand Down