UNPKG

wallet-storage

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

93 lines (81 loc) 3.71 kB
import { entity, table } from '../../storage/index.client'; import { verifyTruthy } from '../../utility/index.client'; import { Monitor } from '../Monitor'; import { WalletMonitorTask } from './WalletMonitorTask'; import { attemptToPostReqsToNetwork } from '../../storage/methods/attemptToPostReqsToNetwork'; export class TaskSendWaiting extends WalletMonitorTask { static taskName = 'SendWaiting'; constructor(monitor: Monitor, public triggerMsecs = 1000 * 60 * 5, public agedMsecs = 0) { super(monitor, TaskSendWaiting.taskName); } trigger(nowMsecsSinceEpoch: number): { run: boolean; } { return { run: nowMsecsSinceEpoch > this.lastRunMsecsSinceEpoch + this.triggerMsecs }; } async runTask(): Promise<string> { let log = ''; const limit = 100; let offset = 0; const agedLimit = new Date(Date.now() - this.agedMsecs); for (; ;) { const reqs = await this.storage.findProvenTxReqs({ partial: {}, status: ['unsent'], paged: { limit, offset } }); if (reqs.length === 0) break; log += `${reqs.length} reqs with status 'unsent'\n`; const agedReqs = reqs.filter(req => verifyTruthy(req.updated_at) < agedLimit); log += ` Of those reqs, ${agedReqs.length} where last updated before ${agedLimit.toISOString()}.\n`; log += await this.processUnsent(agedReqs, 2); if (reqs.length < limit) break; offset += limit; } return log } /** * Process an array of 'unsent' status table.ProvenTxReq * * Send rawTx to transaction processor(s), requesting proof callbacks when possible. * * Set status 'invalid' if req is invalid. * * Set status to 'callback' on successful network submission with callback service. * * Set status to 'unmined' on successful network submission without callback service. * * Add mapi responses to database table if received. * * Increments attempts if sending was attempted. * * @param reqApis */ async processUnsent(reqApis: table.ProvenTxReq[], indent = 0) : Promise<string> { let log = '' for (let i = 0; i < reqApis.length; i++) { const reqApi = reqApis[i] log += ' '.repeat(indent) log += `${i} reqId=${reqApi.provenTxReqId} attempts=${reqApi.attempts} txid=${reqApi.txid}: \n` if (reqApi.status !== 'unsent') { log += ` status now ${reqApi.status}\n` continue } const req = new entity.ProvenTxReq(reqApi) const reqs: entity.ProvenTxReq[] = [] if (req.batch) { // Make sure wew process entire batch together for efficient beef generation const batchReqApis = await this.storage.findProvenTxReqs({ partial: { batch: req.batch, status: 'unsent' } }) for (const bra of batchReqApis) { // Remove any matching batchReqApis from reqApis const index = reqApis.findIndex(ra => ra.provenTxReqId === bra.provenTxReqId) if (index > -1) reqApis.slice(index, index + 1); // And add to reqs being processed now: reqs.push(new entity.ProvenTxReq(bra)) } } else { // Just a single non-batched req... reqs.push(req) } const r = await this.storage.runAsStorageProvider(async (sp) => { return attemptToPostReqsToNetwork(sp, reqs) }) log += r.log } return log } }