From 154229d5f5109de66459bc3f35760c926491b60e Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Mon, 8 Mar 2021 17:51:04 -0800 Subject: [PATCH] fix(hydrateUtxosWL): Adding usrObj for rate limit control --- src/middleware/route-ratelimit2.js | 8 ++++++ src/routes/v4/slp.js | 41 +++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/middleware/route-ratelimit2.js b/src/middleware/route-ratelimit2.js index aed2bb7..20c37be 100644 --- a/src/middleware/route-ratelimit2.js +++ b/src/middleware/route-ratelimit2.js @@ -141,6 +141,14 @@ class RateLimits { } } } else { + // This should be a corner case. Calls should not be going into this + // code path, so the system should throw up big warning signs when they + // do. + // This code path happens when an internal call is made but does not + // pass the usrObj. Legacy code needs to be refactored to use the usrObj + // 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. console.log( 'Internal call. req.body.usrObj does not exist. Applying high-speed internal rate limits.' ) diff --git a/src/routes/v4/slp.js b/src/routes/v4/slp.js index b7bc984..6beec5c 100644 --- a/src/routes/v4/slp.js +++ b/src/routes/v4/slp.js @@ -36,9 +36,13 @@ util.inspect.defaultOptions = { depth: 5 } // Determine the Access password for a private instance of SLPDB. // https://gist.github.com/christroutner/fc717ca704dec3dded8b52fae387eab2 // Password for General Purpose (GP) SLPDB. -const SLPDB_PASS_GP = process.env.SLPDB_PASS_GP ? process.env.SLPDB_PASS_GP : 'BITBOX' +const SLPDB_PASS_GP = process.env.SLPDB_PASS_GP + ? process.env.SLPDB_PASS_GP + : 'BITBOX' // Password for Whitelist (WL) SLPDB. -const SLPDB_PASS_WL = process.env.SLPDB_PASS_WL ? process.env.SLPDB_PASS_WL : 'BITBOX' +const SLPDB_PASS_WL = process.env.SLPDB_PASS_WL + ? process.env.SLPDB_PASS_WL + : 'BITBOX' // const rawtransactions = require('./full-node/rawtransactions') const RawTransactions = require('./full-node/rawtransactions') @@ -46,7 +50,7 @@ const rawTransactions = new RawTransactions() // Setup REST and TREST URLs used by slpjs // Dev note: this allows for unit tests to mock the URL. -if (!process.env.REST_URL) process.env.REST_URL = 'https://bchn.fullstack.cash/v4/' +if (!process.env.REST_URL) { process.env.REST_URL = 'https://bchn.fullstack.cash/v4/' } if (!process.env.TREST_URL) { process.env.TREST_URL = 'https://testnet.fullstack.cash/v4/' } @@ -1982,7 +1986,9 @@ class Slp { // Extract a delay value if the user passed it in. const usrObjIn = req.body.usrObj let utxoDelay = 0 - if (usrObjIn && usrObjIn.utxoDelay) { utxoDelay = usrObjIn.utxoDelay } + if (usrObjIn && usrObjIn.utxoDelay) { + utxoDelay = usrObjIn.utxoDelay + } // console.log('req: ', req) // console.log(`req._remoteAddress: ${req._remoteAddress}`) @@ -2031,7 +2037,10 @@ class Slp { const theseUtxos = utxos[i].utxos // Get SLP token details. - const details = await _this.bchjs.SLP.Utils.tokenUtxoDetails(theseUtxos, usrObj) + const details = await _this.bchjs.SLP.Utils.tokenUtxoDetails( + theseUtxos, + usrObj + ) // console.log('details: ', details) // Replace the original UTXO data with the hydrated data. @@ -2082,6 +2091,23 @@ class Slp { try { const utxos = req.body.utxos + // Extract a delay value if the user passed it in. + const usrObjIn = req.body.usrObj + let utxoDelay = 0 + if (usrObjIn && usrObjIn.utxoDelay) { + utxoDelay = usrObjIn.utxoDelay + } + + // Generate a user object that can be passed along with internal calls + // from bch-js. + const usrObj = { + ip: req._remoteAddress, + jwtToken: req.locals.jwtToken, + proLimit: req.locals.proLimit, + apiLevel: req.locals.apiLevel, + utxoDelay + } + // Validate inputs if (!Array.isArray(utxos)) { res.status(422) @@ -2117,7 +2143,10 @@ class Slp { // console.log(`theseUtxos: ${JSON.stringify(theseUtxos, null, 2)}`) // Get SLP token details. - const details = await _this.bchjs.SLP.Utils.tokenUtxoDetailsWL(theseUtxos) + const details = await _this.bchjs.SLP.Utils.tokenUtxoDetailsWL( + theseUtxos, + usrObj + ) // console.log('details : ', details) // Replace the original UTXO data with the hydrated data.