add noBalance options + mempoolAddressIndex
This commit is contained in:
parent
6a899e4b9c
commit
e7e33313cf
@ -44,6 +44,7 @@ function AddressHistory(args) {
|
|||||||
AddressHistory.prototype._mergeAndSortTxids = function(summaries) {
|
AddressHistory.prototype._mergeAndSortTxids = function(summaries) {
|
||||||
var appearanceIds = {};
|
var appearanceIds = {};
|
||||||
var unconfirmedAppearanceIds = {};
|
var unconfirmedAppearanceIds = {};
|
||||||
|
|
||||||
for (var i = 0; i < summaries.length; i++) {
|
for (var i = 0; i < summaries.length; i++) {
|
||||||
var summary = summaries[i];
|
var summary = summaries[i];
|
||||||
for (var key in summary.appearanceIds) {
|
for (var key in summary.appearanceIds) {
|
||||||
@ -79,6 +80,8 @@ AddressHistory.prototype.get = function(callback) {
|
|||||||
return callback(new TypeError('Maximum number of addresses (' + this.maxAddressesQuery + ') exceeded'));
|
return callback(new TypeError('Maximum number of addresses (' + this.maxAddressesQuery + ') exceeded'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.options.noBalance = true;
|
||||||
|
|
||||||
if (this.addresses.length === 1) {
|
if (this.addresses.length === 1) {
|
||||||
var address = this.addresses[0];
|
var address = this.addresses[0];
|
||||||
self.node.services.address.getAddressSummary(address, this.options, function(err, summary) {
|
self.node.services.address.getAddressSummary(address, this.options, function(err, summary) {
|
||||||
@ -89,10 +92,11 @@ AddressHistory.prototype.get = function(callback) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var opts = _.clone(this.options);
|
var opts = _.clone(this.options);
|
||||||
|
|
||||||
opts.fullTxList = true;
|
opts.fullTxList = true;
|
||||||
async.mapLimit(
|
async.mapLimit(
|
||||||
self.addresses,
|
self.addresses,
|
||||||
self.maxAddressesLimit,
|
self.maxaddressesLimit,
|
||||||
function(address, next) {
|
function(address, next) {
|
||||||
self.node.services.address.getAddressSummary(address, opts, next);
|
self.node.services.address.getAddressSummary(address, opts, next);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -57,6 +57,7 @@ var AddressService = function(options) {
|
|||||||
}
|
}
|
||||||
this.mempoolIndex = null; // Used for larger mempool indexes
|
this.mempoolIndex = null; // Used for larger mempool indexes
|
||||||
this.mempoolSpentIndex = {}; // Used for small quick synchronous lookups
|
this.mempoolSpentIndex = {}; // Used for small quick synchronous lookups
|
||||||
|
this.mempoolAddressIndex = {}; // Used to check if an address is on the spend pool
|
||||||
};
|
};
|
||||||
|
|
||||||
inherits(AddressService, BaseService);
|
inherits(AddressService, BaseService);
|
||||||
@ -70,6 +71,7 @@ AddressService.prototype.start = function(callback) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
|
|
||||||
function(next) {
|
function(next) {
|
||||||
// Flush any existing mempool index
|
// Flush any existing mempool index
|
||||||
if (fs.existsSync(self.mempoolIndexPath)) {
|
if (fs.existsSync(self.mempoolIndexPath)) {
|
||||||
@ -88,8 +90,7 @@ AddressService.prototype.start = function(callback) {
|
|||||||
},
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
self.mempoolIndex = levelup(
|
self.mempoolIndex = levelup(
|
||||||
self.mempoolIndexPath,
|
self.mempoolIndexPath, {
|
||||||
{
|
|
||||||
db: self.levelupStore,
|
db: self.levelupStore,
|
||||||
keyEncoding: 'binary',
|
keyEncoding: 'binary',
|
||||||
valueEncoding: 'binary',
|
valueEncoding: 'binary',
|
||||||
@ -154,20 +155,17 @@ AddressService.prototype.getAPIMethods = function() {
|
|||||||
* Called by the Bus to get the available events for this service.
|
* Called by the Bus to get the available events for this service.
|
||||||
*/
|
*/
|
||||||
AddressService.prototype.getPublishEvents = function() {
|
AddressService.prototype.getPublishEvents = function() {
|
||||||
return [
|
return [{
|
||||||
{
|
|
||||||
name: 'address/transaction',
|
name: 'address/transaction',
|
||||||
scope: this,
|
scope: this,
|
||||||
subscribe: this.subscribe.bind(this, 'address/transaction'),
|
subscribe: this.subscribe.bind(this, 'address/transaction'),
|
||||||
unsubscribe: this.unsubscribe.bind(this, 'address/transaction')
|
unsubscribe: this.unsubscribe.bind(this, 'address/transaction')
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: 'address/balance',
|
name: 'address/balance',
|
||||||
scope: this,
|
scope: this,
|
||||||
subscribe: this.subscribe.bind(this, 'address/balance'),
|
subscribe: this.subscribe.bind(this, 'address/balance'),
|
||||||
unsubscribe: this.unsubscribe.bind(this, 'address/balance')
|
unsubscribe: this.unsubscribe.bind(this, 'address/balance')
|
||||||
}
|
}];
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -305,6 +303,14 @@ AddressService.prototype.updateMempoolIndex = function(tx, add, callback) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hashBufferHex = addressInfo.hashBuffer.toString('hex');
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
this.mempoolAddressIndex[hashBufferHex] = true;
|
||||||
|
} else {
|
||||||
|
delete this.mempoolAddressIndex[hashBufferHex];
|
||||||
|
}
|
||||||
|
|
||||||
// Update output index
|
// Update output index
|
||||||
var outputIndexBuffer = new Buffer(4);
|
var outputIndexBuffer = new Buffer(4);
|
||||||
outputIndexBuffer.writeUInt32BE(outputIndex);
|
outputIndexBuffer.writeUInt32BE(outputIndex);
|
||||||
@ -397,6 +403,12 @@ AddressService.prototype.updateMempoolIndex = function(tx, add, callback) {
|
|||||||
value: inputValue
|
value: inputValue
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var inputHashBufferHex = inputHashBuffer.toString('hex');
|
||||||
|
if (add) {
|
||||||
|
this.mempoolAddressIndex[inputHashBufferHex] = true;
|
||||||
|
} else {
|
||||||
|
delete this.mempoolAddressIndex[inputHashBufferHex];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
@ -1208,7 +1220,9 @@ AddressService.prototype.getUnspentOutputsForAddress = function(address, queryMe
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.getOutputs(address, {queryMempool: queryMempool}, function(err, outputs) {
|
this.getOutputs(address, {
|
||||||
|
queryMempool: queryMempool
|
||||||
|
}, function(err, outputs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
} else if (!outputs.length) {
|
} else if (!outputs.length) {
|
||||||
@ -1336,6 +1350,7 @@ AddressService.prototype.getAddressSummary = function(addressArg, options, callb
|
|||||||
}
|
}
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
|
||||||
function(next) {
|
function(next) {
|
||||||
self._getAddressConfirmedSummary(address, options, next);
|
self._getAddressConfirmedSummary(address, options, next);
|
||||||
},
|
},
|
||||||
@ -1357,9 +1372,7 @@ AddressService.prototype.getAddressSummary = function(addressArg, options, callb
|
|||||||
var seconds = Math.round(timeDelta / 1000);
|
var seconds = Math.round(timeDelta / 1000);
|
||||||
log.warn('Slow (' + seconds + 's) getAddressSummary request for address: ' + address.toString());
|
log.warn('Slow (' + seconds + 's) getAddressSummary request for address: ' + address.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(null, summary);
|
callback(null, summary);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -1375,6 +1388,7 @@ AddressService.prototype._getAddressConfirmedSummary = function(address, options
|
|||||||
};
|
};
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
|
||||||
function(next) {
|
function(next) {
|
||||||
self._getAddressConfirmedInputsSummary(address, baseResult, options, next);
|
self._getAddressConfirmedInputsSummary(address, baseResult, options, next);
|
||||||
},
|
},
|
||||||
@ -1434,6 +1448,7 @@ AddressService.prototype._getAddressConfirmedOutputsSummary = function(address,
|
|||||||
var txid = output.txid;
|
var txid = output.txid;
|
||||||
var outputIndex = output.outputIndex;
|
var outputIndex = output.outputIndex;
|
||||||
|
|
||||||
|
if (!options.noBalance) {
|
||||||
// Bitcoind's isSpent only works for confirmed transactions
|
// Bitcoind's isSpent only works for confirmed transactions
|
||||||
var spentDB = self.node.services.bitcoind.isSpent(txid, outputIndex);
|
var spentDB = self.node.services.bitcoind.isSpent(txid, outputIndex);
|
||||||
result.totalReceived += output.satoshis;
|
result.totalReceived += output.satoshis;
|
||||||
@ -1455,6 +1470,7 @@ AddressService.prototype._getAddressConfirmedOutputsSummary = function(address,
|
|||||||
result.unconfirmedBalance -= output.satoshis;
|
result.unconfirmedBalance -= output.satoshis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
@ -1504,8 +1520,14 @@ AddressService.prototype._getAddressMempoolSummary = function(address, options,
|
|||||||
var addressStr = address.toString();
|
var addressStr = address.toString();
|
||||||
var hashBuffer = address.hashBuffer;
|
var hashBuffer = address.hashBuffer;
|
||||||
var hashTypeBuffer = constants.HASH_TYPES_MAP[address.type];
|
var hashTypeBuffer = constants.HASH_TYPES_MAP[address.type];
|
||||||
|
var hashBufferHex = hashBuffer.toString('hex');
|
||||||
|
|
||||||
|
if (!this.mempoolAddressIndex[hashBufferHex]) {
|
||||||
|
return callback(null, result);
|
||||||
|
}
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
|
||||||
function(next) {
|
function(next) {
|
||||||
self._getInputsMempool(addressStr, hashBuffer, hashTypeBuffer, function(err, mempoolInputs) {
|
self._getInputsMempool(addressStr, hashBuffer, hashTypeBuffer, function(err, mempoolInputs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -1518,11 +1540,13 @@ AddressService.prototype._getAddressMempoolSummary = function(address, options,
|
|||||||
next(null, result);
|
next(null, result);
|
||||||
});
|
});
|
||||||
|
|
||||||
}, function(result, next) {
|
},
|
||||||
|
function(result, next) {
|
||||||
self._getOutputsMempool(addressStr, hashBuffer, hashTypeBuffer, function(err, mempoolOutputs) {
|
self._getOutputsMempool(addressStr, hashBuffer, hashTypeBuffer, function(err, mempoolOutputs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
if (!options.noBalance) {
|
||||||
for (var i = 0; i < mempoolOutputs.length; i++) {
|
for (var i = 0; i < mempoolOutputs.length; i++) {
|
||||||
var output = mempoolOutputs[i];
|
var output = mempoolOutputs[i];
|
||||||
|
|
||||||
@ -1538,6 +1562,7 @@ AddressService.prototype._getAddressMempoolSummary = function(address, options,
|
|||||||
result.unconfirmedBalance += output.satoshis;
|
result.unconfirmedBalance += output.satoshis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
next(null, result);
|
next(null, result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user