Get rid of block hashes cache (#2018)

check_known_head and check_known_orphans catches majority of cases
This commit is contained in:
Antioch Peverell 2018-11-28 17:48:50 +00:00 committed by Ignotus Peverell
parent add068f10d
commit 60cbcbd96b
2 changed files with 2 additions and 36 deletions

View file

@ -23,7 +23,6 @@ use std::time::{Duration, Instant};
use util::RwLock;
use lmdb;
use lru_cache::LruCache;
use core::core::hash::{Hash, Hashed, ZERO_HASH};
use core::core::merkle_proof::MerkleProof;
@ -50,9 +49,6 @@ pub const MAX_ORPHAN_SIZE: usize = 200;
/// When evicting, very old orphans are evicted first
const MAX_ORPHAN_AGE_SECS: u64 = 300;
/// Number of recent hashes we keep to de-duplicate block or header sends
const HASHES_CACHE_SIZE: usize = 200;
#[derive(Debug, Clone)]
struct Orphan {
block: Block,
@ -152,8 +148,6 @@ pub struct Chain {
adapter: Arc<ChainAdapter + Send + Sync>,
orphans: Arc<OrphanBlockPool>,
txhashset: Arc<RwLock<txhashset::TxHashSet>>,
// Recently processed blocks to avoid double-processing
block_hashes_cache: Arc<RwLock<LruCache<Hash, bool>>>,
verifier_cache: Arc<RwLock<VerifierCache>>,
// POW verification function
pow_verifier: fn(&BlockHeader) -> Result<(), pow::Error>,
@ -221,7 +215,6 @@ impl Chain {
txhashset: Arc::new(RwLock::new(txhashset)),
pow_verifier,
verifier_cache,
block_hashes_cache: Arc::new(RwLock::new(LruCache::new(HASHES_CACHE_SIZE))),
archive_mode,
genesis: genesis.header.clone(),
})
@ -276,17 +269,8 @@ impl Chain {
(maybe_new_head, prev_head)
};
let add_to_hash_cache = |hash: Hash| {
// only add to hash cache below if block is definitively accepted
// or rejected
let mut cache = self.block_hashes_cache.write();
cache.insert(hash, true);
};
match maybe_new_head {
Ok(head) => {
add_to_hash_cache(b.hash());
let status = self.determine_status(head.clone(), prev_head);
// notifying other parts of the system of the update
@ -333,7 +317,6 @@ impl Chain {
b.header.height,
e
);
add_to_hash_cache(b.hash());
Err(ErrorKind::Other(format!("{:?}", e).to_owned()).into())
}
},
@ -377,7 +360,6 @@ impl Chain {
Ok(pipe::BlockContext {
opts,
pow_verifier: self.pow_verifier,
block_hashes_cache: self.block_hashes_cache.clone(),
verifier_cache: self.verifier_cache.clone(),
txhashset,
batch,

View file

@ -20,11 +20,9 @@ use util::RwLock;
use chrono::prelude::Utc;
use chrono::Duration;
use lru_cache::LruCache;
use chain::OrphanBlockPool;
use core::consensus;
use core::core::hash::{Hash, Hashed};
use core::core::hash::Hashed;
use core::core::verifier_cache::VerifierCache;
use core::core::Committed;
use core::core::{Block, BlockHeader, BlockSums};
@ -47,9 +45,6 @@ pub struct BlockContext<'a> {
pub txhashset: &'a mut txhashset::TxHashSet,
/// The active batch to use for block processing.
pub batch: store::Batch<'a>,
/// Recently processed blocks to avoid double-processing
pub block_hashes_cache: Arc<RwLock<LruCache<Hash, bool>>>,
/// The verifier cache (caching verifier for rangeproofs and kernel signatures)
pub verifier_cache: Arc<RwLock<VerifierCache>>,
/// Recent orphan blocks to avoid double-processing
@ -84,7 +79,6 @@ fn process_header_for_block(
// from cheapest to most expensive (delay hitting the db until last).
fn check_known(block: &Block, ctx: &mut BlockContext) -> Result<(), Error> {
check_known_head(&block.header, ctx)?;
check_known_cache(&block.header, ctx)?;
check_known_orphans(&block.header, ctx)?;
check_known_store(&block.header, ctx)?;
Ok(())
@ -106,6 +100,7 @@ pub fn process_block(b: &Block, ctx: &mut BlockContext) -> Result<Option<Tip>, E
b.kernels().len(),
);
// Check if we have already processed this block previously.
check_known(b, ctx)?;
// Delay hitting the db for current chain head until we know
@ -291,17 +286,6 @@ fn check_known_head(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(),
Ok(())
}
/// Quick in-memory check to fast-reject any block handled recently.
/// Keeps duplicates from the network in check.
/// Checks against the cache of recently processed block hashes.
fn check_known_cache(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), Error> {
let mut cache = ctx.block_hashes_cache.write();
if cache.contains_key(&header.hash()) {
return Err(ErrorKind::Unfit("already known in cache".to_string()).into());
}
Ok(())
}
/// Check if this block is in the set of known orphans.
fn check_known_orphans(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), Error> {
if ctx.orphans.contains(&header.hash()) {