@bsv/wallet-toolbox 1.4.0 → 1.4.2
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/mobile/out/src/monitor/tasks/TaskCheckForProofs.d.ts +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckForProofs.js +12 -2
- package/mobile/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckNoSends.js +6 -1
- package/mobile/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts +20 -0
- package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskNewHeader.js +20 -2
- package/mobile/out/src/monitor/tasks/TaskNewHeader.js.map +1 -1
- package/mobile/package-lock.json +2 -2
- package/mobile/package.json +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.js +12 -2
- package/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.js +6 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.d.ts +20 -0
- package/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.js +20 -2
- package/out/src/monitor/tasks/TaskNewHeader.js.map +1 -1
- package/out/test/monitor/Monitor.test.js +10 -0
- package/out/test/monitor/Monitor.test.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/monitor/tasks/TaskCheckForProofs.ts +13 -2
- package/src/monitor/tasks/TaskCheckNoSends.ts +7 -1
- package/src/monitor/tasks/TaskNewHeader.ts +27 -1
- package/test/monitor/Monitor.test.ts +11 -0
package/package.json
CHANGED
|
@@ -50,6 +50,11 @@ export class TaskCheckForProofs extends WalletMonitorTask {
|
|
|
50
50
|
const countsAsAttempt = TaskCheckForProofs.checkNow
|
|
51
51
|
TaskCheckForProofs.checkNow = false
|
|
52
52
|
|
|
53
|
+
const maxAcceptableHeight = this.monitor.lastNewHeader?.height
|
|
54
|
+
if (maxAcceptableHeight === undefined) {
|
|
55
|
+
return log
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
const limit = 100
|
|
54
59
|
let offset = 0
|
|
55
60
|
for (;;) {
|
|
@@ -60,7 +65,7 @@ export class TaskCheckForProofs extends WalletMonitorTask {
|
|
|
60
65
|
})
|
|
61
66
|
if (reqs.length === 0) break
|
|
62
67
|
log += `${reqs.length} reqs with status 'callback', 'unmined', 'sending', 'unknown', or 'unconfirmed'\n`
|
|
63
|
-
const r = await getProofs(this, reqs, 2, countsAsAttempt)
|
|
68
|
+
const r = await getProofs(this, reqs, 2, countsAsAttempt, false, maxAcceptableHeight)
|
|
64
69
|
log += `${r.log}\n`
|
|
65
70
|
//console.log(log);
|
|
66
71
|
if (reqs.length < limit) break
|
|
@@ -90,7 +95,8 @@ export async function getProofs(
|
|
|
90
95
|
reqs: TableProvenTxReq[],
|
|
91
96
|
indent = 0,
|
|
92
97
|
countsAsAttempt = false,
|
|
93
|
-
ignoreStatus = false
|
|
98
|
+
ignoreStatus = false,
|
|
99
|
+
maxAcceptableHeight: number
|
|
94
100
|
): Promise<{
|
|
95
101
|
proven: TableProvenTxReq[]
|
|
96
102
|
invalid: TableProvenTxReq[]
|
|
@@ -179,6 +185,11 @@ export async function getProofs(
|
|
|
179
185
|
// one more time.
|
|
180
186
|
//
|
|
181
187
|
r = await task.monitor.services.getMerklePath(req.txid)
|
|
188
|
+
if (r.header && r.header.height > maxAcceptableHeight) {
|
|
189
|
+
// Ignore proofs from bleeding edge of new blocks as these are the most often re-orged.
|
|
190
|
+
log += ` ignoring possible proof from very new block at height ${r.header.height} ${r.header.hash}\n`
|
|
191
|
+
continue
|
|
192
|
+
}
|
|
182
193
|
ptx = await EntityProvenTx.fromReq(req, r, countsAsAttempt && req.status !== 'nosend')
|
|
183
194
|
|
|
184
195
|
if (ptx) {
|
|
@@ -47,6 +47,12 @@ export class TaskCheckNoSends extends WalletMonitorTask {
|
|
|
47
47
|
const countsAsAttempt = TaskCheckNoSends.checkNow
|
|
48
48
|
TaskCheckNoSends.checkNow = false
|
|
49
49
|
|
|
50
|
+
const maxAcceptableHeight = this.monitor.lastNewHeader?.height
|
|
51
|
+
if (maxAcceptableHeight === undefined) {
|
|
52
|
+
return log
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
50
56
|
const limit = 100
|
|
51
57
|
let offset = 0
|
|
52
58
|
for (;;) {
|
|
@@ -57,7 +63,7 @@ export class TaskCheckNoSends extends WalletMonitorTask {
|
|
|
57
63
|
})
|
|
58
64
|
if (reqs.length === 0) break
|
|
59
65
|
log += `${reqs.length} reqs with status 'nosend'\n`
|
|
60
|
-
const r = await getProofs(this, reqs, 2, countsAsAttempt)
|
|
66
|
+
const r = await getProofs(this, reqs, 2, countsAsAttempt, false, maxAcceptableHeight)
|
|
61
67
|
log += `${r.log}\n`
|
|
62
68
|
//console.log(log);
|
|
63
69
|
if (reqs.length < limit) break
|
|
@@ -2,9 +2,29 @@ import { BlockHeader } from '../../services/chaintracker/chaintracks/Api/BlockHe
|
|
|
2
2
|
import { Monitor } from '../Monitor'
|
|
3
3
|
import { WalletMonitorTask } from './WalletMonitorTask'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* This task polls for new block headers performing two essential functions:
|
|
7
|
+
* 1. The arrival of a new block is the right time to check for proofs for recently broadcast transactions.
|
|
8
|
+
* 2. The height of the block is used to limit which proofs are accepted with the aim of avoiding re-orged proofs.
|
|
9
|
+
*
|
|
10
|
+
* The most common new block orphan is one which is almost immediately orphaned.
|
|
11
|
+
* Waiting a minute before pursuing proof requests avoids almost all the re-org work that could be done.
|
|
12
|
+
* Thus this task queues new headers for one cycle.
|
|
13
|
+
* If a new header arrives during that cycle, it replaces the queued header and delays again.
|
|
14
|
+
* Only when there is an elapsed cycle without a new header does proof solicitation get triggered,
|
|
15
|
+
* with that header height as the limit for which proofs are accepted.
|
|
16
|
+
*/
|
|
5
17
|
export class TaskNewHeader extends WalletMonitorTask {
|
|
6
18
|
static taskName = 'NewHeader'
|
|
19
|
+
/**
|
|
20
|
+
* This is always the most recent chain tip header returned from the chaintracker.
|
|
21
|
+
*/
|
|
7
22
|
header?: BlockHeader
|
|
23
|
+
/**
|
|
24
|
+
* Tracks the value of `header` except that it is set to undefined
|
|
25
|
+
* when a cycle without a new header occurs and `processNewBlockHeader` is called.
|
|
26
|
+
*/
|
|
27
|
+
queuedHeader?: BlockHeader
|
|
8
28
|
|
|
9
29
|
constructor(
|
|
10
30
|
monitor: Monitor,
|
|
@@ -38,7 +58,13 @@ export class TaskNewHeader extends WalletMonitorTask {
|
|
|
38
58
|
} else {
|
|
39
59
|
isNew = false
|
|
40
60
|
}
|
|
41
|
-
if (isNew)
|
|
61
|
+
if (isNew) {
|
|
62
|
+
this.queuedHeader = this.header
|
|
63
|
+
} else if (this.queuedHeader) {
|
|
64
|
+
// Only process new block header if it has remained the chain tip for a full cycle
|
|
65
|
+
this.monitor.processNewBlockHeader(this.queuedHeader)
|
|
66
|
+
this.queuedHeader = undefined
|
|
67
|
+
}
|
|
42
68
|
return log
|
|
43
69
|
}
|
|
44
70
|
}
|
|
@@ -143,6 +143,17 @@ describe('Monitor tests', () => {
|
|
|
143
143
|
for (const { activeStorage: storage, monitor } of ctxs) {
|
|
144
144
|
if (!monitor) throw new sdk.WERR_INTERNAL('test requires setup with monitor')
|
|
145
145
|
|
|
146
|
+
monitor.lastNewHeader = {
|
|
147
|
+
height: 999999999,
|
|
148
|
+
hash: '',
|
|
149
|
+
time: 0,
|
|
150
|
+
version: 0,
|
|
151
|
+
previousHash: '',
|
|
152
|
+
merkleRoot: '',
|
|
153
|
+
bits: 0,
|
|
154
|
+
nonce: 0
|
|
155
|
+
}
|
|
156
|
+
|
|
146
157
|
{
|
|
147
158
|
for (const txid of expectedTxids) {
|
|
148
159
|
// no matching ProvenTx exists.
|