@bsv/wallet-toolbox 1.6.14 → 1.6.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/client.md +123 -93
- package/docs/services.md +123 -93
- package/docs/wallet.md +123 -93
- package/mobile/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/Chaintracks.js +125 -109
- package/mobile/out/src/services/chaintracker/chaintracks/Chaintracks.js.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts +16 -4
- package/mobile/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +65 -45
- package/mobile/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js.map +1 -1
- package/mobile/package-lock.json +2 -2
- package/mobile/package.json +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts +1 -0
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js +125 -109
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts +16 -4
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +65 -45
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/services/chaintracker/chaintracks/Chaintracks.ts +124 -109
- package/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts +75 -50
package/docs/client.md
CHANGED
|
@@ -8516,10 +8516,15 @@ export class BulkFileDataManager {
|
|
|
8516
8516
|
readonly maxRetained?: number;
|
|
8517
8517
|
readonly fromKnownSourceUrl?: string;
|
|
8518
8518
|
constructor(options: BulkFileDataManagerOptions | Chain)
|
|
8519
|
+
async deleteBulkFiles(): Promise<void>
|
|
8520
|
+
async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void>
|
|
8521
|
+
heightRangesFromBulkFiles(files: BulkHeaderFileInfo[]): {
|
|
8522
|
+
all: HeightRange;
|
|
8523
|
+
cdn: HeightRange;
|
|
8524
|
+
incremental: HeightRange;
|
|
8525
|
+
}
|
|
8519
8526
|
async createReader(range?: HeightRange, maxBufferSize?: number): Promise<BulkFileDataReader>
|
|
8520
8527
|
async updateFromUrl(cdnUrl: string): Promise<void>
|
|
8521
|
-
async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void>
|
|
8522
|
-
async deleteBulkFiles(): Promise<void>
|
|
8523
8528
|
async merge(files: BulkHeaderFileInfo[]): Promise<BulkFileDataManagerMergeResult>
|
|
8524
8529
|
toLogString(what?: BulkFileDataManagerMergeResult | BulkFileData[] | BulkHeaderFileInfo[]): string
|
|
8525
8530
|
async mergeIncrementalBlockHeaders(newBulkHeaders: BlockHeader[], incrementalChainWork?: string): Promise<void>
|
|
@@ -8536,6 +8541,19 @@ export class BulkFileDataManager {
|
|
|
8536
8541
|
|
|
8537
8542
|
See also: [BlockHeader](./client.md#interface-blockheader), [BulkFileDataManagerMergeResult](./services.md#interface-bulkfiledatamanagermergeresult), [BulkFileDataManagerOptions](./services.md#interface-bulkfiledatamanageroptions), [BulkFileDataReader](./services.md#class-bulkfiledatareader), [BulkHeaderFileInfo](./services.md#interface-bulkheaderfileinfo), [Chain](./client.md#type-chain), [ChaintracksFetchApi](./services.md#interface-chaintracksfetchapi), [ChaintracksFsApi](./services.md#interface-chaintracksfsapi), [ChaintracksStorageBulkFileApi](./services.md#interface-chaintracksstoragebulkfileapi), [HeightRange](./services.md#class-heightrange)
|
|
8538
8543
|
|
|
8544
|
+
###### Method setStorage
|
|
8545
|
+
|
|
8546
|
+
If `bfds` are going to be backed by persistent storage,
|
|
8547
|
+
must be called before making storage available.
|
|
8548
|
+
|
|
8549
|
+
Synchronizes bfds and storage files, after which this manager maintains sync.
|
|
8550
|
+
There should be no changes to bulk files by direct access to storage bulk file methods.
|
|
8551
|
+
|
|
8552
|
+
```ts
|
|
8553
|
+
async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void>
|
|
8554
|
+
```
|
|
8555
|
+
See also: [ChaintracksStorageBulkFileApi](./services.md#interface-chaintracksstoragebulkfileapi)
|
|
8556
|
+
|
|
8539
8557
|
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
|
|
8540
8558
|
|
|
8541
8559
|
---
|
|
@@ -9404,130 +9422,142 @@ export class Chaintracks implements ChaintracksManagementApi {
|
|
|
9404
9422
|
const cdnSyncRepeatMsecs = 24 * 60 * 60 * 1000;
|
|
9405
9423
|
const syncCheckRepeatMsecs = 30 * 60 * 1000;
|
|
9406
9424
|
while (!this.stopMainThread) {
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
skipBulkSync
|
|
9414
|
-
|
|
9415
|
-
|
|
9425
|
+
try {
|
|
9426
|
+
const now = Date.now();
|
|
9427
|
+
lastSyncCheck = now;
|
|
9428
|
+
const presentHeight = await this.getPresentHeight();
|
|
9429
|
+
const before = await this.storage.getAvailableHeightRanges();
|
|
9430
|
+
let skipBulkSync = !before.live.isEmpty && before.live.maxHeight >= presentHeight - this.addLiveRecursionLimit / 2;
|
|
9431
|
+
if (skipBulkSync && now - lastSyncCheck > cdnSyncRepeatMsecs) {
|
|
9432
|
+
skipBulkSync = false;
|
|
9433
|
+
}
|
|
9434
|
+
this.log(`Chaintracks Update Services: Bulk Header Sync Review
|
|
9416
9435
|
presentHeight=${presentHeight} addLiveRecursionLimit=${this.addLiveRecursionLimit}
|
|
9417
9436
|
Before synchronize: bulk ${before.bulk}, live ${before.live}
|
|
9418
9437
|
${skipBulkSync ? "Skipping" : "Starting"} syncBulkStorage.
|
|
9419
9438
|
`);
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
needSyncCheck = true;
|
|
9439
|
-
}
|
|
9440
|
-
else if (ihr.noPrev) {
|
|
9441
|
-
if (recursions-- <= 0) {
|
|
9442
|
-
this.log(`Ignoring liveHeader ${header.height} ${header.hash} addLiveRecursionLimit=${this.addLiveRecursionLimit} exceeded.`);
|
|
9439
|
+
if (!skipBulkSync) {
|
|
9440
|
+
lastBulkSync = now;
|
|
9441
|
+
if (this.available)
|
|
9442
|
+
await this.syncBulkStorage(presentHeight, before);
|
|
9443
|
+
else
|
|
9444
|
+
await this.syncBulkStorageNoLock(presentHeight, before);
|
|
9445
|
+
}
|
|
9446
|
+
let count = 0;
|
|
9447
|
+
let liveHeaderDupes = 0;
|
|
9448
|
+
let needSyncCheck = false;
|
|
9449
|
+
for (; !needSyncCheck && !this.stopMainThread;) {
|
|
9450
|
+
let header = this.liveHeaders.shift();
|
|
9451
|
+
if (header) {
|
|
9452
|
+
let recursions = this.addLiveRecursionLimit;
|
|
9453
|
+
for (; !needSyncCheck && !this.stopMainThread;) {
|
|
9454
|
+
const ihr = await this.addLiveHeader(header);
|
|
9455
|
+
if (this.invalidInsertHeaderResult(ihr)) {
|
|
9456
|
+
this.log(`Ignoring liveHeader ${header.height} ${header.hash} due to invalid insert result.`);
|
|
9443
9457
|
needSyncCheck = true;
|
|
9444
9458
|
}
|
|
9445
|
-
else {
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
if (!prevHeader) {
|
|
9449
|
-
this.log(`Ignoring liveHeader ${header.height} ${header.hash} failed to find previous header by hash ${asString(hash)}`);
|
|
9459
|
+
else if (ihr.noPrev) {
|
|
9460
|
+
if (recursions-- <= 0) {
|
|
9461
|
+
this.log(`Ignoring liveHeader ${header.height} ${header.hash} addLiveRecursionLimit=${this.addLiveRecursionLimit} exceeded.`);
|
|
9450
9462
|
needSyncCheck = true;
|
|
9451
9463
|
}
|
|
9452
9464
|
else {
|
|
9453
|
-
|
|
9454
|
-
|
|
9465
|
+
const hash = header.previousHash;
|
|
9466
|
+
const prevHeader = await this.getMissingBlockHeader(hash);
|
|
9467
|
+
if (!prevHeader) {
|
|
9468
|
+
this.log(`Ignoring liveHeader ${header.height} ${header.hash} failed to find previous header by hash ${asString(hash)}`);
|
|
9469
|
+
needSyncCheck = true;
|
|
9470
|
+
}
|
|
9471
|
+
else {
|
|
9472
|
+
this.liveHeaders.unshift(header);
|
|
9473
|
+
header = prevHeader;
|
|
9474
|
+
}
|
|
9455
9475
|
}
|
|
9456
9476
|
}
|
|
9457
|
-
}
|
|
9458
|
-
else {
|
|
9459
|
-
if (this.subscriberCallbacksEnabled)
|
|
9460
|
-
this.log(`addLiveHeader ${header.height}${ihr.added ? " added" : ""}${ihr.dupe ? " dupe" : ""}${ihr.isActiveTip ? " isActiveTip" : ""}${ihr.reorgDepth ? " reorg depth " + ihr.reorgDepth : ""}${ihr.noPrev ? " noPrev" : ""}${ihr.noActiveAncestor || ihr.noTip || ihr.badPrev ? " error" : ""}`);
|
|
9461
|
-
if (ihr.dupe) {
|
|
9462
|
-
liveHeaderDupes++;
|
|
9463
|
-
}
|
|
9464
|
-
if (ihr.added) {
|
|
9465
|
-
count++;
|
|
9466
|
-
}
|
|
9467
|
-
break;
|
|
9468
|
-
}
|
|
9469
|
-
}
|
|
9470
|
-
}
|
|
9471
|
-
else {
|
|
9472
|
-
const bheader = this.baseHeaders.shift();
|
|
9473
|
-
if (bheader) {
|
|
9474
|
-
const prev = await this.storage.findLiveHeaderForBlockHash(bheader.previousHash);
|
|
9475
|
-
if (!prev) {
|
|
9476
|
-
this.log(`Ignoring header with unknown previousHash ${bheader.previousHash} in live storage.`);
|
|
9477
|
-
}
|
|
9478
|
-
else {
|
|
9479
|
-
const header: BlockHeader = {
|
|
9480
|
-
...bheader,
|
|
9481
|
-
height: prev.height + 1,
|
|
9482
|
-
hash: blockHash(bheader)
|
|
9483
|
-
};
|
|
9484
|
-
const ihr = await this.addLiveHeader(header);
|
|
9485
|
-
if (this.invalidInsertHeaderResult(ihr)) {
|
|
9486
|
-
this.log(`Ignoring invalid baseHeader ${header.height} ${header.hash}.`);
|
|
9487
|
-
}
|
|
9488
9477
|
else {
|
|
9489
9478
|
if (this.subscriberCallbacksEnabled)
|
|
9490
|
-
this.log(`
|
|
9479
|
+
this.log(`addLiveHeader ${header.height}${ihr.added ? " added" : ""}${ihr.dupe ? " dupe" : ""}${ihr.isActiveTip ? " isActiveTip" : ""}${ihr.reorgDepth ? " reorg depth " + ihr.reorgDepth : ""}${ihr.noPrev ? " noPrev" : ""}${ihr.noActiveAncestor || ihr.noTip || ihr.badPrev ? " error" : ""}`);
|
|
9480
|
+
if (ihr.dupe) {
|
|
9481
|
+
liveHeaderDupes++;
|
|
9482
|
+
}
|
|
9491
9483
|
if (ihr.added) {
|
|
9492
9484
|
count++;
|
|
9493
9485
|
}
|
|
9486
|
+
break;
|
|
9494
9487
|
}
|
|
9495
9488
|
}
|
|
9496
9489
|
}
|
|
9497
9490
|
else {
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9491
|
+
const bheader = this.baseHeaders.shift();
|
|
9492
|
+
if (bheader) {
|
|
9493
|
+
const prev = await this.storage.findLiveHeaderForBlockHash(bheader.previousHash);
|
|
9494
|
+
if (!prev) {
|
|
9495
|
+
this.log(`Ignoring header with unknown previousHash ${bheader.previousHash} in live storage.`);
|
|
9496
|
+
}
|
|
9497
|
+
else {
|
|
9498
|
+
const header: BlockHeader = {
|
|
9499
|
+
...bheader,
|
|
9500
|
+
height: prev.height + 1,
|
|
9501
|
+
hash: blockHash(bheader)
|
|
9502
|
+
};
|
|
9503
|
+
const ihr = await this.addLiveHeader(header);
|
|
9504
|
+
if (this.invalidInsertHeaderResult(ihr)) {
|
|
9505
|
+
this.log(`Ignoring invalid baseHeader ${header.height} ${header.hash}.`);
|
|
9506
|
+
}
|
|
9507
|
+
else {
|
|
9508
|
+
if (this.subscriberCallbacksEnabled)
|
|
9509
|
+
this.log(`addBaseHeader ${header.height}${ihr.added ? " added" : ""}${ihr.dupe ? " dupe" : ""}${ihr.isActiveTip ? " isActiveTip" : ""}${ihr.reorgDepth ? " reorg depth " + ihr.reorgDepth : ""}${ihr.noPrev ? " noPrev" : ""}${ihr.noActiveAncestor || ihr.noTip || ihr.badPrev ? " error" : ""}`);
|
|
9510
|
+
if (ihr.added) {
|
|
9511
|
+
count++;
|
|
9512
|
+
}
|
|
9513
|
+
}
|
|
9502
9514
|
}
|
|
9503
|
-
|
|
9504
|
-
|
|
9515
|
+
}
|
|
9516
|
+
else {
|
|
9517
|
+
if (count > 0) {
|
|
9518
|
+
if (liveHeaderDupes > 0) {
|
|
9519
|
+
this.log(`${liveHeaderDupes} duplicate headers ignored.`);
|
|
9520
|
+
liveHeaderDupes = 0;
|
|
9521
|
+
}
|
|
9522
|
+
const updated = await this.storage.getAvailableHeightRanges();
|
|
9523
|
+
this.log(`After adding ${count} live headers
|
|
9505
9524
|
After live: bulk ${updated.bulk}, live ${updated.live}
|
|
9506
9525
|
`);
|
|
9507
|
-
|
|
9508
|
-
}
|
|
9509
|
-
if (!this.subscriberCallbacksEnabled) {
|
|
9510
|
-
const live = await this.storage.findLiveHeightRange();
|
|
9511
|
-
if (!live.isEmpty) {
|
|
9512
|
-
this.subscriberCallbacksEnabled = true;
|
|
9513
|
-
this.log(`listening at height of ${live.maxHeight}`);
|
|
9526
|
+
count = 0;
|
|
9514
9527
|
}
|
|
9528
|
+
if (!this.subscriberCallbacksEnabled) {
|
|
9529
|
+
const live = await this.storage.findLiveHeightRange();
|
|
9530
|
+
if (!live.isEmpty) {
|
|
9531
|
+
this.subscriberCallbacksEnabled = true;
|
|
9532
|
+
this.log(`listening at height of ${live.maxHeight}`);
|
|
9533
|
+
}
|
|
9534
|
+
}
|
|
9535
|
+
if (!this.available) {
|
|
9536
|
+
this.available = true;
|
|
9537
|
+
}
|
|
9538
|
+
needSyncCheck = Date.now() - lastSyncCheck > syncCheckRepeatMsecs;
|
|
9539
|
+
if (!needSyncCheck)
|
|
9540
|
+
await wait(1000);
|
|
9515
9541
|
}
|
|
9516
|
-
if (!this.available) {
|
|
9517
|
-
this.available = true;
|
|
9518
|
-
}
|
|
9519
|
-
needSyncCheck = Date.now() - lastSyncCheck > syncCheckRepeatMsecs;
|
|
9520
|
-
if (!needSyncCheck)
|
|
9521
|
-
await wait(1000);
|
|
9522
9542
|
}
|
|
9523
9543
|
}
|
|
9524
9544
|
}
|
|
9545
|
+
catch (eu: unknown) {
|
|
9546
|
+
const e = WalletError.fromUnknown(eu);
|
|
9547
|
+
if (!this.available) {
|
|
9548
|
+
this.startupError = e;
|
|
9549
|
+
this.stopMainThread = true;
|
|
9550
|
+
}
|
|
9551
|
+
else {
|
|
9552
|
+
this.log(`Error occurred during chaintracks main thread processing: ${e.stack || e.message}`);
|
|
9553
|
+
}
|
|
9554
|
+
}
|
|
9525
9555
|
}
|
|
9526
9556
|
}
|
|
9527
9557
|
}
|
|
9528
9558
|
```
|
|
9529
9559
|
|
|
9530
|
-
See also: [BaseBlockHeader](./client.md#interface-baseblockheader), [BlockHeader](./client.md#interface-blockheader), [Chain](./client.md#type-chain), [ChaintracksFsApi](./services.md#interface-chaintracksfsapi), [ChaintracksInfoApi](./services.md#interface-chaintracksinfoapi), [ChaintracksManagementApi](./services.md#interface-chaintracksmanagementapi), [ChaintracksOptions](./services.md#interface-chaintracksoptions), [HeaderListener](./services.md#type-headerlistener), [HeightRange](./services.md#class-heightrange), [HeightRanges](./services.md#interface-heightranges), [LiveBlockHeader](./services.md#interface-liveblockheader), [ReorgListener](./services.md#type-reorglistener), [Services](./services.md#class-services), [asString](./client.md#function-asstring), [blockHash](./services.md#function-blockhash), [wait](./client.md#function-wait)
|
|
9560
|
+
See also: [BaseBlockHeader](./client.md#interface-baseblockheader), [BlockHeader](./client.md#interface-blockheader), [Chain](./client.md#type-chain), [ChaintracksFsApi](./services.md#interface-chaintracksfsapi), [ChaintracksInfoApi](./services.md#interface-chaintracksinfoapi), [ChaintracksManagementApi](./services.md#interface-chaintracksmanagementapi), [ChaintracksOptions](./services.md#interface-chaintracksoptions), [HeaderListener](./services.md#type-headerlistener), [HeightRange](./services.md#class-heightrange), [HeightRanges](./services.md#interface-heightranges), [LiveBlockHeader](./services.md#interface-liveblockheader), [ReorgListener](./services.md#type-reorglistener), [Services](./services.md#class-services), [WalletError](./client.md#class-walleterror), [asString](./client.md#function-asstring), [blockHash](./services.md#function-blockhash), [wait](./client.md#function-wait)
|
|
9531
9561
|
|
|
9532
9562
|
###### Method addHeader
|
|
9533
9563
|
|
package/docs/services.md
CHANGED
|
@@ -2835,10 +2835,15 @@ export class BulkFileDataManager {
|
|
|
2835
2835
|
readonly maxRetained?: number;
|
|
2836
2836
|
readonly fromKnownSourceUrl?: string;
|
|
2837
2837
|
constructor(options: BulkFileDataManagerOptions | Chain)
|
|
2838
|
+
async deleteBulkFiles(): Promise<void>
|
|
2839
|
+
async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void>
|
|
2840
|
+
heightRangesFromBulkFiles(files: BulkHeaderFileInfo[]): {
|
|
2841
|
+
all: HeightRange;
|
|
2842
|
+
cdn: HeightRange;
|
|
2843
|
+
incremental: HeightRange;
|
|
2844
|
+
}
|
|
2838
2845
|
async createReader(range?: HeightRange, maxBufferSize?: number): Promise<BulkFileDataReader>
|
|
2839
2846
|
async updateFromUrl(cdnUrl: string): Promise<void>
|
|
2840
|
-
async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void>
|
|
2841
|
-
async deleteBulkFiles(): Promise<void>
|
|
2842
2847
|
async merge(files: BulkHeaderFileInfo[]): Promise<BulkFileDataManagerMergeResult>
|
|
2843
2848
|
toLogString(what?: BulkFileDataManagerMergeResult | BulkFileData[] | BulkHeaderFileInfo[]): string
|
|
2844
2849
|
async mergeIncrementalBlockHeaders(newBulkHeaders: BlockHeader[], incrementalChainWork?: string): Promise<void>
|
|
@@ -2855,6 +2860,19 @@ export class BulkFileDataManager {
|
|
|
2855
2860
|
|
|
2856
2861
|
See also: [BlockHeader](./client.md#interface-blockheader), [BulkFileDataManagerMergeResult](./services.md#interface-bulkfiledatamanagermergeresult), [BulkFileDataManagerOptions](./services.md#interface-bulkfiledatamanageroptions), [BulkFileDataReader](./services.md#class-bulkfiledatareader), [BulkHeaderFileInfo](./services.md#interface-bulkheaderfileinfo), [Chain](./client.md#type-chain), [ChaintracksFetchApi](./services.md#interface-chaintracksfetchapi), [ChaintracksFsApi](./services.md#interface-chaintracksfsapi), [ChaintracksStorageBulkFileApi](./services.md#interface-chaintracksstoragebulkfileapi), [HeightRange](./services.md#class-heightrange)
|
|
2857
2862
|
|
|
2863
|
+
###### Method setStorage
|
|
2864
|
+
|
|
2865
|
+
If `bfds` are going to be backed by persistent storage,
|
|
2866
|
+
must be called before making storage available.
|
|
2867
|
+
|
|
2868
|
+
Synchronizes bfds and storage files, after which this manager maintains sync.
|
|
2869
|
+
There should be no changes to bulk files by direct access to storage bulk file methods.
|
|
2870
|
+
|
|
2871
|
+
```ts
|
|
2872
|
+
async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void>
|
|
2873
|
+
```
|
|
2874
|
+
See also: [ChaintracksStorageBulkFileApi](./services.md#interface-chaintracksstoragebulkfileapi)
|
|
2875
|
+
|
|
2858
2876
|
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
|
|
2859
2877
|
|
|
2860
2878
|
---
|
|
@@ -3481,130 +3499,142 @@ export class Chaintracks implements ChaintracksManagementApi {
|
|
|
3481
3499
|
const cdnSyncRepeatMsecs = 24 * 60 * 60 * 1000;
|
|
3482
3500
|
const syncCheckRepeatMsecs = 30 * 60 * 1000;
|
|
3483
3501
|
while (!this.stopMainThread) {
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
skipBulkSync
|
|
3491
|
-
|
|
3492
|
-
|
|
3502
|
+
try {
|
|
3503
|
+
const now = Date.now();
|
|
3504
|
+
lastSyncCheck = now;
|
|
3505
|
+
const presentHeight = await this.getPresentHeight();
|
|
3506
|
+
const before = await this.storage.getAvailableHeightRanges();
|
|
3507
|
+
let skipBulkSync = !before.live.isEmpty && before.live.maxHeight >= presentHeight - this.addLiveRecursionLimit / 2;
|
|
3508
|
+
if (skipBulkSync && now - lastSyncCheck > cdnSyncRepeatMsecs) {
|
|
3509
|
+
skipBulkSync = false;
|
|
3510
|
+
}
|
|
3511
|
+
this.log(`Chaintracks Update Services: Bulk Header Sync Review
|
|
3493
3512
|
presentHeight=${presentHeight} addLiveRecursionLimit=${this.addLiveRecursionLimit}
|
|
3494
3513
|
Before synchronize: bulk ${before.bulk}, live ${before.live}
|
|
3495
3514
|
${skipBulkSync ? "Skipping" : "Starting"} syncBulkStorage.
|
|
3496
3515
|
`);
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
needSyncCheck = true;
|
|
3516
|
-
}
|
|
3517
|
-
else if (ihr.noPrev) {
|
|
3518
|
-
if (recursions-- <= 0) {
|
|
3519
|
-
this.log(`Ignoring liveHeader ${header.height} ${header.hash} addLiveRecursionLimit=${this.addLiveRecursionLimit} exceeded.`);
|
|
3516
|
+
if (!skipBulkSync) {
|
|
3517
|
+
lastBulkSync = now;
|
|
3518
|
+
if (this.available)
|
|
3519
|
+
await this.syncBulkStorage(presentHeight, before);
|
|
3520
|
+
else
|
|
3521
|
+
await this.syncBulkStorageNoLock(presentHeight, before);
|
|
3522
|
+
}
|
|
3523
|
+
let count = 0;
|
|
3524
|
+
let liveHeaderDupes = 0;
|
|
3525
|
+
let needSyncCheck = false;
|
|
3526
|
+
for (; !needSyncCheck && !this.stopMainThread;) {
|
|
3527
|
+
let header = this.liveHeaders.shift();
|
|
3528
|
+
if (header) {
|
|
3529
|
+
let recursions = this.addLiveRecursionLimit;
|
|
3530
|
+
for (; !needSyncCheck && !this.stopMainThread;) {
|
|
3531
|
+
const ihr = await this.addLiveHeader(header);
|
|
3532
|
+
if (this.invalidInsertHeaderResult(ihr)) {
|
|
3533
|
+
this.log(`Ignoring liveHeader ${header.height} ${header.hash} due to invalid insert result.`);
|
|
3520
3534
|
needSyncCheck = true;
|
|
3521
3535
|
}
|
|
3522
|
-
else {
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
if (!prevHeader) {
|
|
3526
|
-
this.log(`Ignoring liveHeader ${header.height} ${header.hash} failed to find previous header by hash ${asString(hash)}`);
|
|
3536
|
+
else if (ihr.noPrev) {
|
|
3537
|
+
if (recursions-- <= 0) {
|
|
3538
|
+
this.log(`Ignoring liveHeader ${header.height} ${header.hash} addLiveRecursionLimit=${this.addLiveRecursionLimit} exceeded.`);
|
|
3527
3539
|
needSyncCheck = true;
|
|
3528
3540
|
}
|
|
3529
3541
|
else {
|
|
3530
|
-
|
|
3531
|
-
|
|
3542
|
+
const hash = header.previousHash;
|
|
3543
|
+
const prevHeader = await this.getMissingBlockHeader(hash);
|
|
3544
|
+
if (!prevHeader) {
|
|
3545
|
+
this.log(`Ignoring liveHeader ${header.height} ${header.hash} failed to find previous header by hash ${asString(hash)}`);
|
|
3546
|
+
needSyncCheck = true;
|
|
3547
|
+
}
|
|
3548
|
+
else {
|
|
3549
|
+
this.liveHeaders.unshift(header);
|
|
3550
|
+
header = prevHeader;
|
|
3551
|
+
}
|
|
3532
3552
|
}
|
|
3533
3553
|
}
|
|
3534
|
-
}
|
|
3535
|
-
else {
|
|
3536
|
-
if (this.subscriberCallbacksEnabled)
|
|
3537
|
-
this.log(`addLiveHeader ${header.height}${ihr.added ? " added" : ""}${ihr.dupe ? " dupe" : ""}${ihr.isActiveTip ? " isActiveTip" : ""}${ihr.reorgDepth ? " reorg depth " + ihr.reorgDepth : ""}${ihr.noPrev ? " noPrev" : ""}${ihr.noActiveAncestor || ihr.noTip || ihr.badPrev ? " error" : ""}`);
|
|
3538
|
-
if (ihr.dupe) {
|
|
3539
|
-
liveHeaderDupes++;
|
|
3540
|
-
}
|
|
3541
|
-
if (ihr.added) {
|
|
3542
|
-
count++;
|
|
3543
|
-
}
|
|
3544
|
-
break;
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
}
|
|
3548
|
-
else {
|
|
3549
|
-
const bheader = this.baseHeaders.shift();
|
|
3550
|
-
if (bheader) {
|
|
3551
|
-
const prev = await this.storage.findLiveHeaderForBlockHash(bheader.previousHash);
|
|
3552
|
-
if (!prev) {
|
|
3553
|
-
this.log(`Ignoring header with unknown previousHash ${bheader.previousHash} in live storage.`);
|
|
3554
|
-
}
|
|
3555
|
-
else {
|
|
3556
|
-
const header: BlockHeader = {
|
|
3557
|
-
...bheader,
|
|
3558
|
-
height: prev.height + 1,
|
|
3559
|
-
hash: blockHash(bheader)
|
|
3560
|
-
};
|
|
3561
|
-
const ihr = await this.addLiveHeader(header);
|
|
3562
|
-
if (this.invalidInsertHeaderResult(ihr)) {
|
|
3563
|
-
this.log(`Ignoring invalid baseHeader ${header.height} ${header.hash}.`);
|
|
3564
|
-
}
|
|
3565
3554
|
else {
|
|
3566
3555
|
if (this.subscriberCallbacksEnabled)
|
|
3567
|
-
this.log(`
|
|
3556
|
+
this.log(`addLiveHeader ${header.height}${ihr.added ? " added" : ""}${ihr.dupe ? " dupe" : ""}${ihr.isActiveTip ? " isActiveTip" : ""}${ihr.reorgDepth ? " reorg depth " + ihr.reorgDepth : ""}${ihr.noPrev ? " noPrev" : ""}${ihr.noActiveAncestor || ihr.noTip || ihr.badPrev ? " error" : ""}`);
|
|
3557
|
+
if (ihr.dupe) {
|
|
3558
|
+
liveHeaderDupes++;
|
|
3559
|
+
}
|
|
3568
3560
|
if (ihr.added) {
|
|
3569
3561
|
count++;
|
|
3570
3562
|
}
|
|
3563
|
+
break;
|
|
3571
3564
|
}
|
|
3572
3565
|
}
|
|
3573
3566
|
}
|
|
3574
3567
|
else {
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3568
|
+
const bheader = this.baseHeaders.shift();
|
|
3569
|
+
if (bheader) {
|
|
3570
|
+
const prev = await this.storage.findLiveHeaderForBlockHash(bheader.previousHash);
|
|
3571
|
+
if (!prev) {
|
|
3572
|
+
this.log(`Ignoring header with unknown previousHash ${bheader.previousHash} in live storage.`);
|
|
3573
|
+
}
|
|
3574
|
+
else {
|
|
3575
|
+
const header: BlockHeader = {
|
|
3576
|
+
...bheader,
|
|
3577
|
+
height: prev.height + 1,
|
|
3578
|
+
hash: blockHash(bheader)
|
|
3579
|
+
};
|
|
3580
|
+
const ihr = await this.addLiveHeader(header);
|
|
3581
|
+
if (this.invalidInsertHeaderResult(ihr)) {
|
|
3582
|
+
this.log(`Ignoring invalid baseHeader ${header.height} ${header.hash}.`);
|
|
3583
|
+
}
|
|
3584
|
+
else {
|
|
3585
|
+
if (this.subscriberCallbacksEnabled)
|
|
3586
|
+
this.log(`addBaseHeader ${header.height}${ihr.added ? " added" : ""}${ihr.dupe ? " dupe" : ""}${ihr.isActiveTip ? " isActiveTip" : ""}${ihr.reorgDepth ? " reorg depth " + ihr.reorgDepth : ""}${ihr.noPrev ? " noPrev" : ""}${ihr.noActiveAncestor || ihr.noTip || ihr.badPrev ? " error" : ""}`);
|
|
3587
|
+
if (ihr.added) {
|
|
3588
|
+
count++;
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3579
3591
|
}
|
|
3580
|
-
|
|
3581
|
-
|
|
3592
|
+
}
|
|
3593
|
+
else {
|
|
3594
|
+
if (count > 0) {
|
|
3595
|
+
if (liveHeaderDupes > 0) {
|
|
3596
|
+
this.log(`${liveHeaderDupes} duplicate headers ignored.`);
|
|
3597
|
+
liveHeaderDupes = 0;
|
|
3598
|
+
}
|
|
3599
|
+
const updated = await this.storage.getAvailableHeightRanges();
|
|
3600
|
+
this.log(`After adding ${count} live headers
|
|
3582
3601
|
After live: bulk ${updated.bulk}, live ${updated.live}
|
|
3583
3602
|
`);
|
|
3584
|
-
|
|
3585
|
-
}
|
|
3586
|
-
if (!this.subscriberCallbacksEnabled) {
|
|
3587
|
-
const live = await this.storage.findLiveHeightRange();
|
|
3588
|
-
if (!live.isEmpty) {
|
|
3589
|
-
this.subscriberCallbacksEnabled = true;
|
|
3590
|
-
this.log(`listening at height of ${live.maxHeight}`);
|
|
3603
|
+
count = 0;
|
|
3591
3604
|
}
|
|
3605
|
+
if (!this.subscriberCallbacksEnabled) {
|
|
3606
|
+
const live = await this.storage.findLiveHeightRange();
|
|
3607
|
+
if (!live.isEmpty) {
|
|
3608
|
+
this.subscriberCallbacksEnabled = true;
|
|
3609
|
+
this.log(`listening at height of ${live.maxHeight}`);
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
if (!this.available) {
|
|
3613
|
+
this.available = true;
|
|
3614
|
+
}
|
|
3615
|
+
needSyncCheck = Date.now() - lastSyncCheck > syncCheckRepeatMsecs;
|
|
3616
|
+
if (!needSyncCheck)
|
|
3617
|
+
await wait(1000);
|
|
3592
3618
|
}
|
|
3593
|
-
if (!this.available) {
|
|
3594
|
-
this.available = true;
|
|
3595
|
-
}
|
|
3596
|
-
needSyncCheck = Date.now() - lastSyncCheck > syncCheckRepeatMsecs;
|
|
3597
|
-
if (!needSyncCheck)
|
|
3598
|
-
await wait(1000);
|
|
3599
3619
|
}
|
|
3600
3620
|
}
|
|
3601
3621
|
}
|
|
3622
|
+
catch (eu: unknown) {
|
|
3623
|
+
const e = WalletError.fromUnknown(eu);
|
|
3624
|
+
if (!this.available) {
|
|
3625
|
+
this.startupError = e;
|
|
3626
|
+
this.stopMainThread = true;
|
|
3627
|
+
}
|
|
3628
|
+
else {
|
|
3629
|
+
this.log(`Error occurred during chaintracks main thread processing: ${e.stack || e.message}`);
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3602
3632
|
}
|
|
3603
3633
|
}
|
|
3604
3634
|
}
|
|
3605
3635
|
```
|
|
3606
3636
|
|
|
3607
|
-
See also: [BaseBlockHeader](./client.md#interface-baseblockheader), [BlockHeader](./client.md#interface-blockheader), [Chain](./client.md#type-chain), [ChaintracksFsApi](./services.md#interface-chaintracksfsapi), [ChaintracksInfoApi](./services.md#interface-chaintracksinfoapi), [ChaintracksManagementApi](./services.md#interface-chaintracksmanagementapi), [ChaintracksOptions](./services.md#interface-chaintracksoptions), [HeaderListener](./services.md#type-headerlistener), [HeightRange](./services.md#class-heightrange), [HeightRanges](./services.md#interface-heightranges), [LiveBlockHeader](./services.md#interface-liveblockheader), [ReorgListener](./services.md#type-reorglistener), [Services](./services.md#class-services), [asString](./client.md#function-asstring), [blockHash](./services.md#function-blockhash), [wait](./client.md#function-wait)
|
|
3637
|
+
See also: [BaseBlockHeader](./client.md#interface-baseblockheader), [BlockHeader](./client.md#interface-blockheader), [Chain](./client.md#type-chain), [ChaintracksFsApi](./services.md#interface-chaintracksfsapi), [ChaintracksInfoApi](./services.md#interface-chaintracksinfoapi), [ChaintracksManagementApi](./services.md#interface-chaintracksmanagementapi), [ChaintracksOptions](./services.md#interface-chaintracksoptions), [HeaderListener](./services.md#type-headerlistener), [HeightRange](./services.md#class-heightrange), [HeightRanges](./services.md#interface-heightranges), [LiveBlockHeader](./services.md#interface-liveblockheader), [ReorgListener](./services.md#type-reorglistener), [Services](./services.md#class-services), [WalletError](./client.md#class-walleterror), [asString](./client.md#function-asstring), [blockHash](./services.md#function-blockhash), [wait](./client.md#function-wait)
|
|
3608
3638
|
|
|
3609
3639
|
###### Method addHeader
|
|
3610
3640
|
|