mempool: keep everything on the js heap.

This commit is contained in:
Christopher Jeffrey 2016-08-15 17:27:11 -07:00
parent c8bc9fb8b6
commit b0caa3f03a
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 35 additions and 85 deletions

View File

@ -87,7 +87,6 @@ function Mempool(options) {
this.total = 0; this.total = 0;
this.tx = {}; this.tx = {};
this.spents = {}; this.spents = {};
this.coins = {};
this.time = new RBT(timeCmp); this.time = new RBT(timeCmp);
this.coinIndex = new AddressIndex(this); this.coinIndex = new AddressIndex(this);
this.txIndex = new AddressIndex(this); this.txIndex = new AddressIndex(this);
@ -325,22 +324,11 @@ Mempool.prototype.limitOrphans = function limitOrphans() {
* @param {Function} callback - Returns [Error, {@link TX}]. * @param {Function} callback - Returns [Error, {@link TX}].
*/ */
Mempool.prototype.getTX = function getTX(hash, callback) { Mempool.prototype.getTX = function getTX(hash) {
var data = this.tx[hash]; var entry = this.tx[hash];
var tx; if (!entry)
if (!data)
return; return;
return entry.tx;
try {
tx = bcoin.tx.fromRaw(data);
} catch (e) {
delete this.tx[hash];
this.logger.warning('Possible memory corruption.');
return;
}
return tx;
}; };
/** /**
@ -350,22 +338,8 @@ Mempool.prototype.getTX = function getTX(hash, callback) {
* @param {Function} callback - Returns [Error, {@link TX}]. * @param {Function} callback - Returns [Error, {@link TX}].
*/ */
Mempool.prototype.getEntry = function getEntry(hash, callback) { Mempool.prototype.getEntry = function getEntry(hash) {
var data = this.tx[hash]; return this.tx[hash];
var tx;
if (!data)
return;
try {
tx = MempoolEntry.fromRaw(data);
} catch (e) {
delete this.tx[hash];
this.logger.warning('Possible memory corruption.');
return;
}
return tx;
}; };
/** /**
@ -375,25 +349,19 @@ Mempool.prototype.getEntry = function getEntry(hash, callback) {
* @param {Function} callback - Returns [Error, {@link Coin}]. * @param {Function} callback - Returns [Error, {@link Coin}].
*/ */
Mempool.prototype.getCoin = function getCoin(hash, index, callback) { Mempool.prototype.getCoin = function getCoin(hash, index) {
var key = hash + index; var entry = this.tx[hash];
var data = this.coins[key];
var coin;
if (!data) if (!entry)
return; return;
try { if (this.isSpent(hash, index))
coin = bcoin.coin.fromRaw(data);
coin.hash = hash;
coin.index = index;
} catch (e) {
delete this.coins[key];
this.logger.warning('Possible memory corruption.');
return; return;
}
return coin; if (index >= entry.tx.outputs.length)
return;
return bcoin.coin.fromTX(entry.tx, index);
}; };
/** /**
@ -406,23 +374,9 @@ Mempool.prototype.getCoin = function getCoin(hash, index, callback) {
* @param {Function} callback - Returns [Error, Boolean]. * @param {Function} callback - Returns [Error, Boolean].
*/ */
Mempool.prototype.isSpent = function isSpent(hash, index, callback) { Mempool.prototype.isSpent = function isSpent(hash, index) {
var key = hash + index; var key = hash + index;
var data = this.spents[key]; return this.spents[key];
var spender;
if (!data)
return;
try {
spender = bcoin.outpoint.fromRaw(data);
} catch (e) {
delete this.spents[key];
this.logger.warning('Possible memory corruption.');
return;
}
return spender;
}; };
/** /**
@ -545,7 +499,7 @@ Mempool.prototype.fillCoins = function fillCoins(tx) {
* @param {Function} callback - Returns [Error, Boolean]. * @param {Function} callback - Returns [Error, Boolean].
*/ */
Mempool.prototype.hasTX = function hasTX(hash, callback) { Mempool.prototype.hasTX = function hasTX(hash) {
return this.tx[hash] != null; return this.tx[hash] != null;
}; };
@ -555,7 +509,7 @@ Mempool.prototype.hasTX = function hasTX(hash, callback) {
* @param {Function} callback - Returns [Error, {@link TX}[]]. * @param {Function} callback - Returns [Error, {@link TX}[]].
*/ */
Mempool.prototype.getRange = function getRange(start, end, callback) { Mempool.prototype.getRange = function getRange(start, end) {
var items = this.time.range(start, end); var items = this.time.range(start, end);
var entries = []; var entries = [];
var i, item, hash, entry; var i, item, hash, entry;
@ -1107,15 +1061,20 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx) {
* (not very useful in practice, only used for testing). * (not very useful in practice, only used for testing).
*/ */
Mempool.prototype.getBalance = function getBalance(callback) { Mempool.prototype.getBalance = function getBalance() {
var keys = Object.keys(this.coins); var keys = Object.keys(this.tx);
var total = 0; var total = 0;
var i, key, data; var i, j, key, tx, hash, coin;
for (i = 0; i < keys.length; i++) { for (i = 0; i < keys.length; i++) {
key = keys[i]; key = keys[i];
data = this.coins[key]; tx = this.tx[key].tx;
total += utils.read64N(data, 8); hash = tx.hash('hex');
for (j = 0; j < tx.outputs.length; j++) {
coin = this.getCoin(hash, j);
if (coin)
total += coin.value;
}
} }
return total; return total;
@ -1126,7 +1085,7 @@ Mempool.prototype.getBalance = function getBalance(callback) {
* @param {Function} callback - Returns [Error, {@link TX}[]]. * @param {Function} callback - Returns [Error, {@link TX}[]].
*/ */
Mempool.prototype.getHistory = function getHistory(callback) { Mempool.prototype.getHistory = function getHistory() {
var keys = Object.keys(this.tx); var keys = Object.keys(this.tx);
var txs = []; var txs = [];
var i, key, tx; var i, key, tx;
@ -1431,7 +1390,7 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) {
var hash = tx.hash('hex'); var hash = tx.hash('hex');
var i, input, output, key, coin, spender; var i, input, output, key, coin, spender;
this.tx[hash] = entry.toRaw(); this.tx[hash] = entry;
this.time.insert(entry.ts, hash); this.time.insert(entry.ts, hash);
if (this.options.indexAddress) if (this.options.indexAddress)
@ -1449,10 +1408,7 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) {
if (this.options.indexAddress) if (this.options.indexAddress)
this.coinIndex.removeCoin(input.coin); this.coinIndex.removeCoin(input.coin);
spender = bcoin.outpoint.fromTX(tx, i).toRaw(); this.spents[key] = bcoin.outpoint.fromTX(tx, i);
delete this.coins[key];
this.spents[key] = spender;
} }
for (i = 0; i < tx.outputs.length; i++) { for (i = 0; i < tx.outputs.length; i++) {
@ -1462,12 +1418,10 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry) {
if (output.script.isUnspendable()) if (output.script.isUnspendable())
continue; continue;
coin = bcoin.coin.fromTX(tx, i); if (this.options.indexAddress) {
coin = bcoin.coin.fromTX(tx, i);
if (this.options.indexAddress)
this.coinIndex.addCoin(coin); this.coinIndex.addCoin(coin);
}
this.coins[key] = coin.toRaw();
} }
}; };
@ -1534,8 +1488,6 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(entry, limit, cal
if (self.options.indexAddress) if (self.options.indexAddress)
self.coinIndex.removeCoin(input.coin); self.coinIndex.removeCoin(input.coin);
self.coins[key] = input.coin.toRaw();
} }
for (i = 0; i < tx.outputs.length; i++) { for (i = 0; i < tx.outputs.length; i++) {
@ -1549,8 +1501,6 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(entry, limit, cal
coin = bcoin.coin.fromTX(tx, i); coin = bcoin.coin.fromTX(tx, i);
self.coinIndex.removeCoin(coin); self.coinIndex.removeCoin(coin);
} }
delete self.coins[key];
} }
return callback(); return callback();

View File

@ -1539,7 +1539,7 @@ Pool.prototype.has = function has(type, hash, force, callback) {
} else { } else {
// If we recently rejected this item. Ignore. // If we recently rejected this item. Ignore.
if (self.rejects.test(hash, 'hex')) { if (self.rejects.test(hash, 'hex')) {
self.logger.debug('Peer sent a known reject: %s.', utils.revHex(hash)); self.logger.spam('Peer sent a known reject: %s.', utils.revHex(hash));
return callback(null, true); return callback(null, true);
} }
} }