v2.5.10 stable (#11239)
* ropsten #6631425 foundation #8798209 (#11201) * [stable] builtin, istanbul and mordor testnet backports (#11234) * ethcore-builtin (#10850) * [builtin]: support `multiple prices and activations` in chain spec (#11039) * [chain specs]: activate `Istanbul` on mainnet (#11228) * ethcore/res: add mordor testnet configuration (#11200) * Update list of bootnodes for xDai chain (#11236) * ethcore: remove `test-helper feat` from build (#11047) * Secret store: fix Instant::now() related race in net_keep_alive (#11155) (#11159) * [stable]: backport #10691 and #10683 (#11143) * Fix compiler warning (that will become an error) (#10683) * Refactor Clique stepping (#10691) * Add Constantinople eips to the dev (instant_seal) config (#10809) * Add cargo-remote dir to .gitignore (?) * Insert explicit warning into the panic hook (#11225) * Fix docker centos build (#11226) * Update MIX bootnodes. (#11203) * Use provided usd-per-eth value if an endpoint is specified (#11209) * Add new line after writing block to hex file. (#10984) * Type annotation for next_key() matching of json filter options (#11192) (but no `FilterOption` in 2.5 so…) * Upgrade jsonrpc to latest (#11206) * [CI] check evmbin build (#11096) * Correct EIP-712 encoding (#11092) * [client]: Fix for incorrectly dropped consensus messages (#11086) * Fix block detail updating (#11015) * Switching sccache from local to Redis (#10971) * Made ecrecover implementation trait public (#11188) * [dependencies]: jsonrpc `14.0.1` (#11183) * [receipt]: add `sender` & `receiver` to `RichReceipts` (#11179) * [ethcore/builtin]: do not panic in blake2pricer on short input (#11180) * util Host: fix a double Read Lock bug in fn Host::session_readable() (#11175) * ethcore client: fix a double Read Lock bug in fn Client::logs() (#11172) * Change how RPCs eth_call and eth_estimateGas handle "Pending" (#11127) * Cleanup stratum a bit (#11161) * Upgrade to jsonrpc v14 (#11151) * SecretStore: expose restore_key_public in HTTP API (#10241)
This commit is contained in:
@@ -195,6 +195,12 @@ pub trait BlockProvider {
|
||||
where F: Fn(&LogEntry) -> bool + Send + Sync, Self: Sized;
|
||||
}
|
||||
|
||||
/// Interface for querying blocks with pending db transaction by hash and by number.
|
||||
trait InTransactionBlockProvider {
|
||||
/// Get the familial details concerning a block.
|
||||
fn uncommitted_block_details(&self, hash: &H256) -> Option<BlockDetails>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
|
||||
enum CacheId {
|
||||
BlockHeader(H256),
|
||||
@@ -424,6 +430,19 @@ impl BlockProvider for BlockChain {
|
||||
}
|
||||
}
|
||||
|
||||
impl InTransactionBlockProvider for BlockChain {
|
||||
fn uncommitted_block_details(&self, hash: &H256) -> Option<BlockDetails> {
|
||||
let result = self.db.key_value().read_with_two_layer_cache(
|
||||
db::COL_EXTRA,
|
||||
&self.pending_block_details,
|
||||
&self.block_details,
|
||||
hash
|
||||
)?;
|
||||
self.cache_man.lock().note_used(CacheId::BlockDetails(*hash));
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which walks the blockchain towards the genesis.
|
||||
#[derive(Clone)]
|
||||
pub struct AncestryIter<'a> {
|
||||
@@ -592,7 +611,7 @@ impl BlockChain {
|
||||
let best_block_rlp = bc.block(&best_block_hash)
|
||||
.expect("Best block is from a known block hash; qed");
|
||||
|
||||
// and write them
|
||||
// and write them to the cache.
|
||||
let mut best_block = bc.best_block.write();
|
||||
*best_block = BestBlock {
|
||||
total_difficulty: best_block_total_difficulty,
|
||||
@@ -795,7 +814,7 @@ impl BlockChain {
|
||||
batch.put(db::COL_HEADERS, &hash, &compressed_header);
|
||||
batch.put(db::COL_BODIES, &hash, &compressed_body);
|
||||
|
||||
let maybe_parent = self.block_details(&block_parent_hash);
|
||||
let maybe_parent = self.uncommitted_block_details(&block_parent_hash);
|
||||
|
||||
if let Some(parent_details) = maybe_parent {
|
||||
// parent known to be in chain.
|
||||
@@ -858,12 +877,31 @@ impl BlockChain {
|
||||
}
|
||||
}
|
||||
|
||||
/// clears all caches for testing purposes
|
||||
/// clears all caches, re-loads best block from disk for testing purposes
|
||||
pub fn clear_cache(&self) {
|
||||
self.block_bodies.write().clear();
|
||||
self.block_details.write().clear();
|
||||
self.block_hashes.write().clear();
|
||||
self.block_headers.write().clear();
|
||||
// Fetch best block details from disk
|
||||
let best_block_hash = self.db.key_value().get(db::COL_EXTRA, b"best")
|
||||
.expect("Low-level database error when fetching 'best' block. Some issue with disk?")
|
||||
.as_ref()
|
||||
.map(|r| H256::from_slice(r))
|
||||
.unwrap();
|
||||
let best_block_total_difficulty = self.block_details(&best_block_hash)
|
||||
.expect("Best block is from a known block hash; a known block hash always comes with a known block detail; qed")
|
||||
.total_difficulty;
|
||||
let best_block_rlp = self.block(&best_block_hash)
|
||||
.expect("Best block is from a known block hash; qed");
|
||||
|
||||
// and write them to the cache
|
||||
let mut best_block = self.best_block.write();
|
||||
*best_block = BestBlock {
|
||||
total_difficulty: best_block_total_difficulty,
|
||||
header: best_block_rlp.decode_header(),
|
||||
block: best_block_rlp,
|
||||
};
|
||||
}
|
||||
|
||||
/// Update the best ancient block to the given hash, after checking that
|
||||
@@ -1033,7 +1071,7 @@ impl BlockChain {
|
||||
///
|
||||
/// Used in snapshots to glue the chunks together at the end.
|
||||
pub fn add_child(&self, batch: &mut DBTransaction, block_hash: H256, child_hash: H256) {
|
||||
let mut parent_details = self.block_details(&block_hash)
|
||||
let mut parent_details = self.uncommitted_block_details(&block_hash)
|
||||
.unwrap_or_else(|| panic!("Invalid block hash: {:?}", block_hash));
|
||||
|
||||
parent_details.children.push(child_hash);
|
||||
@@ -1140,7 +1178,7 @@ impl BlockChain {
|
||||
/// Mark a block to be considered finalized. Returns `Some(())` if the operation succeeds, and `None` if the block
|
||||
/// hash is not found.
|
||||
pub fn mark_finalized(&self, batch: &mut DBTransaction, block_hash: H256) -> Option<()> {
|
||||
let mut block_details = self.block_details(&block_hash)?;
|
||||
let mut block_details = self.uncommitted_block_details(&block_hash)?;
|
||||
block_details.is_finalized = true;
|
||||
|
||||
self.update_block_details(batch, block_hash, block_details);
|
||||
@@ -1333,7 +1371,7 @@ impl BlockChain {
|
||||
/// Uses the given parent details or attempts to load them from the database.
|
||||
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));
|
||||
let mut parent_details = self.uncommitted_block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash));
|
||||
parent_details.children.push(info.hash);
|
||||
|
||||
// create current block details.
|
||||
@@ -1638,7 +1676,7 @@ mod tests {
|
||||
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 parent_details = bc.uncommitted_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() {
|
||||
common_types::engines::ForkChoice::New
|
||||
|
||||
Reference in New Issue
Block a user