mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-22 00:52:01 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10520a2e08 | ||
|
|
05b654d54a | ||
|
|
3c4051c3a5 | ||
|
|
0f3cc1e9e8 | ||
|
|
b9873f7ed8 | ||
|
|
82cd9270fa | ||
|
|
ac6b45b162 | ||
|
|
66a99c0560 | ||
|
|
17e4a32ff4 | ||
|
|
6a430b4da6 | ||
|
|
77ab090bc2 |
+2
-1
@@ -16,7 +16,8 @@
|
||||
"test:integration:local": "RESTURL=http://localhost:3000/v4/ mocha --timeout 30000 test/integration",
|
||||
"test:integration:local:bchn": "RESTURL=http://localhost:3000/v4/ bash test/integration/test-bchn-integration.sh",
|
||||
"test:integration:local:testnet": "RESTURL=http://localhost:4000/v4/ mocha --timeout 30000 test/integration/testnet",
|
||||
"test:temp": "export RESTURL=http://localhost:3000/v4/ && export IS_USING_FREE_TIER=true && mocha --timeout 30000 test/integration/chains/bchn/",
|
||||
"test:temp": "export RESTURL=http://localhost:3000/v4/ && mocha --timeout 30000 -g '#tokenUtxoDetails' test/integration/",
|
||||
"test:temp2": "mocha --timeout 30000 -g '#tokenUtxoDetails' test/unit/",
|
||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
|
||||
"docs": "./node_modules/.bin/apidoc -i src/ -o docs"
|
||||
|
||||
+64
-19
@@ -431,10 +431,14 @@ class Utils {
|
||||
* '00ea27261196a411776f81029c0ebe34362936b4a9847deb1f7a40a02b3a1476',
|
||||
* valid: true } ]
|
||||
*/
|
||||
// This function has two responses. If SLPDB is working correctly, the output
|
||||
// will be like the examples above. If SLPDB has fallen behind real-time
|
||||
// processing, it will return this output:
|
||||
// [ null ]
|
||||
async validateTxid(txid) {
|
||||
const path = `${this.restURL}slp/validateTxid`
|
||||
|
||||
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
|
||||
console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
|
||||
|
||||
// Handle a single TXID or an array of TXIDs.
|
||||
let txids
|
||||
@@ -449,7 +453,9 @@ class Utils {
|
||||
},
|
||||
_this.axiosOptions
|
||||
)
|
||||
// console.log(`response.data: ${JSON.stringify(response.data, null, 2)}`)
|
||||
// console.log(
|
||||
// `validateTxid response.data: ${JSON.stringify(response.data, null, 2)}`
|
||||
// )
|
||||
|
||||
const validatedTxids = response.data
|
||||
|
||||
@@ -1288,22 +1294,53 @@ class Utils {
|
||||
// property. i.e. it has been successfully hydrated with SLP
|
||||
// information.
|
||||
|
||||
// CT 12/13/2020: Disabling the cache until I get processing of tokens
|
||||
// to be more stable.
|
||||
// If the value has been cached, use the cached version first.
|
||||
let isValid = cachedTxValidation[utxo.txid]
|
||||
if (!isValid) isValid = null
|
||||
// let isValid = null
|
||||
|
||||
// There are two possible responses from SLPDB. If SLPDB is functioning
|
||||
// correctly, then validateTxid() will return this:
|
||||
// isValid: [
|
||||
// {
|
||||
// "txid": "ff0c0354f8d3ddb34fa36f73494eb58ea24f8b8da6904aa8ed43b7a74886c583",
|
||||
// "valid": true
|
||||
// }
|
||||
// ]
|
||||
//
|
||||
// If SLPDB has fallen behind real-time processing, it will return this:
|
||||
// isValid: [
|
||||
// null
|
||||
// ]
|
||||
//
|
||||
// Note: validateTxid3() has the same output as validateTxid().
|
||||
// validateTxid2() uses slp-validate, which has a different output format.
|
||||
|
||||
// If not in the cache, try the general SLPDB.
|
||||
if (isValid == null) {
|
||||
if (isValid === null) {
|
||||
// console.log(`utxo: ${JSON.stringify(utxo, null, 2)}`)
|
||||
isValid = await this.validateTxid(utxo.txid)
|
||||
// console.log(
|
||||
// `validateTxid() isValid: ${JSON.stringify(isValid, null, 2)}`
|
||||
// )
|
||||
|
||||
if (isValid !== null) {
|
||||
isValid = isValid[0].valid
|
||||
// Handle corner case where SLPDB returns an array with a null element.
|
||||
if (isValid[0] === null)
|
||||
isValid = [{ txid: utxo.txid, valid: null }]
|
||||
|
||||
// Save the result to the local cache.
|
||||
cachedTxValidation[utxo.txid] = isValid
|
||||
}
|
||||
isValid = isValid[0].valid
|
||||
|
||||
// Save the result to the local cache.
|
||||
// cachedTxValidation[utxo.txid] = isValid
|
||||
}
|
||||
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
|
||||
|
||||
// console.log(
|
||||
// `pre-validateTxid3() isValid: ${JSON.stringify(isValid, null, 2)}`
|
||||
// )
|
||||
|
||||
// If still null, check the whitelist SLPDB
|
||||
if (isValid === null) {
|
||||
// console.log(
|
||||
@@ -1337,32 +1374,40 @@ class Utils {
|
||||
// )}`
|
||||
// )
|
||||
|
||||
if (isValid !== null) {
|
||||
isValid = isValid[0].valid
|
||||
if (isValid[0] !== null) isValid = isValid[0].valid
|
||||
|
||||
// Save the result to the local cache.
|
||||
cachedTxValidation[utxo.txid] = isValid
|
||||
}
|
||||
// Save the result to the local cache.
|
||||
// cachedTxValidation[utxo.txid] = isValid
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(
|
||||
// `pre-validateTxid2() isValid: ${JSON.stringify(isValid, null, 2)}`
|
||||
// )
|
||||
|
||||
// If still null, as a last resort, check it against slp-validate
|
||||
if (isValid === null) {
|
||||
isValid = await this.validateTxid2(utxo.txid)
|
||||
try {
|
||||
isValid = await this.validateTxid2(utxo.txid)
|
||||
} catch (err) {
|
||||
// Mark as invalid if validateTxid2() throws an error.
|
||||
isValid = null
|
||||
}
|
||||
// console.log(
|
||||
// `slp-validate isValid: ${JSON.stringify(isValid, null, 2)}`
|
||||
// )
|
||||
|
||||
if (isValid !== null) {
|
||||
isValid = isValid.isValid
|
||||
if (isValid !== null) isValid = isValid.isValid
|
||||
|
||||
// Save the result to the local cache.
|
||||
cachedTxValidation[utxo.txid] = isValid
|
||||
}
|
||||
// Save the result to the local cache.
|
||||
// cachedTxValidation[utxo.txid] = isValid
|
||||
}
|
||||
|
||||
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
|
||||
outAry[i].isValid = isValid
|
||||
|
||||
// Save the txid to the local cache to reduce API calls.
|
||||
cachedTxValidation[utxo.txid] = isValid
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+97
-91
@@ -464,97 +464,27 @@ describe(`#SLP`, () => {
|
||||
assert.equal(data[0].isValid, false)
|
||||
})
|
||||
|
||||
// it("should handle a range of UTXO types", async () => {
|
||||
// const utxos = [
|
||||
// // Malformed SLP tx
|
||||
// {
|
||||
// note: "Malformed SLP tx",
|
||||
// tx_hash:
|
||||
// "f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
// tx_pos: 1,
|
||||
// value: 546
|
||||
// },
|
||||
// // Normal TX (non-SLP)
|
||||
// {
|
||||
// note: "Normal TX (non-SLP)",
|
||||
// tx_hash:
|
||||
// "01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
||||
// tx_pos: 0,
|
||||
// value: 400000
|
||||
// },
|
||||
// // Valid PSF SLP tx
|
||||
// {
|
||||
// note: "Valid PSF SLP tx",
|
||||
// tx_hash:
|
||||
// "daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
||||
// tx_pos: 1,
|
||||
// value: 546
|
||||
// },
|
||||
// // Valid SLP token not in whitelist
|
||||
// {
|
||||
// note: "Valid SLP token not in whitelist",
|
||||
// tx_hash:
|
||||
// "3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
|
||||
// tx_pos: 1,
|
||||
// value: 546
|
||||
// },
|
||||
// // Token send on BCHN network.
|
||||
// {
|
||||
// note: "Token send on BCHN network",
|
||||
// tx_hash:
|
||||
// "402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019",
|
||||
// tx_pos: 1,
|
||||
// value: 546
|
||||
// },
|
||||
// // Token send on ABC network.
|
||||
// {
|
||||
// note: "Token send on ABC network",
|
||||
// tx_hash:
|
||||
// "336bfe2168aac4c3303508a9e8548a0d33797a83b85b76a12d845c8d6674f79d",
|
||||
// tx_pos: 1,
|
||||
// value: 546
|
||||
// },
|
||||
// // Known invalid SLP token send of PSF tokens.
|
||||
// {
|
||||
// note: "Known invalid SLP token send of PSF tokens",
|
||||
// tx_hash:
|
||||
// "2bf691ad3679d928fef880b8a45b93b233f8fa0d0a92cf792313dbe77b1deb74",
|
||||
// tx_pos: 1,
|
||||
// value: 546
|
||||
// }
|
||||
// ]
|
||||
//
|
||||
// const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
|
||||
// // console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
||||
//
|
||||
// // Malformed SLP tx
|
||||
// assert.equal(data[0].tx_hash, utxos[0].tx_hash)
|
||||
// assert.equal(data[0].isValid, false)
|
||||
//
|
||||
// // Normal TX (non-SLP)
|
||||
// assert.equal(data[1].tx_hash, utxos[1].tx_hash)
|
||||
// assert.equal(data[1].isValid, false)
|
||||
//
|
||||
// // Valid PSF SLP tx
|
||||
// assert.equal(data[2].tx_hash, utxos[2].tx_hash)
|
||||
// assert.equal(data[2].isValid, true)
|
||||
//
|
||||
// // Valid SLP token not in whitelist
|
||||
// assert.equal(data[3].tx_hash, utxos[3].tx_hash)
|
||||
// assert.equal(data[3].isValid, true)
|
||||
//
|
||||
// // Token send on BCHN network
|
||||
// assert.equal(data[4].tx_hash, utxos[4].tx_hash)
|
||||
// assert.equal(data[4].isValid, null)
|
||||
//
|
||||
// // Token send on ABC network
|
||||
// assert.equal(data[5].tx_hash, utxos[5].tx_hash)
|
||||
// assert.equal(data[5].isValid, true)
|
||||
//
|
||||
// // Known invalid SLP token send of PSF tokens
|
||||
// assert.equal(data[6].tx_hash, utxos[6].tx_hash)
|
||||
// assert.equal(data[6].isValid, false)
|
||||
// })
|
||||
it("should handle null SLPDB validations", async () => {
|
||||
const utxos = [
|
||||
{
|
||||
height: 665577,
|
||||
tx_hash:
|
||||
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
|
||||
tx_pos: 1,
|
||||
value: 546
|
||||
},
|
||||
{
|
||||
height: 665577,
|
||||
tx_hash:
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
|
||||
tx_pos: 1,
|
||||
value: 546
|
||||
}
|
||||
]
|
||||
|
||||
const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
|
||||
console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#balancesForAddress", () => {
|
||||
@@ -695,6 +625,82 @@ describe(`#SLP`, () => {
|
||||
console.log("Error: ", err)
|
||||
}
|
||||
})
|
||||
|
||||
it("should handle null SLPDB validations", async () => {
|
||||
const utxos = [
|
||||
{
|
||||
height: 665577,
|
||||
tx_hash:
|
||||
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
|
||||
tx_pos: 1,
|
||||
value: 546
|
||||
},
|
||||
{
|
||||
height: 665577,
|
||||
tx_hash:
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
||||
tx_pos: 1,
|
||||
value: 546
|
||||
}
|
||||
]
|
||||
|
||||
const data = await bchjs.SLP.Utils.hydrateUtxos([{ utxos: utxos }])
|
||||
console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#validateTxid", () => {
|
||||
/*
|
||||
it("should return null on a known invalid TXID", async () => {
|
||||
const txid =
|
||||
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid(txid)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
|
||||
assert.property(result[0], "txid")
|
||||
assert.equal(result[0].txid, txid)
|
||||
|
||||
assert.property(result[0], "valid")
|
||||
assert.equal(result[0].valid, null)
|
||||
})
|
||||
|
||||
it("should return true a known valid TXID", async () => {
|
||||
const txid =
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488"
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid(txid)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.isArray(result)
|
||||
|
||||
assert.property(result[0], "txid")
|
||||
assert.equal(result[0].txid, txid)
|
||||
|
||||
assert.property(result[0], "valid")
|
||||
assert.equal(result[0].valid, true)
|
||||
})
|
||||
*/
|
||||
// This test is not necessary.
|
||||
it("should handle a null response from SLPDB", async () => {
|
||||
const txid =
|
||||
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419"
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid(txid)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
})
|
||||
|
||||
it("should handle a null response from SLPDB", async () => {
|
||||
const txid = [
|
||||
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
|
||||
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488"
|
||||
]
|
||||
|
||||
const result = await bchjs.SLP.Utils.validateTxid(txid)
|
||||
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#validateTxid2", () => {
|
||||
|
||||
@@ -1771,6 +1771,64 @@ describe("#SLP Utils", () => {
|
||||
// The UTXO should have been validated by the third validation source.
|
||||
assert.equal(data[0].isValid, true)
|
||||
})
|
||||
|
||||
it("should handle SLPDB returning null corner case", 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' corner case.
|
||||
sandbox.stub(uut.Utils, "validateTxid").resolves([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", () => {
|
||||
|
||||
Reference in New Issue
Block a user