mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-21 16:51:59 -07:00
feat(validateTxid2): slp-validate based validation of SLP txids
This commit is contained in:
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
"test:integration:free": "bash test/integration/test-free-tier.sh",
|
"test:integration:free": "bash test/integration/test-free-tier.sh",
|
||||||
"test:integration:free:bchn": "bash test/integration/test-free-tier-bchn.sh",
|
"test:integration:free:bchn": "bash test/integration/test-free-tier-bchn.sh",
|
||||||
"test:integration:free:testnet": "bash test/integration/testnet/test-free-tier.sh",
|
"test:integration:free:testnet": "bash test/integration/testnet/test-free-tier.sh",
|
||||||
"test:temp": "mocha --timeout 30000 -g '#hydrateUtxos' test/integration/slp.js",
|
"test:temp": "mocha --timeout 30000 -g '#validateTxid2' test/unit/slp-utils.js",
|
||||||
"test:integration:api": "RESTURL=https://api.fullstack.cash/v3/ mocha --timeout 30000 test/integration",
|
"test:integration:api": "RESTURL=https://api.fullstack.cash/v3/ mocha --timeout 30000 test/integration",
|
||||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||||
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
|
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
|
||||||
|
|||||||
@@ -455,6 +455,66 @@ class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api SLP.Utils.validateTxid2() validateTxid2()
|
||||||
|
* @apiName validateTxid2
|
||||||
|
* @apiGroup SLP Utils
|
||||||
|
* @apiDescription Validate that txid is an SLP transaction.
|
||||||
|
*
|
||||||
|
* This second validatoin version uses the slp-validate slp library. It is
|
||||||
|
* much slower and less efficient than SLPDB and is prone to time-outs for
|
||||||
|
* tokens with large DAGs. However, it operates independently of SLPDB and
|
||||||
|
* is a great second validation option, particularly when SLPDB returns 'null'
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* Due to the inefficiency of this call, only a single TXID can be input at a
|
||||||
|
* time. This call will throw an error if the input is an array.
|
||||||
|
*
|
||||||
|
* @apiExample Example usage:
|
||||||
|
*
|
||||||
|
* // validate single SLP txid
|
||||||
|
* (async () => {
|
||||||
|
* try {
|
||||||
|
* let validated = await bchjs.SLP.Utils.validateTxid(
|
||||||
|
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
|
||||||
|
* );
|
||||||
|
* console.log(validated);
|
||||||
|
* } catch (error) {
|
||||||
|
* console.error(error);
|
||||||
|
* }
|
||||||
|
* })();
|
||||||
|
*
|
||||||
|
* // returns
|
||||||
|
* [ { txid:
|
||||||
|
* 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
|
||||||
|
* valid: true } ]
|
||||||
|
*/
|
||||||
|
async validateTxid2(txid) {
|
||||||
|
try {
|
||||||
|
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!txid ||
|
||||||
|
txid === "" ||
|
||||||
|
typeof txid !== "string" ||
|
||||||
|
txid.length !== 64
|
||||||
|
)
|
||||||
|
throw new Error(`txid must be 64 character string.`)
|
||||||
|
|
||||||
|
const path = `${this.restURL}slp/validateTxid2/${txid}`
|
||||||
|
|
||||||
|
const response = await axios.get(path, _this.axiosOptions)
|
||||||
|
return response.data
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response && error.response.data) throw error.response.data
|
||||||
|
|
||||||
|
if (error.error && error.error.indexOf("Network error") > -1)
|
||||||
|
throw new Error("slp-validate timed out")
|
||||||
|
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api SLP.Utils.tokenStats() tokenStats()
|
* @api SLP.Utils.tokenStats() tokenStats()
|
||||||
* @apiName tokenStats
|
* @apiName tokenStats
|
||||||
|
|||||||
@@ -607,6 +607,36 @@ describe(`#SLP`, () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("#validateTxid2", () => {
|
||||||
|
it("should invalidate a known invalid TXID", async () => {
|
||||||
|
const txid =
|
||||||
|
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||||
|
|
||||||
|
const result = await bchjs.SLP.Utils.validateTxid2(txid)
|
||||||
|
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||||
|
|
||||||
|
assert.property(result, "txid")
|
||||||
|
assert.equal(result.txid, txid)
|
||||||
|
|
||||||
|
assert.property(result, "isValid")
|
||||||
|
assert.equal(result.isValid, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should validate a known valid TXID", async () => {
|
||||||
|
const txid =
|
||||||
|
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488"
|
||||||
|
|
||||||
|
const result = await bchjs.SLP.Utils.validateTxid2(txid)
|
||||||
|
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||||
|
|
||||||
|
assert.property(result, "txid")
|
||||||
|
assert.equal(result.txid, txid)
|
||||||
|
|
||||||
|
assert.property(result, "isValid")
|
||||||
|
assert.equal(result.isValid, true)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#tokentype1", () => {
|
describe("#tokentype1", () => {
|
||||||
|
|||||||
@@ -1815,4 +1815,103 @@ describe("#SLP Utils", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("#validateTxid2", () => {
|
||||||
|
it("should throw an error if the input is an array", async () => {
|
||||||
|
try {
|
||||||
|
const txid = [
|
||||||
|
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||||
|
]
|
||||||
|
|
||||||
|
await slp.Utils.validateTxid2(txid)
|
||||||
|
|
||||||
|
assert2.equal(true, false, "Unexpected result")
|
||||||
|
} catch (err) {
|
||||||
|
// console.log("err: ", err)
|
||||||
|
assert2.include(err.message, "txid must be 64 character string")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should throw an error for a malformed txid", async () => {
|
||||||
|
try {
|
||||||
|
const txid =
|
||||||
|
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783"
|
||||||
|
|
||||||
|
await slp.Utils.validateTxid2(txid)
|
||||||
|
|
||||||
|
assert2.equal(true, false, "Unexpected result")
|
||||||
|
} catch (err) {
|
||||||
|
// console.log("err: ", err)
|
||||||
|
assert2.include(err.message, "txid must be 64 character string")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should invalidate a known invalid TXID", async () => {
|
||||||
|
const txid =
|
||||||
|
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||||
|
|
||||||
|
// Mock live network calls.
|
||||||
|
sandbox.stub(axios, "get").resolves({
|
||||||
|
data: {
|
||||||
|
txid: txid,
|
||||||
|
isValid: false,
|
||||||
|
msg: ""
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await slp.Utils.validateTxid2(txid)
|
||||||
|
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||||
|
|
||||||
|
assert2.property(result, "txid")
|
||||||
|
assert2.equal(result.txid, txid)
|
||||||
|
|
||||||
|
assert2.property(result, "isValid")
|
||||||
|
assert2.equal(result.isValid, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should validate a known valid TXID", async () => {
|
||||||
|
const txid =
|
||||||
|
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488"
|
||||||
|
|
||||||
|
// Mock live network calls.
|
||||||
|
sandbox.stub(axios, "get").resolves({
|
||||||
|
data: {
|
||||||
|
txid: txid,
|
||||||
|
isValid: true,
|
||||||
|
msg: ""
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await slp.Utils.validateTxid2(txid)
|
||||||
|
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||||
|
|
||||||
|
assert2.property(result, "txid")
|
||||||
|
assert2.equal(result.txid, txid)
|
||||||
|
|
||||||
|
assert2.property(result, "isValid")
|
||||||
|
assert2.equal(result.isValid, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
// slp-validate can take a long time. bch-api cuts it off if it fails to
|
||||||
|
// return is less than 10 seconds. This test case handle this situation.
|
||||||
|
it("should handle timeout errors", async () => {
|
||||||
|
try {
|
||||||
|
const txid =
|
||||||
|
"eacb1085dfa296fef6d4ae2c0f4529a1bef096dd2325bdcc6dcb5241b3bdb579"
|
||||||
|
|
||||||
|
// Mock live network calls.
|
||||||
|
sandbox.stub(axios, "get").rejects({
|
||||||
|
error:
|
||||||
|
"Network error: Could not communicate with full node or other external service."
|
||||||
|
})
|
||||||
|
|
||||||
|
await slp.Utils.validateTxid2(txid)
|
||||||
|
|
||||||
|
assert2.equal(true, false, "Unexpected result")
|
||||||
|
} catch (err) {
|
||||||
|
// console.log("err: ", err)
|
||||||
|
assert2.include(err.message, "slp-validate timed out")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user