Merge pull request #112 from Permissionless-Software-Foundation/ct-unstable

fix(decodeOpReturn): Switching to POST from GET to getRawTx call
This commit is contained in:
Chris Troutner
2021-02-24 15:14:51 -08:00
committed by GitHub
3 changed files with 55 additions and 28 deletions
+1
View File
@@ -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",
+36 -10
View File
@@ -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)}`)
+18 -18
View File
@@ -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'