Merge pull request #69 from maraoz/polish/addresses

polish API: /v1/addresses
This commit is contained in:
Manuel Aráoz 2015-04-30 05:19:14 -03:00
commit 145de82bbc
7 changed files with 104 additions and 47 deletions

View File

@ -63,7 +63,7 @@ Addresses.addressesParam = function(req, res, next, addresses) {
*/ */
Addresses.get = function(req, res) { Addresses.get = function(req, res) {
$.checkState(req.address instanceof Address); $.checkState(req.address instanceof Address);
node.getAddressInfo(req.address) node.addressService.getSummary(req.address)
.then(function(info) { .then(function(info) {
res.send(info); res.send(info);
}); });

View File

@ -1,6 +1,67 @@
'use strict'; 'use strict';
var mockAddresses = { var mockAddresses = {
'13fas9TWPMRBakZ822mvddS6PM92udNB2g': {
summary: {
address: '13fas9TWPMRBakZ822mvddS6PM92udNB2g',
transactions: [
'4469092947a437f9b4276e0a7e3c899a2b74b2fe325e49202c3005911adaab85',
'afa55c2ce0e1038d87921d4de7b13a456edfa5ca6f44cddaf4cda9f1db441481'
],
confirmed: {
balance: 0,
sent: 675000000,
received: 675000000
},
unconfirmed: {
balance: 0,
sent: 675000000,
received: 675000000
}
},
utxos: []
},
'17afxUJouat3fkaaQ9tZrDThxdkXGL4WrM': {
summary: {
address: '17afxUJouat3fkaaQ9tZrDThxdkXGL4WrM',
transactions: [
'2ccc3f59d28c709770a8bc478b112e10feda4bf55197c2e48deaa0eb6bca0311',
'92f55c2c0b8317eafad83c73487fbeceb8279d0eb57e398763298e6cc983b356'
],
confirmed: {
balance: 0,
sent: 100000000000,
received: 100000000000
},
unconfirmed: {
balance: 0,
sent: 100000000000,
received: 100000000000
}
},
utxos: []
},
'17DC6Fxidja2DN7oHTVgfx3uQ4KGArYEwg': {
summary: {
'address': '17DC6Fxidja2DN7oHTVgfx3uQ4KGArYEwg',
'transactions': [
'33d1ad0d24e2cb466054e47060c8ae527af7a3c46445335bebf9d24a6f5b1e9e',
'6884733345b952b244a44cf770be62afbcf41549d8a89d2a4bea9f479e09dd47',
'2847ae66175042438532c2eccc5b39935fd1216453e62e2c3cb9c8e5020cc771'
],
'confirmed': {
'balance': 0,
'sent': 65000000000,
'received': 65000000000
},
'unconfirmed': {
'balance': 0,
'sent': 65000000000,
'received': 65000000000
}
},
utxos: []
},
'1CT9huFgxMFveRvzZ7zPPJNoaMm2Fo64VH': { '1CT9huFgxMFveRvzZ7zPPJNoaMm2Fo64VH': {
summary: { summary: {
address: '1CT9huFgxMFveRvzZ7zPPJNoaMm2Fo64VH', address: '1CT9huFgxMFveRvzZ7zPPJNoaMm2Fo64VH',

View File

@ -2,7 +2,6 @@
var chai = require('chai'); var chai = require('chai');
var should = chai.should(); var should = chai.should();
var request = require('supertest');
var EventEmitter = require('eventemitter2').EventEmitter2; var EventEmitter = require('eventemitter2').EventEmitter2;
var Promise = require('bluebird'); var Promise = require('bluebird');
@ -10,7 +9,6 @@ Promise.longStackTraces();
var bitcore = require('bitcore'); var bitcore = require('bitcore');
var _ = bitcore.deps._; var _ = bitcore.deps._;
var BitcoreHTTP = require('../../lib/http');
var mockAddresses = require('../data/addresses'); var mockAddresses = require('../data/addresses');
var mockTransactions = require('../data/transactions'); var mockTransactions = require('../data/transactions');
@ -19,7 +17,7 @@ describe('BitcoreHTTP v1 addresses routes', function() {
// mocks // mocks
var transactionList = _.values(mockTransactions); var transactionList = _.values(mockTransactions);
var nodeMock, app, agent; var nodeMock, agent;
var txs_for_addr = function(addr) { var txs_for_addr = function(addr) {
var amount = mockAddresses[addr].summary.transactions.length; var amount = mockAddresses[addr].summary.transactions.length;
return transactionList.slice(0, amount); return transactionList.slice(0, amount);
@ -51,8 +49,9 @@ describe('BitcoreHTTP v1 addresses routes', function() {
beforeEach(function() { beforeEach(function() {
nodeMock = new EventEmitter(); nodeMock = new EventEmitter();
nodeMock.getAddressInfo = function(address) { nodeMock.addressService = {};
return Promise.resolve(mockAddresses[address.toString()]); nodeMock.addressService.getSummary = function(address) {
return Promise.resolve(mockAddresses[address.toString()].summary);
}; };
nodeMock.listTransactions = function(opts) { nodeMock.listTransactions = function(opts) {
return Promise.resolve(txs_for_addr(opts.address)); return Promise.resolve(txs_for_addr(opts.address));
@ -60,8 +59,7 @@ describe('BitcoreHTTP v1 addresses routes', function() {
nodeMock.getUTXOs = function(addresses) { nodeMock.getUTXOs = function(addresses) {
return Promise.resolve(utxos_for_addrs(addresses)); return Promise.resolve(utxos_for_addrs(addresses));
}; };
app = new BitcoreHTTP(nodeMock).app; agent = require('../app')(nodeMock);
agent = request(app);
}); });
var failsWithInvalidAddress = function(agent, url, cb) { var failsWithInvalidAddress = function(agent, url, cb) {
@ -79,7 +77,7 @@ describe('BitcoreHTTP v1 addresses routes', function() {
it('works with valid address ' + addr, function(cb) { it('works with valid address ' + addr, function(cb) {
agent.get('/v1/addresses/' + addr) agent.get('/v1/addresses/' + addr)
.expect(200) .expect(200)
.expect(JSON.stringify(info), cb); .expect(JSON.stringify(info.summary), cb);
}); });
}); });
}); });

View File

@ -18,7 +18,7 @@ describe('BitcoreHTTP v1 node routes', function() {
peerCount: 8, peerCount: 8,
version: 'test', version: 'test',
network: 'regtest', network: 'regtest',
height: 1234, height: 60000,
}; };
nodeMock.getStatus = function() { nodeMock.getStatus = function() {
return Promise.resolve(nodeMock.status); return Promise.resolve(nodeMock.status);

View File

@ -188,10 +188,17 @@ BitcoreNode.prototype.getStatus = function() {
peerCount: this.networkMonitor.getConnectedPeers(), peerCount: this.networkMonitor.getConnectedPeers(),
version: pjson.version, version: pjson.version,
network: bitcore.Networks.defaultNetwork.name, network: bitcore.Networks.defaultNetwork.name,
height: this.blockchain.getCurrentHeight(), height: this.getCurrentHeight(),
}); });
}; };
BitcoreNode.prototype.getCurrentHeight = function() {
if (!this.blockchain) {
return 0;
}
return this.blockchain.getCurrentHeight();
};
BitcoreNode.prototype.getSyncProgress = function() { BitcoreNode.prototype.getSyncProgress = function() {
return !_.isUndefined(this.reportedMaxHeight) ? return !_.isUndefined(this.reportedMaxHeight) ?
(this.blockchain.getCurrentHeight() / this.reportedMaxHeight) : 0; (this.blockchain.getCurrentHeight() / this.reportedMaxHeight) : 0;

View File

@ -120,27 +120,26 @@ TransactionService.prototype._confirmOutput = function(ops, block, transaction)
key: Index.getOutput(txid, index), key: Index.getOutput(txid, index),
value: output.toJSON() value: output.toJSON()
}); });
var address; var script = output.script;
if (output.script.isPublicKeyHashOut() || output.script.isScriptHashOut()) { if (!script.isPublicKeyHashOut() && !script.isScriptHashOut()) {
address = output.script.toAddress(); return;
}
if (address) {
var out4addr = output.toObject();
out4addr.heightConfirmed = block.height;
ops.push({
type: 'put',
key: Index.getOutputsForAddress(address, txid, index),
value: JSON.stringify(out4addr)
});
} }
var address = output.script.toAddress();
//console.log('o', address.type, address.toString());
var obj = output.toObject();
obj.heightConfirmed = block.height;
ops.push({
type: 'put',
key: Index.getOutputsForAddress(address, txid, index),
value: JSON.stringify(obj)
});
}; };
}; };
TransactionService.prototype._confirmInput = function(ops, block, transaction) { TransactionService.prototype._confirmInput = function(ops, block, transaction) {
var self = this;
var txid = transaction.id; var txid = transaction.id;
return function(input, index) { return function(input, index) {
if (input.prevTxId.toString('hex') === NULLTXHASH) { if (input.isNull()) {
return Promise.resolve(); return Promise.resolve();
} }
ops.push({ ops.push({
@ -151,34 +150,27 @@ TransactionService.prototype._confirmInput = function(ops, block, transaction) {
})) }))
}); });
var script = input.script; var script = input.script;
if (!(script.isPublicKeyHashIn() || script.isPublicKeyIn() || script.isScriptHashIn())) { if (!(script.isPublicKeyHashIn() || script.isScriptHashIn())) {
return; return Promise.resolve();
} }
return Promise.try(function() { return Promise.try(function() {
var address = self._getAddressForInput(input); var address = input.script.toAddress();
if (address) { //console.log('i', address.type, address.toString());
ops.push({ ops.push({
type: 'put', type: 'put',
key: Index.getSpentOutputsForAddress(address, txid, index), key: Index.getSpentOutputsForAddress(address, txid, index),
value: JSON.stringify({ value: JSON.stringify({
heightSpent: block.height, heightSpent: block.height,
spentTx: txid, spentTx: txid,
spentTxInputIndex: index, spentTxInputIndex: index,
spendInput: input.toObject() spendInput: input.toObject()
}) })
}); });
}
}); });
}; };
}; };
TransactionService.prototype._getAddressForInput = function(input) {
var script = input.script;
// TODO: move this to bitcore
return new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress();
};
TransactionService.prototype._confirmTransaction = function(ops, block, transaction) { TransactionService.prototype._confirmTransaction = function(ops, block, transaction) {
var self = this; var self = this;
ops.push({ ops.push({

View File

@ -39,7 +39,6 @@
"bluebird": "^2.9.12", "bluebird": "^2.9.12",
"body-parser": "^1.12.0", "body-parser": "^1.12.0",
"bufferput": "bitpay/node-bufferput", "bufferput": "bitpay/node-bufferput",
"buffertools": "*",
"compression": "^1.4.1", "compression": "^1.4.1",
"config": "^1.12.0", "config": "^1.12.0",
"cors": "^2.5.3", "cors": "^2.5.3",