mirror of
https://github.com/fullstack-cash/bch-api.git
synced 2026-09-21 16:52:04 -07:00
feat(GET MempoolAncestors): Added wrapper for full node RPC call
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
"dev": "nodemon ./dist/app.js",
|
"dev": "nodemon ./dist/app.js",
|
||||||
"test": "npm run test-v3",
|
"test": "npm run test-v3",
|
||||||
"test-v3": "export NETWORK=mainnet && nyc --reporter=text mocha --timeout 25000 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",
|
"test:integration": "mocha test/v3/integration",
|
||||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||||
"coverage:report": "export NETWORK=testnet && nyc --reporter=html mocha test/v2/",
|
"coverage:report": "export NETWORK=testnet && nyc --reporter=html mocha test/v2/",
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ router.get("/getChainTips", getChainTips)
|
|||||||
router.get("/getDifficulty", getDifficulty)
|
router.get("/getDifficulty", getDifficulty)
|
||||||
router.get("/getMempoolEntry/:txid", getMempoolEntrySingle)
|
router.get("/getMempoolEntry/:txid", getMempoolEntrySingle)
|
||||||
router.post("/getMempoolEntry", getMempoolEntryBulk)
|
router.post("/getMempoolEntry", getMempoolEntryBulk)
|
||||||
|
router.get("/getMempoolAncestors/:txid", getMempoolAncestorsSingle)
|
||||||
router.get("/getMempoolInfo", getMempoolInfo)
|
router.get("/getMempoolInfo", getMempoolInfo)
|
||||||
router.get("/getRawMempool", getRawMempool)
|
router.get("/getRawMempool", getRawMempool)
|
||||||
router.get("/getTxOut/:txid/:n", getTxOut)
|
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
|
* @api {get} /blockchain/getMempoolInfo Get mempool info
|
||||||
* @apiName getMempoolInfo
|
* @apiName getMempoolInfo
|
||||||
@@ -1089,6 +1146,7 @@ module.exports = {
|
|||||||
getRawMempool,
|
getRawMempool,
|
||||||
getMempoolEntrySingle,
|
getMempoolEntrySingle,
|
||||||
getMempoolEntryBulk,
|
getMempoolEntryBulk,
|
||||||
|
getMempoolAncestorsSingle,
|
||||||
getTxOut,
|
getTxOut,
|
||||||
getTxOutProofSingle,
|
getTxOutProofSingle,
|
||||||
getTxOutProofBulk,
|
getTxOutProofBulk,
|
||||||
|
|||||||
@@ -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()", () => {
|
describe("getTxOut()", () => {
|
||||||
// block route handler.
|
// block route handler.
|
||||||
const getTxOut = blockchainRoute.testableComponents.getTxOut
|
const getTxOut = blockchainRoute.testableComponents.getTxOut
|
||||||
|
|||||||
@@ -258,6 +258,33 @@ const mockTxOut = {
|
|||||||
const mockTxOutProof =
|
const mockTxOutProof =
|
||||||
"000000200798039affceb7a381e15dc62443c286efe7cae852393b656807000000000000cf9a7d6c654fd1c4558229a619a550ff749b373fa0f0027eed68b1abf6175d5c07c50f5cffff001d0452403b34000000070d0765da76980d542b5670d27ccda9e717073270f8921ad017deb7ee83fe6c4c22830a48cc8392197f1742a3d81805bd2aa4eb7469f38c74f674429d682cb87efcff1713fd0c388a50f0d11adf05363397ef79d16cdb786d47c941c2cb89f2588f42aced9c05f4203b4440616a9e4266ec47909b9580a643f402b5d4e82cc3cddd73df05a33abf6af3975d973d3033d10c4168a73d58d01f685a96d5a2519cd0de9c77faf3f8725ddf155cbdc8ab8102f173e2d0a0d74767f3bff22f588158d6d5bc71c079c7659cc864819c43877635007650502eb4060fcc9feec3280a41d602ad0a"
|
"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 = {
|
module.exports = {
|
||||||
mockBlockHash,
|
mockBlockHash,
|
||||||
mockBlockchainInfo,
|
mockBlockchainInfo,
|
||||||
@@ -267,5 +294,6 @@ module.exports = {
|
|||||||
mockBlockHeaderConcise,
|
mockBlockHeaderConcise,
|
||||||
mockBlockHeader,
|
mockBlockHeader,
|
||||||
mockTxOut,
|
mockTxOut,
|
||||||
mockTxOutProof
|
mockTxOutProof,
|
||||||
|
mockAncestors
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user