Address Service: Updated tests and fixed various bugs
This commit is contained in:
parent
ead6c2f45f
commit
e79c00db10
@ -50,7 +50,7 @@ AddressHistory.prototype._mergeAndSortTxids = function(summaries) {
|
|||||||
delete summary.appearanceIds[key];
|
delete summary.appearanceIds[key];
|
||||||
}
|
}
|
||||||
for (var unconfirmedKey in summary.unconfirmedAppearanceIds) {
|
for (var unconfirmedKey in summary.unconfirmedAppearanceIds) {
|
||||||
unconfirmedAppearanceIds[unconfirmedKey] = summary.unconfirmedAppearanceIds[key];
|
unconfirmedAppearanceIds[unconfirmedKey] = summary.unconfirmedAppearanceIds[unconfirmedKey];
|
||||||
delete summary.unconfirmedAppearanceIds[key];
|
delete summary.unconfirmedAppearanceIds[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,8 +74,6 @@ AddressHistory.prototype._mergeAndSortTxids = function(summaries) {
|
|||||||
*/
|
*/
|
||||||
AddressHistory.prototype.get = function(callback) {
|
AddressHistory.prototype.get = function(callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var totalCount;
|
|
||||||
|
|
||||||
if (this.addresses.length > this.maxAddressesQuery) {
|
if (this.addresses.length > this.maxAddressesQuery) {
|
||||||
return callback(new Error('Maximum number of addresses (' + this.maxAddressQuery + ') exceeded'));
|
return callback(new Error('Maximum number of addresses (' + this.maxAddressQuery + ') exceeded'));
|
||||||
}
|
}
|
||||||
@ -86,7 +84,7 @@ AddressHistory.prototype.get = function(callback) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
return finish(summary.txids);
|
return self.finish.call(self, summary.txids, callback);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var opts = _.clone(this.options);
|
var opts = _.clone(this.options);
|
||||||
@ -101,53 +99,54 @@ AddressHistory.prototype.get = function(callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
var txids = self._mergeAndSortTxids(summaries);
|
var txids = self._mergeAndSortTxids(summaries);
|
||||||
return finish(txids);
|
return self.finish.call(self, txids, callback);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function finish(allTxids) {
|
};
|
||||||
totalCount = allTxids.length;
|
|
||||||
|
|
||||||
// Slice the page starting with the most recent
|
AddressHistory.prototype.finish = function(allTxids, callback) {
|
||||||
var txids;
|
var self = this;
|
||||||
if (self.options.from >= 0 && self.options.to >= 0) {
|
var totalCount = allTxids.length;
|
||||||
var fromOffset = totalCount - self.options.from;
|
|
||||||
var toOffset = totalCount - self.options.to;
|
|
||||||
txids = allTxids.slice(toOffset, fromOffset);
|
|
||||||
} else {
|
|
||||||
txids = allTxids;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that this query isn't too long
|
|
||||||
if (txids.length > self.maxHistoryQueryLength) {
|
|
||||||
return callback(new Error(
|
|
||||||
'Maximum length query (' + self.maxAddressQueryLength + ') exceeded for addresses:' +
|
|
||||||
self.address.join(',')
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse to include most recent at the top
|
|
||||||
txids.reverse();
|
|
||||||
|
|
||||||
async.eachSeries(
|
|
||||||
txids,
|
|
||||||
function(txid, next) {
|
|
||||||
self.getDetailedInfo(txid, next);
|
|
||||||
},
|
|
||||||
function(err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
callback(null, {
|
|
||||||
totalCount: totalCount,
|
|
||||||
items: self.detailedArray
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Slice the page starting with the most recent
|
||||||
|
var txids;
|
||||||
|
if (self.options.from >= 0 && self.options.to >= 0) {
|
||||||
|
var fromOffset = totalCount - self.options.from;
|
||||||
|
var toOffset = totalCount - self.options.to;
|
||||||
|
txids = allTxids.slice(toOffset, fromOffset);
|
||||||
|
} else {
|
||||||
|
txids = allTxids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that this query isn't too long
|
||||||
|
if (txids.length > self.maxHistoryQueryLength) {
|
||||||
|
return callback(new Error(
|
||||||
|
'Maximum length query (' + self.maxAddressQueryLength + ') exceeded for addresses:' +
|
||||||
|
self.address.join(',')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse to include most recent at the top
|
||||||
|
txids.reverse();
|
||||||
|
|
||||||
|
async.eachSeries(
|
||||||
|
txids,
|
||||||
|
function(txid, next) {
|
||||||
|
self.getDetailedInfo(txid, next);
|
||||||
|
},
|
||||||
|
function(err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
callback(null, {
|
||||||
|
totalCount: totalCount,
|
||||||
|
items: self.detailedArray
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -760,6 +760,11 @@ AddressService.prototype.createInputsStream = function(addressStr, options) {
|
|||||||
inputStream.end();
|
inputStream.end();
|
||||||
}).pipe(inputStream);
|
}).pipe(inputStream);
|
||||||
|
|
||||||
|
|
||||||
|
inputStream.on('end', function() {
|
||||||
|
stream.end();
|
||||||
|
});
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -976,6 +981,10 @@ AddressService.prototype.createOutputsStream = function(addressStr, options) {
|
|||||||
})
|
})
|
||||||
.pipe(outputStream);
|
.pipe(outputStream);
|
||||||
|
|
||||||
|
outputStream.on('end', function() {
|
||||||
|
stream.end();
|
||||||
|
});
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -1342,7 +1351,7 @@ AddressService.prototype.getAddressSummary = function(addressArg, options, callb
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var summary = self._transformAddressSummaryFromCache(result, options);
|
var summary = self._transformAddressSummaryFromResult(result, options);
|
||||||
|
|
||||||
var timeDelta = new Date() - startTime;
|
var timeDelta = new Date() - startTime;
|
||||||
if (timeDelta > 5000) {
|
if (timeDelta > 5000) {
|
||||||
@ -1537,7 +1546,7 @@ AddressService.prototype._getAddressMempoolSummary = function(address, options,
|
|||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
AddressService.prototype._transformAddressSummaryFromCache = function(result, options) {
|
AddressService.prototype._transformAddressSummaryFromResult = function(result, options) {
|
||||||
|
|
||||||
var confirmedTxids = result.txids;
|
var confirmedTxids = result.txids;
|
||||||
var unconfirmedTxids = Object.keys(result.unconfirmedAppearanceIds);
|
var unconfirmedTxids = Object.keys(result.unconfirmedAppearanceIds);
|
||||||
|
|||||||
@ -35,220 +35,65 @@ describe('Address Service History', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#get', function() {
|
describe('#_mergeAndSortTxids', function() {
|
||||||
it('will complete the async each limit series', function(done) {
|
it('will merge and sort multiple summaries', function() {
|
||||||
var addresses = [address];
|
var summaries = [
|
||||||
var summary = {
|
{
|
||||||
txids: []
|
totalReceived: 10000000,
|
||||||
};
|
totalSpent: 0,
|
||||||
var history = new AddressHistory({
|
balance: 10000000,
|
||||||
node: {
|
appearances: 2,
|
||||||
services: {
|
unconfirmedBalance: 20000000,
|
||||||
address: {
|
unconfirmedAppearances: 2,
|
||||||
getAddressSummary: sinon.stub().callsArgWith(2, null, summary)
|
appearanceIds: {
|
||||||
}
|
'56fafeb01961831b926558d040c246b97709fd700adcaa916541270583e8e579': 154,
|
||||||
|
'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce': 120
|
||||||
|
},
|
||||||
|
unconfirmedAppearanceIds: {
|
||||||
|
'ec94d845c603f292a93b7c829811ac624b76e52b351617ca5a758e9d61a11681': 1452898347406,
|
||||||
|
'ed11a08e3102f9610bda44c80c46781d97936a4290691d87244b1b345b39a693': 1452898331964
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
options: {},
|
{
|
||||||
addresses: addresses
|
totalReceived: 59990000,
|
||||||
});
|
totalSpent: 0,
|
||||||
var expected = [{}];
|
balance: 49990000,
|
||||||
history.detailedArray = expected;
|
appearances: 3,
|
||||||
history.getDetailedInfo = sinon.stub().callsArg(1);
|
unconfirmedBalance: 1000000,
|
||||||
history.get(function(err, results) {
|
unconfirmedAppearances: 3,
|
||||||
if (err) {
|
appearanceIds: {
|
||||||
throw err;
|
'bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2': 156,
|
||||||
|
'f3c1ba3ef86a0420d6102e40e2cfc8682632ab95d09d86a27f5d466b9fa9da47': 152,
|
||||||
|
'f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f': 151
|
||||||
|
},
|
||||||
|
unconfirmedAppearanceIds: {
|
||||||
|
'f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345': 1452897902377,
|
||||||
|
'edc080f2084eed362aa488ccc873a24c378dc0979aa29b05767517b70569414a': 1452897971363,
|
||||||
|
'f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9': 1452897923107
|
||||||
|
}
|
||||||
}
|
}
|
||||||
history.getDetailedInfo.callCount.should.equal(1);
|
];
|
||||||
history.combineTransactionInfo.callCount.should.equal(1);
|
var node = {};
|
||||||
results.should.deep.equal({
|
var options = {};
|
||||||
totalCount: 1,
|
|
||||||
items: expected
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('handle an error from getDetailedInfo', function(done) {
|
|
||||||
var addresses = [address];
|
var addresses = [address];
|
||||||
var history = new AddressHistory({
|
var history = new AddressHistory({
|
||||||
node: {},
|
node: node,
|
||||||
options: {},
|
options: options,
|
||||||
addresses: addresses
|
addresses: addresses
|
||||||
});
|
});
|
||||||
var expected = [{}];
|
var txids = history._mergeAndSortTxids(summaries);
|
||||||
history.sortedArray = expected;
|
txids.should.deep.equal([
|
||||||
history.transactionInfo = [{}];
|
'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce',
|
||||||
history.getDetailedInfo = sinon.stub().callsArgWith(1, new Error('test'));
|
'f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f',
|
||||||
history.get(function(err) {
|
'f3c1ba3ef86a0420d6102e40e2cfc8682632ab95d09d86a27f5d466b9fa9da47',
|
||||||
err.message.should.equal('test');
|
'56fafeb01961831b926558d040c246b97709fd700adcaa916541270583e8e579',
|
||||||
done();
|
'bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2',
|
||||||
});
|
'f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345',
|
||||||
});
|
'f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9',
|
||||||
});
|
'edc080f2084eed362aa488ccc873a24c378dc0979aa29b05767517b70569414a',
|
||||||
|
'ed11a08e3102f9610bda44c80c46781d97936a4290691d87244b1b345b39a693',
|
||||||
describe('#_mergeAndSortTxids', function() {
|
'ec94d845c603f292a93b7c829811ac624b76e52b351617ca5a758e9d61a11681'
|
||||||
it('will sort latest to oldest using height', function() {
|
]);
|
||||||
var transactionInfo = [
|
|
||||||
{
|
|
||||||
height: 276328
|
|
||||||
},
|
|
||||||
{
|
|
||||||
height: 273845,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
height: 555655
|
|
||||||
},
|
|
||||||
{
|
|
||||||
height: 325496
|
|
||||||
},
|
|
||||||
{
|
|
||||||
height: 329186
|
|
||||||
},
|
|
||||||
{
|
|
||||||
height: 534195
|
|
||||||
}
|
|
||||||
];
|
|
||||||
transactionInfo.sort(AddressHistory.sortByHeight);
|
|
||||||
transactionInfo[0].height.should.equal(555655);
|
|
||||||
transactionInfo[1].height.should.equal(534195);
|
|
||||||
transactionInfo[2].height.should.equal(329186);
|
|
||||||
transactionInfo[3].height.should.equal(325496);
|
|
||||||
transactionInfo[4].height.should.equal(276328);
|
|
||||||
transactionInfo[5].height.should.equal(273845);
|
|
||||||
});
|
|
||||||
it('mempool and tip with time in the future', function() {
|
|
||||||
var transactionInfo = [
|
|
||||||
{
|
|
||||||
timestamp: 1442050425439,
|
|
||||||
height: 14,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442050424328,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442050424429,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442050425439,
|
|
||||||
height: 15
|
|
||||||
}
|
|
||||||
];
|
|
||||||
transactionInfo.sort(AddressHistory.sortByHeight);
|
|
||||||
transactionInfo[0].height.should.equal(-1);
|
|
||||||
transactionInfo[0].timestamp.should.equal(1442050424429);
|
|
||||||
transactionInfo[1].height.should.equal(-1);
|
|
||||||
transactionInfo[1].timestamp.should.equal(1442050424328);
|
|
||||||
transactionInfo[2].height.should.equal(15);
|
|
||||||
transactionInfo[3].height.should.equal(14);
|
|
||||||
});
|
|
||||||
it('tip with time in the future and mempool', function() {
|
|
||||||
var transactionInfo = [
|
|
||||||
{
|
|
||||||
timestamp: 1442050425439,
|
|
||||||
height: 14,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442050424328,
|
|
||||||
height: -1
|
|
||||||
}
|
|
||||||
];
|
|
||||||
transactionInfo.sort(AddressHistory.sortByHeight);
|
|
||||||
transactionInfo[0].height.should.equal(-1);
|
|
||||||
transactionInfo[1].height.should.equal(14);
|
|
||||||
});
|
|
||||||
it('many transactions in the mempool', function() {
|
|
||||||
var transactionInfo = [
|
|
||||||
{
|
|
||||||
timestamp: 1442259670462,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442259785114,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442259759896,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442259692601,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442259692601,
|
|
||||||
height: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442259749463,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442259737719,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442259773138,
|
|
||||||
height: -1,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
transactionInfo.sort(AddressHistory.sortByHeight);
|
|
||||||
transactionInfo[0].timestamp.should.equal(1442259785114);
|
|
||||||
transactionInfo[1].timestamp.should.equal(1442259773138);
|
|
||||||
transactionInfo[2].timestamp.should.equal(1442259759896);
|
|
||||||
transactionInfo[3].timestamp.should.equal(1442259749463);
|
|
||||||
transactionInfo[4].timestamp.should.equal(1442259737719);
|
|
||||||
transactionInfo[5].timestamp.should.equal(1442259692601);
|
|
||||||
transactionInfo[6].timestamp.should.equal(1442259670462);
|
|
||||||
transactionInfo[7].height.should.equal(100);
|
|
||||||
});
|
|
||||||
it('mempool and mempool', function() {
|
|
||||||
var transactionInfo = [
|
|
||||||
{
|
|
||||||
timestamp: 1442050424328,
|
|
||||||
height: -1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442050425439,
|
|
||||||
height: -1,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
transactionInfo.sort(AddressHistory.sortByHeight);
|
|
||||||
transactionInfo[0].timestamp.should.equal(1442050425439);
|
|
||||||
transactionInfo[1].timestamp.should.equal(1442050424328);
|
|
||||||
});
|
|
||||||
it('mempool and mempool with the same timestamp', function() {
|
|
||||||
var transactionInfo = [
|
|
||||||
{
|
|
||||||
timestamp: 1442050425439,
|
|
||||||
height: -1,
|
|
||||||
txid: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamp: 1442050425439,
|
|
||||||
height: -1,
|
|
||||||
txid: '2'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
transactionInfo.sort(AddressHistory.sortByHeight);
|
|
||||||
transactionInfo[0].txid.should.equal('1');
|
|
||||||
transactionInfo[1].txid.should.equal('2');
|
|
||||||
});
|
|
||||||
it('matching block heights', function() {
|
|
||||||
var transactionInfo = [
|
|
||||||
{
|
|
||||||
height: 325496,
|
|
||||||
txid: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
height: 325496,
|
|
||||||
txid: '2'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
transactionInfo.sort(AddressHistory.sortByHeight);
|
|
||||||
transactionInfo[0].txid.should.equal('1');
|
|
||||||
transactionInfo[1].txid.should.equal('2');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -2080,13 +2080,13 @@ describe('Address Service', function() {
|
|||||||
var summary = {};
|
var summary = {};
|
||||||
addressService._getAddressConfirmedSummary = sinon.stub().callsArgWith(2, null, cache);
|
addressService._getAddressConfirmedSummary = sinon.stub().callsArgWith(2, null, cache);
|
||||||
addressService._getAddressMempoolSummary = sinon.stub().callsArgWith(3, null, cache);
|
addressService._getAddressMempoolSummary = sinon.stub().callsArgWith(3, null, cache);
|
||||||
addressService._transformAddressSummaryFromCache = sinon.stub().returns(summary);
|
addressService._transformAddressSummaryFromResult = sinon.stub().returns(summary);
|
||||||
addressService.getAddressSummary(address, options, function(err, sum) {
|
addressService.getAddressSummary(address, options, function(err, sum) {
|
||||||
addressService._getAddressConfirmedSummary.callCount.should.equal(1);
|
addressService._getAddressConfirmedSummary.callCount.should.equal(1);
|
||||||
addressService._getAddressMempoolSummary.callCount.should.equal(1);
|
addressService._getAddressMempoolSummary.callCount.should.equal(1);
|
||||||
addressService._getAddressMempoolSummary.args[0][2].should.equal(cache);
|
addressService._getAddressMempoolSummary.args[0][2].should.equal(cache);
|
||||||
addressService._transformAddressSummaryFromCache.callCount.should.equal(1);
|
addressService._transformAddressSummaryFromResult.callCount.should.equal(1);
|
||||||
addressService._transformAddressSummaryFromCache.args[0][0].should.equal(cache);
|
addressService._transformAddressSummaryFromResult.args[0][0].should.equal(cache);
|
||||||
sum.should.equal(summary);
|
sum.should.equal(summary);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@ -2111,7 +2111,7 @@ describe('Address Service', function() {
|
|||||||
addressService._getAddressConfirmedSummary = sinon.stub().callsArgWith(2, null, cache);
|
addressService._getAddressConfirmedSummary = sinon.stub().callsArgWith(2, null, cache);
|
||||||
addressService._getAddressConfirmedSummary = sinon.stub().callsArgWith(2, null, cache);
|
addressService._getAddressConfirmedSummary = sinon.stub().callsArgWith(2, null, cache);
|
||||||
addressService._getAddressMempoolSummary = sinon.stub().callsArgWith(3, null, cache);
|
addressService._getAddressMempoolSummary = sinon.stub().callsArgWith(3, null, cache);
|
||||||
addressService._transformAddressSummaryFromCache = sinon.stub().returns(summary);
|
addressService._transformAddressSummaryFromResult = sinon.stub().returns(summary);
|
||||||
addressService.getAddressSummary(address, options, function() {
|
addressService.getAddressSummary(address, options, function() {
|
||||||
log.warn.callCount.should.equal(1);
|
log.warn.callCount.should.equal(1);
|
||||||
done();
|
done();
|
||||||
@ -2120,7 +2120,119 @@ describe('Address Service', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.skip('#_getAddressConfirmedSummary', function() {
|
describe('#_getAddressConfirmedSummary', function() {
|
||||||
|
it('will pass arguments correctly', function(done) {
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
var address = new bitcore.Address('12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX');
|
||||||
|
var options = {};
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var result = {};
|
||||||
|
as._getAddressConfirmedInputsSummary = sinon.stub().callsArgWith(3, null, result);
|
||||||
|
as._getAddressConfirmedOutputsSummary = sinon.stub().callsArgWith(3, null, result);
|
||||||
|
as._setAndSortTxidsFromAppearanceIds = sinon.stub().callsArgWith(1, null, result);
|
||||||
|
as._getAddressConfirmedSummary(address, options, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
var expectedResult = {
|
||||||
|
appearanceIds: {},
|
||||||
|
totalReceived: 0,
|
||||||
|
balance: 0,
|
||||||
|
unconfirmedAppearanceIds: {},
|
||||||
|
unconfirmedBalance: 0
|
||||||
|
};
|
||||||
|
as._getAddressConfirmedInputsSummary.args[0][0].should.equal(address);
|
||||||
|
as._getAddressConfirmedInputsSummary.args[0][1].should.deep.equal(expectedResult);
|
||||||
|
as._getAddressConfirmedInputsSummary.args[0][2].should.deep.equal(options);
|
||||||
|
as._getAddressConfirmedOutputsSummary.args[0][0].should.equal(address);
|
||||||
|
as._getAddressConfirmedOutputsSummary.args[0][1].should.deep.equal(result);
|
||||||
|
as._getAddressConfirmedOutputsSummary.args[0][2].should.equal(options);
|
||||||
|
as._setAndSortTxidsFromAppearanceIds.args[0][0].should.equal(result);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('will pass error correctly (inputs)', function(done) {
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
var address = new bitcore.Address('12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX');
|
||||||
|
var options = {};
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var result = {};
|
||||||
|
as._getAddressConfirmedInputsSummary = sinon.stub().callsArgWith(3, new Error('test'));
|
||||||
|
as._getAddressConfirmedSummary(address, options, function(err) {
|
||||||
|
should.exist(err);
|
||||||
|
err.message.should.equal('test');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('will pass error correctly (outputs)', function(done) {
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
var address = new bitcore.Address('12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX');
|
||||||
|
var options = {};
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var result = {};
|
||||||
|
as._getAddressConfirmedInputsSummary = sinon.stub().callsArgWith(3, null, result);
|
||||||
|
as._getAddressConfirmedOutputsSummary = sinon.stub().callsArgWith(3, new Error('test'));
|
||||||
|
as._getAddressConfirmedSummary(address, options, function(err) {
|
||||||
|
should.exist(err);
|
||||||
|
err.message.should.equal('test');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('will pass error correctly (sort)', function(done) {
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
var address = new bitcore.Address('12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX');
|
||||||
|
var options = {};
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var result = {};
|
||||||
|
as._getAddressConfirmedInputsSummary = sinon.stub().callsArgWith(3, null, result);
|
||||||
|
as._getAddressConfirmedOutputsSummary = sinon.stub().callsArgWith(3, null, result);
|
||||||
|
as._setAndSortTxidsFromAppearanceIds = sinon.stub().callsArgWith(1, new Error('test'));
|
||||||
|
as._getAddressConfirmedSummary(address, options, function(err) {
|
||||||
|
should.exist(err);
|
||||||
|
err.message.should.equal('test');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#_getAddressConfirmedInputsSummary', function() {
|
describe('#_getAddressConfirmedInputsSummary', function() {
|
||||||
@ -2282,13 +2394,212 @@ describe('Address Service', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.skip('#_setAndSortTxidsFromAppearanceIds', function() {
|
describe('#_setAndSortTxidsFromAppearanceIds', function() {
|
||||||
|
it('will sort correctly', function(done) {
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var result = {
|
||||||
|
appearanceIds: {
|
||||||
|
'22488dbb99aed86e7081ac480e3459fa40ccab7ee18bef98b84b3cdce6bf05be': 200,
|
||||||
|
'1c413601acbd608240fc635b95886c3c1f76ec8589c3392a58b5715ceb618e93': 100,
|
||||||
|
'206d3834c010d46a2cf478cb1c5fe252be41f683c8a738e3ebe27f1aae67f505': 101
|
||||||
|
}
|
||||||
|
};
|
||||||
|
as._setAndSortTxidsFromAppearanceIds(result, function(err, result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
should.exist(result.txids);
|
||||||
|
result.txids[0].should.equal('1c413601acbd608240fc635b95886c3c1f76ec8589c3392a58b5715ceb618e93');
|
||||||
|
result.txids[1].should.equal('206d3834c010d46a2cf478cb1c5fe252be41f683c8a738e3ebe27f1aae67f505');
|
||||||
|
result.txids[2].should.equal('22488dbb99aed86e7081ac480e3459fa40ccab7ee18bef98b84b3cdce6bf05be');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.skip('#_getAddressMempoolSummary', function() {
|
describe('#_getAddressMempoolSummary', function() {
|
||||||
|
it('skip if options not enabled', function(done) {
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var resultBase = {
|
||||||
|
unconfirmedAppearanceIds: {},
|
||||||
|
unconfirmedBalance: 0
|
||||||
|
};
|
||||||
|
var address = new bitcore.Address('12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX');
|
||||||
|
var options = {};
|
||||||
|
as._getAddressMempoolSummary(address, options, resultBase, function(err, result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
Object.keys(result.unconfirmedAppearanceIds).length.should.equal(0);
|
||||||
|
result.unconfirmedBalance.should.equal(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('include all txids and balance from inputs and outputs', function(done) {
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var resultBase = {
|
||||||
|
unconfirmedAppearanceIds: {},
|
||||||
|
unconfirmedBalance: 0
|
||||||
|
};
|
||||||
|
var address = new bitcore.Address('12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX');
|
||||||
|
var options = {
|
||||||
|
queryMempool: true
|
||||||
|
};
|
||||||
|
var mempoolInputs = [
|
||||||
|
{
|
||||||
|
address: '3NbU8XzUgKyuCgYgZEKsBtUvkTm2r7Xgwj',
|
||||||
|
hashType: 'scripthash',
|
||||||
|
txid: '70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8',
|
||||||
|
inputIndex: 0,
|
||||||
|
timestamp: 1452874536321,
|
||||||
|
height: -1,
|
||||||
|
confirmations: 0
|
||||||
|
}
|
||||||
|
];
|
||||||
|
var mempoolOutputs = [
|
||||||
|
{
|
||||||
|
address: '3NbU8XzUgKyuCgYgZEKsBtUvkTm2r7Xgwj',
|
||||||
|
hashType: 'scripthash',
|
||||||
|
txid: '35fafaf572341798b2ce2858755afa7c8800bb6b1e885d3e030b81255b5e172d',
|
||||||
|
outputIndex: 0,
|
||||||
|
height: -1,
|
||||||
|
timestamp: 1452874521466,
|
||||||
|
satoshis: 131368318,
|
||||||
|
script: '76a9148c66db6e9f74b1db9c400eaa2aed3743417f38e688ac',
|
||||||
|
confirmations: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: '3NbU8XzUgKyuCgYgZEKsBtUvkTm2r7Xgwj',
|
||||||
|
hashType: 'scripthash',
|
||||||
|
txid: '57b7842afc97a2b46575b490839df46e9273524c6ea59ba62e1e86477cf25247',
|
||||||
|
outputIndex: 0,
|
||||||
|
height: -1,
|
||||||
|
timestamp: 1452874521466,
|
||||||
|
satoshis: 131368318,
|
||||||
|
script: '76a9148c66db6e9f74b1db9c400eaa2aed3743417f38e688ac',
|
||||||
|
confirmations: 0
|
||||||
|
}
|
||||||
|
];
|
||||||
|
var spentIndexSyncKey = encoding.encodeSpentIndexSyncKey(
|
||||||
|
new Buffer(mempoolOutputs[1].txid, 'hex'),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
as.mempoolSpentIndex[spentIndexSyncKey] = true;
|
||||||
|
as._getInputsMempool = sinon.stub().callsArgWith(3, null, mempoolInputs);
|
||||||
|
as._getOutputsMempool = sinon.stub().callsArgWith(3, null, mempoolOutputs);
|
||||||
|
as._getAddressMempoolSummary(address, options, resultBase, function(err, result) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
var txid1 = '70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8';
|
||||||
|
var txid2 = '35fafaf572341798b2ce2858755afa7c8800bb6b1e885d3e030b81255b5e172d';
|
||||||
|
var txid3 = '57b7842afc97a2b46575b490839df46e9273524c6ea59ba62e1e86477cf25247';
|
||||||
|
result.unconfirmedAppearanceIds[txid1].should.equal(1452874536321);
|
||||||
|
result.unconfirmedAppearanceIds[txid2].should.equal(1452874521466);
|
||||||
|
result.unconfirmedAppearanceIds[txid3].should.equal(1452874521466);
|
||||||
|
result.unconfirmedBalance.should.equal(131368318);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.skip('#_transformAddressSummaryFromCache', function() {
|
describe('#_transformAddressSummaryFromResult', function() {
|
||||||
|
var result = {
|
||||||
|
totalReceived: 1000000,
|
||||||
|
balance: 500000,
|
||||||
|
txids: [
|
||||||
|
'70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8',
|
||||||
|
'b1bfa8dbbde790cb46b9763ef3407c1a21c8264b67bfe224f462ec0e1f569e92'
|
||||||
|
],
|
||||||
|
appearanceIds: {
|
||||||
|
'b1bfa8dbbde790cb46b9763ef3407c1a21c8264b67bfe224f462ec0e1f569e92': 100000,
|
||||||
|
'70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8': 200000
|
||||||
|
},
|
||||||
|
unconfirmedAppearanceIds: {
|
||||||
|
'35fafaf572341798b2ce2858755afa7c8800bb6b1e885d3e030b81255b5e172d': 1452874536321,
|
||||||
|
'57b7842afc97a2b46575b490839df46e9273524c6ea59ba62e1e86477cf25247': 1452874521466
|
||||||
|
},
|
||||||
|
unconfirmedBalance: 500000
|
||||||
|
};
|
||||||
|
var testnode = {
|
||||||
|
services: {
|
||||||
|
bitcoind: {
|
||||||
|
on: sinon.stub()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datadir: 'testdir'
|
||||||
|
};
|
||||||
|
it('will transform result into summary', function() {
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var options = {};
|
||||||
|
var summary = as._transformAddressSummaryFromResult(result, options);
|
||||||
|
summary.totalReceived.should.equal(1000000);
|
||||||
|
summary.totalSpent.should.equal(500000);
|
||||||
|
summary.balance.should.equal(500000);
|
||||||
|
summary.appearances.should.equal(2);
|
||||||
|
summary.unconfirmedAppearances.should.equal(2);
|
||||||
|
summary.unconfirmedBalance.should.equal(500000);
|
||||||
|
summary.txids.length.should.equal(4);
|
||||||
|
});
|
||||||
|
it('will omit txlist', function() {
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var options = {
|
||||||
|
noTxList: true
|
||||||
|
};
|
||||||
|
var summary = as._transformAddressSummaryFromResult(result, options);
|
||||||
|
should.not.exist(summary.txids);
|
||||||
|
});
|
||||||
|
it('will include full appearance ids', function() {
|
||||||
|
var as = new AddressService({
|
||||||
|
mempoolMemoryIndex: true,
|
||||||
|
node: testnode
|
||||||
|
});
|
||||||
|
var options = {
|
||||||
|
fullTxList: true
|
||||||
|
};
|
||||||
|
var summary = as._transformAddressSummaryFromResult(result, options);
|
||||||
|
should.exist(summary.appearanceIds);
|
||||||
|
should.exist(summary.unconfirmedAppearanceIds);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user