switch back to leveldown mempool.
This commit is contained in:
parent
eda31da3ea
commit
a58b566c69
@ -113,7 +113,7 @@ bcoin.fullnode = require('./bcoin/fullnode');
|
||||
bcoin.chainblock = require('./bcoin/chainblock');
|
||||
bcoin.chaindb = require('./bcoin/chaindb');
|
||||
bcoin.chain = require('./bcoin/chain');
|
||||
bcoin.mempool = require('./bcoin/mempool');
|
||||
bcoin.mempool = require('./bcoin/mempool2');
|
||||
bcoin.keypair = require('./bcoin/keypair');
|
||||
bcoin.address = require('./bcoin/address');
|
||||
bcoin.walletdb = require('./bcoin/walletdb');
|
||||
|
||||
@ -330,7 +330,16 @@ BST.prototype.rangeCompare = function rangeCompare(key, gteKey, lteKey) {
|
||||
*/
|
||||
|
||||
BST.prototype.open = function open(options, callback) {
|
||||
if (!callback) {
|
||||
callback = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
this.options = options;
|
||||
|
||||
return utils.nextTick(callback);
|
||||
};
|
||||
|
||||
@ -434,7 +443,7 @@ BST.destroy = function destroy(location, callback) {
|
||||
};
|
||||
|
||||
BST.repair = function repair(location, callback) {
|
||||
return utils.asyncify(callback)(new Error('Cannot repair.'));
|
||||
return utils.nextTick(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -54,9 +54,6 @@ function getLocation(name) {
|
||||
}
|
||||
|
||||
function getBackend(backend) {
|
||||
if (backend === 'bst')
|
||||
return require('./bst');
|
||||
|
||||
if (bcoin.isBrowser)
|
||||
return require('level-js');
|
||||
|
||||
@ -70,10 +67,12 @@ function getBackend(backend) {
|
||||
else if (backend === 'lmdb')
|
||||
backend = 'lmdb';
|
||||
else if (backend === 'memory')
|
||||
backend = 'memdown';
|
||||
backend = 'bst';
|
||||
|
||||
if (backend !== 'memdown')
|
||||
bcoin.ensurePrefix();
|
||||
if (backend === 'bst')
|
||||
return require('./bst');
|
||||
|
||||
bcoin.ensurePrefix();
|
||||
|
||||
return require(backend);
|
||||
}
|
||||
|
||||
@ -138,223 +138,33 @@ Mempool.prototype.removeBlock = function removeBlock(block, callback, force) {
|
||||
|
||||
Mempool.prototype.limitMempoolSize = function limitMempoolSize(callback) {
|
||||
var self = this;
|
||||
var txs;
|
||||
|
||||
if (this.totalSize <= Mempool.MAX_MEMPOOL_SIZE)
|
||||
return utils.asyncify(callback)(null, true);
|
||||
if (this.size <= Mempool.MAX_MEMPOOL_SIZE)
|
||||
return callback(null, true);
|
||||
|
||||
try {
|
||||
txs = this.getRangeSync({
|
||||
start: 0,
|
||||
end: utils.now() - Mempool.MEMPOOL_EXPIRY
|
||||
});
|
||||
} catch (e) {
|
||||
return utils.asyncify(callback)(e);
|
||||
}
|
||||
|
||||
utils.forEachSerial(function(tx, next) {
|
||||
self.removeUnchecked(tx, next);
|
||||
}, function(err) {
|
||||
this.db.getRange({
|
||||
start: 0,
|
||||
end: utils.now() - Mempool.MEMPOOL_EXPIRY
|
||||
}, function(err, txs) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
try {
|
||||
self.purgeOrphansSync();
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
utils.forEachSerial(function(tx, next) {
|
||||
self.removeUnchecked(tx, next);
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
return callback(null, self.totalSize <= Mempool.MAX_MEMPOOL_SIZE);
|
||||
self.purgeOrphans(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
return callback(null, self.size <= Mempool.MAX_MEMPOOL_SIZE);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Mempool.prototype.getRangeSync = function getRangeSync(options) {
|
||||
var hashes = this.psIndex.range(options.start, options.end);
|
||||
var txs = [];
|
||||
var i, tx;
|
||||
|
||||
for (i = 0; i < hashes.length; i++) {
|
||||
tx = this.getTXSync(hashes[i]);
|
||||
if (tx)
|
||||
txs.push(tx);
|
||||
}
|
||||
|
||||
return txs;
|
||||
};
|
||||
|
||||
Mempool.prototype.purgeOrphansSync = function purgeOrphansSync() {
|
||||
var keys = Object.keys(this.orphans);
|
||||
var key, i;
|
||||
|
||||
this.waiting = {};
|
||||
this.totalOrphans = 0;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
this.totalSize -= this.orphans[key].length;
|
||||
delete this.orphans[key];
|
||||
}
|
||||
};
|
||||
|
||||
Mempool.prototype.getSync =
|
||||
Mempool.prototype.getTXSync = function getTXSync(hash) {
|
||||
var tx;
|
||||
|
||||
if (hash instanceof bcoin.tx)
|
||||
hash = hash.hash('hex');
|
||||
|
||||
tx = this.txs[hash];
|
||||
|
||||
if (!tx)
|
||||
return;
|
||||
|
||||
return bcoin.tx.fromExtended(tx);
|
||||
};
|
||||
|
||||
Mempool.prototype.getCoinSync = function getCoinSync(hash, index) {
|
||||
var key = hash + '/' + index;
|
||||
var coin;
|
||||
|
||||
coin = this.coins[key];
|
||||
|
||||
if (!coin)
|
||||
return;
|
||||
|
||||
coin = bcoin.coin.fromRaw(coin);
|
||||
coin.hash = hash;
|
||||
coin.index = index;
|
||||
|
||||
return coin;
|
||||
};
|
||||
|
||||
Mempool.prototype.isSpentSync = function isSpentSync(hash, index) {
|
||||
var key = hash + '/' + index;
|
||||
|
||||
return this.spent[key] != null;
|
||||
};
|
||||
|
||||
Mempool.prototype.isDoubleSpendSync = function isDoubleSpendSync(tx) {
|
||||
var i, input;
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
if (this.isSpentSync(input.prevout.hash, input.prevout.index))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Mempool.prototype.getCoinsByAddressSync = function getCoinsByAddressSync(addresses) {
|
||||
var coins = [];
|
||||
var i, j, address, keys, key, coin;
|
||||
|
||||
if (!Array.isArray(addresses))
|
||||
addresses = [addresses];
|
||||
|
||||
addresses = utils.uniqs(addresses);
|
||||
|
||||
for (i = 0; i < addresses.length; i++) {
|
||||
address = addresses[i];
|
||||
keys = this.addressMap.getCoins(address);
|
||||
for (j = 0; j < keys.length; j++) {
|
||||
key = keys[j];
|
||||
coin = this.getCoinSync(key[0], key[1]);
|
||||
if (coin)
|
||||
coins.push(coin);
|
||||
}
|
||||
}
|
||||
|
||||
return coins;
|
||||
};
|
||||
|
||||
Mempool.prototype.getByAddressSync =
|
||||
Mempool.prototype.getTXByAddressSync = function getTXByAddressSync(addresses, callback) {
|
||||
var uniq = {};
|
||||
var txs = [];
|
||||
var i, j, address, hashes, hash, tx;
|
||||
|
||||
if (!Array.isArray(addresses))
|
||||
addresses = [addresses];
|
||||
|
||||
addresses = utils.uniqs(addresses);
|
||||
|
||||
for (i = 0; i < addresses.length; i++) {
|
||||
address = addresses[i];
|
||||
hashes = this.addressMap.getTX(address);
|
||||
for (j = 0; j < hashes.length; j++) {
|
||||
hash = hashes[j];
|
||||
|
||||
if (uniq[hash])
|
||||
continue;
|
||||
|
||||
tx = this.getTXSync(hash);
|
||||
|
||||
if (!tx)
|
||||
continue;
|
||||
|
||||
uniq[hash] = true;
|
||||
|
||||
txs.push(tx);
|
||||
}
|
||||
}
|
||||
|
||||
return txs;
|
||||
};
|
||||
|
||||
Mempool.prototype.fillTXSync = function fillTXSync(tx) {
|
||||
var i, input, prev;
|
||||
|
||||
if (tx.isCoinbase())
|
||||
return tx;
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
|
||||
if (input.coin)
|
||||
continue;
|
||||
|
||||
prev = this.getTXSync(input.prevout.hash);
|
||||
|
||||
if (!prev)
|
||||
continue;
|
||||
|
||||
input.coin = bcoin.coin(prev, input.prevout.index);
|
||||
}
|
||||
|
||||
return tx;
|
||||
};
|
||||
|
||||
Mempool.prototype.fillCoinsSync = function fillCoinsSync(tx) {
|
||||
var i, input;
|
||||
|
||||
if (tx.isCoinbase())
|
||||
return tx;
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
|
||||
if (input.coin)
|
||||
continue;
|
||||
|
||||
try {
|
||||
input.coin = this.getCoinSync(input.prevout.hash, input.prevout.index);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
}
|
||||
|
||||
return tx;
|
||||
};
|
||||
|
||||
Mempool.prototype.hasSync =
|
||||
Mempool.prototype.hasTXSync = function hasTXSync(hash) {
|
||||
if (hash instanceof bcoin.tx)
|
||||
hash = hash.hash('hex');
|
||||
|
||||
return this.txs[hash] != null;
|
||||
};
|
||||
|
||||
Mempool.prototype.add =
|
||||
Mempool.prototype.addTX = function addTX(tx, callback, force) {
|
||||
var self = this;
|
||||
|
||||
1040
lib/bcoin/mempool2.js
Normal file
1040
lib/bcoin/mempool2.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -130,7 +130,7 @@ Miner.prototype.start = function start() {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
self.node.fillCoins(tx, function(err) {
|
||||
self.mempool.fillAllCoins(tx, function(err) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
|
||||
@ -1536,6 +1536,15 @@ TXPool.prototype.getTX = function getTX(hash, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.hasTX = function hasTX(hash, callback) {
|
||||
return this.getTX(hash, function(err, tx) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
return callback(null, tx != null);
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
var prefix = this.prefix + '/';
|
||||
var key = prefix + 'u/t/' + hash + '/' + index;
|
||||
@ -1559,6 +1568,15 @@ TXPool.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.hasCoin = function hasCoin(hash, index, callback) {
|
||||
return this.getCoin(hash, index, function(err, coin) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
return callback(null, coin != null);
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.getBalance = function getBalance(address, callback) {
|
||||
var confirmed = new bn(0);
|
||||
var unconfirmed = new bn(0);
|
||||
@ -1684,46 +1702,61 @@ TXPool.prototype.removeUnchecked = function removeUnchecked(hash, callback, forc
|
||||
|
||||
batch.del(prefix + 't/t/' + hash);
|
||||
batch.del(prefix + 't/s/s/' + pad32(tx.ps) + '/' + hash);
|
||||
batch.del(prefix + 'D/' + hash);
|
||||
|
||||
tx.getAddresses().forEach(function(address) {
|
||||
batch.del(prefix + 't/a/' + address + '/' + hash);
|
||||
});
|
||||
|
||||
tx.inputs.forEach(function(input) {
|
||||
utils.forEachSerial(tx.inputs, function(input, next) {
|
||||
var key = input.prevout.hash + '/' + input.prevout.index;
|
||||
var address;
|
||||
|
||||
if (tx.isCoinbase())
|
||||
return;
|
||||
return next();
|
||||
|
||||
if (!input.coin)
|
||||
return;
|
||||
return next();
|
||||
|
||||
address = input.getAddress();
|
||||
|
||||
batch.del(prefix + 'u/t/' + key);
|
||||
batch.del(prefix + 's/t/' + key);
|
||||
|
||||
if (address)
|
||||
batch.del(prefix + 'u/a/' + address + '/' + key);
|
||||
});
|
||||
self.hasTX(input.prevout.hash, function(err, result) {
|
||||
if (err)
|
||||
return next(err);
|
||||
|
||||
tx.outputs.forEach(function(output, i) {
|
||||
var key = hash + '/' + i;
|
||||
var address = output.getAddress();
|
||||
if (result) {
|
||||
batch.put(prefix + 'u/t/' + key, input.coin.toRaw());
|
||||
if (address)
|
||||
batch.put(prefix + 'u/a/' + address + '/' + key, DUMMY);
|
||||
} else {
|
||||
batch.del(prefix + 'u/t/' + key);
|
||||
if (address)
|
||||
batch.del(prefix + 'u/a/' + address + '/' + key);
|
||||
}
|
||||
|
||||
batch.del(prefix + 'u/t/' + key);
|
||||
|
||||
if (address)
|
||||
batch.del(prefix + 'u/a/' + address + '/' + key);
|
||||
});
|
||||
|
||||
batch.write(function(err) {
|
||||
next();
|
||||
});
|
||||
}, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.emit('remove tx', tx);
|
||||
return callback();
|
||||
|
||||
tx.outputs.forEach(function(output, i) {
|
||||
var key = hash + '/' + i;
|
||||
var address = output.getAddress();
|
||||
|
||||
batch.del(prefix + 'u/t/' + key);
|
||||
|
||||
if (address)
|
||||
batch.del(prefix + 'u/a/' + address + '/' + key);
|
||||
});
|
||||
|
||||
batch.write(function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
self.emit('remove tx', tx);
|
||||
return callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user