@bsv/wallet-toolbox 2.1.9 → 2.1.11

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.
Files changed (120) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/docs/client.md +447 -170
  3. package/docs/monitor.md +153 -16
  4. package/docs/setup.md +4 -8
  5. package/docs/storage.md +37 -8
  6. package/docs/wallet.md +447 -170
  7. package/out/src/CWIStyleWalletManager.d.ts +57 -5
  8. package/out/src/CWIStyleWalletManager.d.ts.map +1 -1
  9. package/out/src/CWIStyleWalletManager.js +282 -46
  10. package/out/src/CWIStyleWalletManager.js.map +1 -1
  11. package/out/src/Setup.d.ts.map +1 -1
  12. package/out/src/Setup.js +1 -2
  13. package/out/src/Setup.js.map +1 -1
  14. package/out/src/SetupClient.d.ts.map +1 -1
  15. package/out/src/SetupClient.js +1 -2
  16. package/out/src/SetupClient.js.map +1 -1
  17. package/out/src/WalletAuthenticationManager.d.ts +1 -1
  18. package/out/src/WalletAuthenticationManager.d.ts.map +1 -1
  19. package/out/src/WalletAuthenticationManager.js +41 -31
  20. package/out/src/WalletAuthenticationManager.js.map +1 -1
  21. package/out/src/__tests/CWIStyleWalletManager.test.js +219 -10
  22. package/out/src/__tests/CWIStyleWalletManager.test.js.map +1 -1
  23. package/out/src/index.all.d.ts +1 -2
  24. package/out/src/index.all.d.ts.map +1 -1
  25. package/out/src/index.all.js +1 -2
  26. package/out/src/index.all.js.map +1 -1
  27. package/out/src/monitor/Monitor.d.ts +4 -3
  28. package/out/src/monitor/Monitor.d.ts.map +1 -1
  29. package/out/src/monitor/Monitor.js +39 -11
  30. package/out/src/monitor/Monitor.js.map +1 -1
  31. package/out/src/monitor/MonitorDaemon.d.ts +2 -1
  32. package/out/src/monitor/MonitorDaemon.d.ts.map +1 -1
  33. package/out/src/monitor/MonitorDaemon.js +1 -4
  34. package/out/src/monitor/MonitorDaemon.js.map +1 -1
  35. package/out/src/monitor/index.all.d.ts +4 -0
  36. package/out/src/monitor/index.all.d.ts.map +1 -0
  37. package/out/src/monitor/index.all.js +43 -0
  38. package/out/src/monitor/index.all.js.map +1 -0
  39. package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts +26 -0
  40. package/out/src/monitor/tasks/TaskReviewDoubleSpends.d.ts.map +1 -0
  41. package/out/src/monitor/tasks/TaskReviewDoubleSpends.js +124 -0
  42. package/out/src/monitor/tasks/TaskReviewDoubleSpends.js.map +1 -0
  43. package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts +34 -0
  44. package/out/src/monitor/tasks/TaskReviewProvenTxs.d.ts.map +1 -0
  45. package/out/src/monitor/tasks/TaskReviewProvenTxs.js +131 -0
  46. package/out/src/monitor/tasks/TaskReviewProvenTxs.js.map +1 -0
  47. package/out/src/monitor/tasks/TaskReviewUtxos.d.ts +23 -0
  48. package/out/src/monitor/tasks/TaskReviewUtxos.d.ts.map +1 -0
  49. package/out/src/monitor/tasks/TaskReviewUtxos.js +71 -0
  50. package/out/src/monitor/tasks/TaskReviewUtxos.js.map +1 -0
  51. package/out/src/monitor/tasks/TaskSendWaiting.d.ts +14 -1
  52. package/out/src/monitor/tasks/TaskSendWaiting.d.ts.map +1 -1
  53. package/out/src/monitor/tasks/TaskSendWaiting.js +86 -20
  54. package/out/src/monitor/tasks/TaskSendWaiting.js.map +1 -1
  55. package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.d.ts +2 -0
  56. package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.d.ts.map +1 -0
  57. package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.js +161 -0
  58. package/out/src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.js.map +1 -0
  59. package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.d.ts +2 -0
  60. package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.d.ts.map +1 -0
  61. package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.js +214 -0
  62. package/out/src/monitor/tasks/__tests/TaskReviewProvenTxs.test.js.map +1 -0
  63. package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.d.ts +2 -0
  64. package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.d.ts.map +1 -0
  65. package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.js +92 -0
  66. package/out/src/monitor/tasks/__tests/TaskReviewUtxos.test.js.map +1 -0
  67. package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.d.ts +2 -0
  68. package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.d.ts.map +1 -0
  69. package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.js +139 -0
  70. package/out/src/monitor/tasks/__tests/TaskSendWaiting.test.js.map +1 -0
  71. package/out/src/monitor/tasks/index.all.d.ts +19 -0
  72. package/out/src/monitor/tasks/index.all.d.ts.map +1 -0
  73. package/out/src/monitor/tasks/index.all.js +35 -0
  74. package/out/src/monitor/tasks/index.all.js.map +1 -0
  75. package/out/src/sdk/WalletStorage.interfaces.d.ts +9 -0
  76. package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
  77. package/out/src/services/Services.d.ts.map +1 -1
  78. package/out/src/services/Services.js +10 -2
  79. package/out/src/services/Services.js.map +1 -1
  80. package/out/src/services/__tests/getFiatExchangeRate.test.d.ts +2 -0
  81. package/out/src/services/__tests/getFiatExchangeRate.test.d.ts.map +1 -0
  82. package/out/src/services/__tests/getFiatExchangeRate.test.js +156 -0
  83. package/out/src/services/__tests/getFiatExchangeRate.test.js.map +1 -0
  84. package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.js +1 -1
  85. package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.js.map +1 -1
  86. package/out/src/services/createDefaultWalletServicesOptions.js +1 -1
  87. package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  88. package/out/src/services/providers/__tests/exchangeRates.test.js +4 -0
  89. package/out/src/services/providers/__tests/exchangeRates.test.js.map +1 -1
  90. package/out/src/storage/StorageKnex.d.ts +3 -1
  91. package/out/src/storage/StorageKnex.d.ts.map +1 -1
  92. package/out/src/storage/StorageKnex.js +26 -5
  93. package/out/src/storage/StorageKnex.js.map +1 -1
  94. package/out/src/storage/StorageProvider.d.ts +6 -1
  95. package/out/src/storage/StorageProvider.d.ts.map +1 -1
  96. package/out/src/storage/StorageProvider.js +6 -0
  97. package/out/src/storage/StorageProvider.js.map +1 -1
  98. package/out/src/storage/StorageReaderWriter.d.ts +2 -1
  99. package/out/src/storage/StorageReaderWriter.d.ts.map +1 -1
  100. package/out/src/storage/StorageReaderWriter.js.map +1 -1
  101. package/out/src/storage/WalletStorageManager.d.ts +7 -0
  102. package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
  103. package/out/src/storage/WalletStorageManager.js +33 -2
  104. package/out/src/storage/WalletStorageManager.js.map +1 -1
  105. package/out/src/storage/__test/findStaleMerkleRoots.test.d.ts +2 -0
  106. package/out/src/storage/__test/findStaleMerkleRoots.test.d.ts.map +1 -0
  107. package/out/src/storage/__test/findStaleMerkleRoots.test.js +41 -0
  108. package/out/src/storage/__test/findStaleMerkleRoots.test.js.map +1 -0
  109. package/out/src/storage/__test/findStaleMerkleRootsKnex.test.d.ts +2 -0
  110. package/out/src/storage/__test/findStaleMerkleRootsKnex.test.d.ts.map +1 -0
  111. package/out/src/storage/__test/findStaleMerkleRootsKnex.test.js +73 -0
  112. package/out/src/storage/__test/findStaleMerkleRootsKnex.test.js.map +1 -0
  113. package/out/src/utility/Format.d.ts.map +1 -1
  114. package/out/src/utility/Format.js +1 -0
  115. package/out/src/utility/Format.js.map +1 -1
  116. package/out/src/utility/index.all.d.ts +1 -0
  117. package/out/src/utility/index.all.d.ts.map +1 -1
  118. package/out/src/utility/index.all.js +1 -0
  119. package/out/src/utility/index.all.js.map +1 -1
  120. package/package.json +3 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskReviewUtxos.js","sourceRoot":"","sources":["../../../../src/monitor/tasks/TaskReviewUtxos.ts"],"names":[],"mappings":"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"}
