UNPKG

@bsv/wallet-toolbox

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

119 lines 5.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BulkIngestorBase = void 0; const HeightRange_1 = require("../util/HeightRange"); class BulkIngestorBase { /** * * @param chain * @param localCachePath defaults to './data/ingest_headers/' * @returns */ static createBulkIngestorBaseOptions(chain) { const options = { chain, jsonResource: `${chain}NetBlockHeaders.json` }; return options; } constructor(options) { this.log = () => { }; if (!options.jsonResource) throw new Error('The jsonFilename options property is required.'); this.chain = options.chain; this.jsonFilename = options.jsonResource; } async setStorage(storage, log) { this.storageEngine = storage; this.log = log; } async shutdown() { } storageOrUndefined() { return this.storageEngine; } storage() { if (!this.storageEngine) throw new Error('storageEngine must be set.'); return this.storageEngine; } /** * At least one derived BulkIngestor must override this method to provide the current height of the active chain tip. * @returns undefined unless overridden */ async getPresentHeight() { return undefined; } /** * A BulkIngestor has two potential goals: * 1. To source missing bulk headers and include them in bulk storage. * 2. To source missing live headers to be forwarded to live storage. * * @param presentHeight current height of the active chain tip, may lag the true value. * @param before current bulk and live storage height ranges, either may be empty. * @param priorLiveHeaders any headers accumulated by prior bulk ingestor(s) that are too recent for bulk storage. * @returns updated priorLiveHeaders including any accumulated by this ingestor */ async synchronize(presentHeight, before, priorLiveHeaders) { const storage = this.storage(); const r = { liveHeaders: priorLiveHeaders, liveRange: HeightRange_1.HeightRange.from(priorLiveHeaders), done: false, log: '' }; // Decisions to be made: // Q1. Are we already done? // Q2. Are there live headers that should be migrated to bulk? // Q3. What range of headers do we still need to retrieve? // Q1: We are done if we have enough live headers and they include presentHeight. const currentFullRange = before.bulk.union(before.live); if (currentFullRange.maxHeight >= presentHeight) { r.done = true; return r; } const targetBulkRange = new HeightRange_1.HeightRange(0, Math.max(0, presentHeight - storage.liveHeightThreshold)); let missingBulkRange = targetBulkRange.subtract(before.bulk); const updateMissingBulkRange = async () => { before = await storage.getAvailableHeightRanges(); missingBulkRange = targetBulkRange.subtract(before.bulk); }; // Q2: If missingBulkRange isn't empty and there are live headers in storage, // migrate from existing live headers in excess of reorgHeightThreshold. if (!missingBulkRange.isEmpty && !before.live.isEmpty) { const countToMigrate = Math.min(missingBulkRange.length, Math.max(0, before.live.length - storage.reorgHeightThreshold)); r.log += `Migrating ${countToMigrate} live headers to bulk storage.\n`; await storage.migrateLiveToBulk(countToMigrate); await updateMissingBulkRange(); if (!missingBulkRange.isEmpty) { // If there are still missing bulk headers, MUST flush live storage. const countToFlush = before.live.length; r.log += `Flushing ${countToFlush} live headers from live storage.\n`; await storage.deleteLiveBlockHeaders(); await updateMissingBulkRange(); } } const targetFullRange = new HeightRange_1.HeightRange(0, presentHeight); // Q3: What to fetch... let rangeToFetch; if (missingBulkRange.isEmpty) { // If there are no missing bulk headers, we don't need existing bulk range. rangeToFetch = targetFullRange.subtract(before.bulk); // And if there are live headers in excess of reorgHeightThreshold, they can be skipped as well. if (before.live.length > storage.reorgHeightThreshold) { rangeToFetch = rangeToFetch.subtract(new HeightRange_1.HeightRange(before.live.minHeight, before.live.maxHeight - storage.reorgHeightThreshold)); } } else { // If there are missing bulk headers, ingest from start of missing through present height. rangeToFetch = new HeightRange_1.HeightRange(missingBulkRange.minHeight, presentHeight); } const newLiveHeaders = await this.fetchHeaders(before, rangeToFetch, missingBulkRange, priorLiveHeaders); await updateMissingBulkRange(); r.liveHeaders = newLiveHeaders; r.liveRange = HeightRange_1.HeightRange.from(r.liveHeaders); r.done = missingBulkRange.isEmpty && r.liveRange.maxHeight >= presentHeight; return r; } } exports.BulkIngestorBase = BulkIngestorBase; //# sourceMappingURL=BulkIngestorBase.js.map