fix(waterfallValidateTxid): Skipping validateTxid3() if it throws an error

This commit is contained in:
Chris Troutner
2021-08-09 10:35:51 -07:00
parent 8965dfc57f
commit 8c5e111d60
2 changed files with 63 additions and 53 deletions
+44 -36
View File
@@ -11,7 +11,7 @@ const Util = require('../util')
let _this let _this
class Utils { class Utils {
constructor (config) { constructor(config) {
this.restURL = config.restURL this.restURL = config.restURL
this.apiToken = config.apiToken this.apiToken = config.apiToken
this.slpParser = slpParser this.slpParser = slpParser
@@ -197,7 +197,7 @@ class Utils {
* circulatingSupply: 19882.03820723, * circulatingSupply: 19882.03820723,
* mintingBatonStatus: 'ALIVE' } ] * mintingBatonStatus: 'ALIVE' } ]
*/ */
async list (id) { async list(id) {
let path let path
let method let method
@@ -309,7 +309,7 @@ class Utils {
* array of addresses. * array of addresses.
*/ */
// Retrieve token balances for a given address. // Retrieve token balances for a given address.
async balancesForAddress (address) { async balancesForAddress(address) {
try { try {
// Single address. // Single address.
if (typeof address === 'string') { if (typeof address === 'string') {
@@ -376,7 +376,7 @@ class Utils {
* *
*/ */
// Retrieve token balances for a given tokenId. // Retrieve token balances for a given tokenId.
async balancesForToken (tokenId) { async balancesForToken(tokenId) {
try { try {
const path = `${this.restURL}slp/balancesForToken/${tokenId}` const path = `${this.restURL}slp/balancesForToken/${tokenId}`
@@ -438,7 +438,7 @@ class Utils {
// will be like the examples above. If SLPDB has fallen behind real-time // will be like the examples above. If SLPDB has fallen behind real-time
// processing, it will return this output: // processing, it will return this output:
// [ null ] // [ null ]
async validateTxid (txid, usrObj = null) { async validateTxid(txid, usrObj = null) {
const path = `${this.restURL}slp/validateTxid` const path = `${this.restURL}slp/validateTxid`
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`) // console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
@@ -506,7 +506,7 @@ class Utils {
* 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb', * 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
* valid: true } ] * valid: true } ]
*/ */
async validateTxid2 (txid) { async validateTxid2(txid) {
try { try {
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`) // console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
@@ -585,7 +585,7 @@ class Utils {
* } * }
* ] * ]
*/ */
async getWhitelist () { async getWhitelist() {
try { try {
const path = `${this.restURL}slp/whitelist` const path = `${this.restURL}slp/whitelist`
@@ -655,7 +655,7 @@ class Utils {
* '00ea27261196a411776f81029c0ebe34362936b4a9847deb1f7a40a02b3a1476', * '00ea27261196a411776f81029c0ebe34362936b4a9847deb1f7a40a02b3a1476',
* valid: true } ] * valid: true } ]
*/ */
async validateTxid3 (txid, usrObj = null) { async validateTxid3(txid, usrObj = null) {
const path = `${this.restURL}slp/validateTxid3` const path = `${this.restURL}slp/validateTxid3`
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`) // console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
@@ -731,7 +731,7 @@ class Utils {
* satoshisLockedUp: 135408 * satoshisLockedUp: 135408
* } * }
*/ */
async tokenStats (tokenId) { async tokenStats(tokenId) {
try { try {
const path = `${this.restURL}slp/tokenStats/${tokenId}` const path = `${this.restURL}slp/tokenStats/${tokenId}`
@@ -802,7 +802,7 @@ class Utils {
* ] * ]
*/ */
// Retrieve token transactions for a given tokenId and address. // Retrieve token transactions for a given tokenId and address.
async transactions (tokenId, address) { async transactions(tokenId, address) {
try { try {
const path = `${this.restURL}slp/transactions/${tokenId}/${address}` const path = `${this.restURL}slp/transactions/${tokenId}/${address}`
@@ -842,7 +842,7 @@ class Utils {
* burnTotal: 100 * burnTotal: 100
* } * }
*/ */
async burnTotal (transactionId) { async burnTotal(transactionId) {
try { try {
const path = `${this.restURL}slp/burnTotal/${transactionId}` const path = `${this.restURL}slp/burnTotal/${transactionId}`
@@ -876,7 +876,7 @@ class Utils {
* })() * })()
* *
*/ */
async txDetails (txid) { async txDetails(txid) {
try { try {
if ( if (
!txid || !txid ||
@@ -942,7 +942,7 @@ class Utils {
* *
*/ */
// Reimplementation of decodeOpReturn() using slp-parser. // Reimplementation of decodeOpReturn() using slp-parser.
async decodeOpReturn (txid, cache = null, usrObj = null) { async decodeOpReturn(txid, cache = null, usrObj = null) {
// The cache object is an in-memory cache (JS Object) that can be passed // The cache object is an in-memory cache (JS Object) that can be passed
// into this function. It helps if multiple vouts from the same TXID are // into this function. It helps if multiple vouts from the same TXID are
// being evaluated. In that case, it can significantly reduce the number // being evaluated. In that case, it can significantly reduce the number
@@ -1109,7 +1109,7 @@ class Utils {
* "tokenType": 1 * "tokenType": 1
* } * }
*/ */
async tokenUtxoDetails (utxos, usrObj = null) { async tokenUtxoDetails(utxos, usrObj = null) {
try { try {
// Throw error if input is not an array. // Throw error if input is not an array.
if (!Array.isArray(utxos)) throw new Error('Input must be an array.') if (!Array.isArray(utxos)) throw new Error('Input must be an array.')
@@ -1200,7 +1200,7 @@ class Utils {
* could burn tokens. It's safest to ignore UTXOs with a value of `null`. * could burn tokens. It's safest to ignore UTXOs with a value of `null`.
* *
*/ */
async tokenUtxoDetailsWL (utxos, usrObj = null) { async tokenUtxoDetailsWL(utxos, usrObj = null) {
try { try {
// Throw error if input is not an array. // Throw error if input is not an array.
if (!Array.isArray(utxos)) throw new Error('Input must be an array.') if (!Array.isArray(utxos)) throw new Error('Input must be an array.')
@@ -1294,7 +1294,7 @@ class Utils {
// //
// If the usrObj has a utxoDelay property, then it will delay the loop for // If the usrObj has a utxoDelay property, then it will delay the loop for
// each UTXO by that many milliseconds. // each UTXO by that many milliseconds.
async _hydrateUtxo (utxos, usrObj = null) { async _hydrateUtxo(utxos, usrObj = null) {
try { try {
const decodeOpReturnCache = {} const decodeOpReturnCache = {}
@@ -1557,7 +1557,7 @@ class Utils {
* // returns * // returns
* true * true
*/ */
async waterfallValidateTxid (txid, usrObj = null) { async waterfallValidateTxid(txid, usrObj = null) {
try { try {
// console.log('txid: ', txid) // console.log('txid: ', txid)
@@ -1588,25 +1588,31 @@ class Utils {
// Note: validateTxid3() has the same output as validateTxid(). // Note: validateTxid3() has the same output as validateTxid().
// validateTxid2() uses slp-validate, which has a different output format. // validateTxid2() uses slp-validate, which has a different output format.
// Validate against the whitelist SLPDB first. // If the whitelist SLPDB is having issues, the try/catch will skip it
const whitelistResult = await this.validateTxid3(txid, usrObj) // and continue execution.
// console.log( try {
// `whitelist-SLPDB for ${txid}: ${JSON.stringify( // Validate against the whitelist SLPDB first.
// whitelistResult, const whitelistResult = await this.validateTxid3(txid, usrObj)
// null, // console.log(
// 2 // `whitelist-SLPDB for ${txid}: ${JSON.stringify(
// )}` // whitelistResult,
// ) // null,
// 2
// )}`
// )
// Safely retrieve the returned value. // Safely retrieve the returned value.
if (whitelistResult[0] !== null) isValid = whitelistResult[0].valid if (whitelistResult[0] !== null) isValid = whitelistResult[0].valid
// Exit if isValid is not null. // Exit if isValid is not null.
if (isValid !== null) { if (isValid !== null) {
// Save to the cache. // Save to the cache.
cachedTxValidation[txid] = isValid cachedTxValidation[txid] = isValid
return isValid return isValid
}
} catch {
/* exit quietly */
} }
// Try the general SLPDB, if the whitelist returned null. // Try the general SLPDB, if the whitelist returned null.
@@ -1842,7 +1848,7 @@ class Utils {
*/ */
// Same as tokenUtxoDetails(), but reduces API calls by having bch-api server // Same as tokenUtxoDetails(), but reduces API calls by having bch-api server
// do the heavy lifting. // do the heavy lifting.
async hydrateUtxos (utxos, usrObj) { async hydrateUtxos(utxos, usrObj) {
try { try {
// Throw error if input is not an array. // Throw error if input is not an array.
if (!Array.isArray(utxos)) throw new Error('Input must be an array.') if (!Array.isArray(utxos)) throw new Error('Input must be an array.')
@@ -1858,6 +1864,8 @@ class Utils {
return response.data return response.data
} catch (error) { } catch (error) {
console.log('Error in hydrateUtxos(): ', error)
if (error.response && error.response.data) { if (error.response && error.response.data) {
throw new Error(JSON.stringify(error.response.data, null, 2)) throw new Error(JSON.stringify(error.response.data, null, 2))
} }
@@ -1881,7 +1889,7 @@ class Utils {
*/ */
// Same as tokenUtxoDetailsWL(), but reduces API calls by having bch-api server // Same as tokenUtxoDetailsWL(), but reduces API calls by having bch-api server
// do the heavy lifting. // do the heavy lifting.
async hydrateUtxosWL (utxos) { async hydrateUtxosWL(utxos) {
try { try {
// Throw error if input is not an array. // Throw error if input is not an array.
if (!Array.isArray(utxos)) throw new Error('Input must be an array.') if (!Array.isArray(utxos)) throw new Error('Input must be an array.')
@@ -1927,7 +1935,7 @@ class Utils {
* valid: true } ] * valid: true } ]
* *
*/ */
async getStatus (txid) { async getStatus(txid) {
const path = `${this.restURL}slp/status` const path = `${this.restURL}slp/status`
try { try {
+19 -17
View File
@@ -2281,23 +2281,25 @@ describe('#SLP Utils', () => {
assert.equal(result, true) assert.equal(result, true)
}) })
it('catches and throws an error', async () => { // CT 08-09-21 Changed behavior. validateTxid3() is now wrapped in a
try { // try/catch statement that exits quietly if there is an error.
const txid = 'fakeTxid' // it('catches and throws an error', async () => {
// try {
// Force an error // const txid = 'fakeTxid'
sandbox //
.stub(uut.Utils, 'validateTxid3') // // Force an error
.rejects(new Error('fake error')) // sandbox
// .stub(uut.Utils, 'validateTxid3')
await await uut.Utils.waterfallValidateTxid(txid) // .rejects(new Error('fake error'))
//
assert.fail('Unexpected result') // await await uut.Utils.waterfallValidateTxid(txid)
} catch (err) { //
// console.log(`err.message: ${err.message}`) // assert.fail('Unexpected result')
assert.include(err.message, 'fake error') // } catch (err) {
} // // console.log(`err.message: ${err.message}`)
}) // assert.include(err.message, 'fake error')
// }
// })
}) })
describe('#getWhitelist', () => { describe('#getWhitelist', () => {