From 5c2bf8f7e1bbb51a06eabd961b5ad9ce1d3f11cd Mon Sep 17 00:00:00 2001 From: natsoni Date: Tue, 23 Sep 2025 23:14:48 +0200 Subject: [PATCH] Fallback to core for stale blocks on $getBlock calls --- .../api/bitcoin/bitcoin-api-abstract-factory.ts | 2 +- backend/src/api/bitcoin/bitcoin-api.ts | 2 +- backend/src/api/bitcoin/esplora-api.ts | 16 ++++++++++++++-- backend/src/api/blocks.ts | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts b/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts index e1aead616..dc5960f5d 100644 --- a/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts +++ b/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts @@ -15,7 +15,7 @@ export interface AbstractBitcoinApi { $getTxsForBlock(hash: string, fallbackToCore?: boolean): Promise; $getBlockHash(height: number): Promise; $getBlockHeader(hash: string): Promise; - $getBlock(hash: string): Promise; + $getBlock(hash: string, fallbackToCore?: boolean): Promise; $getRawBlock(hash: string): Promise; $getAddress(address: string): Promise; $getAddressTransactions(address: string, lastSeenTxId: string): Promise; diff --git a/backend/src/api/bitcoin/bitcoin-api.ts b/backend/src/api/bitcoin/bitcoin-api.ts index 5c5691c35..df7569dd2 100644 --- a/backend/src/api/bitcoin/bitcoin-api.ts +++ b/backend/src/api/bitcoin/bitcoin-api.ts @@ -141,7 +141,7 @@ class BitcoinApi implements AbstractBitcoinApi { return this.bitcoindClient.getBlockHeader(hash, false); } - async $getBlock(hash: string): Promise { + async $getBlock(hash: string, fallbackToCore = false): Promise { const foundBlock = blocks.getBlocks().find((block) => block.id === hash); if (foundBlock) { return foundBlock; diff --git a/backend/src/api/bitcoin/esplora-api.ts b/backend/src/api/bitcoin/esplora-api.ts index 8d2e088c1..ff51d7559 100644 --- a/backend/src/api/bitcoin/esplora-api.ts +++ b/backend/src/api/bitcoin/esplora-api.ts @@ -449,8 +449,20 @@ class ElectrsApi implements AbstractBitcoinApi { return this.failoverRouter.$get('/block/' + hash + '/header'); } - $getBlock(hash: string): Promise { - return this.failoverRouter.$get('/block/' + hash); + async $getBlock(hash: string, fallbackToCore = false): Promise { + try { + const block = await this.failoverRouter.$get('/block/' + hash); + return block; + } catch (e: any) { + if (fallbackToCore && isAxiosError(e) && e.response?.status === 404) { + // might be a stale block, see if Core has it? + const coreBlock = await bitcoinCoreApi.$getBlock(hash); + if (coreBlock?.stale) { + return coreBlock; + } + } + throw e; + } } $getRawBlock(hash: string): Promise { diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index ff233f3a3..4eb7ea09c 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -1324,7 +1324,7 @@ class Blocks { summaryVersion = 1; } if (height == null) { - const block = await bitcoinApi.$getBlock(hash); + const block = await bitcoinApi.$getBlock(hash, true); height = block.height; }