@bsv/wallet-toolbox 1.5.12 → 1.5.13
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 +180 -75
- package/docs/monitor.md +39 -2
- package/docs/wallet.md +180 -75
- package/mobile/out/src/monitor/Monitor.d.ts +23 -0
- package/mobile/out/src/monitor/Monitor.d.ts.map +1 -1
- package/mobile/out/src/monitor/Monitor.js +26 -16
- package/mobile/out/src/monitor/Monitor.js.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckForProofs.js +8 -0
- package/mobile/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskSendWaiting.d.ts.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskSendWaiting.js +9 -0
- package/mobile/out/src/monitor/tasks/TaskSendWaiting.js.map +1 -1
- package/mobile/out/src/sdk/types.d.ts +11 -0
- package/mobile/out/src/sdk/types.d.ts.map +1 -1
- package/mobile/out/src/sdk/types.js.map +1 -1
- package/mobile/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/mobile/out/src/storage/methods/processAction.js +6 -64
- package/mobile/out/src/storage/methods/processAction.js.map +1 -1
- package/mobile/out/src/utility/aggregateResults.d.ts +8 -0
- package/mobile/out/src/utility/aggregateResults.d.ts.map +1 -0
- package/mobile/out/src/utility/aggregateResults.js +59 -0
- package/mobile/out/src/utility/aggregateResults.js.map +1 -0
- package/mobile/package-lock.json +2 -2
- package/mobile/package.json +1 -1
- package/out/src/monitor/Monitor.d.ts +23 -0
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +26 -16
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckForProofs.js +8 -0
- package/out/src/monitor/tasks/TaskCheckForProofs.js.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskSendWaiting.js +9 -0
- package/out/src/monitor/tasks/TaskSendWaiting.js.map +1 -1
- package/out/src/sdk/types.d.ts +11 -0
- package/out/src/sdk/types.d.ts.map +1 -1
- package/out/src/sdk/types.js.map +1 -1
- package/out/src/services/__tests/ARC.timeout.man.test.js +1 -1
- package/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/out/src/storage/methods/processAction.js +6 -64
- package/out/src/storage/methods/processAction.js.map +1 -1
- package/out/src/utility/aggregateResults.d.ts +8 -0
- package/out/src/utility/aggregateResults.d.ts.map +1 -0
- package/out/src/utility/aggregateResults.js +59 -0
- package/out/src/utility/aggregateResults.js.map +1 -0
- package/out/test/monitor/Monitor.test.js +101 -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/Monitor.ts +36 -15
- package/src/monitor/tasks/TaskCheckForProofs.ts +9 -0
- package/src/monitor/tasks/TaskSendWaiting.ts +12 -1
- package/src/sdk/types.ts +12 -0
- package/src/services/__tests/ARC.timeout.man.test.ts +1 -1
- package/src/storage/methods/processAction.ts +7 -78
- package/src/utility/aggregateResults.ts +68 -0
- package/test/monitor/Monitor.test.ts +123 -1
package/package.json
CHANGED
package/src/monitor/Monitor.ts
CHANGED
|
@@ -42,6 +42,12 @@ export interface MonitorOptions {
|
|
|
42
42
|
unprovenAttemptsLimitTest: number
|
|
43
43
|
|
|
44
44
|
unprovenAttemptsLimitMain: number
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* These are hooks for a wallet-toolbox client to get transaction updates.
|
|
48
|
+
*/
|
|
49
|
+
onTransactionBroadcasted?: (broadcastResult: sdk.ReviewActionResult) => Promise<void>
|
|
50
|
+
onTransactionProven?: (txStatus: sdk.ProvenTransactionStatus) => Promise<void>
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
/**
|
|
@@ -75,6 +81,8 @@ export class Monitor {
|
|
|
75
81
|
chain: sdk.Chain
|
|
76
82
|
storage: MonitorStorage
|
|
77
83
|
chaintracks: ChaintracksServiceClient
|
|
84
|
+
onTransactionBroadcasted?: (broadcastResult: sdk.ReviewActionResult) => Promise<void>
|
|
85
|
+
onTransactionProven?: (txStatus: sdk.ProvenTransactionStatus) => Promise<void>
|
|
78
86
|
|
|
79
87
|
constructor(options: MonitorOptions) {
|
|
80
88
|
this.options = { ...options }
|
|
@@ -82,6 +90,8 @@ export class Monitor {
|
|
|
82
90
|
this.chain = this.services.chain
|
|
83
91
|
this.storage = options.storage
|
|
84
92
|
this.chaintracks = options.chaintracks
|
|
93
|
+
this.onTransactionProven = options.onTransactionProven
|
|
94
|
+
this.onTransactionBroadcasted = options.onTransactionBroadcasted
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
oneSecond = 1000
|
|
@@ -286,6 +296,32 @@ export class Monitor {
|
|
|
286
296
|
TaskCheckForProofs.checkNow = true
|
|
287
297
|
}
|
|
288
298
|
|
|
299
|
+
/**
|
|
300
|
+
* This is a function run from a TaskSendWaiting Monitor task.
|
|
301
|
+
*
|
|
302
|
+
* This allows the user of wallet-toolbox to 'subscribe' for transaction broadcast updates.
|
|
303
|
+
*
|
|
304
|
+
* @param broadcastResult
|
|
305
|
+
*/
|
|
306
|
+
callOnBroadcastedTransaction(broadcastResult: sdk.ReviewActionResult): void {
|
|
307
|
+
if (this.onTransactionBroadcasted) {
|
|
308
|
+
this.onTransactionBroadcasted(broadcastResult)
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* This is a function run from a TaskCheckForProofs Monitor task.
|
|
314
|
+
*
|
|
315
|
+
* This allows the user of wallet-toolbox to 'subscribe' for transaction updates.
|
|
316
|
+
*
|
|
317
|
+
* @param txStatus
|
|
318
|
+
*/
|
|
319
|
+
callOnProvenTransaction(txStatus: sdk.ProvenTransactionStatus): void {
|
|
320
|
+
if (this.onTransactionProven) {
|
|
321
|
+
this.onTransactionProven(txStatus)
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
289
325
|
/**
|
|
290
326
|
* Process reorg event received from Chaintracks
|
|
291
327
|
*
|
|
@@ -301,18 +337,3 @@ export class Monitor {
|
|
|
301
337
|
/* */
|
|
302
338
|
}
|
|
303
339
|
}
|
|
304
|
-
|
|
305
|
-
function sum<T>(a: T[], getNum: (v: T) => number): number {
|
|
306
|
-
let s = 0
|
|
307
|
-
for (const v of a) s += getNum(v)
|
|
308
|
-
return s
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function filter<T>(a: T[], pred: (v: T) => boolean): { ts: T[]; fs: T[] } {
|
|
312
|
-
const ts: T[] = []
|
|
313
|
-
const fs: T[] = []
|
|
314
|
-
for (const v of a)
|
|
315
|
-
if (pred(v)) ts.push(v)
|
|
316
|
-
else fs.push(v)
|
|
317
|
-
return { ts, fs }
|
|
318
|
-
}
|
|
@@ -216,6 +216,15 @@ export async function getProofs(
|
|
|
216
216
|
req.apiHistory = r.history
|
|
217
217
|
req.provenTxId = r.provenTxId
|
|
218
218
|
req.notified = true
|
|
219
|
+
|
|
220
|
+
task.monitor.callOnProvenTransaction({
|
|
221
|
+
txid,
|
|
222
|
+
txIndex: index,
|
|
223
|
+
blockHeight: height,
|
|
224
|
+
blockHash,
|
|
225
|
+
merklePath,
|
|
226
|
+
merkleRoot
|
|
227
|
+
})
|
|
219
228
|
} else {
|
|
220
229
|
if (countsAsAttempt && req.status !== 'nosend') {
|
|
221
230
|
req.attempts++
|
|
@@ -3,7 +3,9 @@ import { verifyTruthy } from '../../utility/index.client'
|
|
|
3
3
|
import { Monitor } from '../Monitor'
|
|
4
4
|
import { WalletMonitorTask } from './WalletMonitorTask'
|
|
5
5
|
import { attemptToPostReqsToNetwork } from '../../storage/methods/attemptToPostReqsToNetwork'
|
|
6
|
-
import { ProvenTxReqStatus } from '../../sdk'
|
|
6
|
+
import { ProvenTxReqStatus, WERR_INTERNAL } from '../../sdk'
|
|
7
|
+
import { ReviewActionResult, SendWithResult } from '@bsv/sdk'
|
|
8
|
+
import { aggregateActionResults } from '../../utility/aggregateResults'
|
|
7
9
|
|
|
8
10
|
export class TaskSendWaiting extends WalletMonitorTask {
|
|
9
11
|
static taskName = 'SendWaiting'
|
|
@@ -103,6 +105,15 @@ export class TaskSendWaiting extends WalletMonitorTask {
|
|
|
103
105
|
return attemptToPostReqsToNetwork(sp, reqs)
|
|
104
106
|
})
|
|
105
107
|
|
|
108
|
+
if (this.monitor.onTransactionBroadcasted) {
|
|
109
|
+
const rar = await this.storage.runAsStorageProvider(async sp => {
|
|
110
|
+
const ars: SendWithResult[] = [{ txid: req.txid, status: 'sending' }]
|
|
111
|
+
const { rar } = await aggregateActionResults(sp, ars, r)
|
|
112
|
+
return rar
|
|
113
|
+
})
|
|
114
|
+
this.monitor.callOnBroadcastedTransaction(rar[0])
|
|
115
|
+
}
|
|
116
|
+
|
|
106
117
|
log += r.log
|
|
107
118
|
}
|
|
108
119
|
return log
|
package/src/sdk/types.ts
CHANGED
|
@@ -133,6 +133,18 @@ export type ReqHistoryNote = {
|
|
|
133
133
|
[key: string]: boolean | string | number | undefined
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* The transaction status that a client will receive when subscribing to transaction updates in the Monitor.
|
|
138
|
+
*/
|
|
139
|
+
export interface ProvenTransactionStatus {
|
|
140
|
+
txid: string
|
|
141
|
+
txIndex: number
|
|
142
|
+
blockHeight: number
|
|
143
|
+
blockHash: string
|
|
144
|
+
merklePath: number[]
|
|
145
|
+
merkleRoot: string
|
|
146
|
+
}
|
|
147
|
+
|
|
136
148
|
/**
|
|
137
149
|
* `listOutputs` special operation basket name value.
|
|
138
150
|
*
|
|
@@ -45,7 +45,7 @@ describe('ARC tests', () => {
|
|
|
45
45
|
|
|
46
46
|
const headers: Record<string, string> = {
|
|
47
47
|
'Content-Type': 'application/json',
|
|
48
|
-
'XDeployment-ID': 'wallet-toolbox-test11'
|
|
48
|
+
'XDeployment-ID': 'wallet-toolbox-test11'
|
|
49
49
|
//Authorization: `Bearer ${envMain.gorillaPoolApiKey}`
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -7,9 +7,7 @@ import {
|
|
|
7
7
|
parseTxScriptOffsets,
|
|
8
8
|
randomBytesBase64,
|
|
9
9
|
sdk,
|
|
10
|
-
sha256Hash,
|
|
11
10
|
stampLog,
|
|
12
|
-
stampLogFormat,
|
|
13
11
|
StorageProvider,
|
|
14
12
|
TableCommission,
|
|
15
13
|
TableOutput,
|
|
@@ -17,16 +15,14 @@ import {
|
|
|
17
15
|
TableProvenTxReq,
|
|
18
16
|
TableTransaction,
|
|
19
17
|
TxScriptOffsets,
|
|
20
|
-
validateStorageFeeModel,
|
|
21
18
|
verifyId,
|
|
22
19
|
verifyInteger,
|
|
23
|
-
verifyNumber,
|
|
24
20
|
verifyOne,
|
|
25
21
|
verifyOneOrNone,
|
|
26
22
|
verifyTruthy
|
|
27
23
|
} from '../../index.client'
|
|
28
|
-
import { ReviewActionResult
|
|
29
|
-
import {
|
|
24
|
+
import { ReviewActionResult } from '../../sdk'
|
|
25
|
+
import { aggregateActionResults } from '../../utility/aggregateResults'
|
|
30
26
|
|
|
31
27
|
export async function processAction(
|
|
32
28
|
storage: StorageProvider,
|
|
@@ -122,15 +118,6 @@ export async function shareReqsWithWorld(
|
|
|
122
118
|
// Collect what we know about these sendWith transaction txids from storage.
|
|
123
119
|
const r = await storage.getReqsAndBeefToShareWithWorld(txids, [])
|
|
124
120
|
|
|
125
|
-
// Initialize aggregate results for each txid
|
|
126
|
-
const ars: {
|
|
127
|
-
txid: string
|
|
128
|
-
status: SendWithResultStatus
|
|
129
|
-
getReq: GetReqsAndBeefDetail
|
|
130
|
-
postReq?: PostReqsToNetworkDetails
|
|
131
|
-
ndr?: ReviewActionResult
|
|
132
|
-
}[] = []
|
|
133
|
-
|
|
134
121
|
const readyToSendReqs: EntityProvenTxReq[] = []
|
|
135
122
|
for (const getReq of r.details) {
|
|
136
123
|
let status: SendWithResultStatus = 'failed'
|
|
@@ -139,9 +126,8 @@ export async function shareReqsWithWorld(
|
|
|
139
126
|
status = 'sending'
|
|
140
127
|
readyToSendReqs.push(new EntityProvenTxReq(getReq.req!))
|
|
141
128
|
}
|
|
142
|
-
|
|
129
|
+
swr.push({
|
|
143
130
|
txid: getReq.txid,
|
|
144
|
-
getReq,
|
|
145
131
|
status
|
|
146
132
|
})
|
|
147
133
|
}
|
|
@@ -171,11 +157,11 @@ export async function shareReqsWithWorld(
|
|
|
171
157
|
await storage.updateTransaction(transactionIds, { status: 'sending' }, trx)
|
|
172
158
|
})
|
|
173
159
|
}
|
|
174
|
-
return
|
|
160
|
+
return { swr, ndr }
|
|
175
161
|
}
|
|
176
162
|
|
|
177
163
|
if (readyToSendReqIds.length < 1) {
|
|
178
|
-
return
|
|
164
|
+
return { swr, ndr }
|
|
179
165
|
}
|
|
180
166
|
|
|
181
167
|
if (batch) {
|
|
@@ -189,53 +175,8 @@ export async function shareReqsWithWorld(
|
|
|
189
175
|
//
|
|
190
176
|
const prtn = await storage.attemptToPostReqsToNetwork(readyToSendReqs)
|
|
191
177
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const txid = ar.txid
|
|
195
|
-
const d = prtn.details.find(d => d.txid === txid)
|
|
196
|
-
if (!d) throw new sdk.WERR_INTERNAL(`missing details for ${txid}`)
|
|
197
|
-
ar.ndr = { txid: d.txid, status: 'success', competingTxs: d.competingTxs }
|
|
198
|
-
switch (d.status) {
|
|
199
|
-
case 'success':
|
|
200
|
-
// processing network has accepted this transaction
|
|
201
|
-
ar.status = 'unproven'
|
|
202
|
-
break
|
|
203
|
-
case 'doubleSpend':
|
|
204
|
-
// confirmed double spend.
|
|
205
|
-
ar.status = 'failed'
|
|
206
|
-
ar.ndr.status = 'doubleSpend'
|
|
207
|
-
if (d.competingTxs) ar.ndr.competingBeef = await createMergedBeefOfTxids(d.competingTxs, storage)
|
|
208
|
-
break
|
|
209
|
-
case 'serviceError':
|
|
210
|
-
// services might improve
|
|
211
|
-
ar.status = 'sending'
|
|
212
|
-
ar.ndr.status = 'serviceError'
|
|
213
|
-
break
|
|
214
|
-
case 'invalidTx':
|
|
215
|
-
// nothing will fix this transaction
|
|
216
|
-
ar.status = 'failed'
|
|
217
|
-
ar.ndr.status = 'invalidTx'
|
|
218
|
-
break
|
|
219
|
-
case 'unknown':
|
|
220
|
-
case 'invalid':
|
|
221
|
-
default:
|
|
222
|
-
throw new sdk.WERR_INTERNAL(`processAction with notDelayed status ${d.status} should not occur.`)
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return createResults()
|
|
227
|
-
|
|
228
|
-
function createResults(): { swr: SendWithResult[]; ndr: ReviewActionResult[] | undefined } {
|
|
229
|
-
swr = []
|
|
230
|
-
ndr = isDelayed ? undefined : []
|
|
231
|
-
for (const ar of ars) {
|
|
232
|
-
swr.push({ txid: ar.txid, status: ar.status })
|
|
233
|
-
if (ar.ndr && ndr) {
|
|
234
|
-
ndr.push(ar.ndr)
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return { swr, ndr }
|
|
238
|
-
}
|
|
178
|
+
const { swr: swrRes, rar } = await aggregateActionResults(storage, swr, prtn)
|
|
179
|
+
return { swr: swrRes, ndr: rar }
|
|
239
180
|
}
|
|
240
181
|
|
|
241
182
|
interface ReqTxStatus {
|
|
@@ -452,15 +393,3 @@ async function commitNewTxToStorage(
|
|
|
452
393
|
|
|
453
394
|
return r
|
|
454
395
|
}
|
|
455
|
-
|
|
456
|
-
async function createMergedBeefOfTxids(txids: string[], storage: StorageProvider): Promise<number[]> {
|
|
457
|
-
const beef = new Beef()
|
|
458
|
-
const options: StorageGetBeefOptions = {
|
|
459
|
-
mergeToBeef: beef,
|
|
460
|
-
ignoreNewProven: true
|
|
461
|
-
}
|
|
462
|
-
for (const txid of txids) {
|
|
463
|
-
await storage.getBeefForTransaction(txid, options)
|
|
464
|
-
}
|
|
465
|
-
return beef.toBinary()
|
|
466
|
-
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Beef, ReviewActionResult, SendWithResult } from '@bsv/sdk'
|
|
2
|
+
import { PostReqsToNetworkResult } from '../storage/methods/attemptToPostReqsToNetwork'
|
|
3
|
+
import { StorageGetBeefOptions, WERR_INTERNAL } from '../sdk'
|
|
4
|
+
import { StorageProvider } from '../index.client'
|
|
5
|
+
|
|
6
|
+
export const aggregateActionResults = async (
|
|
7
|
+
storage: StorageProvider,
|
|
8
|
+
sendWithResultReqs: SendWithResult[],
|
|
9
|
+
postToNetworkResult: PostReqsToNetworkResult
|
|
10
|
+
): Promise<{
|
|
11
|
+
swr: SendWithResult[]
|
|
12
|
+
rar: ReviewActionResult[]
|
|
13
|
+
}> => {
|
|
14
|
+
const swr: SendWithResult[] = []
|
|
15
|
+
const rar: ReviewActionResult[] = []
|
|
16
|
+
|
|
17
|
+
for (const ar of sendWithResultReqs) {
|
|
18
|
+
const txid = ar.txid
|
|
19
|
+
|
|
20
|
+
const d = postToNetworkResult.details.find(d => d.txid === txid)
|
|
21
|
+
if (!d) throw new WERR_INTERNAL(`missing details for ${txid}`)
|
|
22
|
+
|
|
23
|
+
const arNdr: ReviewActionResult = { txid: d.txid, status: 'success', competingTxs: d.competingTxs }
|
|
24
|
+
switch (d.status) {
|
|
25
|
+
case 'success':
|
|
26
|
+
// processing network has accepted this transaction
|
|
27
|
+
ar.status = 'unproven'
|
|
28
|
+
break
|
|
29
|
+
case 'doubleSpend':
|
|
30
|
+
// confirmed double spend.
|
|
31
|
+
ar.status = 'failed'
|
|
32
|
+
arNdr.status = 'doubleSpend'
|
|
33
|
+
if (d.competingTxs) arNdr.competingBeef = await createMergedBeefOfTxids(d.competingTxs, storage)
|
|
34
|
+
break
|
|
35
|
+
case 'serviceError':
|
|
36
|
+
// services might improve
|
|
37
|
+
ar.status = 'sending'
|
|
38
|
+
arNdr.status = 'serviceError'
|
|
39
|
+
break
|
|
40
|
+
case 'invalidTx':
|
|
41
|
+
// nothing will fix this transaction
|
|
42
|
+
ar.status = 'failed'
|
|
43
|
+
arNdr.status = 'invalidTx'
|
|
44
|
+
break
|
|
45
|
+
case 'unknown':
|
|
46
|
+
case 'invalid':
|
|
47
|
+
default:
|
|
48
|
+
throw new WERR_INTERNAL(`processAction with notDelayed status ${d.status} should not occur.`)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
swr.push({ txid, status: ar.status })
|
|
52
|
+
rar.push(arNdr)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { swr, rar }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function createMergedBeefOfTxids(txids: string[], storage: StorageProvider): Promise<number[]> {
|
|
59
|
+
const beef = new Beef()
|
|
60
|
+
const options: StorageGetBeefOptions = {
|
|
61
|
+
mergeToBeef: beef,
|
|
62
|
+
ignoreNewProven: true
|
|
63
|
+
}
|
|
64
|
+
for (const txid of txids) {
|
|
65
|
+
await storage.getBeefForTransaction(txid, options)
|
|
66
|
+
}
|
|
67
|
+
return beef.toBinary()
|
|
68
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MerklePath } from '@bsv/sdk'
|
|
1
|
+
import { Beef, MerklePath } from '@bsv/sdk'
|
|
2
2
|
import { asArray, EntityProvenTxReq, sdk, verifyOne, verifyTruthy, wait } from '../../src/index.client'
|
|
3
3
|
import { TaskCheckForProofs } from '../../src/monitor/tasks/TaskCheckForProofs'
|
|
4
4
|
import { TaskClock } from '../../src/monitor/tasks/TaskClock'
|
|
@@ -490,4 +490,126 @@ describe('Monitor tests', () => {
|
|
|
490
490
|
await ctx.storage.destroy()
|
|
491
491
|
}
|
|
492
492
|
})
|
|
493
|
+
|
|
494
|
+
test('8 ProcessProvenTransaction', async () => {
|
|
495
|
+
const ctxs: TestWallet<{}>[] = []
|
|
496
|
+
ctxs.push(await _tu.createLegacyWalletSQLiteCopy('monitorTest8'))
|
|
497
|
+
let mockResultIndex = 0
|
|
498
|
+
let updatesReceived = 0
|
|
499
|
+
|
|
500
|
+
const expectedTxids = [
|
|
501
|
+
'c099c52277426abb863dc902d0389b008ddf2301d6b40ac718746ac16ca59136',
|
|
502
|
+
'6935ce33b9e3b9ee60360ce0606aa0a0970b4840203f457b5559212676dc33ab',
|
|
503
|
+
'67ca2475886b3fc2edd76a2eb8c32bd0bc308176c7dff463e0507942aeebcbec',
|
|
504
|
+
'3fa94b62a3b10d8c18bada527a9b68c4e70db67140719df16c44fb0328782532',
|
|
505
|
+
'519675259eff036c6597e4a497d37c132e718171dde4ea2257e84c947ecf656b'
|
|
506
|
+
]
|
|
507
|
+
|
|
508
|
+
_tu.mockMerklePathServicesAsCallback(ctxs, async txid => {
|
|
509
|
+
expect(expectedTxids).toContain(txid)
|
|
510
|
+
const r = mockGetMerklePathResults[mockResultIndex++]
|
|
511
|
+
return r
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
for (const { activeStorage: storage, monitor } of ctxs) {
|
|
515
|
+
if (!monitor) throw new sdk.WERR_INTERNAL('test requires setup with monitor')
|
|
516
|
+
|
|
517
|
+
monitor.lastNewHeader = {
|
|
518
|
+
height: 999999999,
|
|
519
|
+
hash: '',
|
|
520
|
+
time: 0,
|
|
521
|
+
version: 0,
|
|
522
|
+
previousHash: '',
|
|
523
|
+
merkleRoot: '',
|
|
524
|
+
bits: 0,
|
|
525
|
+
nonce: 0
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
monitor.onTransactionProven = async (txStatus: sdk.ProvenTransactionStatus) => {
|
|
529
|
+
expect(txStatus.txid).toBeTruthy()
|
|
530
|
+
expect(txStatus.blockHash).toBeTruthy()
|
|
531
|
+
expect(txStatus.blockHeight).toBeTruthy()
|
|
532
|
+
expect(txStatus.merkleRoot).toBeTruthy()
|
|
533
|
+
updatesReceived++
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
for (const txid of expectedTxids) {
|
|
537
|
+
// no matching ProvenTx exists.
|
|
538
|
+
expect((await storage.findProvenTxs({ partial: { txid } })).length).toBe(0)
|
|
539
|
+
const req = verifyTruthy(await EntityProvenTxReq.fromStorageTxid(storage, txid))
|
|
540
|
+
expect(req.status).toBe('unmined')
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const task = new TaskCheckForProofs(monitor, 1)
|
|
544
|
+
monitor._tasks.push(task)
|
|
545
|
+
|
|
546
|
+
await monitor.runTask('CheckForProofs')
|
|
547
|
+
|
|
548
|
+
for (const txid of expectedTxids) {
|
|
549
|
+
const proven = verifyOne(await storage.findProvenTxs({ partial: { txid } }))
|
|
550
|
+
expect(proven.merklePath).toBeTruthy()
|
|
551
|
+
const req = verifyTruthy(await EntityProvenTxReq.fromStorageTxid(storage, txid))
|
|
552
|
+
expect(req.status).toBe('completed')
|
|
553
|
+
expect(req.provenTxId).toBe(proven.provenTxId)
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
expect(updatesReceived).toEqual(expectedTxids.length)
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
for (const ctx of ctxs) {
|
|
560
|
+
await ctx.storage.destroy()
|
|
561
|
+
}
|
|
562
|
+
})
|
|
563
|
+
|
|
564
|
+
test('9 ProcessBroadcastedTransactions', async () => {
|
|
565
|
+
const ctxs: TestWallet<{}>[] = []
|
|
566
|
+
ctxs.push(await _tu.createLegacyWalletSQLiteCopy('monitorTest8'))
|
|
567
|
+
let updatesReceived = 0
|
|
568
|
+
let txidsPosted: string[] = []
|
|
569
|
+
|
|
570
|
+
const expectedTxids = [
|
|
571
|
+
'd9ec73b2e0f06e0f482d2d1db9ceccf2f212f0b24afbe10846ac907567be571f',
|
|
572
|
+
'b7634f08d8c7f3c6244050bebf73a79f40e672aba7d5232663609a58b123b816',
|
|
573
|
+
'3d2ea64ee584a1f6eb161dbedf3a8d299e3e4497ac7a203d23c044c998c6aa08',
|
|
574
|
+
'a3a8fe7f541c1383ff7b975af49b27284ae720af5f2705d8409baaf519190d26',
|
|
575
|
+
'6d68cc6fa7363e59aaccbaa65f0ca613a6ae8af718453ab5d3a2b022c59b5cc6'
|
|
576
|
+
]
|
|
577
|
+
|
|
578
|
+
_tu.mockPostServicesAsCallback(ctxs, (beef: Beef, txids: string[]) => {
|
|
579
|
+
txidsPosted.push(...txids)
|
|
580
|
+
return 'success'
|
|
581
|
+
})
|
|
582
|
+
|
|
583
|
+
for (const { activeStorage: storage, monitor } of ctxs) {
|
|
584
|
+
if (!monitor) throw new sdk.WERR_INTERNAL('test requires setup with monitor')
|
|
585
|
+
|
|
586
|
+
for (const txid of expectedTxids) {
|
|
587
|
+
const req = verifyTruthy(await EntityProvenTxReq.fromStorageTxid(storage, txid))
|
|
588
|
+
expect(req.status).toBe('unsent')
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
monitor.onTransactionBroadcasted = async (broadcastResult: sdk.ReviewActionResult) => {
|
|
592
|
+
expect(broadcastResult.status).toBe('success')
|
|
593
|
+
expect(expectedTxids).toContain(broadcastResult.txid)
|
|
594
|
+
updatesReceived++
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const task = new TaskSendWaiting(monitor, 1, 1)
|
|
598
|
+
monitor._tasks.push(task)
|
|
599
|
+
|
|
600
|
+
await monitor.runTask('SendWaiting')
|
|
601
|
+
|
|
602
|
+
expect(txidsPosted).toEqual(expectedTxids)
|
|
603
|
+
for (const txid of expectedTxids) {
|
|
604
|
+
const req = verifyOne(await storage.findProvenTxReqs({ partial: { txid } }))
|
|
605
|
+
expect(req.status).toBe('unmined')
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
expect(updatesReceived).toEqual(expectedTxids.length)
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
for (const ctx of ctxs) {
|
|
612
|
+
await ctx.storage.destroy()
|
|
613
|
+
}
|
|
614
|
+
})
|
|
493
615
|
})
|