@@ -5,14 +5,27 @@ export declare class TaskSendWaiting extends WalletMonitorTask {
5
5
  triggerMsecs: number;
6
6
  agedMsecs: number;
7
7
  sendingMsecs: number;
8
+ triggerQuickMsecs: number;
9
+ chunkLimit: number;
8
10
  static taskName: string;
9
11
  lastSendingRunMsecsSinceEpoch: number | undefined;
10
12
  includeSending: boolean;
11
- constructor(monitor: Monitor, triggerMsecs?: number, agedMsecs?: number, sendingMsecs?: number);
13
+ triggerNextMsecs: number;
14
+ /**
15
+ * @param monitor Wallet monitor owning this task.
16
+ * @param triggerMsecs Normal interval between SendWaiting runs when no backlog remains.
17
+ * @param agedMsecs Minimum age a request must reach before this task will attempt to send it.
18
+ * @param sendingMsecs Minimum interval before stale `sending` requests are included again.
19
+ * @param triggerQuickMsecs Follow-up interval used when a full chunk was consumed and more work may remain.
20
+ * @param chunkLimit Maximum number of waiting requests to fetch and inspect in a single run.
21
+ */
22
+ constructor(monitor: Monitor, triggerMsecs?: number, agedMsecs?: number, sendingMsecs?: number, triggerQuickMsecs?: number, chunkLimit?: number);
12
23
  trigger(nowMsecsSinceEpoch: number): {
13
24
  run: boolean;
14
25
  };
15
26
  runTask(): Promise<string>;
27
+ private expandBatches;
28
+ private filterAgedReqs;
16
29
  /**
17
30
  * Process an array of 'unsent' status table.ProvenTxReq
18
31
  *
@@ -1 +1 @@
1
- {"version":3,"file":"TaskSendWaiting.d.ts","sourceRoot":"","sources":["../../../../src/monitor/tasks/TaskSendWaiting.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAKvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAG/E,qBAAa,eAAgB,SAAQ,iBAAiB;IAQ3C,YAAY;IACZ,SAAS;IACT,YAAY;IATrB,MAAM,CAAC,QAAQ,SAAgB;IAE/B,6BAA6B,EAAE,MAAM,GAAG,SAAS,CAAA;IACjD,cAAc,EAAE,OAAO,CAAO;gBAG5B,OAAO,EAAE,OAAO,EACT,YAAY,SAAwB,EACpC,SAAS,SAAwB,EACjC,YAAY,SAAwB;IAK7C,OAAO,CAAC,kBAAkB,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE;IAS/C,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAwBhC;;;;;;;;;;;;;;;;OAgBG;IACG,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CA4D9E"}
1
+ {"version":3,"file":"TaskSendWaiting.d.ts","sourceRoot":"","sources":["../../../../src/monitor/tasks/TaskSendWaiting.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAKvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAG/E,qBAAa,eAAgB,SAAQ,iBAAiB;IAiB3C,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,iBAAiB;IACjB,UAAU;IApBnB,MAAM,CAAC,QAAQ,SAAgB;IAE/B,6BAA6B,EAAE,MAAM,GAAG,SAAS,CAAA;IACjD,cAAc,EAAE,OAAO,CAAO;IAC9B,gBAAgB,EAAE,MAAM,CAAA;IAExB;;;;;;;OAOG;gBAED,OAAO,EAAE,OAAO,EACT,YAAY,SAAwB,EACpC,SAAS,SAAwB,EACjC,YAAY,SAAwB,EACpC,iBAAiB,SAAwB,EACzC,UAAU,SAAM;IAMzB,OAAO,CAAC,kBAAkB,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE;IAS/C,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;YAqClB,aAAa;IA8B3B,OAAO,CAAC,cAAc;IAuBtB;;;;;;;;;;;;;;;;OAgBG;IACG,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CA6D9E"}
@@ -8,12 +8,23 @@ const aggregateResults_1 = require("../../utility/aggregateResults");
8
8
  const utilityHelpers_1 = require("../../utility/utilityHelpers");
9
9
  const EntityProvenTxReq_1 = require("../../storage/schema/entities/EntityProvenTxReq");
10
10
  class TaskSendWaiting extends WalletMonitorTask_1.WalletMonitorTask {
11
- constructor(monitor, triggerMsecs = Monitor_1.Monitor.oneSecond * 8, agedMsecs = Monitor_1.Monitor.oneSecond * 7, sendingMsecs = Monitor_1.Monitor.oneMinute * 5) {
11
+ /**
12
+ * @param monitor Wallet monitor owning this task.
13
+ * @param triggerMsecs Normal interval between SendWaiting runs when no backlog remains.
14
+ * @param agedMsecs Minimum age a request must reach before this task will attempt to send it.
15
+ * @param sendingMsecs Minimum interval before stale `sending` requests are included again.
16
+ * @param triggerQuickMsecs Follow-up interval used when a full chunk was consumed and more work may remain.
17
+ * @param chunkLimit Maximum number of waiting requests to fetch and inspect in a single run.
18
+ */
19
+ constructor(monitor, triggerMsecs = Monitor_1.Monitor.oneSecond * 8, agedMsecs = Monitor_1.Monitor.oneSecond * 7, sendingMsecs = Monitor_1.Monitor.oneMinute * 5, triggerQuickMsecs = Monitor_1.Monitor.oneSecond * 1, chunkLimit = 100) {
12
20
  super(monitor, TaskSendWaiting.taskName);
13
21
  this.triggerMsecs = triggerMsecs;
14
22
  this.agedMsecs = agedMsecs;
15
23
  this.sendingMsecs = sendingMsecs;
24
+ this.triggerQuickMsecs = triggerQuickMsecs;
25
+ this.chunkLimit = chunkLimit;
16
26
  this.includeSending = true;
27
+ this.triggerNextMsecs = this.triggerQuickMsecs;
17
28
  }
18
29
  trigger(nowMsecsSinceEpoch) {
19
30
  this.includeSending =
@@ -21,34 +32,88 @@ class TaskSendWaiting extends WalletMonitorTask_1.WalletMonitorTask {
21
32
  if (this.includeSending)
22
33
  this.lastSendingRunMsecsSinceEpoch = nowMsecsSinceEpoch;
23
34
  return {
24
- run: nowMsecsSinceEpoch > this.lastRunMsecsSinceEpoch + this.triggerMsecs
35
+ run: nowMsecsSinceEpoch > this.lastRunMsecsSinceEpoch + this.triggerNextMsecs
25
36
  };
26
37
  }
27
38
  async runTask() {
28
39
  let log = '';
29
- const limit = 100;
30
- let offset = 0;
31
- const agedLimit = new Date(Date.now() - this.agedMsecs);
40
+ const nowMsecsSinceEpoch = Date.now();
41
+ const agedLimit = new Date(nowMsecsSinceEpoch - this.agedMsecs);
32
42
  const status = this.includeSending ? ['unsent', 'sending'] : ['unsent'];
33
- for (;;) {
34
- let reqs = await this.storage.findProvenTxReqs({
35
- partial: {},
36
- status,
37
- paged: { limit, offset }
38
- });
39
- const count = reqs.length;
40
- if (reqs.length === 0)
41
- break;
42
- log += `${reqs.length} reqs with status ${status.join(' or ')}\n`;
43
- const agedReqs = reqs.filter(req => (0, utilityHelpers_1.verifyTruthy)(req.updated_at) < agedLimit);
43
+ const reqs = await this.storage.findProvenTxReqs({
44
+ partial: {},
45
+ status,
46
+ paged: { limit: this.chunkLimit, offset: 0 }
47
+ });
48
+ const count = reqs.length;
49
+ if (count > 0) {
50
+ log += `${count} reqs with status ${status.join(' or ')}\n`;
51
+ const filteredReqs = await this.expandBatches(reqs, status);
52
+ const agedReqs = this.filterAgedReqs(filteredReqs, agedLimit);
44
53
  log += ` Of those reqs, ${agedReqs.length} where last updated before ${agedLimit.toISOString()}.\n`;
45
54
  log += await this.processUnsent(agedReqs, 2);
46
- if (count < limit)
47
- break;
48
- offset += limit;
55
+ if (count >= this.chunkLimit) {
56
+ this.triggerNextMsecs = this.triggerQuickMsecs;
57
+ }
58
+ else if (agedReqs.length < filteredReqs.length) {
59
+ const ageAllMsecs = Math.max(...filteredReqs.map(req => (0, utilityHelpers_1.verifyTruthy)(req.updated_at).getTime() + this.agedMsecs - nowMsecsSinceEpoch), 0);
60
+ this.triggerNextMsecs = ageAllMsecs;
61
+ }
62
+ else {
63
+ this.triggerNextMsecs = this.triggerMsecs;
64
+ }
65
+ }
66
+ else {
67
+ this.triggerNextMsecs = this.triggerMsecs;
49
68
  }
50
69
  return log;
51
70
  }
71
+ async expandBatches(reqs, status) {
72
+ const expanded = [];
73
+ const seenReqIds = new Set();
74
+ const seenBatches = new Set();
75
+ for (const req of reqs) {
76
+ if (seenReqIds.has(req.provenTxReqId))
77
+ continue;
78
+ if (!req.batch || seenBatches.has(req.batch)) {
79
+ seenReqIds.add(req.provenTxReqId);
80
+ expanded.push(req);
81
+ continue;
82
+ }
83
+ seenBatches.add(req.batch);
84
+ const batchReqs = await this.storage.findProvenTxReqs({
85
+ partial: { batch: req.batch },
86
+ status
87
+ });
88
+ for (const batchReq of batchReqs) {
89
+ if (seenReqIds.has(batchReq.provenTxReqId))
90
+ continue;
91
+ seenReqIds.add(batchReq.provenTxReqId);
92
+ expanded.push(batchReq);
93
+ }
94
+ }
95
+ return expanded;
96
+ }
97
+ filterAgedReqs(reqs, agedLimit) {
98
+ const agedReqs = [];
99
+ const seenBatches = new Set();
100
+ for (const req of reqs) {
101
+ if (!req.batch) {
102
+ if ((0, utilityHelpers_1.verifyTruthy)(req.updated_at) < agedLimit)
103
+ agedReqs.push(req);
104
+ continue;
105
+ }
106
+ if (seenBatches.has(req.batch))
107
+ continue;
108
+ seenBatches.add(req.batch);
109
+ const batchReqs = reqs.filter(candidate => candidate.batch === req.batch);
110
+ const youngestUpdatedAt = Math.max(...batchReqs.map(batchReq => (0, utilityHelpers_1.verifyTruthy)(batchReq.updated_at).getTime()));
111
+ if (youngestUpdatedAt < agedLimit.getTime()) {
112
+ agedReqs.push(...batchReqs);
113
+ }
114
+ }
115
+ return agedReqs;
116
+ }
52
117
  /**
53
118
  * Process an array of 'unsent' status table.ProvenTxReq
54
119
  *
@@ -91,7 +156,8 @@ class TaskSendWaiting extends WalletMonitorTask_1.WalletMonitorTask {
91
156
  logs[reqApi.txid] += ` batch ${req.batch}`;
92
157
  // Make sure wew process entire batch together for efficient beef generation
93
158
  const batchReqApis = await this.storage.findProvenTxReqs({
94
- partial: { batch: req.batch, status: 'unsent' }
159
+ partial: { batch: req.batch },
160
+ status: this.includeSending ? ['unsent', 'sending'] : ['unsent']
95
161
  });
96
162
  for (const bra of batchReqApis) {
97
163
  if (reqApiIds.has(bra.provenTxReqId))
@@ -1 +1 @@
1
- {"version":3,"file":"TaskSendWaiting.js","sourceRoot":"","sources":["../../../../src/monitor/tasks/TaskSendWaiting.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskSendWaiting.js","sourceRoot":"","sources":["../../../../src/monitor/tasks/TaskSendWaiting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TaskReviewDoubleSpends.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskReviewDoubleSpends.test.d.ts","sourceRoot":"","sources":["../../../../../src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const TaskReviewDoubleSpends_1 = require("../TaskReviewDoubleSpends");
4
+ function makeReq(provenTxReqId, txid, updatedAt) {
5
+ const now = new Date();
6
+ return {
7
+ provenTxReqId,
8
+ created_at: now,
9
+ updated_at: updatedAt,
10
+ txid,
11
+ status: 'doubleSpend',
12
+ history: '{}',
13
+ notify: '{}',
14
+ attempts: 0,
15
+ notified: false
16
+ };
17
+ }
18
+ function makeMonitor(statusByTxid, reqs, monitorEvents = []) {
19
+ const updateProvenTxReq = jest.fn().mockResolvedValue(undefined);
20
+ const findProvenTxReqs = jest.fn(async ({ paged }) => reqs.slice(paged.offset, paged.offset + paged.limit));
21
+ const findMonitorEvents = jest.fn().mockResolvedValue(monitorEvents);
22
+ const runAsStorageProvider = jest.fn(async (fn) => await fn({ updateProvenTxReq, findMonitorEvents }));
23
+ const logEvent = jest.fn().mockResolvedValue(undefined);
24
+ return {
25
+ monitor: {
26
+ storage: {
27
+ findProvenTxReqs,
28
+ runAsStorageProvider
29
+ },
30
+ services: {
31
+ getStatusForTxids: jest.fn(async (txids) => ({
32
+ results: txids.map(txid => { var _a; return ({ txid, status: (_a = statusByTxid[txid]) !== null && _a !== void 0 ? _a : 'unknown' }); })
33
+ }))
34
+ },
35
+ logEvent
36
+ },
37
+ updateProvenTxReq,
38
+ findProvenTxReqs,
39
+ findMonitorEvents,
40
+ runAsStorageProvider,
41
+ logEvent
42
+ };
43
+ }
44
+ describe('TaskReviewDoubleSpends', () => {
45
+ afterEach(() => {
46
+ jest.restoreAllMocks();
47
+ });
48
+ test('0 uses the normal cadence after a partial review chunk and stores checkpoint offset after unfails are removed', async () => {
49
+ const now = new Date('2026-01-01T12:00:00.000Z');
50
+ jest.spyOn(Date, 'now').mockReturnValue(now.getTime());
51
+ const reqs = [
52
+ makeReq(1, 'tx1', new Date('2026-01-01T10:30:00.000Z')),
53
+ makeReq(2, 'tx2', new Date('2026-01-01T10:40:00.000Z'))
54
+ ];
55
+ const m = makeMonitor({ tx1: 'success', tx2: 'unknown' }, reqs);
56
+ const task = new TaskReviewDoubleSpends_1.TaskReviewDoubleSpends(m.monitor, 0, 100, 60, 60);
57
+ const log = await task.runTask();
58
+ expect(m.findProvenTxReqs).toHaveBeenCalledWith({
59
+ partial: { status: 'doubleSpend' },
60
+ paged: { limit: 100, offset: 0 }
61
+ });
62
+ expect(m.updateProvenTxReq).toHaveBeenCalledWith([1], { status: 'unfail' });
63
+ expect(m.logEvent).not.toHaveBeenCalled();
64
+ expect(log).toContain('"reviewed":2');
65
+ expect(log).toContain('"unfails":1');
66
+ expect(log).toContain('"resumeOffset":0');
67
+ expect(log).toContain('"expectedProvenTxReqId":2');
68
+ expect(log).toContain('unfail 1 tx1 status:success');
69
+ expect(task.triggerNextMsecs).toBe(0);
70
+ });
71
+ test('0a stores the retained req offset in the post-unfail doubleSpend list', async () => {
72
+ const now = new Date('2026-01-01T12:00:00.000Z');
73
+ jest.spyOn(Date, 'now').mockReturnValue(now.getTime());
74
+ const reqs = [
75
+ makeReq(1, 'tx1', new Date('2026-01-01T10:30:00.000Z')),
76
+ makeReq(2, 'tx2', new Date('2026-01-01T10:35:00.000Z')),
77
+ makeReq(3, 'tx3', new Date('2026-01-01T10:40:00.000Z'))
78
+ ];
79
+ const m = makeMonitor({ tx1: 'success', tx2: 'unknown', tx3: 'unknown' }, reqs);
80
+ const task = new TaskReviewDoubleSpends_1.TaskReviewDoubleSpends(m.monitor, 0, 100, 60, 60);
81
+ const log = await task.runTask();
82
+ expect(m.updateProvenTxReq).toHaveBeenCalledWith([1], { status: 'unfail' });
83
+ expect(log).toContain('"resumeOffset":1');
84
+ expect(log).toContain('"expectedProvenTxReqId":3');
85
+ });
86
+ test('1 skips reqs newer than the minAgeMinutes cutoff and returns empty when nothing is eligible', async () => {
87
+ const now = new Date('2026-01-01T12:00:00.000Z');
88
+ jest.spyOn(Date, 'now').mockReturnValue(now.getTime());
89
+ const reqs = [makeReq(1, 'tx1', new Date('2026-01-01T11:30:01.000Z'))];
90
+ const m = makeMonitor({ tx1: 'unknown' }, reqs);
91
+ const task = new TaskReviewDoubleSpends_1.TaskReviewDoubleSpends(m.monitor, 0, 100, 60, 60);
92
+ const log = await task.runTask();
93
+ expect(m.updateProvenTxReq).not.toHaveBeenCalled();
94
+ expect(m.logEvent).not.toHaveBeenCalled();
95
+ expect(log).toBe('');
96
+ expect(task.triggerNextMsecs).toBe(0);
97
+ });
98
+ test('1b uses the quick cadence after consuming a full review chunk', async () => {
99
+ const now = new Date('2026-01-01T12:00:00.000Z');
100
+ jest.spyOn(Date, 'now').mockReturnValue(now.getTime());
101
+ const reqs = [
102
+ makeReq(1, 'tx1', new Date('2026-01-01T10:30:00.000Z')),
103
+ makeReq(2, 'tx2', new Date('2026-01-01T10:40:00.000Z'))
104
+ ];
105
+ const m = makeMonitor({ tx1: 'success', tx2: 'unknown' }, reqs);
106
+ const task = new TaskReviewDoubleSpends_1.TaskReviewDoubleSpends(m.monitor, 0, 2, 60, 60);
107
+ await task.runTask();
108
+ expect(task.triggerNextMsecs).toBe(60);
109
+ });
110
+ test('2 resumes from the checkpoint offset and advances it', async () => {
111
+ const now = new Date('2026-01-01T12:00:00.000Z');
112
+ jest.spyOn(Date, 'now').mockReturnValue(now.getTime());
113
+ const reqs = [
114
+ makeReq(1, 'tx1', new Date('2026-01-01T10:00:00.000Z')),
115
+ makeReq(2, 'tx2', new Date('2026-01-01T10:05:00.000Z')),
116
+ makeReq(3, 'tx3', new Date('2026-01-01T10:10:00.000Z'))
117
+ ];
118
+ const m = makeMonitor({ tx2: 'unknown', tx3: 'success' }, reqs, [
119
+ { details: JSON.stringify({ resumeOffset: 1, expectedProvenTxReqId: 2 }) }
120
+ ]);
121
+ const task = new TaskReviewDoubleSpends_1.TaskReviewDoubleSpends(m.monitor, 0, 2, 60);
122
+ const log = await task.runTask();
123
+ expect(m.findProvenTxReqs).toHaveBeenNthCalledWith(1, {
124
+ partial: { status: 'doubleSpend' },
125
+ paged: { limit: 1, offset: 1 }
126
+ });
127
+ expect(m.findProvenTxReqs).toHaveBeenNthCalledWith(2, {
128
+ partial: { status: 'doubleSpend' },
129
+ paged: { limit: 2, offset: 2 }
130
+ });
131
+ expect(m.updateProvenTxReq).toHaveBeenCalledWith([3], { status: 'unfail' });
132
+ expect(log).toContain('"reviewed":1');
133
+ expect(log).not.toContain('"resumeOffset"');
134
+ expect(log).not.toContain('"expectedProvenTxReqId"');
135
+ });
136
+ test('3 restarts at offset zero when the checkpoint verification id no longer matches', async () => {
137
+ const now = new Date('2026-01-01T12:00:00.000Z');
138
+ jest.spyOn(Date, 'now').mockReturnValue(now.getTime());
139
+ const reqs = [
140
+ makeReq(10, 'tx10', new Date('2026-01-01T10:00:00.000Z')),
141
+ makeReq(11, 'tx11', new Date('2026-01-01T10:05:00.000Z'))
142
+ ];
143
+ const m = makeMonitor({ tx10: 'unknown', tx11: 'success' }, reqs, [
144
+ { details: JSON.stringify({ resumeOffset: 1, expectedProvenTxReqId: 99 }) }
145
+ ]);
146
+ const task = new TaskReviewDoubleSpends_1.TaskReviewDoubleSpends(m.monitor, 0, 2, 60);
147
+ const log = await task.runTask();
148
+ expect(m.findProvenTxReqs).toHaveBeenNthCalledWith(1, {
149
+ partial: { status: 'doubleSpend' },
150
+ paged: { limit: 1, offset: 1 }
151
+ });
152
+ expect(m.findProvenTxReqs).toHaveBeenNthCalledWith(2, {
153
+ partial: { status: 'doubleSpend' },
154
+ paged: { limit: 2, offset: 0 }
155
+ });
156
+ expect(m.updateProvenTxReq).toHaveBeenCalledWith([11], { status: 'unfail' });
157
+ expect(log).toContain('"resumeOffset":0');
158
+ expect(log).toContain('"expectedProvenTxReqId":10');
159
+ });
160
+ });
161
+ //# sourceMappingURL=TaskReviewDoubleSpends.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskReviewDoubleSpends.test.js","sourceRoot":"","sources":["../../../../../src/monitor/tasks/__tests/TaskReviewDoubleSpends.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TaskReviewProvenTxs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskReviewProvenTxs.test.d.ts","sourceRoot":"","sources":["../../../../../src/monitor/tasks/__tests/TaskReviewProvenTxs.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const TaskReviewProvenTxs_1 = require("../TaskReviewProvenTxs");
4
+ const HeightRange_1 = require("../../../services/chaintracker/chaintracks/util/HeightRange");
5
+ function makeMonitor(options) {
6
+ const reviewHeightRange = jest.fn().mockResolvedValue(options.reviewResult || {
7
+ log: '',
8
+ reviewedHeights: 0,
9
+ mismatchedHeights: 0,
10
+ affectedTransactions: 0,
11
+ updatedTransactions: 0
12
+ });
13
+ const findStaleMerkleRoots = jest.fn(async ({ height }) => { var _a, _b; return (_b = (_a = options.staleRootsByHeight) === null || _a === void 0 ? void 0 : _a[height]) !== null && _b !== void 0 ? _b : []; });
14
+ const findMonitorEvents = jest.fn(async () => options.monitorEvents || []);
15
+ const runAsStorageProvider = jest.fn(async (fn) => await fn({ findStaleMerkleRoots }));
16
+ const reproveHeightMerkleRoot = jest.fn(async (height, staleRoot) => {
17
+ var _a;
18
+ return (((_a = options.reproveResultsByHeightRoot) === null || _a === void 0 ? void 0 : _a[`${height}:${staleRoot}`]) || {
19
+ log: ` reproved ${height}:${staleRoot}\n`,
20
+ updated: [],
21
+ unchanged: [],
22
+ unavailable: []
23
+ });
24
+ });
25
+ const logEvent = jest.fn().mockResolvedValue(undefined);
26
+ const chaintracks = {
27
+ currentHeight: jest.fn().mockResolvedValue(options.tipHeight),
28
+ findHeaderForHeight: jest.fn(async (height) => { var _a; return (_a = options.headersByHeight) === null || _a === void 0 ? void 0 : _a[height]; })
29
+ };
30
+ return {
31
+ monitor: {
32
+ storage: {
33
+ runAsStorageProvider,
34
+ reproveHeightMerkleRoot
35
+ },
36
+ chaintracks,
37
+ chaintracksWithEvents: undefined,
38
+ logEvent
39
+ },
40
+ reviewHeightRange,
41
+ findStaleMerkleRoots,
42
+ findMonitorEvents,
43
+ runAsStorageProvider,
44
+ reproveHeightMerkleRoot,
45
+ logEvent,
46
+ chaintracks
47
+ };
48
+ }
49
+ describe('TaskReviewProvenTxs tests', () => {
50
+ test('0 reviewHeightRange uses findStaleMerkleRoots and reproves only stale roots in the requested range', async () => {
51
+ const m = makeMonitor({
52
+ tipHeight: 120,
53
+ headersByHeight: {
54
+ 107: { height: 107, merkleRoot: 'root-107', hash: 'hash-107' },
55
+ 108: { height: 108, merkleRoot: 'root-108-new', hash: 'hash-108' }
56
+ },
57
+ staleRootsByHeight: {
58
+ 107: [],
59
+ 108: ['root-108-old']
60
+ },
61
+ reproveResultsByHeightRoot: {
62
+ '108:root-108-old': {
63
+ log: ' height 108 stale merkleRoot root-108-old with 2 impacted transactions\n',
64
+ updated: [{}],
65
+ unchanged: [{}],
66
+ unavailable: []
67
+ }
68
+ }
69
+ });
70
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 2, 12);
71
+ const result = await task.reviewHeightRange(new HeightRange_1.HeightRange(107, 108));
72
+ expect(m.findStaleMerkleRoots).toHaveBeenNthCalledWith(1, { height: 107, merkleRoot: 'root-107' });
73
+ expect(m.findStaleMerkleRoots).toHaveBeenNthCalledWith(2, { height: 108, merkleRoot: 'root-108-new' });
74
+ expect(m.reproveHeightMerkleRoot).toHaveBeenCalledTimes(1);
75
+ expect(m.reproveHeightMerkleRoot).toHaveBeenCalledWith(108, 'root-108-old');
76
+ expect(result.reviewedHeights).toBe(2);
77
+ expect(result.mismatchedHeights).toBe(1);
78
+ expect(result.affectedTransactions).toBe(2);
79
+ expect(result.updatedTransactions).toBe(1);
80
+ expect(result.log).toContain('height 108 canonical root-108-new stale root-108-old');
81
+ });
82
+ test('1 reviewHeightRange records unavailable headers and skips empty ranges cleanly', async () => {
83
+ const m = makeMonitor({
84
+ tipHeight: 120,
85
+ headersByHeight: {
86
+ 10: undefined
87
+ }
88
+ });
89
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 2, 12);
90
+ const result = await task.reviewHeightRange(new HeightRange_1.HeightRange(10, 10));
91
+ const empty = await task.reviewHeightRange(HeightRange_1.HeightRange.empty);
92
+ expect(m.reproveHeightMerkleRoot).not.toHaveBeenCalled();
93
+ expect(result.reviewedHeights).toBe(1);
94
+ expect(result.log).toContain('height 10 canonical header unavailable');
95
+ expect(empty.reviewedHeights).toBe(0);
96
+ expect(empty.log).toBe('');
97
+ });
98
+ test('2 getLastReviewedHeight skips plain-text events and uses the latest checkpoint event', async () => {
99
+ const m = makeMonitor({
100
+ tipHeight: 120,
101
+ monitorEvents: [
102
+ { details: 'reviewing heights 10..20 tip=120 minAge=100 maxPerRun=100' },
103
+ { details: JSON.stringify({ reviewedThroughHeight: 20 }) },
104
+ { details: JSON.stringify({ reviewedThroughHeight: 7 }) }
105
+ ]
106
+ });
107
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor);
108
+ jest
109
+ .spyOn(task.storage, 'runAsStorageProvider')
110
+ .mockImplementation(async (fn) => await fn({ findMonitorEvents: m.findMonitorEvents }));
111
+ const lastReviewedHeight = await task.getLastReviewedHeight();
112
+ expect(lastReviewedHeight).toBe(20);
113
+ });
114
+ test('3 runTask starts from height 0 on cold start and caps the range by batch size and minimum age', async () => {
115
+ const m = makeMonitor({
116
+ tipHeight: 250,
117
+ reviewResult: {
118
+ log: '',
119
+ reviewedHeights: 100,
120
+ mismatchedHeights: 0,
121
+ affectedTransactions: 0,
122
+ updatedTransactions: 0
123
+ }
124
+ });
125
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 100, 100);
126
+ jest.spyOn(task, 'getLastReviewedHeight').mockResolvedValue(undefined);
127
+ const reviewSpy = jest.spyOn(task, 'reviewHeightRange').mockResolvedValue(m.reviewHeightRange());
128
+ const log = await task.runTask();
129
+ expect(reviewSpy).toHaveBeenCalledWith(new HeightRange_1.HeightRange(0, 99));
130
+ expect(log).toContain('"reviewedThroughHeight":99');
131
+ expect(log).toContain('"minBlockAge":100');
132
+ expect(log).toContain('reviewing heights 0..99 tip=250 minAge=100 maxPerRun=100');
133
+ expect(m.logEvent).not.toHaveBeenCalled();
134
+ });
135
+ test('4 runTask resumes from the last reviewed height plus one', async () => {
136
+ const m = makeMonitor({
137
+ tipHeight: 250,
138
+ reviewResult: {
139
+ log: ' height 121 canonical root-121-new stale root-121-old\n reproved stale root\n',
140
+ reviewedHeights: 21,
141
+ mismatchedHeights: 1,
142
+ affectedTransactions: 1,
143
+ updatedTransactions: 0
144
+ }
145
+ });
146
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 100, 100);
147
+ jest.spyOn(task, 'getLastReviewedHeight').mockResolvedValue(100);
148
+ const reviewSpy = jest.spyOn(task, 'reviewHeightRange').mockResolvedValue(m.reviewHeightRange());
149
+ const log = await task.runTask();
150
+ expect(reviewSpy).toHaveBeenCalledTimes(1);
151
+ expect(reviewSpy).toHaveBeenCalledWith(new HeightRange_1.HeightRange(101, 150));
152
+ expect(log).toContain('"reviewedThroughHeight":150');
153
+ expect(log).toContain('"minBlockAge":100');
154
+ expect(log).toContain('reviewing heights 101..150 tip=250 minAge=100 maxPerRun=100');
155
+ expect(log).toContain('height 121 canonical root-121-new stale root-121-old');
156
+ expect(m.logEvent).not.toHaveBeenCalled();
157
+ });
158
+ test('5 runTask returns review logs even when the range is clean', async () => {
159
+ const m = makeMonitor({
160
+ tipHeight: 250,
161
+ reviewResult: {
162
+ log: '',
163
+ reviewedHeights: 50,
164
+ mismatchedHeights: 0,
165
+ affectedTransactions: 0,
166
+ updatedTransactions: 0
167
+ }
168
+ });
169
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 50, 100);
170
+ jest.spyOn(task, 'getLastReviewedHeight').mockResolvedValue(149);
171
+ const reviewSpy = jest.spyOn(task, 'reviewHeightRange').mockResolvedValue(m.reviewHeightRange());
172
+ const log = await task.runTask();
173
+ expect(reviewSpy).toHaveBeenCalledTimes(1);
174
+ expect(reviewSpy).toHaveBeenCalledWith(new HeightRange_1.HeightRange(150, 150));
175
+ expect(log).toContain('"reviewedThroughHeight":150');
176
+ expect(log).toContain('"minBlockAge":100');
177
+ expect(log).toContain('reviewing heights 150..150 tip=250 minAge=100 maxPerRun=50');
178
+ expect(m.logEvent).not.toHaveBeenCalled();
179
+ });
180
+ test('6 runTask returns early when the chain tip is below the minimum age window', async () => {
181
+ const m = makeMonitor({
182
+ tipHeight: 5
183
+ });
184
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 100, 100);
185
+ jest.spyOn(task, 'getLastReviewedHeight').mockResolvedValue(undefined);
186
+ const log = await task.runTask();
187
+ expect(m.reviewHeightRange).not.toHaveBeenCalled();
188
+ expect(log).toBe('');
189
+ expect(m.logEvent).not.toHaveBeenCalled();
190
+ });
191
+ test('7 runTask returns early when all eligible heights have already been reviewed', async () => {
192
+ const m = makeMonitor({
193
+ tipHeight: 250
194
+ });
195
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 100, 100);
196
+ jest.spyOn(task, 'getLastReviewedHeight').mockResolvedValue(200);
197
+ const log = await task.runTask();
198
+ expect(m.reviewHeightRange).not.toHaveBeenCalled();
199
+ expect(log).toBe('');
200
+ expect(m.logEvent).not.toHaveBeenCalled();
201
+ });
202
+ test('8 runTask returns empty log when the computed range is empty', async () => {
203
+ const m = makeMonitor({
204
+ tipHeight: 250
205
+ });
206
+ const task = new TaskReviewProvenTxs_1.TaskReviewProvenTxs(m.monitor, 0, 0, 100);
207
+ jest.spyOn(task, 'getLastReviewedHeight').mockResolvedValue(undefined);
208
+ const log = await task.runTask();
209
+ expect(m.reviewHeightRange).not.toHaveBeenCalled();
210
+ expect(log).toBe('');
211
+ expect(m.logEvent).not.toHaveBeenCalled();
212
+ });
213
+ });
214
+ //# sourceMappingURL=TaskReviewProvenTxs.test.js.map