UNPKG

@bsv/wallet-toolbox-client

Version:
82 lines 3.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaskReorg = void 0; const Monitor_1 = require("../Monitor"); const WalletMonitorTask_1 = require("./WalletMonitorTask"); /** * Check the `monitor.deactivatedHeaders` for any headers that have been deactivated. * * When headers are found, review matching ProvenTx records and update proof data as appropriate. * * New deactivated headers are pushed onto the `deactivatedHeaders` array. * They must be shifted out as they are processed. * * The current implementation ages deactivation notifications by 10 minutes with each retry. * If a successful proof update confirms original proof data after 3 retries, the original is retained. * * In normal operation there should rarely be any work for this task to perform. * The most common result is that there are no matching proven_txs records because * generating new proven_txs records intentionally lags new block generation to * minimize this disruption. * * It is very disruptive to update a proven_txs record because: * - Sync'ed storage is impacted. * - Generated beefs are impacted. * - Updated proof data may be unavailable at the time a reorg is first reported. * * Proper reorg handling also requires repairing invalid beefs for new transactions when * createAction fails to verify a generated beef against the chaintracker. */ class TaskReorg extends WalletMonitorTask_1.WalletMonitorTask { constructor(monitor, agedMsecs = Monitor_1.Monitor.oneMinute * 10, maxRetries = 3) { super(monitor, TaskReorg.taskName); this.agedMsecs = agedMsecs; this.maxRetries = maxRetries; this.process = []; } /** * Shift aged deactivated headers onto `process` array. * @param nowMsecsSinceEpoch current time in milliseconds since epoch. * @returns `run` true iff there are aged deactivated headers to process. */ trigger(nowMsecsSinceEpoch) { const cutoff = nowMsecsSinceEpoch - this.agedMsecs; const q = this.monitor.deactivatedHeaders; while (q.length > 0 && cutoff > q[0].whenMsecs) { // Prepare to process deactivated headers that have aged sufficiently (agedMsecs) const header = q.shift(); this.process.push(header); } return { run: this.process.length > 0 }; } async runTask() { let log = ''; for (;;) { // Loop over deactivated headers to process const header = this.process.shift(); if (!header) break; const r = await this.storage.reproveHeader(header.header.hash); log += r.log; if (r.unavailable.length > 0 || r.unchanged.length > 0) { if (header.tries + 1 >= this.maxRetries) { log += ` maximum retries ${this.maxRetries} exceeded\n`; } else { log += ` retrying...\n`; this.monitor.deactivatedHeaders.push({ header: header.header, whenMsecs: Date.now(), tries: header.tries + 1 }); } } } return log; } } exports.TaskReorg = TaskReorg; TaskReorg.taskName = 'Reorg'; //# sourceMappingURL=TaskReorg.js.map