map addresses to ids.
This commit is contained in:
parent
434fdc7a78
commit
ef55d1cebc
@ -37,7 +37,7 @@ function Chain(node, options) {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.mempool = node.mempool;
|
this.mempool = node.mempool;
|
||||||
this.blockdb = node.blockdb;
|
this.blockdb = node.blockdb;
|
||||||
this.db = new bcoin.chaindb(node, this);
|
this.db = new bcoin.chaindb(node, this, options);
|
||||||
this.busy = false;
|
this.busy = false;
|
||||||
this.jobs = [];
|
this.jobs = [];
|
||||||
this.pending = [];
|
this.pending = [];
|
||||||
|
|||||||
@ -35,8 +35,13 @@ function ChainDB(node, chain, options) {
|
|||||||
this.chain = chain;
|
this.chain = chain;
|
||||||
this.file = options.file;
|
this.file = options.file;
|
||||||
|
|
||||||
if (!this.file)
|
if (!this.file) {
|
||||||
this.file = bcoin.prefix + '/chain-' + network.type + '.db';
|
this.file = bcoin.prefix
|
||||||
|
+ '/chain-'
|
||||||
|
+ (options.spv ? 'spv-' : '')
|
||||||
|
+ network.type
|
||||||
|
+ '.db';
|
||||||
|
}
|
||||||
|
|
||||||
this.heightLookup = {};
|
this.heightLookup = {};
|
||||||
this.queue = {};
|
this.queue = {};
|
||||||
|
|||||||
@ -30,6 +30,7 @@ function TXPool(prefix, db, options) {
|
|||||||
this.options = options;
|
this.options = options;
|
||||||
this.busy = false;
|
this.busy = false;
|
||||||
this.jobs = [];
|
this.jobs = [];
|
||||||
|
this.ids = true;
|
||||||
|
|
||||||
if (options.addressFilter)
|
if (options.addressFilter)
|
||||||
this._hasAddress = options.addressFilter;
|
this._hasAddress = options.addressFilter;
|
||||||
@ -85,32 +86,111 @@ TXPool.prototype.add = function add(tx, callback) {
|
|||||||
}, callback);
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self._add(tx, callback);
|
//if (!this.ids)
|
||||||
|
return this._add(tx, this.__getIDs(tx), callback);
|
||||||
|
|
||||||
|
return self._getIDs(tx.getAddresses(), function(err, ids) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
return self._add(tx, ids, callback);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TXPool.prototype._hasAddress = function _hasAddress(address, callback) {
|
// Map of address->id.
|
||||||
if (!address)
|
TXPool.prototype.__getIDs = function _getIDs(tx, callback) {
|
||||||
|
var map = tx.getAddresses();
|
||||||
|
return map.reduce(function(out, addr) {
|
||||||
|
out[addr] = [addr];
|
||||||
|
return out;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
|
TXPool.prototype.__hasAddress = function __hasAddress(map, address, callback) {
|
||||||
|
if (!address || !map[address] || !map[address].length)
|
||||||
return callback(null, false);
|
return callback(null, false);
|
||||||
return callback(null, true);
|
return callback(null, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TXPool.prototype._getIDs = function getIDs(address, callback) {
|
||||||
|
var p = this.prefix + '/';
|
||||||
|
var self = this;
|
||||||
|
var map = {};
|
||||||
|
|
||||||
|
if (Array.isArray(address)) {
|
||||||
|
address = utils.uniqs(address);
|
||||||
|
return utils.forEachSerial(address, function(address, next) {
|
||||||
|
self._getIDs(address, function(err, m) {
|
||||||
|
if (err)
|
||||||
|
return next(err);
|
||||||
|
|
||||||
|
map[address] = m[address];
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}, function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
return callback(null, map);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var iter = this.db.db.iterator({
|
||||||
|
gte: p + 'a/' + address,
|
||||||
|
lte: p + 'a/' + address + '~',
|
||||||
|
keys: true,
|
||||||
|
values: false,
|
||||||
|
fillCache: false,
|
||||||
|
keyAsBuffer: false
|
||||||
|
});
|
||||||
|
|
||||||
|
callback = utils.ensure(callback);
|
||||||
|
|
||||||
|
map[address] = [];
|
||||||
|
|
||||||
|
(function next() {
|
||||||
|
iter.next(function(err, key, value) {
|
||||||
|
if (err) {
|
||||||
|
return iter.end(function() {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === undefined) {
|
||||||
|
return iter.end(function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
map[address] = utils.uniqs(map[address]);
|
||||||
|
return callback(null, map);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
map[address].push(key.split('/')[3]);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
// This big scary function is what a persistent tx pool
|
// This big scary function is what a persistent tx pool
|
||||||
// looks like. It's a semi mempool in that it can handle
|
// looks like. It's a semi mempool in that it can handle
|
||||||
// receiving txs out of order.
|
// receiving txs out of order.
|
||||||
TXPool.prototype._add = function add(tx, callback, force) {
|
TXPool.prototype._add = function add(tx, map, callback, force) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var p = this.prefix + '/';
|
var p = this.prefix + '/';
|
||||||
var hash = tx.hash('hex');
|
var hash = tx.hash('hex');
|
||||||
var updated = false;
|
var updated = false;
|
||||||
var own = false;
|
var own = false;
|
||||||
|
var uniq = {};
|
||||||
var batch;
|
var batch;
|
||||||
|
|
||||||
var unlock = this._lock(add, [tx, callback], force);
|
// var unlock = this._lock(add, [tx, map, callback], force);
|
||||||
if (!unlock)
|
// if (!unlock)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
function done(err, result) {
|
function done(err, result) {
|
||||||
unlock();
|
//unlock();
|
||||||
if (callback)
|
if (callback)
|
||||||
callback(err, result);
|
callback(err, result);
|
||||||
};
|
};
|
||||||
@ -138,20 +218,16 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
if (input.isCoinbase())
|
if (input.isCoinbase())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
uaddr = address;
|
|
||||||
|
|
||||||
if (uaddr) {
|
|
||||||
if (!uniq[uaddr])
|
|
||||||
uniq[uaddr] = true;
|
|
||||||
else
|
|
||||||
uaddr = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uaddr)
|
if (uaddr) {
|
||||||
batch.del(p + 'p/a/' + uaddr + '/' + hash);
|
map[uaddr].forEach(function(id) {
|
||||||
|
batch.del(p + 'p/a/' + id + '/' + hash);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
||||||
@ -159,20 +235,16 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
var address = output.getAddress();
|
var address = output.getAddress();
|
||||||
var uaddr;
|
var uaddr;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
uaddr = address;
|
|
||||||
|
|
||||||
if (uaddr) {
|
|
||||||
if (!uniq[uaddr])
|
|
||||||
uniq[uaddr] = true;
|
|
||||||
else
|
|
||||||
uaddr = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uaddr)
|
if (uaddr) {
|
||||||
batch.del(p + 'p/a/' + uaddr + '/' + hash);
|
map[uaddr].forEach(function(id) {
|
||||||
|
batch.del(p + 'p/a/' + id + '/' + hash);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self.getCoin(hash, i, function(err, coin) {
|
self.getCoin(hash, i, function(err, coin) {
|
||||||
if (err)
|
if (err)
|
||||||
@ -210,8 +282,10 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
// Consume unspent money or add orphans
|
// Consume unspent money or add orphans
|
||||||
utils.forEachSerial(tx.inputs, function(input, next, i) {
|
utils.forEachSerial(tx.inputs, function(input, next, i) {
|
||||||
var key = input.prevout.hash + '/' + input.prevout.index;
|
var key = input.prevout.hash + '/' + input.prevout.index;
|
||||||
|
if (input.isCoinbase())
|
||||||
|
return next();
|
||||||
self.getCoin(input.prevout.hash, input.prevout.index, function(err, coin) {
|
self.getCoin(input.prevout.hash, input.prevout.index, function(err, coin) {
|
||||||
var type, address;
|
var type, address, uaddr;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return next(err);
|
return next(err);
|
||||||
@ -233,17 +307,26 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
type = input.getType();
|
type = input.getType();
|
||||||
address = input.getAddress();
|
address = input.getAddress();
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
if (input.isCoinbase())
|
}
|
||||||
return next();
|
|
||||||
|
|
||||||
if (address) {
|
if (address) {
|
||||||
batch.del(
|
map[address].forEach(function(id) {
|
||||||
p + 'u/a/' + address
|
batch.del(
|
||||||
+ '/' + input.prevout.hash
|
p + 'u/a/' + id
|
||||||
+ '/' + input.prevout.index);
|
+ '/' + input.prevout.hash
|
||||||
|
+ '/' + input.prevout.index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uaddr) {
|
||||||
|
map[uaddr].forEach(function(id) {
|
||||||
|
batch.put(p + 't/a/' + id + '/' + hash, new Buffer([]));
|
||||||
|
if (tx.ts === 0)
|
||||||
|
batch.put(p + 'p/a/' + id + '/' + hash, new Buffer([]));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.del(
|
batch.del(
|
||||||
@ -255,7 +338,7 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only add orphans if this input is ours.
|
// Only add orphans if this input is ours.
|
||||||
self._hasAddress(input.getAddress(), function(err, result) {
|
self.__hasAddress(map, input.getAddress(), function(err, result) {
|
||||||
if (err)
|
if (err)
|
||||||
return done(err);
|
return done(err);
|
||||||
|
|
||||||
@ -308,7 +391,7 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
// Add unspent outputs or resolve orphans
|
// Add unspent outputs or resolve orphans
|
||||||
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
||||||
// Do not add unspents for outputs that aren't ours.
|
// Do not add unspents for outputs that aren't ours.
|
||||||
self._hasAddress(output.getAddress(), function(err, result) {
|
self.__hasAddress(map, output.getAddress(), function(err, result) {
|
||||||
var key, coin;
|
var key, coin;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
@ -382,7 +465,7 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function finish(err) {
|
function finish(err) {
|
||||||
var type, adddress;
|
var type, adddress, uaddr;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return next(err);
|
return next(err);
|
||||||
@ -391,14 +474,26 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
type = output.getType();
|
type = output.getType();
|
||||||
address = output.getAddress();
|
address = output.getAddress();
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
|
}
|
||||||
|
|
||||||
if (address) {
|
if (address) {
|
||||||
batch.put(
|
map[address].forEach(function(id) {
|
||||||
p + 'u/a/' + address
|
batch.put(
|
||||||
+ '/' + hash + '/' + i,
|
p + 'u/a/' + id
|
||||||
new Buffer([]));
|
+ '/' + hash + '/' + i,
|
||||||
|
new Buffer([]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uaddr) {
|
||||||
|
map[uaddr].forEach(function(id) {
|
||||||
|
batch.put(p + 't/a/' + id + '/' + hash, new Buffer([]));
|
||||||
|
if (tx.ts === 0)
|
||||||
|
batch.put(p + 'p/a/' + id + '/' + hash, new Buffer([]));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.put(p + 'u/t/' + hash + '/' + i, coin.toRaw());
|
batch.put(p + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||||
@ -424,23 +519,17 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
else
|
else
|
||||||
batch.put(p + 't/h/' + tx.height + '/' + hash, new Buffer([]));
|
batch.put(p + 't/h/' + tx.height + '/' + hash, new Buffer([]));
|
||||||
|
|
||||||
tx.getAddresses().forEach(function(address) {
|
|
||||||
batch.put(p + 't/a/' + address + '/' + hash, new Buffer([]));
|
|
||||||
if (tx.ts === 0)
|
|
||||||
batch.put(p + 'p/a/' + address + '/' + hash, new Buffer([]));
|
|
||||||
});
|
|
||||||
|
|
||||||
batch.write(function(err) {
|
batch.write(function(err) {
|
||||||
if (err)
|
if (err)
|
||||||
return done(err);
|
return done(err);
|
||||||
|
|
||||||
self.emit('tx', tx);
|
self.emit('tx', tx, map);
|
||||||
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
if (tx.ts !== 0)
|
if (tx.ts !== 0)
|
||||||
self.emit('confirmed', tx);
|
self.emit('confirmed', tx, map);
|
||||||
|
|
||||||
self.emit('updated', tx);
|
self.emit('updated', tx, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
return done(null, true);
|
return done(null, true);
|
||||||
@ -452,12 +541,37 @@ TXPool.prototype._add = function add(tx, callback, force) {
|
|||||||
|
|
||||||
TXPool.prototype.remove = function remove(hash, callback) {
|
TXPool.prototype.remove = function remove(hash, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
if (Array.isArray(hash)) {
|
||||||
|
return utils.forEachSerial(hash, function(hash, next) {
|
||||||
|
self.remove(hash, next);
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash.hash)
|
||||||
|
hash = hash.hash('hex');
|
||||||
|
|
||||||
|
this.getTX(hash, function(err, tx) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
return self._getIDs(tx.getAddresses(), function(err, map) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
return self._remove(tx, map, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
TXPool.prototype._remove = function remove(hash, map, callback) {
|
||||||
|
var self = this;
|
||||||
var p = this.prefix + '/';
|
var p = this.prefix + '/';
|
||||||
var uniq = {};
|
var uniq = {};
|
||||||
|
|
||||||
if (hash.hash)
|
if (hash.hash)
|
||||||
hash = hash.hash('hex');
|
hash = hash.hash('hex');
|
||||||
|
|
||||||
|
// XXX Remove this
|
||||||
this.getTX(hash, function(err, tx) {
|
this.getTX(hash, function(err, tx) {
|
||||||
var batch;
|
var batch;
|
||||||
|
|
||||||
@ -489,29 +603,26 @@ TXPool.prototype.remove = function remove(hash, callback) {
|
|||||||
if (input.isCoinbase())
|
if (input.isCoinbase())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
uaddr = address;
|
|
||||||
|
|
||||||
if (uaddr) {
|
|
||||||
if (!uniq[uaddr])
|
|
||||||
uniq[uaddr] = true;
|
|
||||||
else
|
|
||||||
uaddr = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uaddr) {
|
if (uaddr) {
|
||||||
batch.del(p + 't/a/' + uaddr + '/' + hash);
|
map[uaddr].forEach(function(id) {
|
||||||
if (tx.ts === 0)
|
batch.del(p + 't/a/' + id + '/' + hash);
|
||||||
batch.del(p + 'p/a/' + uaddr + '/' + hash);
|
if (tx.ts === 0)
|
||||||
|
batch.del(p + 'p/a/' + id + '/' + hash);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address) {
|
if (address) {
|
||||||
batch.put(p + 'u/a/' + address
|
map[address].forEach(function(id) {
|
||||||
+ '/' + input.prevout.hash
|
batch.put(p + 'u/a/' + id
|
||||||
+ '/' + input.prevout.index,
|
+ '/' + input.prevout.hash
|
||||||
new Buffer([]));
|
+ '/' + input.prevout.index,
|
||||||
|
new Buffer([]));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.output) {
|
if (input.output) {
|
||||||
@ -529,26 +640,24 @@ TXPool.prototype.remove = function remove(hash, callback) {
|
|||||||
var address = output.getAddress();
|
var address = output.getAddress();
|
||||||
var uaddr;
|
var uaddr;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
uaddr = address;
|
|
||||||
|
|
||||||
if (uaddr) {
|
|
||||||
if (!uniq[uaddr])
|
|
||||||
uniq[uaddr] = true;
|
|
||||||
else
|
|
||||||
uaddr = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uaddr) {
|
if (uaddr) {
|
||||||
batch.del(p + 't/a/' + uaddr + '/' + hash);
|
map[uaddr].forEach(function(id) {
|
||||||
if (tx.ts === 0)
|
batch.del(p + 't/a/' + id + '/' + hash);
|
||||||
batch.del(p + 'p/a/' + uaddr + '/' + hash);
|
if (tx.ts === 0)
|
||||||
|
batch.del(p + 'p/a/' + id + '/' + hash);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address)
|
if (address) {
|
||||||
batch.del(p + 'u/a/' + address + '/' + hash + '/' + i);
|
map[address].forEach(function(id) {
|
||||||
|
batch.del(p + 'u/a/' + id + '/' + hash + '/' + i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
batch.del(p + 'u/t/' + hash + '/' + i);
|
batch.del(p + 'u/t/' + hash + '/' + i);
|
||||||
});
|
});
|
||||||
@ -566,12 +675,37 @@ TXPool.prototype.remove = function remove(hash, callback) {
|
|||||||
|
|
||||||
TXPool.prototype.unconfirm = function unconfirm(hash, callback) {
|
TXPool.prototype.unconfirm = function unconfirm(hash, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
if (Array.isArray(hash)) {
|
||||||
|
return utils.forEachSerial(hash, function(hash, next) {
|
||||||
|
self.unconfirm(hash, next);
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash.hash)
|
||||||
|
hash = hash.hash('hex');
|
||||||
|
|
||||||
|
this.getTX(hash, function(err, tx) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
return self._getIDs(tx.getAddresses(), function(err, map) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
return self._unconfirm(tx, map, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
TXPool.prototype._unconfirm = function unconfirm(hash, map, callback) {
|
||||||
|
var self = this;
|
||||||
var p = this.prefix + '/';
|
var p = this.prefix + '/';
|
||||||
var uniq = {};
|
var uniq = {};
|
||||||
|
|
||||||
if (hash.hash)
|
if (hash.hash)
|
||||||
hash = hash.hash('hex');
|
hash = hash.hash('hex');
|
||||||
|
|
||||||
|
// XXX Remove this.
|
||||||
this.getTX(hash, function(err, tx) {
|
this.getTX(hash, function(err, tx) {
|
||||||
var batch, height;
|
var batch, height;
|
||||||
|
|
||||||
@ -600,20 +734,16 @@ TXPool.prototype.unconfirm = function unconfirm(hash, callback) {
|
|||||||
if (input.isCoinbase())
|
if (input.isCoinbase())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
uaddr = address;
|
|
||||||
|
|
||||||
if (uaddr) {
|
|
||||||
if (!uniq[uaddr])
|
|
||||||
uniq[uaddr] = true;
|
|
||||||
else
|
|
||||||
uaddr = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uaddr)
|
if (uaddr) {
|
||||||
batch.put(p + 'p/a/' + uaddr + '/' + hash, new Buffer([]));
|
map[uaddr].forEach(function(id) {
|
||||||
|
batch.put(p + 'p/a/' + id + '/' + hash, new Buffer([]));
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
utils.forEachSerial(tx.outputs, function(output, next, i) {
|
||||||
@ -621,20 +751,16 @@ TXPool.prototype.unconfirm = function unconfirm(hash, callback) {
|
|||||||
var address = output.getAddress();
|
var address = output.getAddress();
|
||||||
var uaddr;
|
var uaddr;
|
||||||
|
|
||||||
if (type === 'pubkey' || type === 'multisig')
|
if (address && !uniq[address]) {
|
||||||
address = null;
|
uniq[address] = true;
|
||||||
|
uaddr = address;
|
||||||
uaddr = address;
|
|
||||||
|
|
||||||
if (uaddr) {
|
|
||||||
if (!uniq[uaddr])
|
|
||||||
uniq[uaddr] = true;
|
|
||||||
else
|
|
||||||
uaddr = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uaddr)
|
if (uaddr) {
|
||||||
batch.put(p + 'p/a/' + uaddr + '/' + hash, new Buffer([]));
|
map[uaddr].forEach(function(id) {
|
||||||
|
batch.put(p + 'p/a/' + id + '/' + hash, new Buffer([]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self.getCoin(hash, i, function(err, coin) {
|
self.getCoin(hash, i, function(err, coin) {
|
||||||
if (err)
|
if (err)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user