enforce limit at POST /txs requests
This commit is contained in:
parent
1615925ae5
commit
71e3c1ba9c
@ -9,6 +9,9 @@ var Address = require('../models/Address');
|
|||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
|
||||||
|
var MAX_BATCH_SIZE = 100;
|
||||||
|
var RPC_CONCURRENCY = 5;
|
||||||
|
|
||||||
var tDb = require('../../lib/TransactionDb').default();
|
var tDb = require('../../lib/TransactionDb').default();
|
||||||
|
|
||||||
var checkSync = function(req, res) {
|
var checkSync = function(req, res) {
|
||||||
@ -50,7 +53,7 @@ var getAddrs = function(req, res, next) {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
common.handleErrors({
|
common.handleErrors({
|
||||||
message: 'Invalid address:' + e.message,
|
message: 'Invalid addrs param:' + e.message,
|
||||||
code: 1
|
code: 1
|
||||||
}, res, next);
|
}, res, next);
|
||||||
return null;
|
return null;
|
||||||
@ -101,7 +104,7 @@ exports.multiutxo = function(req, res, next) {
|
|||||||
var as = getAddrs(req, res, next);
|
var as = getAddrs(req, res, next);
|
||||||
if (as) {
|
if (as) {
|
||||||
var utxos = [];
|
var utxos = [];
|
||||||
async.each(as, function(a, callback) {
|
async.eachLimit(as, RPC_CONCURRENCY, function(a, callback) {
|
||||||
a.update(function(err) {
|
a.update(function(err) {
|
||||||
if (err) callback(err);
|
if (err) callback(err);
|
||||||
utxos = utxos.concat(a.unspent);
|
utxos = utxos.concat(a.unspent);
|
||||||
@ -123,23 +126,31 @@ exports.multitxs = function(req, res, next) {
|
|||||||
function processTxs(txs, from, to, cb) {
|
function processTxs(txs, from, to, cb) {
|
||||||
txs = _.uniq(_.flatten(txs), 'txid');
|
txs = _.uniq(_.flatten(txs), 'txid');
|
||||||
var nbTxs = txs.length;
|
var nbTxs = txs.length;
|
||||||
var paginated = !_.isUndefined(from) || !_.isUndefined(to);
|
|
||||||
|
|
||||||
if (paginated) {
|
if ( _.isUndefined(from) && _.isUndefined(to)) {
|
||||||
txs.sort(function(a, b) {
|
from = 0;
|
||||||
return (b.ts || b.ts) - (a.ts || a.ts);
|
to = MAX_BATCH_SIZE;
|
||||||
});
|
|
||||||
var start = Math.max(from || 0, 0);
|
|
||||||
var end = Math.min(to || txs.length, txs.length);
|
|
||||||
txs = txs.slice(start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! _.isUndefined(from) && _.isUndefined(to))
|
||||||
|
to = from + MAX_BATCH_SIZE;
|
||||||
|
|
||||||
|
if ( ! _.isUndefined(from) && ! _.isUndefined(to) && to - from > MAX_BATCH_SIZE)
|
||||||
|
to = from + MAX_BATCH_SIZE;
|
||||||
|
|
||||||
|
txs.sort(function(a, b) {
|
||||||
|
return (b.ts || b.ts) - (a.ts || a.ts);
|
||||||
|
});
|
||||||
|
var start = Math.max(from || 0, 0);
|
||||||
|
var end = Math.min(to || nbTxs, nbTxs);
|
||||||
|
txs = txs.slice(start, end);
|
||||||
|
|
||||||
var txIndex = {};
|
var txIndex = {};
|
||||||
_.each(txs, function(tx) {
|
_.each(txs, function(tx) {
|
||||||
txIndex[tx.txid] = tx;
|
txIndex[tx.txid] = tx;
|
||||||
});
|
});
|
||||||
|
|
||||||
async.eachLimit(txs, 5, function(tx, callback) {
|
async.eachLimit(txs, RPC_CONCURRENCY, function(tx, callback) {
|
||||||
tDb.fromIdWithInfo(tx.txid, function(err, tx) {
|
tDb.fromIdWithInfo(tx.txid, function(err, tx) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@ -154,14 +165,12 @@ exports.multitxs = function(req, res, next) {
|
|||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var transactions = _.pluck(txs, 'info');
|
var transactions = _.pluck(txs, 'info');
|
||||||
if (paginated) {
|
transactions = {
|
||||||
transactions = {
|
totalItems: nbTxs,
|
||||||
totalItems: nbTxs,
|
from: +from,
|
||||||
from: +from,
|
to: +to,
|
||||||
to: +to,
|
items: transactions,
|
||||||
items: transactions,
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
return cb(null, transactions);
|
return cb(null, transactions);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -172,17 +181,19 @@ exports.multitxs = function(req, res, next) {
|
|||||||
var as = getAddrs(req, res, next);
|
var as = getAddrs(req, res, next);
|
||||||
if (as) {
|
if (as) {
|
||||||
var txs = [];
|
var txs = [];
|
||||||
async.eachLimit(as, 10, function(a, callback) {
|
async.eachLimit(as, RPC_CONCURRENCY, function(a, callback) {
|
||||||
a.update(function(err) {
|
a.update(function(err) {
|
||||||
if (err) callback(err);
|
if (err) callback(err);
|
||||||
txs.push(a.transactions);
|
txs.push(a.transactions);
|
||||||
callback();
|
callback();
|
||||||
}, {
|
}, {
|
||||||
ignoreCache: req.param('noCache'),
|
ignoreCache: req.param('noCache'),
|
||||||
includeTxInfo: true
|
includeTxInfo: true,
|
||||||
|
dontFillSpent: true,
|
||||||
});
|
});
|
||||||
}, function(err) { // finished callback
|
}, function(err) { // finished callback
|
||||||
if (err) return common.handleErrors(err, res);
|
if (err) return common.handleErrors(err, res);
|
||||||
|
|
||||||
processTxs(txs, from, to, function(err, transactions) {
|
processTxs(txs, from, to, function(err, transactions) {
|
||||||
if (err) return common.handleErrors(err, res);
|
if (err) return common.handleErrors(err, res);
|
||||||
res.jsonp(transactions);
|
res.jsonp(transactions);
|
||||||
|
|||||||
@ -17,7 +17,7 @@ var ADDR_PREFIX = 'txa2-'; //txa-<addr>-<tsr>-<txid>-<n>
|
|||||||
|
|
||||||
// TODO: use bitcore networks module
|
// TODO: use bitcore networks module
|
||||||
var genesisTXID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
var genesisTXID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
||||||
var CONCURRENCY = 10;
|
var CONCURRENCY = 5;
|
||||||
var DEFAULT_SAFE_CONFIRMATIONS = 6;
|
var DEFAULT_SAFE_CONFIRMATIONS = 6;
|
||||||
|
|
||||||
var MAX_OPEN_FILES = 500;
|
var MAX_OPEN_FILES = 500;
|
||||||
@ -448,6 +448,9 @@ TransactionDb.prototype._parseAddrData = function(k, data, ignoreCache) {
|
|||||||
return item;
|
return item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// opts.dontFillSpent
|
||||||
|
|
||||||
TransactionDb.prototype.fromAddr = function(addr, opts, cb) {
|
TransactionDb.prototype.fromAddr = function(addr, opts, cb) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -470,6 +473,10 @@ TransactionDb.prototype.fromAddr = function(addr, opts, cb) {
|
|||||||
})
|
})
|
||||||
.on('error', cb)
|
.on('error', cb)
|
||||||
.on('end', function() {
|
.on('end', function() {
|
||||||
|
if (opts.dontFillSpent) {
|
||||||
|
return cb(null, ret)
|
||||||
|
}
|
||||||
|
|
||||||
async.eachLimit(ret.filter(function(x) {
|
async.eachLimit(ret.filter(function(x) {
|
||||||
return !x.spentIsConfirmed;
|
return !x.spentIsConfirmed;
|
||||||
}), CONCURRENCY, function(o, e_c) {
|
}), CONCURRENCY, function(o, e_c) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user