@bsv/overlay 0.5.0-rc1 → 0.5.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/dist/cjs/package.json +2 -2
- package/dist/cjs/src/Engine.js +249 -220
- package/dist/cjs/src/Engine.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/Engine.js +245 -216
- package/dist/esm/src/Engine.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/Engine.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/API.md +2 -2
- package/package.json +3 -3
- package/src/Engine.ts +243 -218
- package/dist/cjs/src/AdmittanceInstructions.js +0 -3
- package/dist/cjs/src/AdmittanceInstructions.js.map +0 -1
- package/dist/cjs/src/LookupAnswer.js +0 -3
- package/dist/cjs/src/LookupAnswer.js.map +0 -1
- package/dist/cjs/src/LookupQuestion.js +0 -3
- package/dist/cjs/src/LookupQuestion.js.map +0 -1
- package/dist/cjs/src/SHIPAdvertisement.js +0 -3
- package/dist/cjs/src/SHIPAdvertisement.js.map +0 -1
- package/dist/cjs/src/SLAPAdvertisement.js +0 -3
- package/dist/cjs/src/SLAPAdvertisement.js.map +0 -1
- package/dist/cjs/src/STEAK.js +0 -3
- package/dist/cjs/src/STEAK.js.map +0 -1
- package/dist/cjs/src/TaggedBEEF.js +0 -3
- package/dist/cjs/src/TaggedBEEF.js.map +0 -1
- package/dist/esm/src/AdmittanceInstructions.js +0 -2
- package/dist/esm/src/AdmittanceInstructions.js.map +0 -1
- package/dist/esm/src/LookupAnswer.js +0 -2
- package/dist/esm/src/LookupAnswer.js.map +0 -1
- package/dist/esm/src/LookupQuestion.js +0 -2
- package/dist/esm/src/LookupQuestion.js.map +0 -1
- package/dist/esm/src/SHIPAdvertisement.js +0 -2
- package/dist/esm/src/SHIPAdvertisement.js.map +0 -1
- package/dist/esm/src/SLAPAdvertisement.js +0 -2
- package/dist/esm/src/SLAPAdvertisement.js.map +0 -1
- package/dist/esm/src/STEAK.js +0 -2
- package/dist/esm/src/STEAK.js.map +0 -1
- package/dist/esm/src/TaggedBEEF.js +0 -2
- package/dist/esm/src/TaggedBEEF.js.map +0 -1
- package/dist/types/src/AdmittanceInstructions.d.ts +0 -14
- package/dist/types/src/AdmittanceInstructions.d.ts.map +0 -1
- package/dist/types/src/LookupAnswer.d.ts +0 -15
- package/dist/types/src/LookupAnswer.d.ts.map +0 -1
- package/dist/types/src/LookupQuestion.d.ts +0 -15
- package/dist/types/src/LookupQuestion.d.ts.map +0 -1
- package/dist/types/src/SHIPAdvertisement.d.ts +0 -9
- package/dist/types/src/SHIPAdvertisement.d.ts.map +0 -1
- package/dist/types/src/SLAPAdvertisement.d.ts +0 -9
- package/dist/types/src/SLAPAdvertisement.d.ts.map +0 -1
- package/dist/types/src/STEAK.d.ts +0 -10
- package/dist/types/src/STEAK.d.ts.map +0 -1
- package/dist/types/src/TaggedBEEF.d.ts +0 -11
- package/dist/types/src/TaggedBEEF.d.ts.map +0 -1
package/src/Engine.ts
CHANGED
|
@@ -151,124 +151,132 @@ export class Engine {
|
|
|
151
151
|
|
|
152
152
|
const steak: STEAK = {}
|
|
153
153
|
const dupeTopics = new Set<string>()
|
|
154
|
+
const failedTopics = new Set<string>()
|
|
154
155
|
|
|
155
156
|
// Parallelize the topic processing
|
|
156
|
-
const topicPromises = taggedBEEF.topics.map(async topic => {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
const topicPromises = taggedBEEF.topics.map(async (topic) => {
|
|
158
|
+
try {
|
|
159
|
+
if (this.managers[topic] === undefined || this.managers[topic] === null) {
|
|
160
|
+
throw new Error(`This server does not support this topic: ${topic}`)
|
|
161
|
+
}
|
|
160
162
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
// Check for duplicate transactions
|
|
164
|
+
this.startTime(`dupCheck_${txid.substring(0, 10)}`)
|
|
165
|
+
const dupeCheck = await this.storage.doesAppliedTransactionExist({ txid, topic })
|
|
166
|
+
this.endTime(`dupCheck_${txid.substring(0, 10)}`)
|
|
165
167
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
if (dupeCheck) {
|
|
169
|
+
dupeTopics.add(topic)
|
|
170
|
+
steak[topic] = { outputsToAdmit: [], coinsToRetain: [] }
|
|
171
|
+
return
|
|
172
|
+
}
|
|
171
173
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
174
|
+
// Identify previous coins admitted to this specific topic
|
|
175
|
+
const previousCoins: number[] = []
|
|
176
|
+
const outputPromises = tx.inputs.map(async (input, i) => {
|
|
177
|
+
const previousTXID = input.sourceTXID !== undefined ? input.sourceTXID : input.sourceTransaction?.id('hex')
|
|
178
|
+
if (previousTXID !== undefined) {
|
|
179
|
+
// Check if the previous output was admitted to this specific topic
|
|
180
|
+
const output = await this.storage.findOutput(previousTXID, input.sourceOutputIndex, topic)
|
|
181
|
+
if (output !== undefined && output !== null) {
|
|
182
|
+
previousCoins.push(i)
|
|
183
|
+
return output
|
|
184
|
+
}
|
|
182
185
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
})
|
|
186
|
+
return null
|
|
187
|
+
})
|
|
186
188
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
189
|
+
this.startTime(`previousOutputQuery_${txid.substring(0, 10)}`)
|
|
190
|
+
const outputs = await Promise.all(outputPromises)
|
|
191
|
+
this.endTime(`previousOutputQuery_${txid.substring(0, 10)}`)
|
|
190
192
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
193
|
+
const markSpentPromises = outputs.map(async (output) => {
|
|
194
|
+
if (output !== undefined && output !== null) {
|
|
195
|
+
try {
|
|
196
|
+
await this.storage.markUTXOAsSpent(output.txid, output.outputIndex, topic)
|
|
197
|
+
await Promise.all(Object.values(this.lookupServices).map(async l => {
|
|
198
|
+
try {
|
|
199
|
+
if (typeof l.outputSpent === 'function') {
|
|
200
|
+
if (l.spendNotificationMode === 'txid') {
|
|
201
|
+
await l.outputSpent({
|
|
202
|
+
mode: 'txid',
|
|
203
|
+
spendingTxid: txid,
|
|
204
|
+
txid: output.txid,
|
|
205
|
+
outputIndex: output.outputIndex,
|
|
206
|
+
topic
|
|
207
|
+
})
|
|
208
|
+
} else if (l.spendNotificationMode === 'script') {
|
|
209
|
+
const inputIndex = tx.inputs.findIndex(i => {
|
|
210
|
+
let realSource = i.sourceTXID
|
|
211
|
+
if (!realSource) {
|
|
212
|
+
realSource = i.sourceTransaction?.id('hex')
|
|
213
|
+
}
|
|
214
|
+
return realSource === output.txid && i.sourceOutputIndex === output.outputIndex
|
|
215
|
+
})
|
|
216
|
+
if (inputIndex === -1) {
|
|
217
|
+
throw new Error('Could not find input index')
|
|
211
218
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
219
|
+
await l.outputSpent({
|
|
220
|
+
mode: 'script',
|
|
221
|
+
spendingTxid: txid,
|
|
222
|
+
inputIndex,
|
|
223
|
+
sequenceNumber: tx.inputs[inputIndex].sequence ?? 0xffffffff,
|
|
224
|
+
unlockingScript: tx.inputs[inputIndex].unlockingScript!,
|
|
225
|
+
txid: output.txid,
|
|
226
|
+
outputIndex: output.outputIndex,
|
|
227
|
+
topic,
|
|
228
|
+
offChainValues
|
|
229
|
+
})
|
|
230
|
+
} else if (l.spendNotificationMode === 'whole-tx') {
|
|
231
|
+
await l.outputSpent({
|
|
232
|
+
mode: 'whole-tx',
|
|
233
|
+
spendingAtomicBEEF: tx.toAtomicBEEF(),
|
|
234
|
+
txid: output.txid,
|
|
235
|
+
outputIndex: output.outputIndex,
|
|
236
|
+
topic,
|
|
237
|
+
offChainValues
|
|
238
|
+
})
|
|
239
|
+
} else { // none
|
|
240
|
+
await l.outputSpent({
|
|
241
|
+
mode: 'none',
|
|
242
|
+
txid: output.txid,
|
|
243
|
+
outputIndex: output.outputIndex,
|
|
244
|
+
topic
|
|
245
|
+
})
|
|
216
246
|
}
|
|
217
|
-
await l.outputSpent({
|
|
218
|
-
mode: 'script',
|
|
219
|
-
spendingTxid: txid,
|
|
220
|
-
inputIndex,
|
|
221
|
-
sequenceNumber: tx.inputs[inputIndex].sequence ?? 0xffffffff,
|
|
222
|
-
unlockingScript: tx.inputs[inputIndex].unlockingScript!,
|
|
223
|
-
txid: output.txid,
|
|
224
|
-
outputIndex: output.outputIndex,
|
|
225
|
-
topic,
|
|
226
|
-
offChainValues
|
|
227
|
-
})
|
|
228
|
-
} else if (l.spendNotificationMode === 'whole-tx') {
|
|
229
|
-
await l.outputSpent({
|
|
230
|
-
mode: 'whole-tx',
|
|
231
|
-
spendingAtomicBEEF: tx.toAtomicBEEF(),
|
|
232
|
-
txid: output.txid,
|
|
233
|
-
outputIndex: output.outputIndex,
|
|
234
|
-
topic,
|
|
235
|
-
offChainValues
|
|
236
|
-
})
|
|
237
|
-
} else { // none
|
|
238
|
-
await l.outputSpent({
|
|
239
|
-
mode: 'none',
|
|
240
|
-
txid: output.txid,
|
|
241
|
-
outputIndex: output.outputIndex,
|
|
242
|
-
topic
|
|
243
|
-
})
|
|
244
247
|
}
|
|
248
|
+
} catch (error) {
|
|
249
|
+
this.logger.error('Error in lookup service for outputSpent:', error)
|
|
245
250
|
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
} catch (error) {
|
|
251
|
-
this.logger.error('Error marking UTXO as spent:', error)
|
|
251
|
+
}))
|
|
252
|
+
} catch (error) {
|
|
253
|
+
this.logger.error('Error marking UTXO as spent:', error)
|
|
254
|
+
}
|
|
252
255
|
}
|
|
253
|
-
}
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
let admissibleOutputs: AdmittanceInstructions = { outputsToAdmit: [], coinsToRetain: [] }
|
|
257
|
-
// Determine which outputs are admissible for this topic
|
|
258
|
-
const admissibleOutputsPromise = (async () => {
|
|
259
|
-
try {
|
|
260
|
-
this.startTime(`identifyAdmissibleOutputs_${txid.substring(0, 10)}`)
|
|
261
|
-
admissibleOutputs = await this.managers[topic].identifyAdmissibleOutputs(taggedBEEF.beef, previousCoins, offChainValues)
|
|
262
|
-
this.endTime(`identifyAdmissibleOutputs_${txid.substring(0, 10)}`)
|
|
263
|
-
} catch (_) {
|
|
264
|
-
steak[topic] = { outputsToAdmit: [], coinsToRetain: [] }
|
|
265
|
-
}
|
|
266
|
-
})()
|
|
256
|
+
})
|
|
267
257
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
258
|
+
let admissibleOutputs: AdmittanceInstructions = { outputsToAdmit: [], coinsToRetain: [] }
|
|
259
|
+
// Determine which outputs are admissible for this topic
|
|
260
|
+
const admissibleOutputsPromise = (async () => {
|
|
261
|
+
try {
|
|
262
|
+
this.startTime(`identifyAdmissibleOutputs_${txid.substring(0, 10)}`)
|
|
263
|
+
admissibleOutputs = await this.managers[topic].identifyAdmissibleOutputs(taggedBEEF.beef, previousCoins, offChainValues)
|
|
264
|
+
this.endTime(`identifyAdmissibleOutputs_${txid.substring(0, 10)}`)
|
|
265
|
+
} catch (_) {
|
|
266
|
+
failedTopics.add(topic)
|
|
267
|
+
steak[topic] = { outputsToAdmit: [], coinsToRetain: [] }
|
|
268
|
+
}
|
|
269
|
+
})()
|
|
270
|
+
|
|
271
|
+
// Wait for both tasks to complete
|
|
272
|
+
await Promise.all([...markSpentPromises, admissibleOutputsPromise])
|
|
273
|
+
// Keep track of what outputs were admitted for what topic
|
|
274
|
+
steak[topic] = admissibleOutputs
|
|
275
|
+
} catch (error) {
|
|
276
|
+
this.logger.error('Error processing topic during submit:', error)
|
|
277
|
+
failedTopics.add(topic)
|
|
278
|
+
steak[topic] = { outputsToAdmit: [], coinsToRetain: [] }
|
|
279
|
+
}
|
|
272
280
|
})
|
|
273
281
|
|
|
274
282
|
await Promise.all(topicPromises)
|
|
@@ -276,11 +284,18 @@ export class Engine {
|
|
|
276
284
|
// Broadcast the transaction if not historical and broadcaster is configured
|
|
277
285
|
this.startTime(`broadcast_${txid.substring(0, 10)}`)
|
|
278
286
|
if (mode !== 'historical-tx' && this.broadcaster !== undefined) {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
287
|
+
try {
|
|
288
|
+
const response = await this.broadcaster.broadcast(tx)
|
|
289
|
+
if (isBroadcastFailure(response) && this.throwOnBroadcastFailure) {
|
|
290
|
+
const e = new Error(`Failed to broadcast transaction! Error: ${response.description}`)
|
|
291
|
+
;(e as any).more = response.more
|
|
292
|
+
throw e
|
|
293
|
+
}
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (this.throwOnBroadcastFailure) {
|
|
296
|
+
throw error
|
|
297
|
+
}
|
|
298
|
+
this.logger.error('Error broadcasting transaction:', error)
|
|
284
299
|
}
|
|
285
300
|
}
|
|
286
301
|
this.endTime(`broadcast_${txid.substring(0, 10)}`)
|
|
@@ -295,131 +310,141 @@ export class Engine {
|
|
|
295
310
|
if (dupeTopics.has(topic)) {
|
|
296
311
|
continue
|
|
297
312
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
313
|
+
if (failedTopics.has(topic)) {
|
|
314
|
+
continue
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
const admissibleOutputs = steak[topic]
|
|
318
|
+
const outputsToAdmit: number[] = admissibleOutputs.outputsToAdmit
|
|
319
|
+
const outputsConsumed: Array<{
|
|
320
|
+
txid: string
|
|
321
|
+
outputIndex: number
|
|
322
|
+
}> = []
|
|
323
|
+
|
|
324
|
+
const outputsToMarkStale: Array<{
|
|
325
|
+
txid: string
|
|
326
|
+
previousOutputIndex: number
|
|
327
|
+
inputIndex: number
|
|
328
|
+
}> = []
|
|
311
329
|
|
|
312
330
|
// Recompute previousCoins for this topic to use in the update logic
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
331
|
+
const previousCoins: number[] = []
|
|
332
|
+
await Promise.all(tx.inputs.map(async (input, i) => {
|
|
333
|
+
const previousTXID = input.sourceTXID !== undefined ? input.sourceTXID : input.sourceTransaction?.id('hex')
|
|
334
|
+
if (previousTXID !== undefined) {
|
|
335
|
+
const output = await this.storage.findOutput(previousTXID, input.sourceOutputIndex, topic)
|
|
336
|
+
if (output !== undefined && output !== null) {
|
|
337
|
+
previousCoins.push(i)
|
|
338
|
+
}
|
|
320
339
|
}
|
|
321
|
-
}
|
|
322
|
-
}))
|
|
340
|
+
}))
|
|
323
341
|
|
|
324
342
|
// For each of the previous UTXOs for this topic, if the UTXO was not included in the list of UTXOs identified for retention, then it will be marked as stale.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
343
|
+
for (const inputIndex of previousCoins) {
|
|
344
|
+
const previousTXID = tx.inputs[inputIndex].sourceTXID ?? tx.inputs[inputIndex].sourceTransaction?.id('hex')
|
|
345
|
+
if (typeof previousTXID !== 'string') continue
|
|
346
|
+
const previousOutputIndex = tx.inputs[inputIndex].sourceOutputIndex
|
|
347
|
+
if (!admissibleOutputs.coinsToRetain.includes(inputIndex)) {
|
|
348
|
+
outputsToMarkStale.push({
|
|
349
|
+
txid: previousTXID,
|
|
350
|
+
previousOutputIndex,
|
|
351
|
+
inputIndex
|
|
352
|
+
})
|
|
353
|
+
} else {
|
|
354
|
+
outputsConsumed.push({
|
|
355
|
+
txid: previousTXID,
|
|
356
|
+
outputIndex: previousOutputIndex
|
|
357
|
+
})
|
|
358
|
+
}
|
|
340
359
|
}
|
|
341
|
-
}
|
|
342
360
|
|
|
343
361
|
// Remove stale outputs recursively
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
362
|
+
this.startTime(`lookForStaleOutputs_${txid.substring(0, 10)}`)
|
|
363
|
+
await Promise.all(outputsToMarkStale.map(async coin => {
|
|
364
|
+
const output = await this.storage.findOutput(coin.txid, coin.previousOutputIndex, topic)
|
|
365
|
+
if (output !== undefined && output !== null) {
|
|
366
|
+
await this.deleteUTXODeep(output)
|
|
367
|
+
}
|
|
368
|
+
}))
|
|
369
|
+
this.endTime(`lookForStaleOutputs_${txid.substring(0, 10)}`)
|
|
352
370
|
|
|
353
371
|
// Update the STEAK to indicate which coins were removed
|
|
354
|
-
|
|
372
|
+
steak[topic].coinsRemoved = outputsToMarkStale.map(x => x.inputIndex)
|
|
355
373
|
|
|
356
374
|
// Handle admittance and notification of incoming UTXOs
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
375
|
+
const newUTXOs: Array<{ txid: string, outputIndex: number }> = []
|
|
376
|
+
await Promise.all(outputsToAdmit.map(async outputIndex => {
|
|
377
|
+
if (typeof tx.outputs[outputIndex].satoshis !== 'number') return
|
|
378
|
+
this.startTime(`insertNewOutput_${txid.substring(0, 10)}`)
|
|
379
|
+
await this.storage.insertOutput({
|
|
380
|
+
txid,
|
|
381
|
+
outputIndex,
|
|
382
|
+
outputScript: tx.outputs[outputIndex].lockingScript.toBinary(),
|
|
383
|
+
satoshis: tx.outputs[outputIndex].satoshis,
|
|
384
|
+
topic,
|
|
385
|
+
spent: false,
|
|
386
|
+
beef: taggedBEEF.beef,
|
|
387
|
+
consumedBy: [],
|
|
388
|
+
outputsConsumed,
|
|
389
|
+
score: Date.now()
|
|
390
|
+
})
|
|
391
|
+
this.endTime(`insertNewOutput_${txid.substring(0, 10)}`)
|
|
392
|
+
newUTXOs.push({ txid, outputIndex })
|
|
393
|
+
|
|
394
|
+
this.startTime(`notifyLookupService${txid.substring(0, 10)}`)
|
|
395
|
+
await Promise.all(Object.values(this.lookupServices).map(async l => {
|
|
396
|
+
try {
|
|
397
|
+
if (l.admissionMode === 'locking-script') {
|
|
398
|
+
if (
|
|
399
|
+
typeof tx.outputs[outputIndex].lockingScript !== 'object' ||
|
|
400
|
+
typeof tx.outputs[outputIndex].satoshis !== 'number'
|
|
401
|
+
) {
|
|
402
|
+
return
|
|
403
|
+
}
|
|
404
|
+
await l.outputAdmittedByTopic({
|
|
405
|
+
mode: 'locking-script',
|
|
406
|
+
txid,
|
|
407
|
+
outputIndex,
|
|
408
|
+
lockingScript: tx.outputs[outputIndex].lockingScript,
|
|
409
|
+
satoshis: tx.outputs[outputIndex].satoshis,
|
|
410
|
+
topic,
|
|
411
|
+
offChainValues
|
|
412
|
+
})
|
|
413
|
+
} else {
|
|
414
|
+
await l.outputAdmittedByTopic({
|
|
415
|
+
mode: 'whole-tx',
|
|
416
|
+
atomicBEEF: tx.toAtomicBEEF(),
|
|
417
|
+
outputIndex,
|
|
418
|
+
topic,
|
|
419
|
+
offChainValues
|
|
420
|
+
})
|
|
421
|
+
}
|
|
422
|
+
} catch (error) {
|
|
423
|
+
this.logger.error('Error in lookup service for outputAdmittedByTopic:', error)
|
|
384
424
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
txid,
|
|
388
|
-
outputIndex,
|
|
389
|
-
lockingScript: tx.outputs[outputIndex].lockingScript,
|
|
390
|
-
satoshis: tx.outputs[outputIndex].satoshis,
|
|
391
|
-
topic,
|
|
392
|
-
offChainValues
|
|
393
|
-
})
|
|
394
|
-
} else {
|
|
395
|
-
await l.outputAdmittedByTopic({
|
|
396
|
-
mode: 'whole-tx',
|
|
397
|
-
atomicBEEF: tx.toAtomicBEEF(),
|
|
398
|
-
outputIndex,
|
|
399
|
-
topic,
|
|
400
|
-
offChainValues
|
|
401
|
-
})
|
|
402
|
-
}
|
|
425
|
+
}))
|
|
426
|
+
this.endTime(`notifyLookupService${txid.substring(0, 10)}`)
|
|
403
427
|
}))
|
|
404
|
-
this.endTime(`notifyLookupService${txid.substring(0, 10)}`)
|
|
405
|
-
}))
|
|
406
428
|
|
|
407
|
-
|
|
429
|
+
this.startTime(`outputConsumed_${txid.substring(0, 10)}`)
|
|
408
430
|
// Update each output consumed to know who consumed it and insert applied transaction in parallel
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
431
|
+
await Promise.all([
|
|
432
|
+
...outputsConsumed.map(async output => {
|
|
433
|
+
const outputToUpdate = await this.storage.findOutput(output.txid, output.outputIndex, topic)
|
|
434
|
+
if (outputToUpdate !== undefined && outputToUpdate !== null) {
|
|
435
|
+
const newConsumedBy = [...new Set([...newUTXOs, ...outputToUpdate.consumedBy])]
|
|
436
|
+
await this.storage.updateConsumedBy(output.txid, output.outputIndex, topic, newConsumedBy)
|
|
437
|
+
}
|
|
438
|
+
}),
|
|
439
|
+
this.storage.insertAppliedTransaction({
|
|
440
|
+
txid,
|
|
441
|
+
topic
|
|
442
|
+
})
|
|
443
|
+
])
|
|
444
|
+
this.endTime(`outputConsumed_${txid.substring(0, 10)}`)
|
|
445
|
+
} catch (error) {
|
|
446
|
+
this.logger.error('Error updating storage and notifying lookup services for topic', topic, error)
|
|
447
|
+
}
|
|
423
448
|
}
|
|
424
449
|
|
|
425
450
|
// If we don't have an advertiser or we are dealing with historical transactions, just return the steak
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AdmittanceInstructions.js","sourceRoot":"","sources":["../../../src/AdmittanceInstructions.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LookupAnswer.js","sourceRoot":"","sources":["../../../src/LookupAnswer.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LookupQuestion.js","sourceRoot":"","sources":["../../../src/LookupQuestion.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SHIPAdvertisement.js","sourceRoot":"","sources":["../../../src/SHIPAdvertisement.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SLAPAdvertisement.js","sourceRoot":"","sources":["../../../src/SLAPAdvertisement.ts"],"names":[],"mappings":""}
|
package/dist/cjs/src/STEAK.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"STEAK.js","sourceRoot":"","sources":["../../../src/STEAK.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TaggedBEEF.js","sourceRoot":"","sources":["../../../src/TaggedBEEF.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AdmittanceInstructions.js","sourceRoot":"","sources":["../../../src/AdmittanceInstructions.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LookupAnswer.js","sourceRoot":"","sources":["../../../src/LookupAnswer.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LookupQuestion.js","sourceRoot":"","sources":["../../../src/LookupQuestion.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SHIPAdvertisement.js","sourceRoot":"","sources":["../../../src/SHIPAdvertisement.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SLAPAdvertisement.js","sourceRoot":"","sources":["../../../src/SLAPAdvertisement.ts"],"names":[],"mappings":""}
|
package/dist/esm/src/STEAK.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"STEAK.js","sourceRoot":"","sources":["../../../src/STEAK.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TaggedBEEF.js","sourceRoot":"","sources":["../../../src/TaggedBEEF.ts"],"names":[],"mappings":""}
|