From 0e709dd935f0f7615edbe69a5fe5741f86e75144 Mon Sep 17 00:00:00 2001 From: "James S. Cramer" Date: Thu, 7 Feb 2019 12:25:35 -0500 Subject: [PATCH] Remove duplication in transaction data in cache --- lib/localvalidator.ts | 80 ++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/lib/localvalidator.ts b/lib/localvalidator.ts index 9541410b..4c8f373c 100644 --- a/lib/localvalidator.ts +++ b/lib/localvalidator.ts @@ -5,8 +5,8 @@ import * as bitcore from 'bitcore-lib-cash'; import { BitcoreTransaction } from './global'; import BigNumber from 'bignumber.js'; -export interface Validation { hex: string|null; validity: boolean|null; parents: Parent[], details: SlpTransactionDetails|null, invalidReason: string|null } -export type GetRawTransactionsAsync = (txid: string[]) => Promise; +export interface Validation { validity: boolean|null; parents: Parent[], details: SlpTransactionDetails|null, invalidReason: string|null } +export type GetRawTransactionsAsync = (txid: string[]) => Promise<(string|null)[]>; const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) @@ -39,7 +39,7 @@ export class LocalValidator implements SlpValidator { addValidationFromStore(hex: string, isValid: boolean) { let id = (this.BITBOX.Crypto.sha256(this.BITBOX.Crypto.sha256(Buffer.from(hex, 'hex'))).reverse()).toString('hex'); if(!this.cachedValidations[id]) - this.cachedValidations[id] = { hex: hex, validity: isValid, parents: [], details: null, invalidReason: null } + this.cachedValidations[id] = { validity: isValid, parents: [], details: null, invalidReason: null } if(!this.cachedRawTransactions[id]) this.cachedRawTransactions[id] = hex; } @@ -58,7 +58,7 @@ export class LocalValidator implements SlpValidator { async waitForTransactionPreProcessing(txid: string){ // TODO: Add some timeout? while(true) { - if(this.cachedValidations[txid].hex && (this.cachedValidations[txid].details || typeof this.cachedValidations.validity === 'boolean')) + if(this.cachedRawTransactions[txid] && (this.cachedValidations[txid].details || typeof this.cachedValidations.validity === 'boolean')) break await sleep(10); } @@ -66,7 +66,7 @@ export class LocalValidator implements SlpValidator { return } - async getRawTransaction(txid: string) { + async retrieveRawTransaction(txid: string) { if(this.cachedRawTransactions[txid]) return this.cachedRawTransactions[txid]; this.cachedRawTransactions[txid] = (await this.getRawTransactions([txid]))[0] @@ -81,12 +81,12 @@ export class LocalValidator implements SlpValidator { async isValidSlpTxid(txid: string) { if(txid && !this.cachedValidations[txid]) { - this.cachedValidations[txid] = { hex: null, validity: null, parents: [], details: null, invalidReason: null } - this.cachedValidations[txid].hex = await this.getRawTransaction(txid); + this.cachedValidations[txid] = { validity: null, parents: [], details: null, invalidReason: null } + await this.retrieveRawTransaction(txid); } // Check to see how we should proceed based on the validation-cache state - if(!this.cachedValidations[txid].hex) + if(!this.cachedRawTransactions[txid]) await this.waitForTransactionPreProcessing(txid); if(typeof this.cachedValidations[txid].validity === 'boolean') return this.cachedValidations[txid].validity; @@ -94,7 +94,7 @@ export class LocalValidator implements SlpValidator { await this.waitForCurrentValidationProcessing(txid); // Check SLP message validity - let txn: BitcoreTransaction = new bitcore.Transaction(this.cachedValidations[txid].hex) + let txn: BitcoreTransaction = new bitcore.Transaction(this.cachedRawTransactions[txid]) let slpmsg: SlpTransactionDetails; try { slpmsg = this.cachedValidations[txid].details = this.slp.parseSlpOutputScript(txn.outputs[0]._scriptBuffer) @@ -110,21 +110,19 @@ export class LocalValidator implements SlpValidator { else if (slpmsg.transactionType === SlpTransactionType.MINT) { for(let i = 0; i < txn.inputs.length; i++) { let input_txid = txn.inputs[i].prevTxId.toString('hex') - let input_txhex = await this.getRawTransaction(input_txid) - if (input_txhex) { - let input_tx: BitcoreTransaction = new bitcore.Transaction(input_txhex); - try { - let input_slpmsg = this.slp.parseSlpOutputScript(input_tx.outputs[0]._scriptBuffer) - if(input_slpmsg.transactionType === SlpTransactionType.GENESIS) - input_slpmsg.tokenIdHex = input_txid; - if(input_slpmsg.tokenIdHex === slpmsg.tokenIdHex) { - if(input_slpmsg.transactionType === SlpTransactionType.GENESIS || input_slpmsg.transactionType === SlpTransactionType.MINT) { - if(txn.inputs[i].outputIndex === input_slpmsg.batonVout) - this.cachedValidations[txid].parents.push({ txid: txn.inputs[i].prevTxId.toString('hex'), versionType: input_slpmsg.versionType ,valid: null, inputQty: null }) - } + let input_txhex = await this.retrieveRawTransaction(input_txid) + let input_tx: BitcoreTransaction = new bitcore.Transaction(input_txhex); + try { + let input_slpmsg = this.slp.parseSlpOutputScript(input_tx.outputs[0]._scriptBuffer) + if(input_slpmsg.transactionType === SlpTransactionType.GENESIS) + input_slpmsg.tokenIdHex = input_txid; + if(input_slpmsg.tokenIdHex === slpmsg.tokenIdHex) { + if(input_slpmsg.transactionType === SlpTransactionType.GENESIS || input_slpmsg.transactionType === SlpTransactionType.MINT) { + if(txn.inputs[i].outputIndex === input_slpmsg.batonVout) + this.cachedValidations[txid].parents.push({ txid: txn.inputs[i].prevTxId.toString('hex'), versionType: input_slpmsg.versionType ,valid: null, inputQty: null }) } - } catch(_) {} - } + } + } catch(_) {} } if(this.cachedValidations[txid].parents.length !== 1) { this.cachedValidations[txid].invalidReason = "MINT transaction must have 1 valid baton parent." @@ -136,26 +134,24 @@ export class LocalValidator implements SlpValidator { let tokenInQty = new BigNumber(0); for(let i = 0; i < txn.inputs.length; i++) { let input_txid = txn.inputs[i].prevTxId.toString('hex') - let input_txhex = await this.getRawTransaction(input_txid) - if (input_txhex) { - let input_tx: BitcoreTransaction = new bitcore.Transaction(input_txhex); - try { - let input_slpmsg = this.slp.parseSlpOutputScript(input_tx.outputs[0]._scriptBuffer) - if(input_slpmsg.transactionType === SlpTransactionType.GENESIS) - input_slpmsg.tokenIdHex = input_txid; - if(input_slpmsg.tokenIdHex === slpmsg.tokenIdHex) { - if(input_slpmsg.transactionType === SlpTransactionType.SEND) { - tokenInQty = tokenInQty.plus(input_slpmsg.sendOutputs[txn.inputs[i].outputIndex]) - this.cachedValidations[txid].parents.push({txid: txn.inputs[i].prevTxId.toString('hex'), versionType: input_slpmsg.versionType, valid: null, inputQty: input_slpmsg.sendOutputs[txn.inputs[i].outputIndex] }) - } - else if(input_slpmsg.transactionType === SlpTransactionType.GENESIS || input_slpmsg.transactionType === SlpTransactionType.MINT) { - if(txn.inputs[i].outputIndex === 1) - tokenInQty = tokenInQty.plus(input_slpmsg.genesisOrMintQuantity) - this.cachedValidations[txid].parents.push({txid: txn.inputs[i].prevTxId.toString('hex'), versionType: input_slpmsg.versionType, valid: null, inputQty: input_slpmsg.genesisOrMintQuantity }) - } + let input_txhex = await this.retrieveRawTransaction(input_txid) + let input_tx: BitcoreTransaction = new bitcore.Transaction(input_txhex); + try { + let input_slpmsg = this.slp.parseSlpOutputScript(input_tx.outputs[0]._scriptBuffer) + if(input_slpmsg.transactionType === SlpTransactionType.GENESIS) + input_slpmsg.tokenIdHex = input_txid; + if(input_slpmsg.tokenIdHex === slpmsg.tokenIdHex) { + if(input_slpmsg.transactionType === SlpTransactionType.SEND) { + tokenInQty = tokenInQty.plus(input_slpmsg.sendOutputs[txn.inputs[i].outputIndex]) + this.cachedValidations[txid].parents.push({txid: txn.inputs[i].prevTxId.toString('hex'), versionType: input_slpmsg.versionType, valid: null, inputQty: input_slpmsg.sendOutputs[txn.inputs[i].outputIndex] }) } - } catch(_) {} - } + else if(input_slpmsg.transactionType === SlpTransactionType.GENESIS || input_slpmsg.transactionType === SlpTransactionType.MINT) { + if(txn.inputs[i].outputIndex === 1) + tokenInQty = tokenInQty.plus(input_slpmsg.genesisOrMintQuantity) + this.cachedValidations[txid].parents.push({txid: txn.inputs[i].prevTxId.toString('hex'), versionType: input_slpmsg.versionType, valid: null, inputQty: input_slpmsg.genesisOrMintQuantity }) + } + } + } catch(_) {} } // Check token inputs are greater than token outputs (includes valid and invalid inputs)