feat(GET MempoolAncestors): Added wrapper for full node RPC call

This commit is contained in:
Chris Troutner
2020-01-17 15:16:02 -08:00
parent 11c936d731
commit c7ceed8784
4 changed files with 138 additions and 1 deletions
+1
View File
@@ -12,6 +12,7 @@
"dev": "nodemon ./dist/app.js",
"test": "npm run test-v3",
"test-v3": "export NETWORK=mainnet && nyc --reporter=text mocha --timeout 25000 test/v3/",
"test:temp": "export NETWORK=mainnet && mocha --timeout 25000 test/v3/blockchain.js",
"test:integration": "mocha test/v3/integration",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"coverage:report": "export NETWORK=testnet && nyc --reporter=html mocha test/v2/",
+58
View File
@@ -29,6 +29,7 @@ router.get("/getChainTips", getChainTips)
router.get("/getDifficulty", getDifficulty)
router.get("/getMempoolEntry/:txid", getMempoolEntrySingle)
router.post("/getMempoolEntry", getMempoolEntryBulk)
router.get("/getMempoolAncestors/:txid", getMempoolAncestorsSingle)
router.get("/getMempoolInfo", getMempoolInfo)
router.get("/getRawMempool", getRawMempool)
router.get("/getTxOut/:txid/:n", getTxOut)
@@ -585,6 +586,62 @@ async function getMempoolEntryBulk(req, res, next) {
}
}
/**
* @api {get} /blockchain/getMempoolAncestors/:txid Get Mempool Ancestors
* @apiName getMempoolAncestors
* @apiGroup Blockchain
* @apiDescription Returns mempool ancestors data for given TXID. It must be in
* mempool (unconfirmed). This call is handy to tell if a UTXO is bumping up
* against the 25 ancestor chain-limit.
*
* @apiExample Example usage:
* curl -X GET "https://mainnet.bchjs.cash/v3/blockchain/getMempoolEntry/fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33" -H "accept: application/json"
*
*/
async function getMempoolAncestorsSingle(req, res, next) {
try {
// Validate input parameter
const txid = req.params.txid
if (!txid || txid === "") {
res.status(400)
return res.json({ error: "txid can not be empty" })
}
let verbose = req.params.verbose
if (verbose === undefined) verbose = false
const {
BitboxHTTP,
username,
password,
requestConfig
} = routeUtils.setEnvVars()
requestConfig.data.id = "getmempoolancestors"
requestConfig.data.method = "getmempoolancestors"
requestConfig.data.params = [txid, verbose]
const response = await BitboxHTTP(requestConfig)
// console.log(`response: ${util.inspect(response)}`)
return res.json(response.data.result)
} catch (err) {
// Attempt to decode the error message.
const { msg, status } = routeUtils.decodeError(err)
if (msg) {
res.status(status)
return res.json({ error: msg })
}
// Write out error to error log.
//logger.error(`Error in rawtransactions/decodeRawTransaction: `, err)
wlogger.error(`Error in blockchain.ts/getMempoolAncestorsSingle().`, err)
res.status(500)
return res.json({ error: util.inspect(err) })
}
}
/**
* @api {get} /blockchain/getMempoolInfo Get mempool info
* @apiName getMempoolInfo
@@ -1089,6 +1146,7 @@ module.exports = {
getRawMempool,
getMempoolEntrySingle,
getMempoolEntryBulk,
getMempoolAncestorsSingle,
getTxOut,
getTxOutProofSingle,
getTxOutProofBulk,
+50
View File
@@ -786,6 +786,56 @@ describe("#BlockchainRouter", () => {
}
})
describe("getMempoolAncestorsSingle()", () => {
// block route handler.
const getMempoolAncestorsSingle =
blockchainRoute.testableComponents.getMempoolAncestorsSingle
it("should throw 400 if txid is empty", async () => {
const result = await getMempoolAncestorsSingle(req, res)
//console.log(`result: ${util.inspect(result)}`)
assert.hasAllKeys(result, ["error"])
assert.include(result.error, "txid can not be empty")
})
it("should throw 503 when network issues", async () => {
// Save the existing RPC URL.
const savedUrl2 = process.env.RPC_BASEURL
// Manipulate the URL to cause a 500 network error.
process.env.RPC_BASEURL = "http://fakeurl/api/"
req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde`
const result = await getMempoolAncestorsSingle(req, res)
//console.log(`result: ${util.inspect(result)}`)
// Restore the saved URL.
process.env.RPC_BASEURL = savedUrl2
assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.")
assert.include(
result.error,
"Could not communicate with full node",
"Error message expected"
)
})
it("should GET /getMempoolAncestorsSingle", async () => {
nock(`${process.env.RPC_BASEURL}`)
.post(uri => uri.includes("/"))
.reply(200, { result: mockData.mockAncestors })
req.params.txid = `bb0d349892d351da2767f8c45f6f7949713ff09bd12838d53e76158ddee3ce93`
const result = await getMempoolAncestorsSingle(req, res)
// console.log(`result: ${util.inspect(result)}`)
assert.isArray(result)
})
})
describe("getTxOut()", () => {
// block route handler.
const getTxOut = blockchainRoute.testableComponents.getTxOut
+29 -1
View File
@@ -258,6 +258,33 @@ const mockTxOut = {
const mockTxOutProof =
"000000200798039affceb7a381e15dc62443c286efe7cae852393b656807000000000000cf9a7d6c654fd1c4558229a619a550ff749b373fa0f0027eed68b1abf6175d5c07c50f5cffff001d0452403b34000000070d0765da76980d542b5670d27ccda9e717073270f8921ad017deb7ee83fe6c4c22830a48cc8392197f1742a3d81805bd2aa4eb7469f38c74f674429d682cb87efcff1713fd0c388a50f0d11adf05363397ef79d16cdb786d47c941c2cb89f2588f42aced9c05f4203b4440616a9e4266ec47909b9580a643f402b5d4e82cc3cddd73df05a33abf6af3975d973d3033d10c4168a73d58d01f685a96d5a2519cd0de9c77faf3f8725ddf155cbdc8ab8102f173e2d0a0d74767f3bff22f588158d6d5bc71c079c7659cc864819c43877635007650502eb4060fcc9feec3280a41d602ad0a"
const mockAncestors = [
"070504de968fba8a23a1362fd7fc0546a420663f2bcc18099d894a41ecf9cce5",
"20af6b7fcd21a3f38bb65d32fe2d66fb1ae554ed9c00eaf1b17d7e81362381a9",
"227e08663a812cf44d91106b09fc8493fe1a2b7c146f30ca09ebd86c9b84b2a5",
"228833be79d4a833165ea199be160efcaeb9325e71e9455f424b27abc9688ba8",
"2de27df02001e7243435cef6d41ea2312b94a5964912eb21466b936852c0b822",
"2ef76ae690d6f6c9559e20358a75a0ce02250b9b8e80e0aa6f782576239f292a",
"3e314678f52d52694726e6da88b94c9f0ea086d2f9af297b01d014b62247839f",
"4773f840d5255f16c0e5effce48316d8b8824a1d3ddd5da275c5fd99e7b3ee42",
"4804b97112da07e2c187516a915dd4cbd4a3814f3c900b8d08eb1d508ab0ac47",
"4ca69f31081a256cb4711315336fe4358d8f04b67792ca5ee17b5f4089a2446a",
"6ac17dce10ae3a3d1d8e6f42546ad9a4bb981e62cba8d48bab03e01b9ea38ae3",
"6ce71182ef341c481a90d8b081a99d9788bdd91a917f9a6594fdfad2c2024a14",
"8413343ac973fb0968ae1809faa8f0ddf18252975481daa683e88b04afa66ccd",
"9430300f3d7ecdabe39671b6fd0e9c36f763f01a202e619c070554ddc5e8713e",
"94f82b5a2cd1647d8168807ccfdebe41931ea1ab789a050d615f08000a63b624",
"9848db6a7d2835002ca7e1097a685d75eb629f44df94007674635b45d0e97199",
"98d809993353df6c4d55fda5e7b0ed2e383601cef1180a9aa9c87e67e8f4dd94",
"9f5513a35ae8fad3dd061865a97d8127c914e3464527641c089993c06d092535",
"a7201ac90abd2aa42112faa809181c45047b6988a2f649a70a1d5bfb95f46884",
"a9f1284710c655357412a062b01efaeb174820613784ccbfe44b33b86a8bdbc4",
"b814f44c9c8ee24a218b9f295a8c1831106b70c15ffe8aeb7534e10d99935fd0",
"e130ccdcc94dc5eaa4ae37fa50e3ee96283b0e157616bc6e28454b64bae34f48",
"e68dad4a7292105cfa84fcaef7f99e5d4f2ece9613ca625d4d2ebf61efa84118",
"fe94caf5da672be3772d2304a6272eb8bc3d3f5cb4a886f39b7981e1485cf74b"
]
module.exports = {
mockBlockHash,
mockBlockchainInfo,
@@ -267,5 +294,6 @@ module.exports = {
mockBlockHeaderConcise,
mockBlockHeader,
mockTxOut,
mockTxOutProof
mockTxOutProof,
mockAncestors
}