diff --git a/api/controllers/addresses.js b/api/controllers/addresses.js index 8cfffbfe..3edb2516 100644 --- a/api/controllers/addresses.js +++ b/api/controllers/addresses.js @@ -5,8 +5,6 @@ var _ = bitcore.deps._; var $ = bitcore.util.preconditions; var Address = bitcore.Address; -var BitcoreNode = require('../../'); - var Addresses = {}; var node; diff --git a/api/test/v1/addresses.js b/api/test/v1/addresses.js index 341a41f4..86cb8cd5 100644 --- a/api/test/v1/addresses.js +++ b/api/test/v1/addresses.js @@ -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); }); }); }); diff --git a/lib/services/address.js b/lib/services/address.js index f59e3caa..40b754a8 100644 --- a/lib/services/address.js +++ b/lib/services/address.js @@ -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) { diff --git a/test/services/address.js b/test/services/address.js index 7f8ad05b..41661930 100644 --- a/test/services/address.js +++ b/test/services/address.js @@ -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 + } }); }); }); }); -