From 94255721bbedc55a1b84dde90bdab5686c4b4d36 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 6 Dec 2022 13:54:23 +0100 Subject: [PATCH] Add `best_tip_hash` field to `BlockStatus` We add the tip of the best chain known to the block status endpoint. This useful in order to allow a client issuing a sequence of queries to check whether a reorg happened in-between, i.e., to detect any possible inconsistencies. --- src/new_index/schema.rs | 12 +++++++----- src/rest.rs | 3 ++- src/util/block.rs | 11 +++++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/new_index/schema.rs b/src/new_index/schema.rs index 35e49f8de..f0fac286b 100644 --- a/src/new_index/schema.rs +++ b/src/new_index/schema.rs @@ -889,7 +889,7 @@ impl ChainQuery { .map(BlockId::from) } - pub fn get_block_status(&self, hash: &BlockHash) -> BlockStatus { + pub fn get_block_status(&self, hash: &BlockHash, best_tip_hash: &BlockHash) -> BlockStatus { // TODO differentiate orphaned and non-existing blocks? telling them apart requires // an additional db read. @@ -897,16 +897,18 @@ impl ChainQuery { // header_by_blockhash only returns blocks that are part of the best chain, // or None for orphaned blocks. - headers - .header_by_blockhash(hash) - .map_or_else(BlockStatus::orphaned, |header| { + headers.header_by_blockhash(hash).map_or_else( + || BlockStatus::orphaned(*best_tip_hash), + |header| { BlockStatus::confirmed( header.height(), headers .header_by_height(header.height() + 1) .map(|h| *h.hash()), + *best_tip_hash, ) - }) + }, + ) } #[cfg(not(feature = "liquid"))] diff --git a/src/rest.rs b/src/rest.rs index 108215634..4d28b903a 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -673,7 +673,8 @@ fn handle_request( } (&Method::GET, Some(&"block"), Some(hash), Some(&"status"), None, None) => { let hash = BlockHash::from_hex(hash)?; - let status = query.chain().get_block_status(&hash); + let best_tip_hash = query.chain().best_hash(); + let status = query.chain().get_block_status(&hash, &best_tip_hash); let ttl = ttl_by_depth(status.height, query); json_response(status, ttl) } diff --git a/src/util/block.rs b/src/util/block.rs index 1f6b98508..93965221c 100644 --- a/src/util/block.rs +++ b/src/util/block.rs @@ -256,22 +256,29 @@ pub struct BlockStatus { pub in_best_chain: bool, pub height: Option, pub next_best: Option, + pub best_tip_hash: BlockHash, } impl BlockStatus { - pub fn confirmed(height: usize, next_best: Option) -> BlockStatus { + pub fn confirmed( + height: usize, + next_best: Option, + best_tip_hash: BlockHash, + ) -> BlockStatus { BlockStatus { in_best_chain: true, height: Some(height), next_best, + best_tip_hash, } } - pub fn orphaned() -> BlockStatus { + pub fn orphaned(best_tip_hash: BlockHash) -> BlockStatus { BlockStatus { in_best_chain: false, height: None, next_best: None, + best_tip_hash, } } }