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'), []);
|
return callback(new errors.NoOutputs('Address ' + address + ' has no outputs'), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
queryMempool: queryMempool
|
||||||
|
};
|
||||||
|
|
||||||
var isUnspent = function(output, callback) {
|
var isUnspent = function(output, callback) {
|
||||||
self.isUnspent(output, callback);
|
self.isUnspent(output, opts, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
async.filter(outputs, isUnspent, function(results) {
|
async.filter(outputs, isUnspent, function(results) {
|
||||||
@ -1061,25 +1065,37 @@ AddressService.prototype.getUnspentOutputsForAddress = function(address, queryMe
|
|||||||
/**
|
/**
|
||||||
* Will give the inverse of isSpent
|
* Will give the inverse of isSpent
|
||||||
* @param {Object} output
|
* @param {Object} output
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {Boolean} options.queryMempool - Include mempool in results
|
||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
AddressService.prototype.isUnspent = function(output, callback) {
|
AddressService.prototype.isUnspent = function(output, options, callback) {
|
||||||
this.isSpent(output, function(spent) {
|
$.checkArgument(_.isFunction(callback));
|
||||||
|
this.isSpent(output, options, function(spent) {
|
||||||
callback(!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} output - An output as returned from getOutputs
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {Boolean} options.queryMempool - Include mempool in results
|
||||||
* @param {Function} callback
|
* @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 self = this;
|
||||||
var txid = output.prevTxId ? output.prevTxId.toString('hex') : output.txid;
|
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() {
|
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 = [];
|
var txids = [];
|
||||||
|
|
||||||
for(var i = 0; i < outputs.length; i++) {
|
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 spentDB = self.node.services.bitcoind.isSpent(outputs[i].txid, outputs[i].outputIndex);
|
||||||
var spentIndexKey = [outputs[i].txid, outputs[i].outputIndex].join('-');
|
var spentIndexKey = [outputs[i].txid, outputs[i].outputIndex].join('-');
|
||||||
var spentMempool = self.mempoolSpentIndex[spentIndexKey];
|
var spentMempool = self.mempoolSpentIndex[spentIndexKey];
|
||||||
|
|||||||
@ -872,7 +872,7 @@ describe('Address Service', function() {
|
|||||||
|
|
||||||
var am = new AddressService({node: mocknode});
|
var am = new AddressService({node: mocknode});
|
||||||
am.getOutputs = sinon.stub().callsArgWith(2, null, outputs);
|
am.getOutputs = sinon.stub().callsArgWith(2, null, outputs);
|
||||||
am.isUnspent = function(output, callback) {
|
am.isUnspent = function(output, options, callback) {
|
||||||
callback(!outputs[i].spent);
|
callback(!outputs[i].spent);
|
||||||
i++;
|
i++;
|
||||||
};
|
};
|
||||||
@ -914,24 +914,24 @@ describe('Address Service', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should give true when isSpent() gives false', function(done) {
|
it('should give true when isSpent() gives false', function(done) {
|
||||||
am.isSpent = sinon.stub().callsArgWith(1, false);
|
am.isSpent = sinon.stub().callsArgWith(2, false);
|
||||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', function(unspent) {
|
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', {}, function(unspent) {
|
||||||
unspent.should.equal(true);
|
unspent.should.equal(true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should give false when isSpent() gives true', function(done) {
|
it('should give false when isSpent() gives true', function(done) {
|
||||||
am.isSpent = sinon.stub().callsArgWith(1, true);
|
am.isSpent = sinon.stub().callsArgWith(2, true);
|
||||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', function(unspent) {
|
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', {},function(unspent) {
|
||||||
unspent.should.equal(false);
|
unspent.should.equal(false);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should give false when isSpent() returns an error', function(done) {
|
it('should give false when isSpent() returns an error', function(done) {
|
||||||
am.isSpent = sinon.stub().callsArgWith(1, new Error('error'));
|
am.isSpent = sinon.stub().callsArgWith(2, new Error('error'));
|
||||||
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', function(unspent) {
|
am.isUnspent('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', {}, function(unspent) {
|
||||||
unspent.should.equal(false);
|
unspent.should.equal(false);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@ -939,7 +939,6 @@ describe('Address Service', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#isSpent', function() {
|
describe('#isSpent', function() {
|
||||||
var am;
|
|
||||||
var db = {};
|
var db = {};
|
||||||
var testnode = {
|
var testnode = {
|
||||||
db: db,
|
db: db,
|
||||||
@ -949,16 +948,70 @@ describe('Address Service', function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
before(function() {
|
it('should give true if bitcoind.isSpent gives true', function(done) {
|
||||||
am = new AddressService({node: testnode});
|
var am = new AddressService({node: testnode});
|
||||||
am.node.services.bitcoind = {
|
am.node.services.bitcoind = {
|
||||||
isSpent: sinon.stub().returns(true),
|
isSpent: sinon.stub().returns(true),
|
||||||
on: sinon.stub()
|
on: sinon.stub()
|
||||||
};
|
};
|
||||||
|
am.isSpent({}, {}, function(spent) {
|
||||||
|
spent.should.equal(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
it('should give true if bitcoind.isSpent is false and mempoolSpentIndex is true', function(done) {
|
||||||
it('should give true if bitcoind.isSpent gives true', function(done) {
|
var am = new AddressService({node: testnode});
|
||||||
am.isSpent('output', function(spent) {
|
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);
|
spent.should.equal(true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user