From 9678f77bb57b5d44f84418df04056cb2c5534d4d Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 28 Sep 2021 17:18:12 +1000 Subject: [PATCH] Prevent infinite loops --- beacon_node/execution_layer/src/engine_api.rs | 1 + beacon_node/execution_layer/src/lib.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index aa2b2227f2..4d34628f95 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -22,6 +22,7 @@ pub enum Error { IsSyncing, ExecutionBlockNotFound(Hash256), ExecutionHeadBlockNotFound, + ParentHashEqualsBlockHash(Hash256), } impl From for Error { diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 77b0b3058f..2173acf355 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -309,16 +309,25 @@ impl ExecutionLayer { self.execution_blocks().await.put(block.block_hash, block); + // TODO(merge): This function can theoretically loop indefinitely, as per the + // specification. We should consider how to fix this. See discussion: + // + // https://discord.com/channels/595666850260713488/692062809701482577/892307257205878785 loop { if block.total_difficulty >= self.terminal_total_difficulty() { ttd_exceeding_block = Some(block.block_hash); + // Try to prevent infinite loops. + if block.block_hash == block.parent_hash { + return Err(ApiError::ParentHashEqualsBlockHash(block.block_hash)); + } + block = self .get_pow_block(engine, block.parent_hash) .await? .ok_or(ApiError::ExecutionBlockNotFound(block.parent_hash))?; } else { - return Ok::<_, ApiError>(ttd_exceeding_block); + return Ok(ttd_exceeding_block); } } })