Address History: Include count in response results.

This commit is contained in:
Braydon Fuller 2015-09-15 13:17:15 -04:00
parent 696759849f
commit bfba4a1b7f
6 changed files with 66 additions and 114 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
node_modules/
node_modules/*
coverage/*
out/
out/*
build/

View File

@ -278,8 +278,9 @@ describe('Node Functionality', function() {
if (err) {
throw err;
}
results.length.should.equal(1);
var info = results[0];
var items = results.items;
items.length.should.equal(1);
var info = items[0];
should.exist(info.addresses[address]);
info.addresses[address].outputIndexes.length.should.equal(1);
info.addresses[address].outputIndexes[0].should.be.within(0, 1);
@ -419,10 +420,12 @@ describe('Node Functionality', function() {
address6
];
var options = {};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
node.services.address.getAddressHistory(addresses, options, function(err, results) {
if (err) {
throw err;
}
results.totalCount.should.equal(4);
var history = results.items;
history.length.should.equal(4);
history[0].height.should.equal(157);
history[0].confirmations.should.equal(1);
@ -450,10 +453,12 @@ describe('Node Functionality', function() {
start: 157,
end: 156
};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
node.services.address.getAddressHistory(addresses, options, function(err, results) {
if (err) {
throw err;
}
results.totalCount.should.equal(2);
var history = results.items;
history.length.should.equal(2);
history[0].height.should.equal(157);
history[0].confirmations.should.equal(1);
@ -475,10 +480,12 @@ describe('Node Functionality', function() {
start: 155,
end: 154
};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
node.services.address.getAddressHistory(addresses, options, function(err, results) {
if (err) {
throw err;
}
results.totalCount.should.equal(2);
var history = results.items;
history.length.should.equal(2);
history[0].height.should.equal(155);
history[1].height.should.equal(154);
@ -498,10 +505,12 @@ describe('Node Functionality', function() {
from: 0,
to: 3
};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
node.services.address.getAddressHistory(addresses, options, function(err, results) {
if (err) {
throw err;
}
results.totalCount.should.equal(4);
var history = results.items;
history.length.should.equal(3);
history[0].height.should.equal(157);
history[0].confirmations.should.equal(1);
@ -516,10 +525,12 @@ describe('Node Functionality', function() {
address
];
var options = {};
node.services.address.getAddressHistory(addresses, options, function(err, history) {
node.services.address.getAddressHistory(addresses, options, function(err, results) {
if (err) {
throw err;
}
results.totalCount.should.equal(6);
var history = results.items;
history.length.should.equal(6);
history[0].height.should.equal(157);
history[0].addresses[address].inputIndexes.should.deep.equal([0, 1]);
@ -543,11 +554,11 @@ describe('Node Functionality', function() {
address
];
var options = {};
node.services.address.getAddressHistoryCount(addresses, options, function(err, count) {
node.services.address.getAddressHistory(addresses, options, function(err, results) {
if (err) {
throw err;
}
count.should.equal(6);
results.totalCount.should.equal(6);
done();
});
});
@ -558,10 +569,11 @@ describe('Node Functionality', function() {
from: 0,
to: 1
};
node.services.address.getAddressHistory(address, options, function(err, history) {
node.services.address.getAddressHistory(address, options, function(err, results) {
if (err) {
throw err;
}
var history = results.items;
history.length.should.equal(1);
history[0].height.should.equal(157);
done();
@ -572,10 +584,11 @@ describe('Node Functionality', function() {
from: 1,
to: 2
};
node.services.address.getAddressHistory(address, options, function(err, history) {
node.services.address.getAddressHistory(address, options, function(err, results) {
if (err) {
throw err;
}
var history = results.items;
history.length.should.equal(1);
history[0].height.should.equal(156);
done();
@ -586,10 +599,11 @@ describe('Node Functionality', function() {
from: 2,
to: 3
};
node.services.address.getAddressHistory(address, options, function(err, history) {
node.services.address.getAddressHistory(address, options, function(err, results) {
if (err) {
throw err;
}
var history = results.items;
history.length.should.equal(1);
history[0].height.should.equal(155);
done();
@ -600,10 +614,11 @@ describe('Node Functionality', function() {
from: 3,
to: 4
};
node.services.address.getAddressHistory(address, options, function(err, history) {
node.services.address.getAddressHistory(address, options, function(err, results) {
if (err) {
throw err;
}
var history = results.items;
history.length.should.equal(1);
history[0].height.should.equal(154);
done();
@ -614,10 +629,11 @@ describe('Node Functionality', function() {
from: 4,
to: 5
};
node.services.address.getAddressHistory(address, options, function(err, history) {
node.services.address.getAddressHistory(address, options, function(err, results) {
if (err) {
throw err;
}
var history = results.items;
history.length.should.equal(1);
history[0].height.should.equal(153);
history[0].satoshis.should.equal(-10000);
@ -631,10 +647,11 @@ describe('Node Functionality', function() {
from: 5,
to: 6
};
node.services.address.getAddressHistory(address, options, function(err, history) {
node.services.address.getAddressHistory(address, options, function(err, results) {
if (err) {
throw err;
}
var history = results.items;
history.length.should.equal(1);
history[0].height.should.equal(150);
history[0].satoshis.should.equal(10 * 1e8);

View File

@ -27,27 +27,9 @@ function AddressHistory(args) {
AddressHistory.MAX_ADDRESS_QUERIES = 20;
AddressHistory.prototype.getCount = function(callback) {
var self = this;
async.eachLimit(
self.addresses,
AddressHistory.MAX_ADDRESS_QUERIES,
function(address, next) {
self.getTransactionInfo(address, next);
},
function(err) {
if (err) {
return callback(err);
}
self.combineTransactionInfo();
callback(null, self.combinedArray.length);
}
);
};
AddressHistory.prototype.get = function(callback) {
var self = this;
var totalCount;
// TODO check for mempool inputs and outputs by a group of addresses, currently
// each address individually loops through the mempool and does not check input scripts.
@ -64,6 +46,7 @@ AddressHistory.prototype.get = function(callback) {
}
self.combineTransactionInfo();
totalCount = Number(self.combinedArray.length);
self.sortAndPaginateCombinedArray();
async.eachSeries(
@ -75,7 +58,10 @@ AddressHistory.prototype.get = function(callback) {
if (err) {
return callback(err);
}
callback(null, self.detailedArray);
callback(null, {
totalCount: totalCount,
items: self.detailedArray
});
}
);
}

View File

@ -48,8 +48,7 @@ AddressService.prototype.getAPIMethods = function() {
['getOutputs', this, this.getOutputs, 2],
['getUnspentOutputs', this, this.getUnspentOutputs, 2],
['isSpent', this, this.isSpent, 2],
['getAddressHistory', this, this.getAddressHistory, 2],
['getAddressHistoryCount', this, this.getAddressHistoryCount, 2]
['getAddressHistory', this, this.getAddressHistory, 2]
];
};
@ -732,28 +731,30 @@ AddressService.prototype.isSpent = function(output, queryMempool, callback) {
});
};
/**
* This will give the total count of transactions for a single or several addresses
* limited by a range of block heights.
* @param {Array} addresses - An array of addresses
* @param {Object} options - The options to limit the query
* @param {Number} [options.start] - The beginning block height (e.g. 1500 the most recent block height).
* @param {Number} [options.end] - The ending block height (e.g. 0 the older block height, results are inclusive).
* @param {Boolean} [options.queryMempool] - Include the mempool in the query
* @param {Function} callback
*/
AddressService.prototype.getAddressHistoryCount = function(addresses, options, callback) {
var history = new AddressHistory({
node: this.node,
options: options,
addresses: addresses
});
history.getCount(callback);
};
/**
* This will give the history for many addresses limited by a range of block heights (to limit
* the database lookup times) and/or paginated to limit the results length.
*
* The response format will be:
* {
* totalCount: 12 // the total number of items there are between the two heights
* items: [
* {
* addresses: {
* '12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX': {
* inputIndexes: [],
* outputIndexes: [0]
* }
* },
* satoshis: 100,
* height: 300000,
* confirmations: 1,
* timestamp: 1442337090 // in seconds
* fees: 1000 // in satoshis
* tx: <Transaction>
* }
* ]
* }
* @param {Array} addresses - An array of addresses
* @param {Object} options - The options to limit the query
* @param {Number} [options.from] - The pagination "from" index

View File

@ -37,43 +37,6 @@ describe('Address Service History', function() {
});
});
describe('#getCount', function() {
it('will complete the async each limit series', function(done) {
var addresses = [address];
var history = new AddressHistory({
node: {},
options: {},
addresses: addresses
});
history.getTransactionInfo = sinon.stub().callsArg(1);
history.combineTransactionInfo = sinon.stub();
history.get(function(err, results) {
if (err) {
throw err;
}
history.getTransactionInfo.callCount.should.equal(1);
history.combineTransactionInfo.callCount.should.equal(1);
done();
});
});
it('handle an error from getTransactionInfo', function(done) {
var addresses = [address];
var history = new AddressHistory({
node: {},
options: {},
addresses: addresses
});
var expected = [{}];
history.sortedArray = expected;
history.transactionInfo = [{}];
history.getTransactionInfo = sinon.stub().callsArgWith(1, new Error('test'));
history.get(function(err) {
err.message.should.equal('test');
done();
});
});
});
describe('#get', function() {
it('will complete the async each limit series', function(done) {
var addresses = [address];
@ -98,7 +61,10 @@ describe('Address Service History', function() {
history.getDetailedInfo.callCount.should.equal(1);
history.combineTransactionInfo.callCount.should.equal(1);
history.sortAndPaginateCombinedArray.callCount.should.equal(1);
results.should.equal(expected);
results.should.deep.equal({
totalCount: 1,
items: expected
});
done();
});
});

View File

@ -29,7 +29,7 @@ describe('Address Service', function() {
it('should return the correct methods', function() {
var am = new AddressService({node: mocknode});
var methods = am.getAPIMethods();
methods.length.should.equal(6);
methods.length.should.equal(5);
});
});
@ -857,25 +857,6 @@ describe('Address Service', function() {
});
});
describe('#getAddressHistoryCount', function() {
it('will call getCount on address history instance', function(done) {
function TestAddressHistory(args) {
args.node.should.equal(mocknode);
args.addresses.should.deep.equal([]);
args.options.should.deep.equal({});
}
TestAddressHistory.prototype.getCount = sinon.stub().callsArg(0);
var TestAddressService = proxyquire('../../../lib/services/address', {
'./history': TestAddressHistory
});
var am = new TestAddressService({node: mocknode});
am.getAddressHistoryCount([], {}, function(err, history) {
TestAddressHistory.prototype.getCount.callCount.should.equal(1);
done();
});
});
});
describe('#getAddressHistory', function() {
it('will call get on address history instance', function(done) {
function TestAddressHistory(args) {