From ed59327febab3c57fb8dc1cb43045da0d7169f77 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 28 Jan 2020 11:34:29 +1100 Subject: [PATCH] Add check to ensure parent block is in fork choice --- beacon_node/beacon_chain/src/beacon_chain.rs | 25 +++++++++++++++++-- .../src/sync/range_sync/batch_processing.rs | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 75ca098b71..5eeae7b5ee 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -58,8 +58,11 @@ const HEAD_LOCK_TIMEOUT: Duration = Duration::from_secs(1); pub enum BlockProcessingOutcome { /// Block was valid and imported into the block graph. Processed { block_root: Hash256 }, - /// The blocks parent_root is unknown. - ParentUnknown { parent: Hash256 }, + /// The parent block was unknown. + ParentUnknown { + parent: Hash256, + reference_location: String, + }, /// The block slot is greater than the present slot. FutureSlot { present_slot: Slot, @@ -1223,6 +1226,23 @@ impl BeaconChain { }); } + // Reject any block if its parent is not known to fork choice. + // + // A block that is not in fork choice is either: + // + // - Not yet imported: we should reject this block because we should only import a child + // after its parent has been fully imported. + // - Pre-finalized: if the parent block is _prior_ to finalization, we should ignore it + // because it will revert finalization. Note that the finalized block is stored in fork + // choice, so we will not reject any child of the finalized block (this is relevant during + // genesis). + if !self.fork_choice.contains_block(&block.parent_root) { + return Ok(BlockProcessingOutcome::ParentUnknown { + parent: block.parent_root, + reference_location: "fork_choice".to_string(), + }); + } + let block_root_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_BLOCK_ROOT); let block_root = block.canonical_root(); @@ -1260,6 +1280,7 @@ impl BeaconChain { None => { return Ok(BlockProcessingOutcome::ParentUnknown { parent: block.parent_root, + reference_location: "database".to_string(), }); } }; diff --git a/beacon_node/network/src/sync/range_sync/batch_processing.rs b/beacon_node/network/src/sync/range_sync/batch_processing.rs index 27c4fb295e..a054b6b31a 100644 --- a/beacon_node/network/src/sync/range_sync/batch_processing.rs +++ b/beacon_node/network/src/sync/range_sync/batch_processing.rs @@ -70,7 +70,7 @@ fn process_batch( ); successful_block_import = true; } - BlockProcessingOutcome::ParentUnknown { parent } => { + BlockProcessingOutcome::ParentUnknown { parent, .. } => { // blocks should be sequential and all parents should exist warn!( log, "Parent block is unknown";