feat(tokenUtxoDetails()): Using fallback SLP validators

This commit is contained in:
Chris Troutner
2020-12-06 19:18:47 -08:00
parent 1f01e6ae47
commit d1847d2eca
3 changed files with 137 additions and 33 deletions
+32 -17
View File
@@ -1,3 +1,4 @@
// Public npm libraries
const axios = require("axios")
const slpParser = require("slp-parser")
@@ -1111,9 +1112,9 @@ class Utils {
let slpData = false
try {
slpData = await this.decodeOpReturn(utxo.txid, decodeOpReturnCache)
console.log(`slpData: ${JSON.stringify(slpData, null, 2)}`)
// console.log(`slpData: ${JSON.stringify(slpData, null, 2)}`)
} catch (err) {
console.log(`error from decodeOpReturn(${utxo.txid}): `, err)
// console.log(`error from decodeOpReturn(${utxo.txid}): `, err)
// An error will be thrown if the txid is not SLP.
// If error is for some other reason, like a 429 error, mark utxo as 'null'
@@ -1124,10 +1125,10 @@ class Utils {
err.message.indexOf("lokad id") === -1 &&
err.message.indexOf("trailing data") === -1)
) {
console.log(
`unknown error from decodeOpReturn(). Marking as 'null'`,
err
)
// console.log(
// `unknown error from decodeOpReturn(). Marking as 'null'`,
// err
// )
utxo.isValid = null
outAry.push(utxo)
@@ -1136,10 +1137,9 @@ class Utils {
// an SLP UTXO.
// Mark as false and continue the loop.
} else {
console.log("marking as invalid")
// console.log("marking as invalid")
utxo.isValid = false
outAry.push(utxo)
console.log(`outAry: ${JSON.stringify(outAry, null, 2)}`)
}
// Halt the execution of the loop and increase to the next index.
@@ -1285,7 +1285,8 @@ class Utils {
// validate the TXID with SLPDB.
if (outAry[i].tokenType) {
// Only execute this block if the current UTXO has a 'tokenType'
// property. i.e. it has been hydrated with SLP information.
// property. i.e. it has been successfully hydrated with SLP
// information.
// If the value has been cached, use the cached version first.
let isValid = cachedTxValidation[utxo.txid]
@@ -1302,7 +1303,13 @@ class Utils {
// If still null, check the whitelist SLPDB
if (isValid === null) {
console.log(`outAry[${i}]: ${JSON.stringify(outAry[i], null, 2)}`)
// console.log(
// `checking against whitelist SLPDB. outAry[${i}]: ${JSON.stringify(
// outAry[i],
// null,
// 2
// )}`
// )
// Figure out if the token UTXO is in the whitelist.
let utxoInWhitelist = false
@@ -1318,6 +1325,15 @@ class Utils {
// if the general SLPDB is not.
if (utxoInWhitelist) {
isValid = await this.validateTxid3(utxo.txid)
// console.log(
// `whitelist-SLPDB for ${utxo.txid}: ${JSON.stringify(
// isValid,
// null,
// 2
// )}`
// )
isValid = isValid[0].valid
// Save the result to the local cache.
@@ -1328,22 +1344,21 @@ class Utils {
// If still null, as a last resort, check it against slp-validate
if (isValid === null) {
isValid = await this.validateTxid2(utxo.txid)
console.log(
`slp-validate isValid: ${JSON.stringify(isValid, null, 2)}`
)
isValid = isValid.valid
// console.log(
// `slp-validate isValid: ${JSON.stringify(isValid, null, 2)}`
// )
isValid = isValid.isValid
// Save the result to the local cache.
cachedTxValidation[utxo.txid] = isValid
}
console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
outAry[i].isValid = isValid
}
}
console.log(`pt2 outAry: ${JSON.stringify(outAry, null, 2)}`)
return outAry
} catch (error) {
if (error.response && error.response.data) throw error.response.data
+29 -1
View File
@@ -1163,6 +1163,33 @@ const mockValidateTxidArray = [
}
]
const whitelist = [
{
name: "USDH",
tokenId: "c4b0d62156b3fa5c8f3436079b5394f7edc1bef5dc1cd2f9d0c4d46f82cca479"
},
{
name: "SPICE",
tokenId: "4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf"
},
{
name: "PSF",
tokenId: "38e97c5d7d3585a2cbf3f9580c82ca33985f9cb0845d4dcce220cb709f9538b0"
},
{
name: "TROUT",
tokenId: "a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2"
},
{
name: "PSFTEST",
tokenId: "d0ef4de95b78222bfee2326ab11382f4439aa0855936e2fe6ac129a8d778baa0"
},
{
name: "TOK-CH",
tokenId: "497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7"
}
]
module.exports = {
mockList,
mockToken,
@@ -1190,5 +1217,6 @@ module.exports = {
mockInvalidSlpSend,
mockWhitelist,
mockValidateTxid3Valid,
mockValidateTxid3Invalid
mockValidateTxid3Invalid,
whitelist
}
+76 -15
View File
@@ -1695,21 +1695,82 @@ describe("#SLP Utils", () => {
assert.equal(data[0].isValid, false)
})
// it("should validate against the whitelist SLPDB when regular SLPDB returns null", async () => {
// const utxos = [
// // Malformed SLP tx
// {
// note: "Malformed SLP tx",
// tx_hash:
// "f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
// tx_pos: 1,
// value: 546
// }
// ]
//
// const data = await uut.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
// })
it("should use backup validators when regular SLPDB returns null", async () => {
// Mock the call to REST API
// Stub the calls to decodeOpReturn.
sandbox
.stub(uut.Utils, "decodeOpReturn")
.onCall(0)
.resolves({
tokenType: 1,
txType: "SEND",
tokenId:
"497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7",
amounts: ["200000000", "99887500000000"]
})
.onCall(1)
.resolves({
tokenType: 1,
txType: "GENESIS",
ticker: "TOK-CH",
name: "TokyoCash",
tokenId:
"497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7",
documentUri: "",
documentHash: "",
decimals: 8,
mintBatonVout: 0,
qty: "2100000000000000"
})
// Force default SLPDB to return 'null', which should trigger usage of the
// backup whitelist-SLPDB.
sandbox.stub(uut.Utils, "validateTxid").resolves([
{
txid:
"fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb",
valid: null
}
])
// Force the token UTXO to be in the whitelist.
uut.Utils.whitelist = mockData.whitelist
// Mock the response from the whitelist-SLPDB.
sandbox.stub(uut.Utils, "validateTxid3").resolves([
{
txid:
"fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb",
valid: null
}
])
// Mock the response from slp-api
sandbox.stub(uut.Utils, "validateTxid2").resolves({
txid:
"fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb",
isValid: true,
msg: ""
})
const utxos = [
{
txid:
"fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb",
vout: 1,
amount: 0.00000546,
satoshis: 546,
height: 596089,
confirmations: 748
}
]
const data = await uut.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
// The UTXO should have been validated by the third validation source.
assert.equal(data[0].isValid, true)
})
})
describe("#txDetails", () => {