diff --git a/prisma-local/migrations/20260104000000_transaction_orphaned_column/migration.sql b/prisma-local/migrations/20260104000000_transaction_orphaned_column/migration.sql new file mode 100644 index 00000000..3821f8ba --- /dev/null +++ b/prisma-local/migrations/20260104000000_transaction_orphaned_column/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE `Transaction` ADD COLUMN `orphaned` BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma-local/schema.prisma b/prisma-local/schema.prisma index dab9ffb1..a1d0da8c 100644 --- a/prisma-local/schema.prisma +++ b/prisma-local/schema.prisma @@ -71,6 +71,7 @@ model Transaction { hash String @db.VarChar(255) amount Decimal @db.Decimal(24, 8) confirmed Boolean @default(false) + orphaned Boolean @default(false) timestamp Int addressId String opReturn String @db.LongText @default("") diff --git a/services/chronikService.ts b/services/chronikService.ts index 1a80d849..7f6e418a 100644 --- a/services/chronikService.ts +++ b/services/chronikService.ts @@ -8,6 +8,7 @@ import { createManyTransactions, deleteTransactions, fetchUnconfirmedTransactions, + markTransactionsOrphaned, upsertTransaction, getSimplifiedTransactions, getSimplifiedTrasaction @@ -632,8 +633,15 @@ export class ChronikBlockchainClient { const { amount, opReturn } = addressWithTransaction.transaction await this.handleUpdateClientPaymentStatus(amount, opReturn, 'CONFIRMED' as ClientPaymentStatus, addressWithTransaction.address.address) } - } catch (e) { - console.error(`${this.CHRONIK_MSG_PREFIX}: confirmed tx handler failed for ${msg.txid}`, e) + } catch (e: any) { + const msg404 = String(e?.message ?? e) + const is404 = /not found in the index|404/.test(msg404) + if (is404) { + console.log(`${this.CHRONIK_MSG_PREFIX}: [${msg.msgType}] tx ${msg.txid} not found in chronik, marking as orphaned`) + await markTransactionsOrphaned(msg.txid) + } else { + console.error(`${this.CHRONIK_MSG_PREFIX}: confirmed tx handler failed for ${msg.txid}`, e) + } } } else if (msg.msgType === 'TX_ADDED_TO_MEMPOOL') { if (this.isAlreadyBeingProcessed(msg.txid, false)) return diff --git a/services/transactionService.ts b/services/transactionService.ts index b9e534d8..51f6a4ad 100644 --- a/services/transactionService.ts +++ b/services/transactionService.ts @@ -629,6 +629,17 @@ export async function deleteTransactions (transactions: TransactionWithAddressAn )) } +export async function markTransactionsOrphaned (hash: string): Promise { + await prisma.transaction.updateMany({ + where: { + hash + }, + data: { + orphaned: true + } + }) +} + async function fetchAllTransactionsWithNoPrices (): Promise { const x = await prisma.transaction.findMany({ where: {