Compare commits

...
13 Commits
Author SHA1 Message Date
Chris Troutner 8507abd5db Merge pull request #123 from Permissionless-Software-Foundation/dh-apidocs
fix(docs): Fixed bch-api API docs
2021-03-30 06:40:10 -08:00
Daniel Gonzalez fae9a75f6a fix(docs): Fixed bch-api API docs 2021-03-29 21:04:51 -04:00
Chris Troutner fc6da588ee Merge pull request #120 from Permissionless-Software-Foundation/dh-getblock-endpoint
feat(getblock): Added getblock endpoint
2021-03-29 12:17:45 -08:00
Chris Troutner 6f8c00bab9 Making sure integration tests work 2021-03-29 13:08:55 -07:00
Chris Troutner a2ab88adab Merge branch 'master' into dh-getblock-endpoint 2021-03-29 12:13:16 -07:00
Chris Troutner 60528dbd6e Merge pull request #122 from Permissionless-Software-Foundation/timeout
fix(timout): Increasing API timeout from 30 seconds to 5 minutes
2021-03-26 18:11:44 -08:00
Chris Troutner cebf1ea1d6 fix(timout): Increasing API timeout from 30 seconds to 5 minutes 2021-03-26 19:10:33 -07:00
Chris Troutner 11a62af39b Merge pull request #121 from Permissionless-Software-Foundation/ct-unstable
fix(rate limits): Quieting noisy tests
2021-03-26 08:01:45 -07:00
Chris Troutner 83aeabd913 fix(rate limits): Quieting noisy tests 2021-03-26 07:50:41 -07:00
Daniel Gonzalez 7acb778470 feat(getblock): Added getblock endpoint 2021-03-25 17:30:30 -04:00
Chris Troutner 766925c9a8 Merge pull request #119 from Permissionless-Software-Foundation/ct-unstable
Fixing test for BVT
2021-03-16 11:07:00 -07:00
Chris Troutner 51c37e1371 Merge branch 'master' into ct-unstable 2021-03-16 11:03:16 -07:00
Chris Troutner 244acfb26b fix(test): Fixing test for BVT 2021-03-16 11:03:06 -07:00
10 changed files with 390 additions and 52 deletions
+4
View File
@@ -0,0 +1,4 @@
{
"sampleUrl": null
}
+25 -22
View File
@@ -395,9 +395,9 @@
}
},
"@psf/bch-js": {
"version": "4.16.1",
"resolved": "https://registry.npmjs.org/@psf/bch-js/-/bch-js-4.16.1.tgz",
"integrity": "sha512-0rAOLGwxuzCrpe6dbz5nQ9KQTJIJNGzihSVSVfv0PXIeBKQKq+MuEG7u6rZXNeJlLWokosGwf6aysK2EbDGcqA==",
"version": "4.17.6",
"resolved": "https://registry.npmjs.org/@psf/bch-js/-/bch-js-4.17.6.tgz",
"integrity": "sha512-dXR3S7wHZEivB/1LvvuBaAxn8FRRQpBrLtLcuL8c1J9v82xMO+qVr6AwvsOjFzHmcswuT1jlzQ3X1XPAaRgb5w==",
"requires": {
"@psf/bip21": "^2.0.1",
"@psf/bip32-utils": "^1.0.0",
@@ -931,23 +931,23 @@
}
},
"@uppy/companion-client": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-1.8.2.tgz",
"integrity": "sha512-FBjAJU3xaWRqYXDBlrMDQKlRBqi4Ng54Dmnoe3hGSggfgBQAl9RzRAg0WvrGjaK3QjCTZPhzSdTpBrqDP22Rng==",
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-1.8.3.tgz",
"integrity": "sha512-IieE5DMmJC1rJrXHB2u1cO+r3BF7VqnezFAZj8gkNm7zBuplswKALlvwnXI+KU3TNs8isU55xK5yfF0ecglIEw==",
"requires": {
"@uppy/utils": "^3.4.1",
"@uppy/utils": "^3.4.2",
"namespace-emitter": "^2.0.1",
"qs-stringify": "^1.1.0"
}
},
"@uppy/core": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/@uppy/core/-/core-1.16.1.tgz",
"integrity": "sha512-GI8baCa1S21j7KoCq0LK4MLD6sII8OvWVgp+auXNcZIbKa182dOMQRtk7bXVY0OzS1TxkIq0DAzDEUnP7MbnDg==",
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/@uppy/core/-/core-1.16.2.tgz",
"integrity": "sha512-JWK03gXiMMZ+lSVj+v9FIFEOUbKyvRX4v2kaYhf0NqD1MssCwMQe4mvL2MNzjOaYFBwMRacDJh8Mvz2gbu2Vqw==",
"requires": {
"@transloadit/prettier-bytes": "0.0.7",
"@uppy/store-default": "^1.2.5",
"@uppy/utils": "^3.4.1",
"@uppy/utils": "^3.4.2",
"cuid": "^2.1.1",
"lodash.throttle": "^4.1.1",
"mime-match": "^1.0.2",
@@ -961,19 +961,19 @@
"integrity": "sha512-jnf0U8cfb8Bhgt6yh86YRJO9EEnCyG9BgXZ8dPWWLybgC9Expw3Ah/s3T21tcdChgv4zzdhSACd0JKxCQowyYg=="
},
"@uppy/tus": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@uppy/tus/-/tus-1.8.5.tgz",
"integrity": "sha512-a5z+bpAyKKKRWNSOYtIMd2EAKsM7BLhd6hQg2YrQNFFzdwbxaeqmrjKIVW1EUBvg1if/ZZePEm0QevJvNwQs0g==",
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/@uppy/tus/-/tus-1.8.6.tgz",
"integrity": "sha512-axK+TzRRvSkYZUIjfe6XCjfO5NPb/k8AC73p+MOKOzth1JHSZSJHqYi8+HY7T4aXgR86vWE/cE+wHsjvPhyCZw==",
"requires": {
"@uppy/companion-client": "^1.8.2",
"@uppy/utils": "^3.4.1",
"@uppy/companion-client": "^1.8.3",
"@uppy/utils": "^3.4.2",
"tus-js-client": "^2.1.1"
}
},
"@uppy/utils": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-3.4.1.tgz",
"integrity": "sha512-9YVKjVRK/AmX3yV0GJsD5p/eHUzqn4+eXzsjv3wHahipKCo0o7Jwpw/7kl+bv12EHOOy5jPsATWkjn40aSWW8w==",
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-3.4.2.tgz",
"integrity": "sha512-PWLZgX4L+0tdBqImncuATDYb1M6RHgDfGDZCh2Qg+PTG+btyyZ4/GkOEwK5fJ4Gw1gNgWF0ewAFL28+oCrD7/Q==",
"requires": {
"abortcontroller-polyfill": "^1.4.0",
"lodash.throttle": "^4.1.1"
@@ -10930,9 +10930,12 @@
"dev": true
},
"qs": {
"version": "6.9.6",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
"integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"requires": {
"side-channel": "^1.0.4"
}
},
"qs-stringify": {
"version": "1.2.1",
+1 -1
View File
@@ -29,7 +29,7 @@
"node": ">=10.15.1"
},
"dependencies": {
"@psf/bch-js": "^4.16.1",
"@psf/bch-js": "^4.17.6",
"apidoc": "^0.26.0",
"axios": "^0.21.1",
"bitcore-lib-cash": "^8.23.1",
+5 -3
View File
@@ -189,9 +189,11 @@ server.listen(port)
server.on('error', onError)
server.on('listening', onListening)
// Set the time before a timeout error is generated. This impacts testing and
// the handling of timeout errors. Is 10 seconds too agressive?
server.setTimeout(30 * 1000)
// Set the time before a timeout error is generated.
// 10 seconds is way too agressive. 30 Seconds was used for a while, but with
// being able to set a timeout between UTXOs for tokenUtxoDetails, the timeout
// needed to be extended.
server.setTimeout(1000 * 60 * 5) // 5 minutes
/**
* Normalize a port into a number, string, or false.
+17 -16
View File
@@ -82,11 +82,11 @@ class RateLimits {
// Determine if the call is an external or internal API call.
const isInternal = _this.checkInternalIp(req)
console.log(`isInternal: ${isInternal}`)
// console.log(`isInternal: ${isInternal}`)
// Determine if the call originates from another computer on the intranet.
const isWhitelistOrigin = _this.isInWhitelist(req)
console.log('isWhitelistOrigin: ', isWhitelistOrigin)
// console.log('isWhitelistOrigin: ', isWhitelistOrigin)
// Handle the use case of internally-generated requests.
if (isInternal) {
@@ -94,15 +94,15 @@ class RateLimits {
// the usrObj in the body.
if (req.body && req.body.usrObj) {
if (req.body.usrObj.proLimit) {
console.log('Internal call, basic auth, skipping rate limits.')
// console.log('Internal call, basic auth, skipping rate limits.')
// If this is an internal call that originated from a user using
// Basic Authentication, then skip rate-limits.
return next()
} else {
console.log(
'Internal call, applying rate limits. Using JWT if available.'
)
// console.log(
// 'Internal call, applying rate limits. Using JWT if available.'
// )
// Determine if user has exceeded their rate limits. Pass in the
// JWT token if one exists.
@@ -130,10 +130,10 @@ class RateLimits {
// and avoid this code path. This code path is 'pooled': all users
// share the same rate limits. Even at 1000 RPM, this pool will get
// exhausted easily.
const warnMsg =
'Internal call. req.body.usrObj does not exist. Applying high-speed internal rate limits.'
console.log(warnMsg)
wlogger.info(warnMsg)
// const warnMsg =
// 'Internal call. req.body.usrObj does not exist. Applying high-speed internal rate limits.'
// console.log(warnMsg)
// wlogger.info(warnMsg)
const defaultPayload = {
id: '98.76.54.32',
@@ -168,9 +168,9 @@ class RateLimits {
//
} else {
// Handle the normal use-case of external requests
console.log(
'External call, applying rate limits. Using JWT if available.'
)
// console.log(
// 'External call, applying rate limits. Using JWT if available.'
// )
// For calls originating from a whitelist domain, apply a high-RPM
// JWT token to the call.
@@ -233,7 +233,7 @@ class RateLimits {
pointsToConsume = decoded.pointsToConsume
}
console.log(`rate limit key: ${key}`)
// console.log(`rate limit key: ${key}`)
// This function will throw an error if the user exceeds the rate limit.
// The 429 error response is handled by the catch().
@@ -244,7 +244,7 @@ class RateLimits {
// Signal that the user has not exceeded their rate limits.
return false
} catch (err) {
console.log('err: ', err)
// console.log('err: ', err)
const rateLimit = Math.floor(POINTS_PER_MINUTE / pointsToConsume)
@@ -307,7 +307,8 @@ class RateLimits {
// Retrieve the origin.
const origin = req.get('origin')
console.log(`origin: ${origin}`)
if (!process.env.TEST) console.log('origin:', origin)
// If the origin is not determinable, return false.
if (!origin) return false
+1 -1
View File
@@ -181,7 +181,7 @@ class Encryption {
publicKey: 'not found'
})
} catch (err) {
console.log('Error in encryption.js/getPublicKey().', err)
// console.log('Error in encryption.js/getPublicKey().', err)
wlogger.error('Error in encryption.js/getPublicKey().', err)
return _this.errorHandler(err, res)
+47
View File
@@ -53,6 +53,7 @@ class Blockchain {
this.router.post('/getTxOutProof', this.getTxOutProofBulk)
this.router.get('/verifyTxOutProof/:proof', this.verifyTxOutProofSingle)
this.router.post('/verifyTxOutProof', this.verifyTxOutProofBulk)
this.router.post('/getBlock', this.getBlock)
}
root (req, res, next) {
@@ -937,6 +938,52 @@ class Blockchain {
return _this.errorHandler(err, res)
}
}
/**
* @api {post} /blockchain/getBlock/ Get block details
* @apiName getBlock
* @apiGroup Blockchain
* @apiDescription Returns block details
*
* @apiExample Example usage:
* curl "https://api.fullstack.cash/v4/blockchain/getblock/" -X POST -H "Content-Type: application/json" --data-binary '{"blockhash":"000000000000000002a5fe0bdd6e3f04342a975c0f55e57f97e73bb90041676b","verbosity":0 }'
*
* @apiParam {String} blockhash Block hash (required)
* @apiParam {Number} verbosity Default 1 (optional)
*
*/
async getBlock (req, res, next) {
try {
// Validate input parameter
const blockhash = req.body.blockhash
let verbosity = req.body.verbosity
// Default to a value of 1 if another verbosity level is not defined.
if (!verbosity && verbosity !== 0) verbosity = 1
if (!blockhash || blockhash === '') {
res.status(400)
return res.json({ error: 'blockhash can not be empty' })
}
// Axios options
const options = _this.routeUtils.getAxiosOptions()
options.data.id = 'getblock'
options.data.method = 'getblock'
options.data.params = [blockhash, verbosity]
const response = await _this.axios.request(options)
return res.json(response.data.result)
} catch (err) {
// Write out error to error log.
// logger.error(`Error in rawtransactions/decodeRawTransaction: `, err)
wlogger.error('Error in blockchain.js/getBlock()', err)
return _this.errorHandler(err, res)
}
}
}
module.exports = Blockchain
+200
View File
@@ -1823,4 +1823,204 @@ describe('#BlockchainRouter', () => {
assert.equal(result.length, 2)
})
})
describe('#getBlock()', () => {
it('returns proper error when downstream service stalls', async () => {
// Mock the timeout error.
sandbox.stub(uut.axios, 'request').throws({ code: 'ECONNABORTED' })
req.body.blockhash =
'000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700'
const result = await uut.getBlock(req, res)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isAbove(res.statusCode, 499, 'HTTP status code 503 expected.')
assert.include(
result.error,
'Could not communicate with full node',
'Error message expected'
)
})
it('returns proper error when downstream service is down', async () => {
// Mock the timeout error.
sandbox.stub(uut.axios, 'request').throws({ code: 'ECONNREFUSED' })
req.body.blockhash =
'000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700'
const result = await uut.getBlock(req, res)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
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 throw 400 if blockhash is empty', async () => {
const result = await uut.getBlock(req, res)
// console.log(`result: ${util.inspect(result)}`)
assert.hasAllKeys(result, ['error'])
assert.include(result.error, 'blockhash can not be empty')
})
it('should return block info with verbosity 0', async () => {
// Mock the RPC call for unit tests.
if (process.env.TEST === 'unit') {
sandbox
.stub(uut.axios, 'request')
.resolves({ data: { result: mockData.mockBlockInfo.verbosity0 } })
}
req.body.blockhash =
'0000000000000000008e8d83cba6d45a9314bc2ef4538d4e0577c6bed8593536'
req.body.verbosity = 0
const result = await uut.getBlock(req, res)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isString(result)
})
it('should return block info with verbosity 1', async () => {
// Mock the RPC call for unit tests.
if (process.env.TEST === 'unit') {
sandbox
.stub(uut.axios, 'request')
.resolves({ data: { result: mockData.mockBlockInfo.verbosity1 } })
}
req.body.blockhash =
'0000000000000000008e8d83cba6d45a9314bc2ef4538d4e0577c6bed8593536'
req.body.verbosity = 1
const result = await uut.getBlock(req, res)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, 'hash', 'hash property expected')
assert.property(
result,
'confirmations',
'confirmations property expected'
)
assert.property(result, 'size', 'size property expected')
assert.property(result, 'height', 'height property expected')
assert.property(result, 'version', 'version property expected')
assert.property(result, 'versionHex', 'versionHex property expected')
assert.property(result, 'merkleroot', 'merkleroot property expected')
assert.property(result, 'tx', 'tx property expected')
assert.property(result, 'time', 'time property expected')
assert.property(result, 'mediantime', 'mediantime property expected')
assert.property(result, 'nonce', 'nonce property expected')
assert.property(result, 'bits', 'bits property expected')
assert.property(result, 'difficulty', 'difficulty property expected')
assert.property(result, 'chainwork', 'chainwork property expected')
assert.property(result, 'nTx', 'nTx property expected')
assert.property(
result,
'previousblockhash',
'previousblockhash property expected'
)
assert.property(
result,
'nextblockhash',
'nextblockhash property expected'
)
})
it('should return block info with verbosity 2', async () => {
// Mock the RPC call for unit tests.
if (process.env.TEST === 'unit') {
sandbox
.stub(uut.axios, 'request')
.resolves({ data: { result: mockData.mockBlockInfo.verbosity1 } })
}
req.body.blockhash =
'0000000000000000008e8d83cba6d45a9314bc2ef4538d4e0577c6bed8593536'
req.body.verbosity = 2
const result = await uut.getBlock(req, res)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, 'hash', 'hash property expected')
assert.property(
result,
'confirmations',
'confirmations property expected'
)
assert.property(result, 'size', 'size property expected')
assert.property(result, 'height', 'height property expected')
assert.property(result, 'version', 'version property expected')
assert.property(result, 'versionHex', 'versionHex property expected')
assert.property(result, 'merkleroot', 'merkleroot property expected')
assert.property(result, 'tx', 'tx property expected')
assert.property(result, 'time', 'time property expected')
assert.property(result, 'mediantime', 'mediantime property expected')
assert.property(result, 'nonce', 'nonce property expected')
assert.property(result, 'bits', 'bits property expected')
assert.property(result, 'difficulty', 'difficulty property expected')
assert.property(result, 'chainwork', 'chainwork property expected')
assert.property(result, 'nTx', 'nTx property expected')
assert.property(
result,
'previousblockhash',
'previousblockhash property expected'
)
assert.property(
result,
'nextblockhash',
'nextblockhash property expected'
)
})
it('should return block info without verbosity especified', async () => {
// Mock the RPC call for unit tests.
if (process.env.TEST === 'unit') {
sandbox
.stub(uut.axios, 'request')
.resolves({ data: { result: mockData.mockBlockInfo.verbosity1 } })
}
req.body.blockhash =
'0000000000000000008e8d83cba6d45a9314bc2ef4538d4e0577c6bed8593536'
const result = await uut.getBlock(req, res)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, 'hash', 'hash property expected')
assert.property(
result,
'confirmations',
'confirmations property expected'
)
assert.property(result, 'size', 'size property expected')
assert.property(result, 'height', 'height property expected')
assert.property(result, 'version', 'version property expected')
assert.property(result, 'versionHex', 'versionHex property expected')
assert.property(result, 'merkleroot', 'merkleroot property expected')
assert.property(result, 'tx', 'tx property expected')
assert.property(result, 'time', 'time property expected')
assert.property(result, 'mediantime', 'mediantime property expected')
assert.property(result, 'nonce', 'nonce property expected')
assert.property(result, 'bits', 'bits property expected')
assert.property(result, 'difficulty', 'difficulty property expected')
assert.property(result, 'chainwork', 'chainwork property expected')
assert.property(result, 'nTx', 'nTx property expected')
assert.property(
result,
'previousblockhash',
'previousblockhash property expected'
)
assert.property(
result,
'nextblockhash',
'nextblockhash property expected'
)
})
})
})
+82 -2
View File
@@ -285,7 +285,86 @@ const mockAncestors = [
'e68dad4a7292105cfa84fcaef7f99e5d4f2ece9613ca625d4d2ebf61efa84118',
'fe94caf5da672be3772d2304a6272eb8bc3d3f5cb4a886f39b7981e1485cf74b'
]
const mockBlockInfo = {
verbosity0: '20000000',
verbosity1: {
hash: '00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09',
confirmations: 1,
size: 3725,
strippedsize: 3725,
weight: 3725,
height: 6725,
version: 1,
versionHex: '00000000',
merkleroot: 'xxxx',
tx: [
'2afb8264508e2bf3e5288ccad01ed2ab766745b6b9747666b519d59212012c01',
'18f40b1ae56bba3fa1934b737fbe46ed8d5ca40fa9aed95073eeb5a119530cd3',
'349720d878547752607a69eb19e330592fee271fb5376cdfd811bee423558ed8',
'35571c80e7d0e9247b467454ef147d1d5833c775bc2d4164b1bebd4c1f69164f',
'480937e8efacdafeeb97d401ff0dd9ea8e8ddb27244cefa67a03621315bdb0e6',
'523327469d0b90c0de9a905c2fe6e227278fc5b55b9d9911ca151e1c26647065',
'61de4af971d94dbc741762f21dcef08b74b62863a56a1cb3496becdd8d47a858',
'69f70a288403b5bba23030ccd05d2e5cb00394620fdae3b050cff9432cc590ce',
'94472a90fbdba2eb2cba68308415181faedf3585c66b89efcbdb927a0c10ba23',
'bc6f781f9e2f2df460f89995c5e1c7224e48ccbe1aa2a575961f3f5330259864',
'f2d945a79bec5454a9ab4d570a150d81124daa308f1c81106a977d6413476944'
],
time: 111,
mediantime: 111,
nonce: 111,
bits: '1d00ffff',
difficulty: 99.999,
chainwork: 'xxxx',
nTx: 1,
previousblockhash:
'00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09',
nextblockhash:
'00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09'
},
verbosity2: {
hash: '00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09',
confirmations: 1,
size: 3725,
strippedsize: 3725,
weight: 3725,
height: 6725,
version: 1,
versionHex: '00000000',
merkleroot: 'xxxx',
tx: [
{
hex:
'01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000',
txid:
'0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098',
hash:
'0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098',
size: 134,
version: 1,
locktime: 0,
vin: [],
vout: [],
blockhash:
'00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048',
confirmations: 581882,
time: 1231469665,
blocktime: 1231469665
}
],
time: 111,
mediantime: 111,
nonce: 111,
bits: '1d00ffff',
difficulty: 99.999,
chainwork: 'xxxx',
nTx: 1,
previousblockhash:
'00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09',
nextblockhash:
'00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09'
}
}
module.exports = {
mockBlockHash,
mockBlockchainInfo,
@@ -296,5 +375,6 @@ module.exports = {
mockBlockHeader,
mockTxOut,
mockTxOutProof,
mockAncestors
mockAncestors,
mockBlockInfo
}
+8 -7
View File
@@ -129,7 +129,7 @@ describe('#rate-routelimit', () => {
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVlODhhY2JmMDIyMWMxMDAxMmFkOTNmZiIsImVtYWlsIjoiY2hyaXMudHJvdXRuZXJAZ21haWwuY29tIiwiYXBpTGV2ZWwiOjQwLCJyYXRlTGltaXQiOjMsImlhdCI6MTYxNTE1NzA4NywiZXhwIjoxNjE3NzQ5MDg3fQ.RLNGuYAa-CcLdhTGD27tDeaxT6-GIdeR8T4JWZZLDZA'
const result = uut.decodeJwtToken(jwt)
console.log('result: ', result)
// console.log('result: ', result)
assert.property(result, 'id')
// assert.equal(result.id, '123.456.789.10')
@@ -137,7 +137,7 @@ describe('#rate-routelimit', () => {
// assert.equal(result.email, 'test@bchtest.net')
// assert.property(result, 'pointsToConsume')
// assert.equal(result.pointsToConsume, config.anonRateLimit)
assert.property(result, 'duration')
// assert.property(result, 'duration')
// assert.equal(result.duration, 30)
assert.property(result, 'exp')
})
@@ -309,10 +309,10 @@ describe('#rate-routelimit', () => {
let val
for (let i = 0; i < 25; i++) {
console.log('req.locals: ', req.locals)
// console.log('req.locals: ', req.locals)
val = await uut.applyRateLimits(req, res, next)
}
console.log('val: ', val)
// console.log('val: ', val)
assert.property(val, 'error')
assert.include(
@@ -446,7 +446,7 @@ describe('#rate-routelimit', () => {
// Generate a new JWT token for the test.
const jwtPayload = {
id: '5dade3f5739e6c0ff034b9a1',
pointsToConsume: 10
pointsToConsume: 100
}
const jwtToken = uut.generateJwtToken(jwtPayload)
@@ -460,7 +460,7 @@ describe('#rate-routelimit', () => {
for (let i = 0; i < 120; i++) {
val = await uut.applyRateLimits(req, res, next)
}
console.log('val: ', val)
// console.log('val: ', val)
assert.property(val, 'error')
assert.include(
@@ -470,11 +470,12 @@ describe('#rate-routelimit', () => {
assert.equal(
res.locals.pointsToConsume,
10,
100,
'User JWT rate limits applied'
)
} catch (err) {
console.log('err: ', err)
assert.fail('Unexpected result')
}
})