Merge pull request #305 from braydonf/bug/balance
Fixed bug with balance
This commit is contained in:
commit
93436429f1
|
@ -1048,8 +1048,12 @@ AddressService.prototype.getUnspentOutputsForAddress = function(address, queryMe
|
|||
return callback(new errors.NoOutputs('Address ' + address + ' has no outputs'), []);
|
||||
}
|
||||
|
||||
var opts = {
|
||||
queryMempool: queryMempool
|
||||
};
|
||||
|
||||
var isUnspent = function(output, callback) {
|
||||
self.isUnspent(output, callback);
|
||||
self.isUnspent(output, opts, callback);
|
||||
};
|
||||
|
||||
async.filter(outputs, isUnspent, function(results) {
|
||||
|
@ -1061,25 +1065,37 @@ AddressService.prototype.getUnspentOutputsForAddress = function(address, queryMe
|
|||
/**
|
||||
* Will give the inverse of isSpent
|
||||
* @param {Object} output
|
||||
* @param {Object} options
|
||||
* @param {Boolean} options.queryMempool - Include mempool in results
|
||||
* @param {Function} callback
|
||||
*/
|
||||
AddressService.prototype.isUnspent = function(output, callback) {
|
||||
this.isSpent(output, function(spent) {
|
||||
AddressService.prototype.isUnspent = function(output, options, callback) {
|
||||
$.checkArgument(_.isFunction(callback));
|
||||
this.isSpent(output, options, function(spent) {
|
||||
callback(!spent);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Will determine if an output is spent, results do not include the mempool.
|
||||
* Will determine if an output is spent.
|
||||
* @param {Object} output - An output as returned from getOutputs
|
||||
* @param {Object} options
|
||||
* @param {Boolean} options.queryMempool - Include mempool in results
|
||||
* @param {Function} callback
|
||||
*/
|
||||
AddressService.prototype.isSpent = function(output, callback) {
|
||||
AddressService.prototype.isSpent = function(output, options, callback) {
|
||||
$.checkArgument(_.isFunction(callback));
|
||||
var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool;
|
||||
var self = this;
|
||||
var txid = output.prevTxId ? output.prevTxId.toString('hex') : output.txid;
|
||||
|
||||
var spent = self.node.services.bitcoind.isSpent(txid, output.outputIndex);
|
||||
if (!spent && queryMempool) {
|
||||
var spentIndexKey = [txid, output.outputIndex].join('-');
|
||||
spent = self.mempoolSpentIndex[spentIndexKey] ? true : false;
|
||||
}
|
||||
setImmediate(function() {
|
||||
callback(self.node.services.bitcoind.isSpent(txid, output.outputIndex));
|
||||
// TODO error should be the first argument?
|
||||
callback(spent);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1179,7 +1195,7 @@ AddressService.prototype.getAddressSummary = function(address, options, callback
|
|||
var txids = [];
|
||||
|
||||
for(var i = 0; i < outputs.length; i++) {
|
||||
// Bitcoind's isSpent at the moment only works for confirmed transactions
|
||||
// Bitcoind's isSpent only works for confirmed transactions
|
||||
var spentDB = self.node.services.bitcoind.isSpent(outputs[i].txid, outputs[i].outputIndex);
|
||||
var spentIndexKey = [outputs[i].txid, outputs[i].outputIndex].join('-');
|
||||
var spentMempool = self.mempoolSpentIndex[spentIndexKey];
|
||||
|
|
|
@ -872,7 +872,7 @@ describe('Address Service', function() {
|
|||
|
||||
var am = new AddressService({node: mocknode});
|
||||
am.getOutputs = sinon.stub().callsArgWith(2, null, outputs);
|
||||
am.isUnspent = function(output, callback) {
|
||||
am.isUnspent = function(output, options, callback) {
|
||||
callback(!outputs[i].spent);
|
||||
i++;
|
||||
};
|
||||
|
@ -914,24 +914,24 @@ describe('Address Service', function() {
|
|||
});
|
||||
|
||||
it('should give true when isSpent() gives false', function(done) {
|
||||
am.isSpent = sinon.stub().callsArgWith(1, false);
|
||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', function(unspent) {
|
||||
am.isSpent = sinon.stub().callsArgWith(2, false);
|
||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', {}, function(unspent) {
|
||||
unspent.should.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should give false when isSpent() gives true', function(done) {
|
||||
am.isSpent = sinon.stub().callsArgWith(1, true);
|
||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', function(unspent) {
|
||||
am.isSpent = sinon.stub().callsArgWith(2, true);
|
||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', {},function(unspent) {
|
||||
unspent.should.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should give false when isSpent() returns an error', function(done) {
|
||||
am.isSpent = sinon.stub().callsArgWith(1, new Error('error'));
|
||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', function(unspent) {
|
||||
am.isSpent = sinon.stub().callsArgWith(2, new Error('error'));
|
||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', {}, function(unspent) {
|
||||
unspent.should.equal(false);
|
||||
done();
|
||||
});
|
||||
|
@ -939,7 +939,6 @@ describe('Address Service', function() {
|
|||
});
|
||||
|
||||
describe('#isSpent', function() {
|
||||
var am;
|
||||
var db = {};
|
||||
var testnode = {
|
||||
db: db,
|
||||
|
@ -949,16 +948,70 @@ describe('Address Service', function() {
|
|||
}
|
||||
}
|
||||
};
|
||||
before(function() {
|
||||
am = new AddressService({node: testnode});
|
||||
it('should give true if bitcoind.isSpent gives true', function(done) {
|
||||
var am = new AddressService({node: testnode});
|
||||
am.node.services.bitcoind = {
|
||||
isSpent: sinon.stub().returns(true),
|
||||
on: sinon.stub()
|
||||
};
|
||||
am.isSpent({}, {}, function(spent) {
|
||||
spent.should.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should give true if bitcoind.isSpent gives true', function(done) {
|
||||
am.isSpent('output', function(spent) {
|
||||
it('should give true if bitcoind.isSpent is false and mempoolSpentIndex is true', function(done) {
|
||||
var am = new AddressService({node: testnode});
|
||||
am.node.services.bitcoind = {
|
||||
isSpent: sinon.stub().returns(false),
|
||||
on: sinon.stub()
|
||||
};
|
||||
var txid = '3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae7';
|
||||
var outputIndex = 0;
|
||||
var output = {
|
||||
prevTxId: new Buffer(txid, 'hex'),
|
||||
outputIndex: outputIndex
|
||||
};
|
||||
var spentKey = [txid, outputIndex].join('-');
|
||||
am.mempoolSpentIndex[spentKey] = new Buffer(5);
|
||||
am.isSpent(output, {queryMempool: true}, function(spent) {
|
||||
spent.should.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should give false if spent in mempool with queryMempool set to false', function(done) {
|
||||
var am = new AddressService({node: testnode});
|
||||
am.node.services.bitcoind = {
|
||||
isSpent: sinon.stub().returns(false),
|
||||
on: sinon.stub()
|
||||
};
|
||||
var txid = '3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae7';
|
||||
var outputIndex = 0;
|
||||
var output = {
|
||||
prevTxId: new Buffer(txid, 'hex'),
|
||||
outputIndex: outputIndex
|
||||
};
|
||||
var spentKey = [txid, outputIndex].join('-');
|
||||
am.mempoolSpentIndex[spentKey] = new Buffer(5);
|
||||
am.isSpent(output, {queryMempool: false}, function(spent) {
|
||||
spent.should.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('default to querying the mempool', function(done) {
|
||||
var am = new AddressService({node: testnode});
|
||||
am.node.services.bitcoind = {
|
||||
isSpent: sinon.stub().returns(false),
|
||||
on: sinon.stub()
|
||||
};
|
||||
var txid = '3b6bc2939d1a70ce04bc4f619ee32608fbff5e565c1f9b02e4eaa97959c59ae7';
|
||||
var outputIndex = 0;
|
||||
var output = {
|
||||
prevTxId: new Buffer(txid, 'hex'),
|
||||
outputIndex: outputIndex
|
||||
};
|
||||
var spentKey = [txid, outputIndex].join('-');
|
||||
am.mempoolSpentIndex[spentKey] = new Buffer(5);
|
||||
am.isSpent(output, {}, function(spent) {
|
||||
spent.should.equal(true);
|
||||
done();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue