fix address regressions
This commit is contained in:
parent
85ad9fcdb6
commit
671665c052
@ -5,8 +5,6 @@ var _ = bitcore.deps._;
|
||||
var $ = bitcore.util.preconditions;
|
||||
var Address = bitcore.Address;
|
||||
|
||||
var BitcoreNode = require('../../');
|
||||
|
||||
var Addresses = {};
|
||||
|
||||
var node;
|
||||
|
||||
@ -11,17 +11,11 @@ var _ = bitcore.deps._;
|
||||
|
||||
|
||||
var mockAddresses = require('../data/addresses');
|
||||
var mockTransactions = require('../data/transactions');
|
||||
|
||||
describe('BitcoreHTTP v1 addresses routes', function() {
|
||||
|
||||
// mocks
|
||||
var transactionList = _.values(mockTransactions);
|
||||
var nodeMock, agent;
|
||||
var txs_for_addr = function(addr) {
|
||||
var amount = mockAddresses[addr].summary.transactions.length;
|
||||
return transactionList.slice(0, amount);
|
||||
};
|
||||
var utxos_for_addrs = function(addrs) {
|
||||
return _.reduce(addrs, function(utxos, addr) {
|
||||
return utxos.concat(mockAddresses[addr].utxos);
|
||||
@ -53,10 +47,7 @@ describe('BitcoreHTTP v1 addresses routes', function() {
|
||||
nodeMock.addressService.getSummary = function(address) {
|
||||
return Promise.resolve(mockAddresses[address.toString()].summary);
|
||||
};
|
||||
nodeMock.listTransactions = function(opts) {
|
||||
return Promise.resolve(txs_for_addr(opts.address));
|
||||
};
|
||||
nodeMock.getUTXOs = function(addresses) {
|
||||
nodeMock.addressService.getUnspent = function(addresses) {
|
||||
return Promise.resolve(utxos_for_addrs(addresses));
|
||||
};
|
||||
agent = require('../app')(nodeMock);
|
||||
@ -77,19 +68,7 @@ describe('BitcoreHTTP v1 addresses routes', function() {
|
||||
it('works with valid address ' + addr, function(cb) {
|
||||
agent.get('/v1/addresses/' + addr)
|
||||
.expect(200)
|
||||
.expect(JSON.stringify(info.summary), cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('/addresses/:address/transactions', function() {
|
||||
it('fails with invalid address', function(cb) {
|
||||
failsWithInvalidAddress(agent, '/v1/addresses/1BpbpfLdY7oBS9gK7aDXgvMgr1DpvNH3B2/transactions', cb);
|
||||
});
|
||||
_.keys(mockAddresses).forEach(function(addr) {
|
||||
it('works with valid address ' + addr, function(cb) {
|
||||
agent.get('/v1/addresses/' + addr + '/transactions')
|
||||
.expect(200)
|
||||
.expect(JSON.stringify(txs_for_addr(addr)), cb);
|
||||
.expect(info.summary, cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -104,7 +83,7 @@ describe('BitcoreHTTP v1 addresses routes', function() {
|
||||
it('works with valid address ' + addr, function(cb) {
|
||||
agent.get('/v1/addresses/' + addr + '/utxos')
|
||||
.expect(200)
|
||||
.expect(JSON.stringify(utxos_for_addrs([addr])), cb);
|
||||
.expect(utxos_for_addrs([addr]), cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -118,7 +97,7 @@ describe('BitcoreHTTP v1 addresses routes', function() {
|
||||
var path = '/v1/addresses/' + list + '/utxos';
|
||||
agent.get(path)
|
||||
.expect(200)
|
||||
.expect(JSON.stringify(utxos_for_addrs(addresses)), cb);
|
||||
.expect(utxos_for_addrs(addresses), cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
var Promise = require('bluebird');
|
||||
var bitcore = require('bitcore');
|
||||
var TransactionService = require('./transaction');
|
||||
var RPC = require('bitcoind-rpc');
|
||||
var _ = bitcore.deps._;
|
||||
var $ = bitcore.util.preconditions;
|
||||
|
||||
@ -15,8 +14,8 @@ function AddressService(opts) {
|
||||
opts = _.extend({}, opts);
|
||||
this.transactionService = opts.transactionService;
|
||||
this.blockService = opts.blockService;
|
||||
this.database = opts.database || Promise.promisifyAll(new LevelUp(config.get('LevelUp')));
|
||||
this.rpc = opts.rpc || Promise.promisifyAll(new RPC(config.get('RPC')));
|
||||
this.database = opts.database;
|
||||
this.rpc = opts.rpc;
|
||||
}
|
||||
|
||||
AddressService.prototype.getSummary = function(address, confirmations) {
|
||||
|
||||
@ -6,7 +6,6 @@ var events = require('events');
|
||||
var Promise = require('bluebird');
|
||||
|
||||
var bitcore = require('bitcore');
|
||||
var _ = bitcore.deps._;
|
||||
|
||||
var AddressService = require('../../lib/services/address');
|
||||
|
||||
@ -43,7 +42,9 @@ describe('AddressService', function() {
|
||||
beforeEach(initialize);
|
||||
|
||||
it('calls internal functions as expected', function(done) {
|
||||
service.blockService = { getLatest: sinon.mock() };
|
||||
service.blockService = {
|
||||
getLatest: sinon.mock()
|
||||
};
|
||||
service.getAllOutputs = sinon.mock();
|
||||
service.getSpent = sinon.mock();
|
||||
service.buildAddressSummary = sinon.mock();
|
||||
@ -105,17 +106,16 @@ describe('AddressService', function() {
|
||||
AddressService.processOutput = sinon.stub(AddressService, 'processOutput');
|
||||
AddressService.processOutput.onFirstCall().returns('processed');
|
||||
|
||||
var element = {key: 'key', value: 'value'};
|
||||
var element = {
|
||||
key: 'key',
|
||||
value: 'value'
|
||||
};
|
||||
var address = '12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S';
|
||||
service.getAllOutputs(address).then(function(arg) {
|
||||
service.database.createReadStream.firstCall.args[0].should.deep.equal(
|
||||
{
|
||||
gte: 'txa-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-'
|
||||
+ '0000000000000000000000000000000000000000000000000000000000000000-0',
|
||||
lte: 'txa-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-'
|
||||
+ 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff-4294967295'
|
||||
}
|
||||
);
|
||||
service.database.createReadStream.firstCall.args[0].should.deep.equal({
|
||||
gte: 'txa-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-' + '0000000000000000000000000000000000000000000000000000000000000000-0',
|
||||
lte: 'txa-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-' + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff-4294967295'
|
||||
});
|
||||
AddressService.processOutput.firstCall.args[0].should.equal(element);
|
||||
AddressService.processOutput.reset();
|
||||
arg[0].should.equal('processed');
|
||||
@ -131,20 +131,23 @@ describe('AddressService', function() {
|
||||
var dataCall = new events.EventEmitter();
|
||||
service.database.createReadStream.onFirstCall().returns(dataCall);
|
||||
|
||||
var element = {key: 'key', value: JSON.stringify({a: 'b'})};
|
||||
var element = {
|
||||
key: 'key',
|
||||
value: JSON.stringify({
|
||||
a: 'b'
|
||||
})
|
||||
};
|
||||
var address = '12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S';
|
||||
service.getSpent(address).then(function(arg) {
|
||||
service.database.createReadStream.firstCall.args[0].should.deep.equal(
|
||||
{
|
||||
gte: 'txas-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-'
|
||||
+ '0000000000000000000000000000000000000000000000000000000000000000-0',
|
||||
lte: 'txas-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-'
|
||||
+ 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff-4294967295'
|
||||
}
|
||||
);
|
||||
arg[0].should.deep.equal({a: 'b'});
|
||||
done();
|
||||
});
|
||||
service.getSpent(address)
|
||||
.then(function(arg) {
|
||||
service.database.createReadStream.firstCall.args[0].should.deep.equal({
|
||||
gte: 'txas-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-' + '0000000000000000000000000000000000000000000000000000000000000000-0',
|
||||
lte: 'txas-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-' + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff-4294967295'
|
||||
});
|
||||
console.log(arguments);
|
||||
arg[0].should.deep.equal('processed');
|
||||
done();
|
||||
});
|
||||
|
||||
dataCall.emit('data', element);
|
||||
dataCall.emit('end');
|
||||
@ -158,107 +161,203 @@ describe('AddressService', function() {
|
||||
var tip = {
|
||||
height: 10
|
||||
};
|
||||
var allOutputs = [
|
||||
{
|
||||
var allOutputs = [{
|
||||
satoshis: 10,
|
||||
txId: 'A',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 1
|
||||
}];
|
||||
|
||||
it('calculates balance correctly for confirmed balance', function() {
|
||||
var allOutputs = [{
|
||||
satoshis: 10,
|
||||
txId: 'A',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 1
|
||||
}
|
||||
];
|
||||
|
||||
it('calculates balance correctly for confirmed balance', function() {
|
||||
var allOutputs = [ { satoshis: 10, txId: 'A', outputIndex: 1, heightConfirmed: 1 } ];
|
||||
}];
|
||||
var spendOutputs = [];
|
||||
|
||||
service.buildAddressSummary(address, tip, allOutputs, spendOutputs).should.deep.equal({
|
||||
address: address.toString(),
|
||||
transactions: ['A'],
|
||||
confirmed: { balance: 10, sent: 0, received: 10 },
|
||||
unconfirmed: { balance: 10, sent: 0, received: 10 }
|
||||
confirmed: {
|
||||
balance: 10,
|
||||
sent: 0,
|
||||
received: 10
|
||||
},
|
||||
unconfirmed: {
|
||||
balance: 10,
|
||||
sent: 0,
|
||||
received: 10
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('calculates balance correctly for unconfirmed balance', function() {
|
||||
var allOutputs = [
|
||||
{ satoshis: 20, txId: 'B', outputIndex: 1, heightConfirmed: 10 }
|
||||
];
|
||||
var spendOutputs = [ ];
|
||||
var allOutputs = [{
|
||||
satoshis: 20,
|
||||
txId: 'B',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 10
|
||||
}];
|
||||
var spendOutputs = [];
|
||||
|
||||
service.buildAddressSummary(address, tip, allOutputs, spendOutputs).should.deep.equal({
|
||||
address: address.toString(),
|
||||
transactions: ['B'],
|
||||
confirmed: { balance: 0, sent: 0, received: 0 },
|
||||
unconfirmed: { balance: 20, sent: 0, received: 20 }
|
||||
confirmed: {
|
||||
balance: 0,
|
||||
sent: 0,
|
||||
received: 0
|
||||
},
|
||||
unconfirmed: {
|
||||
balance: 20,
|
||||
sent: 0,
|
||||
received: 20
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('works with multiple transactions', function() {
|
||||
var allOutputs = [
|
||||
{ satoshis: 10, txId: 'A', outputIndex: 1, heightConfirmed: 1 },
|
||||
{ satoshis: 20, txId: 'B', outputIndex: 1, heightConfirmed: 10 }
|
||||
];
|
||||
var spendOutputs = [
|
||||
{ spendInput: { prevTxId: 'A', outputIndex: 1 }, spentTx: 'A', heightSpent: 10 }
|
||||
];
|
||||
var allOutputs = [{
|
||||
satoshis: 10,
|
||||
txId: 'A',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 1
|
||||
}, {
|
||||
satoshis: 20,
|
||||
txId: 'B',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 10
|
||||
}];
|
||||
var spendOutputs = [{
|
||||
spendInput: {
|
||||
prevTxId: 'A',
|
||||
outputIndex: 1
|
||||
},
|
||||
spentTx: 'A',
|
||||
heightSpent: 10
|
||||
}];
|
||||
|
||||
service.buildAddressSummary(address, tip, allOutputs, spendOutputs).should.deep.equal({
|
||||
address: address.toString(),
|
||||
transactions: ['A', 'B'],
|
||||
confirmed: { balance: 10, sent: 0, received: 10 },
|
||||
unconfirmed: { balance: 20, sent: 10, received: 30 }
|
||||
confirmed: {
|
||||
balance: 10,
|
||||
sent: 0,
|
||||
received: 10
|
||||
},
|
||||
unconfirmed: {
|
||||
balance: 20,
|
||||
sent: 10,
|
||||
received: 30
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('works with a medium amount of transactions', function() {
|
||||
var allOutputs = [
|
||||
{ satoshis: 10, txId: 'A', outputIndex: 1, heightConfirmed: 1 },
|
||||
{ satoshis: 20, txId: 'B', outputIndex: 1, heightConfirmed: 5 },
|
||||
{ satoshis: 30, txId: 'C', outputIndex: 1, heightConfirmed: 10 }
|
||||
];
|
||||
var spendOutputs = [
|
||||
{ spendInput: { prevTxId: 'A', outputIndex: 1 }, spentTx: 'D', heightSpent: 10 }
|
||||
];
|
||||
var allOutputs = [{
|
||||
satoshis: 10,
|
||||
txId: 'A',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 1
|
||||
}, {
|
||||
satoshis: 20,
|
||||
txId: 'B',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 5
|
||||
}, {
|
||||
satoshis: 30,
|
||||
txId: 'C',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 10
|
||||
}];
|
||||
var spendOutputs = [{
|
||||
spendInput: {
|
||||
prevTxId: 'A',
|
||||
outputIndex: 1
|
||||
},
|
||||
spentTx: 'D',
|
||||
heightSpent: 10
|
||||
}];
|
||||
|
||||
service.buildAddressSummary(address, tip, allOutputs, spendOutputs).should.deep.equal({
|
||||
address: address.toString(),
|
||||
transactions: ['A', 'B', 'C', 'D'],
|
||||
confirmed: { balance: 30, sent: 0, received: 30 },
|
||||
unconfirmed: { balance: 50, sent: 10, received: 60 }
|
||||
confirmed: {
|
||||
balance: 30,
|
||||
sent: 0,
|
||||
received: 30
|
||||
},
|
||||
unconfirmed: {
|
||||
balance: 50,
|
||||
sent: 10,
|
||||
received: 60
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('works with a transaction that includes twice the same address', function() {
|
||||
var allOutputs = [
|
||||
{ satoshis: 10, txId: 'A', outputIndex: 0, heightConfirmed: 1 },
|
||||
{ satoshis: 10, txId: 'A', outputIndex: 1, heightConfirmed: 1 },
|
||||
];
|
||||
var allOutputs = [{
|
||||
satoshis: 10,
|
||||
txId: 'A',
|
||||
outputIndex: 0,
|
||||
heightConfirmed: 1
|
||||
}, {
|
||||
satoshis: 10,
|
||||
txId: 'A',
|
||||
outputIndex: 1,
|
||||
heightConfirmed: 1
|
||||
}, ];
|
||||
var spendOutputs = [];
|
||||
|
||||
service.buildAddressSummary(address, tip, allOutputs, spendOutputs).should.deep.equal({
|
||||
address: address.toString(),
|
||||
transactions: ['A'],
|
||||
confirmed: { balance: 20, sent: 0, received: 20 },
|
||||
unconfirmed: { balance: 20, sent: 0, received: 20 }
|
||||
confirmed: {
|
||||
balance: 20,
|
||||
sent: 0,
|
||||
received: 20
|
||||
},
|
||||
unconfirmed: {
|
||||
balance: 20,
|
||||
sent: 0,
|
||||
received: 20
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('confirmed spent transactions change the balance', function() {
|
||||
var allOutputs = [
|
||||
{ satoshis: 10, txId: 'A', outputIndex: 0, heightConfirmed: 1 },
|
||||
];
|
||||
var spendOutputs = [
|
||||
{ spendInput: { prevTxId: 'A', outputIndex: 0 }, spentTx: 'D', heightSpent: 2 }
|
||||
];
|
||||
var allOutputs = [{
|
||||
satoshis: 10,
|
||||
txId: 'A',
|
||||
outputIndex: 0,
|
||||
heightConfirmed: 1
|
||||
}, ];
|
||||
var spendOutputs = [{
|
||||
spendInput: {
|
||||
prevTxId: 'A',
|
||||
outputIndex: 0
|
||||
},
|
||||
spentTx: 'D',
|
||||
heightSpent: 2
|
||||
}];
|
||||
|
||||
service.buildAddressSummary(address, tip, allOutputs, spendOutputs).should.deep.equal({
|
||||
address: address.toString(),
|
||||
transactions: ['A', 'D'],
|
||||
confirmed: { balance: 0, sent: 10, received: 10 },
|
||||
unconfirmed: { balance: 0, sent: 10, received: 10 }
|
||||
confirmed: {
|
||||
balance: 0,
|
||||
sent: 10,
|
||||
received: 10
|
||||
},
|
||||
unconfirmed: {
|
||||
balance: 0,
|
||||
sent: 10,
|
||||
received: 10
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user