refactor.

This commit is contained in:
Christopher Jeffrey 2016-04-16 05:55:00 -07:00
parent 0d75c8a621
commit 0d7d8073a2
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
8 changed files with 163 additions and 147 deletions

View File

@ -347,7 +347,7 @@ Chain.prototype._preload = function _preload(callback) {
stream.on('data', function(data) { stream.on('data', function(data) {
var blocks = []; var blocks = [];
var need = 80 - buf.size; var need = 80 - buf.size;
var lastEntry; var lastEntry, block, entry, start;
while (data.length >= need) { while (data.length >= need) {
buf.data.push(data.slice(0, need)); buf.data.push(data.slice(0, need));
@ -367,8 +367,8 @@ Chain.prototype._preload = function _preload(callback) {
if (blocks.length === 0) if (blocks.length === 0)
return; return;
blocks.forEach(function(data) { for (i = 0; i < blocks.length; i++) {
var block, entry, start; block = blocks[i];
try { try {
data = parseHeader(data); data = parseHeader(data);
@ -423,7 +423,7 @@ Chain.prototype._preload = function _preload(callback) {
lastEntry = entry; lastEntry = entry;
height++; height++;
}); }
}); });
stream.on('end', function() { stream.on('end', function() {

View File

@ -19,9 +19,13 @@ var DUMMY = new Buffer([0]);
* @exports ChainDB * @exports ChainDB
* @constructor * @constructor
* @param {Object} options * @param {Object} options
* @param {Boolean?} options.prune * @param {Boolean?} options.prune - Whether to prune the chain.
* @param {Boolean?} options.spv * @param {Boolean?} options.spv - SPV-mode, will not save block
* @param {Number?} options.keepBlocks * data, only entries.
* @param {Number?} [options.keepBlocks=288] - Number of
* blocks to keep when pruning.
* @param {Boolean?} options.paranoid - Perform some paranoid checks
* against hashes. Will throw if corruption is detected.
* @param {String?} options.name - Database name * @param {String?} options.name - Database name
* @param {String?} options.location - Database location * @param {String?} options.location - Database location
* @param {String?} options.db - Database backend name * @param {String?} options.db - Database backend name
@ -165,8 +169,8 @@ ChainDB.prototype.addCache = function addCache(entry) {
}; };
/** /**
* Test the cache for a present transaction. * Test the cache for a present entry hash or height.
* @param {Hash} hash * @param {Hash|Number} hash - Hash or height.
*/ */
ChainDB.prototype.hasCache = function hasCache(hash) { ChainDB.prototype.hasCache = function hasCache(hash) {
@ -180,10 +184,10 @@ ChainDB.prototype.hasCache = function hasCache(hash) {
}; };
/** /**
* Get a transaction directly from the LRU cache. This is * Get an entry directly from the LRU cache. This is
* useful for optimization if we don't want to wait on a * useful for optimization if we don't want to wait on a
* nextTick during a `get()` call. * nextTick during a `get()` call.
* @param {Hash} hash * @param {Hash|Number} hash - Hash or height.
*/ */
ChainDB.prototype.getCache = function getCache(hash) { ChainDB.prototype.getCache = function getCache(hash) {
@ -718,14 +722,17 @@ ChainDB.prototype.has = function has(height, callback) {
*/ */
ChainDB.prototype.saveBlock = function saveBlock(block, batch, connect, callback) { ChainDB.prototype.saveBlock = function saveBlock(block, batch, connect, callback) {
var i, tx;
if (this.options.spv) if (this.options.spv)
return utils.nextTick(callback); return utils.nextTick(callback);
batch.put('b/b/' + block.hash('hex'), block.toCompact()); batch.put('b/b/' + block.hash('hex'), block.toCompact());
block.txs.forEach(function(tx) { for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i];
batch.put('t/t/' + tx.hash('hex'), tx.toExtended()); batch.put('t/t/' + tx.hash('hex'), tx.toExtended());
}); }
if (!connect) if (!connect)
return utils.nextTick(callback); return utils.nextTick(callback);
@ -743,6 +750,7 @@ ChainDB.prototype.saveBlock = function saveBlock(block, batch, connect, callback
ChainDB.prototype.removeBlock = function removeBlock(hash, batch, callback) { ChainDB.prototype.removeBlock = function removeBlock(hash, batch, callback) {
var self = this; var self = this;
var i, tx;
if (this.options.spv) if (this.options.spv)
return utils.nextTick(callback); return utils.nextTick(callback);
@ -756,9 +764,10 @@ ChainDB.prototype.removeBlock = function removeBlock(hash, batch, callback) {
batch.del('b/b/' + block.hash('hex')); batch.del('b/b/' + block.hash('hex'));
block.txs.forEach(function(tx) { for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i];
batch.del('t/t/' + tx.hash('hex')); batch.del('t/t/' + tx.hash('hex'));
}); }
self.disconnectBlock(block, batch, callback); self.disconnectBlock(block, batch, callback);
}); });
@ -773,6 +782,7 @@ ChainDB.prototype.removeBlock = function removeBlock(hash, batch, callback) {
ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) { ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
var self = this; var self = this;
var i, j, tx, input, output, key, address, hash, uniq;
if (this.options.spv) { if (this.options.spv) {
self.emit('add block', block); self.emit('add block', block);
@ -788,16 +798,17 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
if (!block) if (!block)
return callback(); return callback();
block.txs.forEach(function(tx) { for (i = 0; i < block.txs.length; i++) {
var hash = tx.hash('hex'); tx = block.txs[i];
var uniq = {}; hash = tx.hash('hex');
uniq = {};
tx.inputs.forEach(function(input) { for (j = 0; j < tx.inputs.length; j++) {
var key = input.prevout.hash + '/' + input.prevout.index; input = tx.inputs[j];
var address; key = input.prevout.hash + '/' + input.prevout.index;
if (tx.isCoinbase()) if (tx.isCoinbase())
return; break;
assert(input.coin); assert(input.coin);
@ -814,11 +825,11 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
} }
batch.del('u/t/' + key); batch.del('u/t/' + key);
}); }
tx.outputs.forEach(function(output, i) { for (j = 0; j < tx.inputs.length; j++) {
var key = hash + '/' + i; output = tx.outputs[j];
var address; key = hash + '/' + j;
if (self.options.indexAddress) { if (self.options.indexAddress) {
address = output.getAddress(); address = output.getAddress();
@ -832,9 +843,9 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
batch.put('u/a/' + address + '/' + key, DUMMY); batch.put('u/a/' + address + '/' + key, DUMMY);
} }
batch.put('u/t/' + key, bcoin.coin(tx, i).toRaw()); batch.put('u/t/' + key, bcoin.coin(tx, j).toRaw());
}); }
}); }
self.emit('add block', block); self.emit('add block', block);
@ -849,13 +860,14 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
* @param {Function} callback - Returns [Error, {@link Block}]. * @param {Function} callback - Returns [Error, {@link Block}].
*/ */
ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callback) { ChainDB.prototype.disconnectBlock = function disconnectBlock(block, batch, callback) {
var self = this; var self = this;
var i, j, tx, input, output, key, address, hash, uniq;
if (this.options.spv) if (this.options.spv)
return utils.nextTick(callback); return utils.nextTick(callback);
this._ensureHistory(hash, function(err, block) { this._ensureHistory(block, function(err, block) {
if (err) if (err)
return callback(err); return callback(err);
@ -863,20 +875,21 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callba
return callback(new Error('Block not found.')); return callback(new Error('Block not found.'));
if (self.options.paranoid) { if (self.options.paranoid) {
if (typeof hash === 'string') if (typeof block === 'string')
assert(block.hash('hex') === hash, 'Database is corrupt.'); assert(block.hash('hex') === block, 'Database is corrupt.');
} }
block.txs.slice().reverse().forEach(function(tx) { for (i = block.txs.length - 1; i >= 0; i--) {
var hash = tx.hash('hex'); tx = block.txs[i];
var uniq = {}; hash = tx.hash('hex');
uniq = {};
tx.inputs.forEach(function(input) { for (j = 0; j < tx.inputs.length; j++) {
var key = input.prevout.hash + '/' + input.prevout.index; input = tx.inputs[j];
var address; key = input.prevout.hash + '/' + input.prevout.index;
if (tx.isCoinbase()) if (tx.isCoinbase())
return; break;
assert(input.coin); assert(input.coin);
@ -893,11 +906,11 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callba
} }
batch.put('u/t/' + key, input.coin.toRaw()); batch.put('u/t/' + key, input.coin.toRaw());
}); }
tx.outputs.forEach(function(output, i) { for (j = 0; j < tx.inputs.length; j++) {
var key = hash + '/' + i; output = tx.outputs[j];
var address; key = hash + '/' + j;
if (self.options.indexAddress) { if (self.options.indexAddress) {
address = output.getAddress(); address = output.getAddress();
@ -912,8 +925,8 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callba
} }
batch.del('u/t/' + key); batch.del('u/t/' + key);
}); }
}); }
self.emit('remove block', block); self.emit('remove block', block);
@ -1032,16 +1045,11 @@ ChainDB.prototype.fillTX = function fillTX(tx, callback) {
* @param {Function} callback - Returns [Error, {@link Coin}[]]. * @param {Function} callback - Returns [Error, {@link Coin}[]].
*/ */
ChainDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, options, callback) { ChainDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, callback) {
var self = this; var self = this;
var ids = []; var ids = [];
var coins = []; var coins = [];
if (!callback) {
callback = options;
options = {};
}
if (typeof addresses === 'string') if (typeof addresses === 'string')
addresses = [addresses]; addresses = [addresses];
@ -1141,17 +1149,12 @@ ChainDB.prototype.getCoin = function getCoin(hash, index, callback) {
* @param {Function} callback - Returns [Error, {@link TX}[]]. * @param {Function} callback - Returns [Error, {@link TX}[]].
*/ */
ChainDB.prototype.getTXByAddress = function getTXByAddress(addresses, options, callback) { ChainDB.prototype.getTXByAddress = function getTXByAddress(addresses, callback) {
var self = this; var self = this;
var hashes = []; var hashes = [];
var txs = []; var txs = [];
var have = {}; var have = {};
if (!callback) {
callback = options;
options = {};
}
if (typeof addresses === 'string') if (typeof addresses === 'string')
addresses = [addresses]; addresses = [addresses];
@ -1543,6 +1546,7 @@ ChainDB.prototype.isSpentTX = function isSpentTX(hash, callback) {
ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) { ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
var futureHeight; var futureHeight;
var i, j, tx, input;
if (this.options.spv) if (this.options.spv)
return callback(); return callback();
@ -1558,11 +1562,15 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
batch.put('b/q/' + futureHeight, block.hash()); batch.put('b/q/' + futureHeight, block.hash());
block.txs.forEach(function(tx) { for (i = 0; i < block.txs.length; i++) {
if (tx.isCoinbase()) tx = block.txs[i];
return;
if (tx.isCoinbase())
break;
for (j = 0; j < tx.inputs.length; j++) {
input = tx.inputs[j];
tx.inputs.forEach(function(input) {
assert(input.coin); assert(input.coin);
batch.put('u/x/' batch.put('u/x/'
@ -1575,8 +1583,8 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
+ '/' + input.prevout.hash + '/' + input.prevout.hash
+ '/' + input.prevout.index, + '/' + input.prevout.index,
DUMMY); DUMMY);
}); }
}); }
this._pruneQueue(block, batch, callback); this._pruneQueue(block, batch, callback);
}; };
@ -1584,6 +1592,8 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
ChainDB.prototype._pruneQueue = function _pruneQueue(block, batch, callback) { ChainDB.prototype._pruneQueue = function _pruneQueue(block, batch, callback) {
var self = this; var self = this;
var key = 'b/q/' + pad32(block.height); var key = 'b/q/' + pad32(block.height);
var i;
this.db.get(key, function(err, hash) { this.db.get(key, function(err, hash) {
if (err && err.type !== 'NotFoundError') if (err && err.type !== 'NotFoundError')
return callback(err); return callback(err);
@ -1610,9 +1620,8 @@ ChainDB.prototype._pruneQueue = function _pruneQueue(block, batch, callback) {
batch.del('b/b/' + hash); batch.del('b/b/' + hash);
compact.hashes.forEach(function(hash) { for (i = 0; i < compact.hashes.length; i++)
batch.del('t/t/' + hash); batch.del('t/t/' + compact.hashes[i]);
});
self._pruneCoinQueue(block, batch, callback); self._pruneCoinQueue(block, batch, callback);
}); });

View File

@ -150,9 +150,16 @@ CoinView.prototype.fill = function fill(obj, spend) {
*/ */
CoinView.prototype.toArray = function toArray() { CoinView.prototype.toArray = function toArray() {
return Object.keys(this.coins).map(function(hash) { var keys = Object.keys(this.coins);
return this.coins[hash]; var out = [];
}, this); var i, hash;
for (i = 0; i < keys.length; i++) {
hash = keys[i];
out = out.concat(this.coins[hash].toArray());
}
return out;
}; };
return CoinView; return CoinView;

View File

@ -14,7 +14,7 @@ var assert = utils.assert;
var request = require('./request'); var request = require('./request');
/** /**
* Client * BCoin HTTP client.
* @exports Client * @exports Client
* @constructor * @constructor
* @param {String} uri * @param {String} uri

View File

@ -1145,9 +1145,9 @@ Mempool.prototype.removeOrphan = function removeOrphan(tx, callback) {
} }
p = new BufferWriter(); p = new BufferWriter();
hashes.forEach(function(hash) {
p.writeHash(hash); for (i = 0; i < hashes.length; i++)
}); p.writeHash(hashes[i]);
batch.put('m/d/' + prev, p.render()); batch.put('m/d/' + prev, p.render());
@ -1410,7 +1410,7 @@ Mempool.prototype._addUnchecked = function addUnchecked(tx, callback, force) {
var self = this; var self = this;
var prefix = 'm/'; var prefix = 'm/';
var hash = tx.hash('hex'); var hash = tx.hash('hex');
var batch; var i, addresses, address, input, output, key, coin, batch;
var unlock = this.writeLock.lock(addUnchecked, [tx, callback], force); var unlock = this.writeLock.lock(addUnchecked, [tx, callback], force);
if (!unlock) if (!unlock)
@ -1423,18 +1423,20 @@ Mempool.prototype._addUnchecked = function addUnchecked(tx, callback, force) {
batch.put(prefix + 't/t/' + hash, tx.toExtended()); batch.put(prefix + 't/t/' + hash, tx.toExtended());
batch.put(prefix + 't/s/s/' + pad32(tx.ps) + '/' + hash, DUMMY); batch.put(prefix + 't/s/s/' + pad32(tx.ps) + '/' + hash, DUMMY);
tx.getAddresses().forEach(function(address) { addresses = tx.getAddresses();
batch.put(prefix + 't/a/' + address + '/' + hash, DUMMY);
});
tx.inputs.forEach(function(input) { for (i = 0; i < addresses.length; i++)
var key = input.prevout.hash + '/' + input.prevout.index; batch.put(prefix + 't/a/' + addresses[i] + '/' + hash, DUMMY);
var address;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
key = input.prevout.hash + '/' + input.prevout.index;
if (tx.isCoinbase()) if (tx.isCoinbase())
return; break;
assert(input.coin); assert(input.coin);
address = input.getAddress(); address = input.getAddress();
batch.del(prefix + 'u/t/' + key); batch.del(prefix + 'u/t/' + key);
@ -1442,18 +1444,19 @@ Mempool.prototype._addUnchecked = function addUnchecked(tx, callback, force) {
if (address) if (address)
batch.del(prefix + 'u/a/' + address + '/' + key); batch.del(prefix + 'u/a/' + address + '/' + key);
}); }
tx.outputs.forEach(function(output, i) { for (i = 0; i < tx.outputs.length; i++) {
var key = hash + '/' + i; output = tx.outputs[i];
var address = output.getAddress(); key = hash + '/' + i;
var coin = bcoin.coin(tx, i).toRaw(); address = output.getAddress();
coin = bcoin.coin(tx, i).toRaw();
batch.put(prefix + 'u/t/' + key, coin); batch.put(prefix + 'u/t/' + key, coin);
if (address) if (address)
batch.put(prefix + 'u/a/' + address + '/' + key, DUMMY); batch.put(prefix + 'u/a/' + address + '/' + key, DUMMY);
}); }
return batch.write(callback); return batch.write(callback);
}; };
@ -1469,7 +1472,7 @@ Mempool.prototype._addUnchecked = function addUnchecked(tx, callback, force) {
Mempool.prototype._removeUnchecked = function removeUnchecked(hash, callback, force) { Mempool.prototype._removeUnchecked = function removeUnchecked(hash, callback, force) {
var self = this; var self = this;
var prefix = 'm/'; var prefix = 'm/';
var batch; var batch, i, addresses, output;
var unlock = this.writeLock.lock(removeUnchecked, [hash, callback], force); var unlock = this.writeLock.lock(removeUnchecked, [hash, callback], force);
if (!unlock) if (!unlock)
@ -1492,9 +1495,10 @@ Mempool.prototype._removeUnchecked = function removeUnchecked(hash, callback, fo
batch.del(prefix + 't/t/' + hash); batch.del(prefix + 't/t/' + hash);
batch.del(prefix + 't/s/s/' + pad32(tx.ps) + '/' + hash); batch.del(prefix + 't/s/s/' + pad32(tx.ps) + '/' + hash);
tx.getAddresses().forEach(function(address) { addresses = tx.getAddresses();
batch.del(prefix + 't/a/' + address + '/' + hash);
}); for (i = 0; i < addresses.length; i++)
batch.del(prefix + 't/a/' + addresses[i] + '/' + hash);
utils.forEachSerial(tx.inputs, function(input, next) { utils.forEachSerial(tx.inputs, function(input, next) {
var key = input.prevout.hash + '/' + input.prevout.index; var key = input.prevout.hash + '/' + input.prevout.index;
@ -1530,15 +1534,16 @@ Mempool.prototype._removeUnchecked = function removeUnchecked(hash, callback, fo
if (err) if (err)
return callback(err); return callback(err);
tx.outputs.forEach(function(output, i) { for (i = 0; i < tx.outputs.length; i++) {
var key = hash + '/' + i; output = tx.outputs[i];
var address = output.getAddress(); key = hash + '/' + i;
address = output.getAddress();
batch.del(prefix + 'u/t/' + key); batch.del(prefix + 'u/t/' + key);
if (address) if (address)
batch.del(prefix + 'u/a/' + address + '/' + key); batch.del(prefix + 'u/a/' + address + '/' + key);
}); }
return batch.write(callback); return batch.write(callback);
}); });

View File

@ -1070,7 +1070,7 @@ Peer.prototype._handleGetData = function handleGetData(items) {
var isWitness = item.type & constants.invWitnessMask; var isWitness = item.type & constants.invWitnessMask;
var type = item.type & ~constants.invWitnessMask; var type = item.type & ~constants.invWitnessMask;
var hash = utils.toHex(item.hash); var hash = utils.toHex(item.hash);
var data; var i, tx, data;
if (type === constants.inv.tx) { if (type === constants.inv.tx) {
if (!self.mempool) { if (!self.mempool) {
@ -1156,14 +1156,16 @@ Peer.prototype._handleGetData = function handleGetData(items) {
self._write(self.framer.merkleBlock(block)); self._write(self.framer.merkleBlock(block));
block.txs.forEach(function(tx) { for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i];
if (isWitness) if (isWitness)
tx = tx.renderWitness(); tx = tx.renderWitness();
else else
tx = tx.renderNormal(); tx = tx.renderNormal();
self._write(self.framer.packet('tx', tx)); self._write(self.framer.packet('tx', tx));
}); }
if (hash === self.hashContinue) { if (hash === self.hashContinue) {
self._write(self.framer.inv([{ self._write(self.framer.inv([{

View File

@ -32,7 +32,6 @@ var constants = bcoin.protocol.constants;
* send another getblocks request. * send another getblocks request.
* @param {Number?} [requestTimeout=120000] - Timeout for in-flight blocks. * @param {Number?} [requestTimeout=120000] - Timeout for in-flight blocks.
* @param {Number?} [invTimeout=60000] - Timeout for broadcasted objects. * @param {Number?} [invTimeout=60000] - Timeout for broadcasted objects.
* @param {Wallet[]?} wallets - Wallets to add to the bloom filter.
* @param {Boolean?} listen - Whether to spin up a server socket * @param {Boolean?} listen - Whether to spin up a server socket
* and listen for peers. * and listen for peers.
* @param {Boolean?} selfish - A selfish pool. Will not serve blocks, * @param {Boolean?} selfish - A selfish pool. Will not serve blocks,
@ -293,10 +292,6 @@ Pool.prototype._init = function _init() {
self.emit('full'); self.emit('full');
bcoin.debug('Chain is fully synced (height=%d).', self.chain.height); bcoin.debug('Chain is fully synced (height=%d).', self.chain.height);
}); });
(this.options.wallets || []).forEach(function(wallet) {
self.addWallet(wallet);
});
}; };
/** /**
@ -893,12 +888,13 @@ Pool.prototype._load = function _load() {
*/ */
Pool.prototype.getMempool = function getMempool() { Pool.prototype.getMempool = function getMempool() {
var i;
if (this.peers.load) if (this.peers.load)
this.peers.load.getMempool(); this.peers.load.getMempool();
this.peers.regular.forEach(function(peer) { for (i = 0; i < this.peers.regular.length; i++)
peer.getMempool(); this.peers.regular[i].getMempool();
});
}; };
Pool.prototype._createPeer = function _createPeer(options) { Pool.prototype._createPeer = function _createPeer(options) {
@ -943,11 +939,14 @@ Pool.prototype._createPeer = function _createPeer(options) {
}); });
peer.on('notfound', function(items) { peer.on('notfound', function(items) {
items.forEach(function(item) { var i, item;
var req = self.request.map[utils.toHex(item.hash)];
for (i = 0; i < items.length; i++) {
item = items[i];
req = self.request.map[utils.toHex(item.hash)];
if (req && req.peer === peer) if (req && req.peer === peer)
item.finish(); item.finish();
}); }
}); });
peer.on('tx', function(tx) { peer.on('tx', function(tx) {
@ -979,6 +978,8 @@ Pool.prototype._createPeer = function _createPeer(options) {
}); });
peer.on('txs', function(txs) { peer.on('txs', function(txs) {
var i, hash;
self.emit('txs', txs, peer); self.emit('txs', txs, peer);
if (!self.options.spv) { if (!self.options.spv) {
@ -986,11 +987,11 @@ Pool.prototype._createPeer = function _createPeer(options) {
return; return;
} }
txs.forEach(function(hash) { for (i = 0; i < txs.length; i++) {
hash = utils.toHex(hash); hash = utils.toHex(txs[i]);
if (self.markTX(hash, 0)) if (self.markTX(hash, 0))
self.getData(peer, self.tx.type, hash); self.getData(peer, self.tx.type, hash);
}); }
}); });
peer.on('version', function(version) { peer.on('version', function(version) {
@ -1356,6 +1357,7 @@ Pool.prototype.updateWatch = function updateWatch() {
Pool.prototype.addWallet = function addWallet(wallet, callback) { Pool.prototype.addWallet = function addWallet(wallet, callback) {
var self = this; var self = this;
var i;
callback = utils.asyncify(callback); callback = utils.asyncify(callback);
@ -1366,9 +1368,8 @@ Pool.prototype.addWallet = function addWallet(wallet, callback) {
if (err) if (err)
return callback(err); return callback(err);
txs.forEach(function(tx) { for (i = 0; i < txs.length; i++)
self.sendTX(tx); self.sendTX(txs[i]);
});
if (!self.options.spv) if (!self.options.spv)
return callback(); return callback();
@ -1713,7 +1714,7 @@ Pool.prototype._sendRequests = function _sendRequests(peer) {
*/ */
Pool.prototype.fulfill = function fulfill(hash) { Pool.prototype.fulfill = function fulfill(hash) {
var item; var i, item;
if (Buffer.isBuffer(hash)) if (Buffer.isBuffer(hash))
hash = utils.toHex(hash); hash = utils.toHex(hash);
@ -1726,9 +1727,8 @@ Pool.prototype.fulfill = function fulfill(hash) {
item.finish(); item.finish();
item.callback.forEach(function(callback) { for (i = 0; i < item.callback.length; i++)
callback(); item.callback[i]();
});
return item; return item;
}; };
@ -1811,10 +1811,12 @@ Pool.prototype.getTX = function getTX(hash, range, callback) {
range = { start: utils.now() - delta, end: 0 }; range = { start: utils.now() - delta, end: 0 };
function done(err, tx, range) { function done(err, tx, range) {
var i;
delete self.validate.map[hash]; delete self.validate.map[hash];
cbs.forEach(function(callback) {
callback(err, tx, range); for (i = 0; i < cbs.length; i++)
}); cbs[i](err, tx, range);
} }
(function next() { (function next() {
@ -2093,11 +2095,13 @@ Pool.prototype._getRandom = function _getRandom(seeds, uniq) {
*/ */
Pool.prototype.setSeeds = function setSeeds(seeds) { Pool.prototype.setSeeds = function setSeeds(seeds) {
var i, seed;
this.seeds = []; this.seeds = [];
this.hosts = {}; this.hosts = {};
seeds.forEach(function(seed) {
this.addSeed(seed); for (i = 0; i < seeds.length; i++)
}, this); this.addSeed(seeds[i]);
}; };
/** /**

View File

@ -547,14 +547,11 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
if (!orphans) { if (!orphans) {
if (self.options.indexAddress && address) { if (self.options.indexAddress && address) {
map.table[address].forEach(function(id) { map.table[address].forEach(function(id) {
batch.put( batch.put(prefix + 'u/a/' + id + '/' + key, DUMMY);
prefix + 'u/a/' + id
+ '/' + hash + '/' + i,
DUMMY);
}); });
} }
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw()); batch.put(prefix + 'u/t/' + key, coin.toRaw());
updated = true; updated = true;
} }
@ -905,6 +902,7 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
return callback(err); return callback(err);
tx.inputs.forEach(function(input) { tx.inputs.forEach(function(input) {
var key = input.prevout.hash + '/' + input.prevout.index;
var address = input.getAddress(); var address = input.getAddress();
if (tx.isCoinbase()) if (tx.isCoinbase())
@ -920,26 +918,17 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
if (self.options.indexAddress && address) { if (self.options.indexAddress && address) {
map.table[address].forEach(function(id) { map.table[address].forEach(function(id) {
batch.put(prefix + 'u/a/' + id batch.put(prefix + 'u/a/' + id + '/' + key, DUMMY);
+ '/' + input.prevout.hash
+ '/' + input.prevout.index,
DUMMY);
}); });
} }
batch.put(prefix + 'u/t/' batch.put(prefix + 'u/t/' + key, input.coin.toRaw());
+ input.prevout.hash batch.del(prefix + 's/t/' + key);
+ '/' + input.prevout.index, batch.del(prefix + 'o/' + key);
input.coin.toRaw());
batch.del(prefix + 's/t/'
+ input.prevout.hash
+ '/' + input.prevout.index);
batch.del(prefix + 'o/' + input.prevout.hash + '/' + input.prevout.index);
}); });
tx.outputs.forEach(function(output, i) { tx.outputs.forEach(function(output, i) {
var key = hash + '/' + i;
var address = output.getAddress(); var address = output.getAddress();
if (self.options.mapAddress) { if (self.options.mapAddress) {
@ -949,11 +938,11 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
if (self.options.indexAddress && address) { if (self.options.indexAddress && address) {
map.table[address].forEach(function(id) { map.table[address].forEach(function(id) {
batch.del(prefix + 'u/a/' + id + '/' + hash + '/' + i); batch.del(prefix + 'u/a/' + id + '/' + key);
}); });
} }
batch.del(prefix + 'u/t/' + hash + '/' + i); batch.del(prefix + 'u/t/' + key);
}); });
batch.write(function(err) { batch.write(function(err) {