mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-22 14:24:44 +00:00
merge with upstream
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
use beacon_chain::{BeaconChainTypes, BlockError};
|
||||
@@ -16,6 +17,7 @@ use types::signed_block_and_blobs::BlockWrapper;
|
||||
use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent};
|
||||
use crate::metrics;
|
||||
|
||||
use self::parent_lookup::PARENT_FAIL_TOLERANCE;
|
||||
use self::{
|
||||
parent_lookup::{ParentLookup, VerifyError},
|
||||
single_block_lookup::SingleBlockRequest,
|
||||
@@ -39,8 +41,11 @@ const FAILED_CHAINS_CACHE_EXPIRY_SECONDS: u64 = 60;
|
||||
const SINGLE_BLOCK_LOOKUP_MAX_ATTEMPTS: u8 = 3;
|
||||
|
||||
pub(crate) struct BlockLookups<T: BeaconChainTypes> {
|
||||
/// A collection of parent block lookups.
|
||||
parent_queue: SmallVec<[ParentLookup<T>; 3]>,
|
||||
/// Parent chain lookups being downloaded.
|
||||
parent_lookups: SmallVec<[ParentLookup<T>; 3]>,
|
||||
|
||||
processing_parent_lookups:
|
||||
HashMap<Hash256, (Vec<Hash256>, SingleBlockRequest<PARENT_FAIL_TOLERANCE>)>,
|
||||
|
||||
/// A cache of failed chain lookups to prevent duplicate searches.
|
||||
failed_chains: LRUTimeCache<Hash256>,
|
||||
@@ -58,7 +63,8 @@ pub(crate) struct BlockLookups<T: BeaconChainTypes> {
|
||||
impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
pub fn new(log: Logger) -> Self {
|
||||
Self {
|
||||
parent_queue: Default::default(),
|
||||
parent_lookups: Default::default(),
|
||||
processing_parent_lookups: Default::default(),
|
||||
failed_chains: LRUTimeCache::new(Duration::from_secs(
|
||||
FAILED_CHAINS_CACHE_EXPIRY_SECONDS,
|
||||
)),
|
||||
@@ -81,6 +87,23 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.parent_lookups.iter_mut().any(|parent_req| {
|
||||
parent_req.add_peer(&hash, &peer_id) || parent_req.contains_block(&hash)
|
||||
}) {
|
||||
// If the block was already downloaded, or is being downloaded in this moment, do not
|
||||
// request it.
|
||||
return;
|
||||
}
|
||||
|
||||
if self
|
||||
.processing_parent_lookups
|
||||
.values()
|
||||
.any(|(hashes, _last_parent_request)| hashes.contains(&hash))
|
||||
{
|
||||
// we are already processing this block, ignore it.
|
||||
return;
|
||||
}
|
||||
|
||||
debug!(
|
||||
self.log,
|
||||
"Searching for block";
|
||||
@@ -123,8 +146,8 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
// Make sure this block is not already downloaded, and that neither it or its parent is
|
||||
// being searched for.
|
||||
if self.parent_queue.iter_mut().any(|parent_req| {
|
||||
parent_req.contains_block(block.block())
|
||||
if self.parent_lookups.iter_mut().any(|parent_req| {
|
||||
parent_req.contains_block(&block_root)
|
||||
|| parent_req.add_peer(&block_root, &peer_id)
|
||||
|| parent_req.add_peer(&parent_root, &peer_id)
|
||||
}) {
|
||||
@@ -132,6 +155,15 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
return;
|
||||
}
|
||||
|
||||
if self
|
||||
.processing_parent_lookups
|
||||
.values()
|
||||
.any(|(hashes, _peers)| hashes.contains(&block_root) || hashes.contains(&parent_root))
|
||||
{
|
||||
// we are already processing this block, ignore it.
|
||||
return;
|
||||
}
|
||||
|
||||
let parent_lookup = ParentLookup::new(block_root, block, peer_id);
|
||||
self.request_parent(parent_lookup, cx);
|
||||
}
|
||||
@@ -212,11 +244,11 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
) {
|
||||
let mut parent_lookup = if let Some(pos) = self
|
||||
.parent_queue
|
||||
.parent_lookups
|
||||
.iter()
|
||||
.position(|request| request.pending_response(id))
|
||||
{
|
||||
self.parent_queue.remove(pos)
|
||||
self.parent_lookups.remove(pos)
|
||||
} else {
|
||||
if block.is_some() {
|
||||
debug!(self.log, "Response for a parent lookup request that was not found"; "peer_id" => %peer_id);
|
||||
@@ -238,13 +270,13 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
self.parent_queue.push(parent_lookup)
|
||||
self.parent_lookups.push(parent_lookup)
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
// Request finished successfully, nothing else to do. It will be removed after the
|
||||
// processing result arrives.
|
||||
self.parent_queue.push(parent_lookup);
|
||||
self.parent_lookups.push(parent_lookup);
|
||||
}
|
||||
Err(e) => match e {
|
||||
VerifyError::RootMismatch
|
||||
@@ -281,7 +313,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
metrics::set_gauge(
|
||||
&metrics::SYNC_PARENT_BLOCK_LOOKUPS,
|
||||
self.parent_queue.len() as i64,
|
||||
self.parent_lookups.len() as i64,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -329,11 +361,11 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
/* Check disconnection for parent lookups */
|
||||
while let Some(pos) = self
|
||||
.parent_queue
|
||||
.parent_lookups
|
||||
.iter_mut()
|
||||
.position(|req| req.check_peer_disconnected(peer_id).is_err())
|
||||
{
|
||||
let parent_lookup = self.parent_queue.remove(pos);
|
||||
let parent_lookup = self.parent_lookups.remove(pos);
|
||||
trace!(self.log, "Parent lookup's peer disconnected"; &parent_lookup);
|
||||
self.request_parent(parent_lookup, cx);
|
||||
}
|
||||
@@ -347,11 +379,11 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
) {
|
||||
if let Some(pos) = self
|
||||
.parent_queue
|
||||
.parent_lookups
|
||||
.iter()
|
||||
.position(|request| request.pending_response(id))
|
||||
{
|
||||
let mut parent_lookup = self.parent_queue.remove(pos);
|
||||
let mut parent_lookup = self.parent_lookups.remove(pos);
|
||||
parent_lookup.download_failed();
|
||||
trace!(self.log, "Parent lookup request failed"; &parent_lookup);
|
||||
self.request_parent(parent_lookup, cx);
|
||||
@@ -360,7 +392,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
};
|
||||
metrics::set_gauge(
|
||||
&metrics::SYNC_PARENT_BLOCK_LOOKUPS,
|
||||
self.parent_queue.len() as i64,
|
||||
self.parent_lookups.len() as i64,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -475,7 +507,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
) {
|
||||
let (mut parent_lookup, peer_id) = if let Some((pos, peer)) = self
|
||||
.parent_queue
|
||||
.parent_lookups
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(pos, request)| {
|
||||
@@ -483,7 +515,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
.get_processing_peer(chain_hash)
|
||||
.map(|peer| (pos, peer))
|
||||
}) {
|
||||
(self.parent_queue.remove(pos), peer)
|
||||
(self.parent_lookups.remove(pos), peer)
|
||||
} else {
|
||||
return debug!(self.log, "Process response for a parent lookup request that was not found"; "chain_hash" => %chain_hash);
|
||||
};
|
||||
@@ -525,15 +557,15 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
);
|
||||
}
|
||||
};
|
||||
let chain_hash = parent_lookup.chain_hash();
|
||||
let blocks = parent_lookup.chain_blocks();
|
||||
let (chain_hash, blocks, hashes, request) = parent_lookup.parts_for_processing();
|
||||
let process_id = ChainSegmentProcessId::ParentLookup(chain_hash);
|
||||
|
||||
let work = WorkEvent::chain_segment(process_id, blocks);
|
||||
|
||||
match beacon_processor_send.try_send(work) {
|
||||
Ok(_) => {
|
||||
self.parent_queue.push(parent_lookup);
|
||||
self.processing_parent_lookups
|
||||
.insert(chain_hash, (hashes, request));
|
||||
}
|
||||
Err(e) => {
|
||||
error!(
|
||||
@@ -587,7 +619,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
metrics::set_gauge(
|
||||
&metrics::SYNC_PARENT_BLOCK_LOOKUPS,
|
||||
self.parent_queue.len() as i64,
|
||||
self.parent_lookups.len() as i64,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -597,14 +629,11 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
result: BatchProcessResult,
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
) {
|
||||
let parent_lookup = if let Some(pos) = self
|
||||
.parent_queue
|
||||
.iter()
|
||||
.position(|request| request.chain_hash() == chain_hash)
|
||||
{
|
||||
self.parent_queue.remove(pos)
|
||||
} else {
|
||||
return debug!(self.log, "Chain process response for a parent lookup request that was not found"; "chain_hash" => %chain_hash);
|
||||
let request = match self.processing_parent_lookups.remove(&chain_hash) {
|
||||
Some((_hashes, request)) => request,
|
||||
None => {
|
||||
return debug!(self.log, "Chain process response for a parent lookup request that was not found"; "chain_hash" => %chain_hash, "result" => ?result)
|
||||
}
|
||||
};
|
||||
|
||||
debug!(self.log, "Parent chain processed"; "chain_hash" => %chain_hash, "result" => ?result);
|
||||
@@ -616,8 +645,8 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
imported_blocks: _,
|
||||
penalty,
|
||||
} => {
|
||||
self.failed_chains.insert(parent_lookup.chain_hash());
|
||||
for &peer_id in parent_lookup.used_peers() {
|
||||
self.failed_chains.insert(chain_hash);
|
||||
for peer_id in request.used_peers {
|
||||
cx.report_peer(peer_id, penalty, "parent_chain_failure")
|
||||
}
|
||||
}
|
||||
@@ -628,7 +657,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
metrics::set_gauge(
|
||||
&metrics::SYNC_PARENT_BLOCK_LOOKUPS,
|
||||
self.parent_queue.len() as i64,
|
||||
self.parent_lookups.len() as i64,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -704,14 +733,14 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
}
|
||||
Ok(_) => {
|
||||
debug!(self.log, "Requesting parent"; &parent_lookup);
|
||||
self.parent_queue.push(parent_lookup)
|
||||
self.parent_lookups.push(parent_lookup)
|
||||
}
|
||||
}
|
||||
|
||||
// We remove and add back again requests so we want this updated regardless of outcome.
|
||||
metrics::set_gauge(
|
||||
&metrics::SYNC_PARENT_BLOCK_LOOKUPS,
|
||||
self.parent_queue.len() as i64,
|
||||
self.parent_lookups.len() as i64,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -722,6 +751,6 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
/// Drops all the parent chain requests and returns how many requests were dropped.
|
||||
pub fn drop_parent_chain_requests(&mut self) -> usize {
|
||||
self.parent_queue.drain(..).len()
|
||||
self.parent_lookups.drain(..).len()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user