diff --git a/lib/mempool/fees.js b/lib/mempool/fees.js index 29c3230c..18f7db1a 100644 --- a/lib/mempool/fees.js +++ b/lib/mempool/fees.js @@ -43,22 +43,47 @@ var FREE_THRESHOLD = constants.tx.FREE_THRESHOLD; * Confirmation stats. * @exports ConfirmStats * @constructor - * @param {Number} buckets - * @param {Number} maxConfirms - * @param {Number} decay * @param {String} type + * @param {Logger} logger */ -function ConfirmStats(buckets, maxConfirms, decay, type, logger) { - var i; - +function ConfirmStats(type, logger) { if (!(this instanceof ConfirmStats)) - return new ConfirmStats(buckets, maxConfirms, decay, type, logger); + return new ConfirmStats(type, logger); this.logger = logger || Logger.global; + + this.type = type; + this.decay = 0; + this.maxConfirms = 0; + + this.buckets = new Float64Array(0); + this.bucketMap = new DoubleMap(); + + this.confAvg = []; + this.curBlockConf = []; + this.unconfTX = []; + + this.oldUnconfTX = new Int32Array(0); + this.curBlockTX = new Int32Array(0); + this.txAvg = new Float64Array(0); + this.curBlockVal = new Float64Array(0); + this.avg = new Float64Array(0); +} + +/** + * Initialize stats. + * @param {Array} buckets + * @param {Number} maxConfirms + * @param {Number} decay + * @private + */ + +ConfirmStats.prototype.init = function init(buckets, maxConfirms, decay) { + var i; + this.maxConfirms = maxConfirms; this.decay = decay; - this.type = type; this.buckets = new Float64Array(buckets.length); this.bucketMap = new DoubleMap(); @@ -83,7 +108,7 @@ function ConfirmStats(buckets, maxConfirms, decay, type, logger) { this.txAvg = new Float64Array(buckets.length); this.curBlockVal = new Float64Array(buckets.length); this.avg = new Float64Array(buckets.length); -} +}; /** * Clear data for the current block. @@ -374,7 +399,9 @@ ConfirmStats.fromRaw = function fromRaw(data, type, logger) { throw new Error('Mismatch in fee/pri conf average bucket count.'); } - stats = new ConfirmStats(buckets, maxConfirms, decay, type, logger); + stats = new ConfirmStats(type, logger); + + stats.init(buckets, maxConfirms, decay); stats.avg = avg; stats.txAvg = txAvg; @@ -392,14 +419,9 @@ ConfirmStats.fromRaw = function fromRaw(data, type, logger) { */ function PolicyEstimator(minRelay, network, logger) { - var fee, priority, boundary; - if (!(this instanceof PolicyEstimator)) return new PolicyEstimator(minRelay, network, logger); - fee = []; - priority = []; - this.network = Network.get(network); this.logger = logger || Logger.global; @@ -411,6 +433,31 @@ function PolicyEstimator(minRelay, network, logger) { ? MIN_PRIORITY : FREE_THRESHOLD; + this.feeStats = new ConfirmStats('FeeRate', this.logger); + this.priStats = new ConfirmStats('Priority', this.logger); + + this.feeUnlikely = 0; + this.feeLikely = INF_FEERATE; + this.priUnlikely = 0; + this.priLikely = INF_PRIORITY; + + this.map = {}; + this.mapSize = 0; + this.bestHeight = 0; + + this.init(); +} + +/** + * Initialize the estimator. + * @private + */ + +PolicyEstimator.prototype.init = function init() { + var fee = []; + var priority = []; + var boundary; + for (boundary = this.minTrackedFee; boundary <= MAX_FEERATE; boundary *= FEE_SPACING) { @@ -427,24 +474,26 @@ function PolicyEstimator(minRelay, network, logger) { priority.push(INF_PRIORITY); - this.feeStats = new ConfirmStats( - fee, MAX_BLOCK_CONFIRMS, - DEFAULT_DECAY, 'FeeRate', - this.logger); + this.feeStats.init(fee, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY); + this.priStats.init(priority, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY); +}; - this.priStats = new ConfirmStats( - priority, MAX_BLOCK_CONFIRMS, - DEFAULT_DECAY, 'Priority', - this.logger); +/** + * Reset the estimator. + */ +PolicyEstimator.prototype.reset = function reset() { this.feeUnlikely = 0; this.feeLikely = INF_FEERATE; this.priUnlikely = 0; this.priLikely = INF_PRIORITY; + this.map = {}; this.mapSize = 0; this.bestHeight = 0; -} + + this.init(); +}; /** * Stop tracking a tx. Remove from map. diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index a359d566..83f82a6d 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -240,6 +240,46 @@ Mempool.prototype._removeBlock = function removeBlock(block) { this.rejects.reset(); }; +/** + * Reset the mempool. + * @returns {Promise} + */ + +Mempool.prototype.reset = co(function* reset() { + var unlock = yield this.locker.lock(); + try { + return this._reset(); + } finally { + unlock(); + } +}); + +/** + * Reset the mempool without a lock. + * @private + */ + +Mempool.prototype._reset = function reset() { + this.size = 0; + this.totalOrphans = 0; + this.totalTX = 0; + + this.waiting = {}; + this.orphans = {}; + this.tx = {}; + this.spents = {}; + this.coinIndex.reset(); + this.txIndex.reset(); + + this.freeCount = 0; + this.lastTime = 0; + + if (this.fees) + this.fees.reset(); + + this.rejects.reset(); +}; + /** * Ensure the size of the mempool stays below 300mb. * @param {Hash} entryHash - TX that initiated the trim. @@ -1810,6 +1850,11 @@ function AddressIndex(mempool) { this.map = {}; } +AddressIndex.prototype.reset = function reset() { + this.index = {}; + this.map = {}; +}; + AddressIndex.prototype.getTX = function getTX(address) { var items = this.index[address]; var out = []; diff --git a/lib/node/fullnode.js b/lib/node/fullnode.js index 4af1ba92..f662c28f 100644 --- a/lib/node/fullnode.js +++ b/lib/node/fullnode.js @@ -218,6 +218,8 @@ FullNode.prototype._init = function _init() { this.chain.on('reset', function(tip) { self.emit('reset', tip); + + self.mempool.reset().catch(onError); }); this.miner.on('block', function(block) {