From feb336c33199c8fdd36afd62484a152edf874c32 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Wed, 24 Feb 2021 15:11:58 -0800 Subject: [PATCH] fix(decodeOpReturn): Switching to POST from GET to getRawTx call --- package.json | 1 + src/slp/utils.js | 46 +++++++++++++++++++++++++++++++++--------- test/unit/slp-utils.js | 36 ++++++++++++++++----------------- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 273ac34..2d7a84e 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "test:temp": "export RESTURL=http://localhost:3000/v4/ && mocha --timeout 30000 -g '#hydrateUtxos' test/integration/", "test:temp2": "mocha --timeout=30000 -g '#Util' test/unit/", "test:temp3": "export RESTURL=https://bchn.fullstack.cash/v4/ && mocha --timeout 30000 -g '#hydrateUtxos' test/integration/", + "test:temp4": "export RESTURL=http://localhost:3000/v4/ && mocha --timeout 30000 -g '#decodeOpReturn' test/integration/", "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", diff --git a/src/slp/utils.js b/src/slp/utils.js index 533a849..16f1c41 100644 --- a/src/slp/utils.js +++ b/src/slp/utils.js @@ -655,7 +655,7 @@ class Utils { // console.log(`txid: ${JSON.stringify(txid, null, 2)}`) // console.log(`path: ${JSON.stringify(path, null, 2)}`) - console.log('ip: ', ip) + console.log('validateTxid3 ip: ', ip) // Handle a single TXID or an array of TXIDs. let txids @@ -925,7 +925,7 @@ class Utils { * */ // Reimplementation of decodeOpReturn() using slp-parser. - async decodeOpReturn (txid, cache = null) { + async decodeOpReturn (txid, cache = null, ip = null) { // The cache object is an in-memory cache (JS Object) that can be passed // into this function. It helps if multiple vouts from the same TXID are // being evaluated. In that case, it can significantly reduce the number @@ -942,16 +942,32 @@ class Utils { if (cachedVal) return cachedVal } + console.log(`decodeOpReturn ip: ${ip}`) + try { // Validate the txid input. if (!txid || txid === '' || typeof txid !== 'string') { throw new Error('txid string must be included.') } + // CT: 2/24/21 Deprected GET in favor of POST, to pass IP address. // Retrieve the transaction object from the full node. - const path = `${this.restURL}rawtransactions/getRawTransaction/${txid}?verbose=true` - const response = await _this.axios.get(path, _this.axiosOptions) - const txDetails = response.data + // const path = `${this.restURL}rawtransactions/getRawTransaction/${txid}?verbose=true` + // const response = await _this.axios.get(path, _this.axiosOptions) + // const txDetails = response.data + + const path = `${this.restURL}rawtransactions/getRawTransaction` + const response = await _this.axios.post( + path, + { + verbose: true, + txids: [txid], + ip + }, + _this.axiosOptions + ) + const txDetails = response.data[0] + // console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`) // SLP spec expects OP_RETURN to be the first output of the transaction. @@ -1069,6 +1085,8 @@ class Utils { // Throw error if input is not an array. if (!Array.isArray(utxos)) throw new Error('Input must be an array.') + console.log(`tokenUtxoDetails ip: ${ip}`) + // Loop through each element in the array and validate the input before // further processing. for (let i = 0; i < utxos.length; i++) { @@ -1100,7 +1118,7 @@ class Utils { } // Hydrate each UTXO with data from SLP OP_REUTRNs. - const outAry = await this._hydrateUtxo(utxos) + const outAry = await this._hydrateUtxo(utxos, ip) // console.log(`outAry: ${JSON.stringify(outAry, null, 2)}`) // *After* each UTXO has been hydrated with SLP data, @@ -1220,10 +1238,12 @@ class Utils { // This is a private function that is called by tokenUtxoDetails(). // It loops through an array of UTXOs and tries to hydrate them with SLP // token information from the OP_RETURN data. - async _hydrateUtxo (utxos) { + async _hydrateUtxo (utxos, ip = null) { try { const decodeOpReturnCache = {} + console.log(`_hydrateUtxo ip: ${ip}`) + // Output Array const outAry = [] @@ -1236,7 +1256,11 @@ class Utils { // If there is no OP_RETURN, mark the UTXO as false. let slpData = false try { - slpData = await this.decodeOpReturn(utxo.txid, decodeOpReturnCache) + slpData = await this.decodeOpReturn( + utxo.txid, + decodeOpReturnCache, + ip + ) // console.log(`slpData: ${JSON.stringify(slpData, null, 2)}`) } catch (err) { // console.log(`error from decodeOpReturn(${utxo.txid}): `, err) @@ -1326,7 +1350,8 @@ class Utils { const genesisData = await this.decodeOpReturn( slpData.tokenId, - decodeOpReturnCache + decodeOpReturnCache, + ip ) // console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`) @@ -1378,7 +1403,8 @@ class Utils { const genesisData = await this.decodeOpReturn( slpData.tokenId, - decodeOpReturnCache + decodeOpReturnCache, + ip ) // console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`) diff --git a/test/unit/slp-utils.js b/test/unit/slp-utils.js index 8da8632..fad8e88 100644 --- a/test/unit/slp-utils.js +++ b/test/unit/slp-utils.js @@ -273,8 +273,8 @@ describe('#SLP Utils', () => { try { // Mock the call to the REST API sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.nonSLPTxDetailsWithoutOpReturn }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.nonSLPTxDetailsWithoutOpReturn] }) const txid = '3793d4906654f648e659f384c0f40b19c8f10c1e9fb72232a9b8edd61abaa1ec' @@ -292,8 +292,8 @@ describe('#SLP Utils', () => { try { // Mock the call to the REST API sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.nonSLPTxDetailsWithOpReturn }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.nonSLPTxDetailsWithOpReturn] }) const txid = '2ff74c48a5d657cf45f699601990bffbbe7a2a516d5480674cbf6c6a4497908f' @@ -310,8 +310,8 @@ describe('#SLP Utils', () => { it('should decode a genesis transaction', async () => { // Mock the call to the REST API sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.txDetailsSLPGenesis }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.txDetailsSLPGenesis] }) const txid = 'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90' @@ -336,8 +336,8 @@ describe('#SLP Utils', () => { it('should decode a mint transaction', async () => { // Mock the call to the REST API sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.txDetailsSLPMint }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.txDetailsSLPMint] }) const txid = '65f21bbfcd545e5eb515e38e861a9dfe2378aaa2c4e458eb9e59e4d40e38f3a4' @@ -357,8 +357,8 @@ describe('#SLP Utils', () => { it('should decode a send transaction', async () => { // Mock the call to the REST API sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.txDetailsSLPSend }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.txDetailsSLPSend] }) const txid = '4f922565af664b6fdf0a1ba3924487344be721b3d8815c62cafc8a51e04a8afa' @@ -372,8 +372,8 @@ describe('#SLP Utils', () => { it('should properly decode a Genesis transaction with no minting baton', async () => { // Mock the call to the REST API. sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.txDetailsSLPGenesisNoBaton }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.txDetailsSLPGenesisNoBaton] }) const txid = '497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7' @@ -387,8 +387,8 @@ describe('#SLP Utils', () => { it('should decode a send transaction with alternate encoding', async () => { // Mock the call to the REST API sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.txDetailsSLPSendAlt }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.txDetailsSLPSendAlt] }) const txid = 'd94357179775425ebc59c93173bd6dc9854095f090a2eb9dcfe9797398bc8eae' @@ -411,8 +411,8 @@ describe('#SLP Utils', () => { try { // Mock the call to the REST API sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.mockInvalidSlpSend }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.mockInvalidSlpSend] }) const txid = 'a60a522cc11ad7011b74e57fbabbd99296e4b9346bcb175dcf84efb737030415' @@ -428,8 +428,8 @@ describe('#SLP Utils', () => { it('should decode a NFT Parent transaction', async () => { // Mock the call to the REST API. sandbox - .stub(uut.Utils.axios, 'get') - .resolves({ data: mockData.txDetailsSLPNftGenesis }) + .stub(uut.Utils.axios, 'post') + .resolves({ data: [mockData.txDetailsSLPNftGenesis] }) const txid = '4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4'