From ed0a46a525de2362f9ab2477dbf8e3699a4f056d Mon Sep 17 00:00:00 2001 From: Patrick Nagurny Date: Tue, 1 Sep 2015 18:22:42 -0400 Subject: [PATCH] add tests --- bitcore-node/addresses.js | 44 +- bitcore-node/transactions.js | 18 +- test/bitcore-node/addresses.js | 559 ++++++++++++++++++ test/bitcore-node/blocks.js | 38 ++ test/bitcore-node/transactions.js | 912 ++++++++++++++++++++++++++++++ 5 files changed, 1543 insertions(+), 28 deletions(-) create mode 100644 test/bitcore-node/addresses.js create mode 100644 test/bitcore-node/transactions.js diff --git a/bitcore-node/addresses.js b/bitcore-node/addresses.js index 13454a1..2b1442a 100644 --- a/bitcore-node/addresses.js +++ b/bitcore-node/addresses.js @@ -9,7 +9,7 @@ function AddressController(node) { this.txController = new TxController(node); } -AddressController.prototype.show = function(req, res, next) { +AddressController.prototype.show = function(req, res) { this.getAddressHistory(req.addr, function(err, data) { if(err) { return common.handleErrors(err, res); @@ -19,23 +19,23 @@ AddressController.prototype.show = function(req, res, next) { }); }; -AddressController.prototype.balance = function(req, res, next) { - this.addressHistorySubQuery(req, res, next, 'balanceSat'); +AddressController.prototype.balance = function(req, res) { + this.addressHistorySubQuery(req, res, 'balanceSat'); }; -AddressController.prototype.totalReceived = function(req, res, next) { - this.addressHistorySubQuery(req, res, next, 'totalReceivedSat'); +AddressController.prototype.totalReceived = function(req, res) { + this.addressHistorySubQuery(req, res, 'totalReceivedSat'); }; -AddressController.prototype.totalSent = function(req, res, next) { - this.addressHistorySubQuery(req, res, next, 'totalSentSat'); +AddressController.prototype.totalSent = function(req, res) { + this.addressHistorySubQuery(req, res, 'totalSentSat'); }; -AddressController.prototype.unconfirmedBalance = function(req, res, next) { - this.addressHistorySubQuery(req, res, next, 'unconfirmedBalanceSat'); +AddressController.prototype.unconfirmedBalance = function(req, res) { + this.addressHistorySubQuery(req, res, 'unconfirmedBalanceSat'); }; -AddressController.prototype.addressHistorySubQuery = function(req, res, next, param) { +AddressController.prototype.addressHistorySubQuery = function(req, res, param) { this.getAddressHistory(req.addr, function(err, data) { if(err) { return common.handleErrors(err, res); @@ -92,7 +92,7 @@ AddressController.prototype.check = function(req, res, next, addresses) { } next(); -} +}; AddressController.prototype.transformAddressHistory = function(txinfos, address) { var transactions = txinfos.map(function(info) { @@ -141,7 +141,7 @@ AddressController.prototype.transformAddressHistory = function(txinfos, address) }; }; -AddressController.prototype.utxo = function(req, res, next) { +AddressController.prototype.utxo = function(req, res) { var self = this; this.node.getUnspentOutputs(req.addr, true, function(err, utxos) { @@ -155,7 +155,7 @@ AddressController.prototype.utxo = function(req, res, next) { }); }; -AddressController.prototype.multiutxo = function(req, res, next) { +AddressController.prototype.multiutxo = function(req, res) { var self = this; this.node.getUnspentOutputs(req.addrs, true, function(err, utxos) { @@ -174,7 +174,7 @@ AddressController.prototype.transformUtxo = function(utxo) { address: utxo.address, txid: utxo.txid, vout: utxo.outputIndex, - ts: utxo.timestamp ? Math.round(utxo.timestamp / 1000) : Math.round(Date.now() / 1000), + ts: utxo.timestamp ? parseInt(utxo.timestamp) : Date.now(), scriptPubKey: utxo.script, amount: utxo.satoshis / 1e8, confirmations: utxo.confirmations @@ -196,13 +196,19 @@ AddressController.prototype.multitxs = function(req, res, next) { AddressController.prototype.transformAddressHistoryForMultiTxs = function(txinfos) { var self = this; + var items = txinfos.map(function(txinfo) { + return txinfo.tx; + }).filter(function(value, index, self) { + return self.indexOf(value) === index; + }).map(function(tx) { + return self.txController.transformTransaction(tx); + }).reverse(); + var transformed = { - totalItems: txinfos.length, + totalItems: items.length, from: 0, - to: txinfos.length, - items: txinfos.map(function(txinfo) { - return self.txController.transformTransaction(txinfo.tx); - }).reverse() + to: items.length, + items: items }; return transformed; diff --git a/bitcore-node/transactions.js b/bitcore-node/transactions.js index 1344952..495528f 100644 --- a/bitcore-node/transactions.js +++ b/bitcore-node/transactions.js @@ -70,7 +70,7 @@ TxController.prototype.transformTransaction = function(transaction) { transformed.blockhash = transaction.__blockHash; transformed.confirmations = confirmations; - transformed.time = transaction.__timestamp ? transaction.__timestamp : Date.now(); // can we get this from bitcoind? + transformed.time = transaction.__timestamp ? Math.round(transaction.__timestamp / 1000) : Math.round(Date.now() / 1000); // can we get this from bitcoind? transformed.blocktime = transformed.time; if(transaction.isCoinbase()) { @@ -104,9 +104,9 @@ TxController.prototype.transformInput = function(input, index) { transformed.valueSat = input.output.satoshis; transformed.value = input.output.satoshis / 1e8; transformed.doubleSpentTxID = null; // TODO - transformed.isConfirmed = null; // TODO - transformed.confirmations = null; // TODO - transformed.unconfirmedInput = null; // TODO + //transformed.isConfirmed = null; // TODO + //transformed.confirmations = null; // TODO + //transformed.unconfirmedInput = null; // TODO } return transformed; @@ -121,10 +121,10 @@ TxController.prototype.transformOutput = function(output, index) { hex: output.script, reqSigs: null, // TODO type: null // TODO - }, - spentTxId: null, // TODO - spentIndex: null, // TODO - spentTs: null // TODO + } + //spentTxId: undefined, // TODO + //spentIndex: undefined, // TODO + //spentTs: undefined // TODO }; var address = bitcore.Script(output.script).toAddress(this.node.network).toString(); @@ -186,7 +186,7 @@ TxController.prototype.list = function(req, res) { async.mapSeries(txs, function(tx, next) { tx.__blockHash = block.hash; tx.__height = blockInfo.height; - tx.__timestamp = block.header.time; + tx.__timestamp = block.header.time * 1000; tx.populateInputs(self.node.services.db, [], function(err) { if(err) { diff --git a/test/bitcore-node/addresses.js b/test/bitcore-node/addresses.js new file mode 100644 index 0000000..ef26d82 --- /dev/null +++ b/test/bitcore-node/addresses.js @@ -0,0 +1,559 @@ +'use strict'; +var sinon = require('sinon'); +var should = require('should'); +var AddressController = require('../../bitcore-node/addresses'); +var _ = require('lodash'); +var bitcore = require('bitcore'); + +var diff = function(a, b) { + if(Array.isArray(a)) { + var r = []; + for(var i = 0; i < a.length; i++) { + if(b[i] === a[i]) { + break; + } else { + if(_.isObject(a[i])) { + r.push(diff(a[i], b[i])); + } else { + r.push(a[i]); + } + } + } + + return r; + } else { + var r = {}; + _.each(a, function(v,k) { + if(b[k] === v) return; + // but what if it returns an empty object? still attach? + r[k] = _.isObject(v) + ? diff(v, b[k]) + : v + ; + }); + return r; + } +} + +var txinfos = [ + { + "address": "mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er", + "satoshis": 2782729129, + "height": 534105, + "confirmations": 123, + "timestamp": 1441068774, + "fees": 35436, + "outputIndexes": [ + 0 + ], + "inputIndexes": [], + "tx": { + "hash": "bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7", + "version": 1, + "inputs": [ + { + "prevTxId": "ea5e5bafbf29cdf6f6097ab344128477e67889d4d6203cb43594836daa6cc425", + "outputIndex": 1, + "sequenceNumber": 4294967294, + "script": "483045022100f4d169783bef70e3943d2a617cce55d9fe4e33fc6f9880b8277265e2f619a97002201238648abcdf52960500664e969046d41755f7fc371971ebc78002fc418465a6012103acdcd31d51272403ce0829447e59e2ac9e08ed0bf92011cbf7420addf24534e6", + "scriptString": "72 0x3045022100f4d169783bef70e3943d2a617cce55d9fe4e33fc6f9880b8277265e2f619a97002201238648abcdf52960500664e969046d41755f7fc371971ebc78002fc418465a601 33 0x03acdcd31d51272403ce0829447e59e2ac9e08ed0bf92011cbf7420addf24534e6", + "output": { + "satoshis": 2796764565, + "script": "76a91488b1fe8aec5ae4358a11447a2f22b2781faedb9b88ac" + } + } + ], + "outputs": [ + { + "satoshis": 2782729129, + "script": "76a9143583efb5e64a4668c6c54bb5fcc30af4417b4f2d88ac" + }, + { + "satoshis": 14000000, + "script": "76a9149713201957f42379e574d7c70d506ee49c2c8ad688ac" + } + ], + "nLockTime": 534089 + } + }, + { + "address": "mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er", + "satoshis": -2782729129, + "height": 534110, + "confirmations": 118, + "timestamp": 1441072817, + "fees": 35437, + "outputIndexes": [], + "inputIndexes": [ + "0" + ], + "tx": { + "hash": "01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3", + "version": 1, + "inputs": [ + { + "prevTxId": "bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7", + "outputIndex": 0, + "sequenceNumber": 4294967294, + "script": "47304402201ee69281db6b95bb1aa3074059b67581635b719e8f64e4c2694db6ec56ad9447022011e91528996ea459b1fb2c0b59363fecbefe4bc2ca90f7b2382bdaa358f2d5640121034cc057b12a68ee79df998004b9a1341bbb18b17ea4939bebaa3bac001e940f24", + "scriptString": "71 0x304402201ee69281db6b95bb1aa3074059b67581635b719e8f64e4c2694db6ec56ad9447022011e91528996ea459b1fb2c0b59363fecbefe4bc2ca90f7b2382bdaa358f2d56401 33 0x034cc057b12a68ee79df998004b9a1341bbb18b17ea4939bebaa3bac001e940f24", + "output": { + "satoshis": 2782729129, + "script": "76a9143583efb5e64a4668c6c54bb5fcc30af4417b4f2d88ac" + } + } + ], + "outputs": [ + { + "satoshis": 2764693692, + "script": "76a91456e446bc3489543d8324c6d0271524c0bd0506dd88ac" + }, + { + "satoshis": 18000000, + "script": "76a914011d2963b619186a318f768dddfd98cd553912a088ac" + } + ], + "nLockTime": 534099 + } + } +]; + +var tx = bitcore.Transaction().fromObject({ + "hash": "63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73", + "version": 1, + "inputs": [ + { + "prevTxId": "ea97726ffc529808094ae5568342267931a058375a20147535a0d095837079f3", + "outputIndex": 1, + "sequenceNumber": 4294967295, + "script": "473044022054233934268b30be779fad874ef42e8db928ba27a1b612d5f111b3ee95eb271c022024272bbaf2dcc4050bd3b9dfa3c93884f6ba6ad7d257598b8245abb65b5ab1e40141040682fdb281a8533e21e13dfd1fcfa424912a85b6cdc4136b5842c85de05ac1f0e4a013f20702adeb53329de13b2ef388e5ed6244676f4f1ee4ee685ab607964d", + "scriptString": "71 0x3044022054233934268b30be779fad874ef42e8db928ba27a1b612d5f111b3ee95eb271c022024272bbaf2dcc4050bd3b9dfa3c93884f6ba6ad7d257598b8245abb65b5ab1e401 65 0x040682fdb281a8533e21e13dfd1fcfa424912a85b6cdc4136b5842c85de05ac1f0e4a013f20702adeb53329de13b2ef388e5ed6244676f4f1ee4ee685ab607964d", + "output": { + "satoshis": 53540000, + "script": "76a91454dcfbff9e109bf369e457f6b0f869f4e647076488ac" + } + }, + { + "prevTxId": "980a9cc2dbc2d3464eb9900ae6d579a03045408563320f62d99316c3d4ff58b7", + "outputIndex": 2, + "sequenceNumber": 4294967295, + "script": "473044022044938ac3f8fcb8da29011df6397ed28cc7e894cdc35d596d4f3623bd8c7e465f022014829c6e0bd7ee97a1bcfef6b85c5fd232653f289394fc6ce6ebb41c73403f1b014104d9ccf88efc6e5be3151fae5e848efd94c91d75e7bf621f9f724a8caff51415338525d3239fae6b93826edf759dd562f77693e55dfa852ffd96a92d683db590f2", + "scriptString": "71 0x3044022044938ac3f8fcb8da29011df6397ed28cc7e894cdc35d596d4f3623bd8c7e465f022014829c6e0bd7ee97a1bcfef6b85c5fd232653f289394fc6ce6ebb41c73403f1b01 65 0x04d9ccf88efc6e5be3151fae5e848efd94c91d75e7bf621f9f724a8caff51415338525d3239fae6b93826edf759dd562f77693e55dfa852ffd96a92d683db590f2", + "output": { + "satoshis": 299829, + "script": "76a914db731c9ebf3874d75ee26b9c19b692d278c283f788ac" + } + } + ], + "outputs": [ + { + "satoshis": 220000, + "script": "76a914b9bbd76588d9e4e09f0369a9aa0b2749a11c4e8d88ac" + }, + { + "satoshis": 53320000, + "script": "76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac" + }, + { + "satoshis": 289829, + "script": "76a914583df9fa56ad961051e00ca93e68dfaf1eab9ec588ac" + } + ], + "nLockTime": 0 +}); + +tx.__height = 534181; +tx.__timestamp = 1441116143000; +tx.__blockHash = '0000000000000041ddc94ecf4f86a456a83b2e320c36c6f0c13ff92c7e75f013'; +var txinfos2 = [ + { + tx: tx + }, + { + tx: tx + } +]; + +var utxos = [ + { + "address": "mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK", + "txid": "63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73", + "outputIndex": 1, + "timestamp": 1441116143, + "satoshis": 53320000, + "script": "76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac", + "blockHeight": 534181, + "confirmations": 50 + }, + { + "address": "moZY18rGNmh4YCPeugtGW46AkkWMQttBUD", + "txid": "63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73", + "outputIndex": 2, + "timestamp": 1441116143, + "satoshis": 289829, + "script": "76a914583df9fa56ad961051e00ca93e68dfaf1eab9ec588ac", + "blockHeight": 534181, + "confirmations": 50 + } +]; + +describe('Addresses', function() { + describe('/addr/:addr', function() { + var node = { + getAddressHistory: sinon.stub().callsArgWith(2, null, txinfos) + }; + + var addresses = new AddressController(node); + var req = { + addr: 'mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er' + }; + + it('should have correct data', function(done) { + var insight = { + "addrStr": "mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er", + "balance": 0, + "balanceSat": 0, + "totalReceived": 27.82729129, + "totalReceivedSat": 2782729129, + "totalSent": 27.82729129, + "totalSentSat": 2782729129, + "unconfirmedBalance": 0, + "unconfirmedBalanceSat": 0, + "unconfirmedTxApperances": 0, + "txApperances": 2, + "transactions": [ + "bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7", + "01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3" + ] + }; + + var res = { + jsonp: function(data) { + should(data).eql(insight); + done(); + } + }; + addresses.show(req, res); + }); + + it('/balance', function(done) { + var insight = 0; + + var res = { + jsonp: function(data) { + should(data).eql(insight); + done(); + } + }; + addresses.balance(req, res); + }); + + it('/totalReceived', function(done) { + var insight = 2782729129; + + var res = { + jsonp: function(data) { + should(data).eql(insight); + done(); + } + }; + + addresses.totalReceived(req, res); + }); + + it('/totalSent', function(done) { + var insight = 2782729129; + + var res = { + jsonp: function(data) { + should(data).eql(insight); + done(); + } + }; + + addresses.totalSent(req, res); + }); + + it('/unconfirmedBalance', function(done) { + var insight = 0; + + var res = { + jsonp: function(data) { + should(data).eql(insight); + done(); + } + }; + + addresses.unconfirmedBalance(req, res); + }); + }); + + describe('/addr/:addr/utxo', function() { + it('should have correct data', function(done) { + var insight = [ + { + "address": "mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK", + "txid": "63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73", + "vout": 1, + "ts": 1441116143, + "scriptPubKey": "76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac", + "amount": 0.5332, + "confirmations": 50, + "confirmationsFromCache": true + } + ]; + + var todos = [ + { + confirmationsFromCache: true + } + ]; + + var node = { + getUnspentOutputs: sinon.stub().callsArgWith(2, null, utxos.slice(0, 1)) + }; + + var addresses = new AddressController(node); + + var req = { + addr: 'mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK' + }; + + var res = { + jsonp: function(data) { + var merged = _.merge(data, todos); + should(merged).eql(insight); + done(); + } + }; + + addresses.utxo(req, res); + }); + }); + + describe('/addrs/:addrs/utxo', function() { + it('should have the correct data', function(done) { + var insight = [ + { + "address": "mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK", + "txid": "63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73", + "vout": 1, + "ts": 1441116143, + "scriptPubKey": "76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac", + "amount": 0.5332, + "confirmations": 50, + "confirmationsFromCache": true + }, + { + "address": "moZY18rGNmh4YCPeugtGW46AkkWMQttBUD", + "txid": "63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73", + "vout": 2, + "ts": 1441116143, + "scriptPubKey": "76a914583df9fa56ad961051e00ca93e68dfaf1eab9ec588ac", + "amount": 0.00289829, + "confirmations": 50, + "confirmationsFromCache": true + } + ]; + + var todos = [ + { + confirmationsFromCache: true + }, { + confirmationsFromCache: true + } + ]; + + var node = { + getUnspentOutputs: sinon.stub().callsArgWith(2, null, utxos) + }; + + var addresses = new AddressController(node); + + var req = { + addrs: 'mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK,moZY18rGNmh4YCPeugtGW46AkkWMQttBUD' + }; + + var res = { + jsonp: function(data) { + var merged = _.merge(data, todos); + should(merged).eql(insight); + done(); + } + }; + + addresses.multiutxo(req, res); + }); + }); + + describe('/addrs/:addrs/txs', function() { + it('should have correct data', function(done) { + var insight = { + "totalItems": 1, + "from": 0, + "to": 1, + "items": [ + { + "txid": "63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "ea97726ffc529808094ae5568342267931a058375a20147535a0d095837079f3", + "vout": 1, + "scriptSig": { + "asm": "3044022054233934268b30be779fad874ef42e8db928ba27a1b612d5f111b3ee95eb271c022024272bbaf2dcc4050bd3b9dfa3c93884f6ba6ad7d257598b8245abb65b5ab1e401 040682fdb281a8533e21e13dfd1fcfa424912a85b6cdc4136b5842c85de05ac1f0e4a013f20702adeb53329de13b2ef388e5ed6244676f4f1ee4ee685ab607964d", + "hex": "473044022054233934268b30be779fad874ef42e8db928ba27a1b612d5f111b3ee95eb271c022024272bbaf2dcc4050bd3b9dfa3c93884f6ba6ad7d257598b8245abb65b5ab1e40141040682fdb281a8533e21e13dfd1fcfa424912a85b6cdc4136b5842c85de05ac1f0e4a013f20702adeb53329de13b2ef388e5ed6244676f4f1ee4ee685ab607964d" + }, + "sequence": 4294967295, + "n": 0, + "addr": "moFfnRwt77pApKnnU6m5uocFaa43aAYpt5", + "valueSat": 53540000, + "value": 0.5354, + "doubleSpentTxID": null + }, + { + "txid": "980a9cc2dbc2d3464eb9900ae6d579a03045408563320f62d99316c3d4ff58b7", + "vout": 2, + "scriptSig": { + "asm": "3044022044938ac3f8fcb8da29011df6397ed28cc7e894cdc35d596d4f3623bd8c7e465f022014829c6e0bd7ee97a1bcfef6b85c5fd232653f289394fc6ce6ebb41c73403f1b01 04d9ccf88efc6e5be3151fae5e848efd94c91d75e7bf621f9f724a8caff51415338525d3239fae6b93826edf759dd562f77693e55dfa852ffd96a92d683db590f2", + "hex": "473044022044938ac3f8fcb8da29011df6397ed28cc7e894cdc35d596d4f3623bd8c7e465f022014829c6e0bd7ee97a1bcfef6b85c5fd232653f289394fc6ce6ebb41c73403f1b014104d9ccf88efc6e5be3151fae5e848efd94c91d75e7bf621f9f724a8caff51415338525d3239fae6b93826edf759dd562f77693e55dfa852ffd96a92d683db590f2" + }, + "sequence": 4294967295, + "n": 1, + "addr": "n1XJBAyU4hNR4xRtY3UxnmAteoJX83p5qv", + "valueSat": 299829, + "value": 0.00299829, + "doubleSpentTxID": null + } + ], + "vout": [ + { + "value": "0.00220000", + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 b9bbd76588d9e4e09f0369a9aa0b2749a11c4e8d OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914b9bbd76588d9e4e09f0369a9aa0b2749a11c4e8d88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mxT2KzTUQvsaYYothDtjcdvyAdaHA9ofMp" + ] + } + }, + { + "value": "0.53320000", + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 d2ec20bb8e5f25a52f730384b803d95683250e0b OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK" + ] + } + }, + { + "value": "0.00289829", + "n": 2, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 583df9fa56ad961051e00ca93e68dfaf1eab9ec5 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914583df9fa56ad961051e00ca93e68dfaf1eab9ec588ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "moZY18rGNmh4YCPeugtGW46AkkWMQttBUD" + ] + } + } + ], + "blockhash": "0000000000000041ddc94ecf4f86a456a83b2e320c36c6f0c13ff92c7e75f013", + "confirmations": 52, + "time": 1441116143, + "blocktime": 1441116143, + "valueOut": 0.53829829, + "size": 470, + "valueIn": 0.53839829, + "fees": 0.0001, + "firstSeenTs": 1441108193 + } + ] + }; + + var todos = { + "items": [ + { + "vin": [ + { + "scriptSig": { + "asm": "3044022054233934268b30be779fad874ef42e8db928ba27a1b612d5f111b3ee95eb271c022024272bbaf2dcc4050bd3b9dfa3c93884f6ba6ad7d257598b8245abb65b5ab1e401 040682fdb281a8533e21e13dfd1fcfa424912a85b6cdc4136b5842c85de05ac1f0e4a013f20702adeb53329de13b2ef388e5ed6244676f4f1ee4ee685ab607964d" + } + }, + { + "scriptSig": { + "asm": "3044022044938ac3f8fcb8da29011df6397ed28cc7e894cdc35d596d4f3623bd8c7e465f022014829c6e0bd7ee97a1bcfef6b85c5fd232653f289394fc6ce6ebb41c73403f1b01 04d9ccf88efc6e5be3151fae5e848efd94c91d75e7bf621f9f724a8caff51415338525d3239fae6b93826edf759dd562f77693e55dfa852ffd96a92d683db590f2" + } + } + ], + "vout": [ + { + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 b9bbd76588d9e4e09f0369a9aa0b2749a11c4e8d OP_EQUALVERIFY OP_CHECKSIG", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [] + } + }, + { + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 d2ec20bb8e5f25a52f730384b803d95683250e0b OP_EQUALVERIFY OP_CHECKSIG", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [] + } + }, + { + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 583df9fa56ad961051e00ca93e68dfaf1eab9ec5 OP_EQUALVERIFY OP_CHECKSIG", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [] + } + } + ], + "firstSeenTs": 1441108193 + } + ] + }; + + var node = { + getAddressHistory: sinon.stub().callsArgWith(2, null, txinfos2), + services: { + db: { + tip: { + __height: 534232 + } + } + }, + network: 'testnet' + }; + + var addresses = new AddressController(node); + + var req = { + addrs: 'mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK,moZY18rGNmh4YCPeugtGW46AkkWMQttBUD' + }; + + var res = { + jsonp: function(data) { + var merged = _.merge(data, todos); + should(merged).eql(insight); + done(); + } + }; + + addresses.multitxs(req, res); + }); + }); +}); \ No newline at end of file diff --git a/test/bitcore-node/blocks.js b/test/bitcore-node/blocks.js index bfb481b..d74eb70 100644 --- a/test/bitcore-node/blocks.js +++ b/test/bitcore-node/blocks.js @@ -30,6 +30,12 @@ var blockIndexes = { chainWork: '00000000000000000000000000000000000000000000000544ea52e0575ba752', prevHash: '000000000001b9c41e6c4a7b81a068b50cf3f522ee4ac1e942e75ec16e090547', height: 533950 + }, + 533974: { + hash: '0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7', + chainWork: '0000000000000000000000000000000000000000000000054626b1839ade284a', + prevHash: '00000000000001a55f3214e9172eb34b20e0bc5bd6b8007f3f149fca2c8991a4', + height: 533974 } }; @@ -162,4 +168,36 @@ describe('Blocks', function() { blocks.list(req, res); }); }); + + describe('/block-index/:height route', function() { + var node = { + services: { + bitcoind: { + getBlockIndex: function(height) { + return blockIndexes[height]; + } + } + } + }; + + it('should have correct data', function(done) { + var blocks = new BlockController(node); + + var insight = { + "blockHash": "0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7" + }; + + var req = {}; + var res = { + jsonp: function(data) { + should(data).eql(insight); + done(); + } + }; + var next = function() {}; + var height = 533974; + + blocks.blockIndex(req, res, next, height); + }); + }); }); \ No newline at end of file diff --git a/test/bitcore-node/transactions.js b/test/bitcore-node/transactions.js new file mode 100644 index 0000000..bbe521f --- /dev/null +++ b/test/bitcore-node/transactions.js @@ -0,0 +1,912 @@ +'use strict'; +var should = require('should'); +var sinon = require('sinon'); +var bitcore = require('bitcore'); +var TxController = require('../../bitcore-node/transactions'); +var _ = require('lodash'); + +/*var diff = function(a, b) { + var r = {}; + _.each(a, function(v,k) { + if(b[k] === v) return; + // but what if it returns an empty object? still attach? + r[k] = _.isObject(v) + ? diff(v, b[k]) + : v + ; + }); + return r; +};*/ + +var diff = function(a, b) { + if(Array.isArray(a)) { + var r = []; + for(var i = 0; i < a.length; i++) { + if(b[i] === a[i]) { + break; + } else { + if(_.isObject(a[i])) { + r.push(diff(a[i], b[i])); + } else { + r.push(a[i]); + } + } + } + + return r; + } else { + var r = {}; + _.each(a, function(v,k) { + if(b[k] === v) return; + // but what if it returns an empty object? still attach? + r[k] = _.isObject(v) + ? diff(v, b[k]) + : v + ; + }); + return r; + } +} + +describe('Transactions', function() { + describe('/tx/:txid', function() { + it('should have correct data', function(done) { + var insight = { + "txid": "b85334bf2df35c6dd5b294efe92ffc793a78edff75a2ca666fc296ffb04bbba0", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "87c9b0f27571fff14b8c2d69e55614eacedd0f59fcc490b721320f9dae145aad", + "vout": 0, + "scriptSig": { + "asm": "30450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c01 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "hex": "4830450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307" + }, + "sequence": 4294967295, + "n": 0, + "addr": "mqdofsXHpePPGBFXuwwypAqCcXi48Xhb2f", + "valueSat": 18535505, + "value": 0.18535505, + "doubleSpentTxID": null, + "isConfirmed": true, + "confirmations": 242, + "unconfirmedInput": false + }, + { + "txid": "d8a10aaedf3dd33b5ddf8979273f3dbf61e4638d1aa6a93c59ea22bc65ac2196", + "vout": 0, + "scriptSig": { + "asm": "30440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb3101 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "hex": "4730440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb31014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307" + }, + "sequence": 4294967295, + "n": 1, + "addr": "mqdofsXHpePPGBFXuwwypAqCcXi48Xhb2f", + "valueSat": 16419885, + "value": 0.16419885, + "doubleSpentTxID": null, + "isConfirmed": true, + "confirmations": 242, + "unconfirmedInput": false + } + ], + "vout": [ + { + "value": "0.21247964", + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 4b7b335f978f130269fe661423258ae9642df8a1 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9144b7b335f978f130269fe661423258ae9642df8a188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mnQ4ZaGessNgdxmWPxbTHcfx4b8R6eUr1X" + ] + } + }, + { + "value": "0.13677426", + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6efcf883b4b6f9997be9a0600f6c095fe2bd2d92 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mqdofsXHpePPGBFXuwwypAqCcXi48Xhb2f" + ] + }, + "spentTxId": "614fe1708825f9c21732394e4784cc6808ac1d8b939736bfdead970567561eec", + "spentIndex": 1, + "spentTs": 1440997099 + } + ], + "blockhash": "0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7", + "confirmations": 230, + "time": 1440987503, + "blocktime": 1440987503, + "valueOut": 0.3492539, + "size": 437, + "valueIn": 0.3495539, + "fees": 0.0003 + }; + + var bitcoreTxObj = { + "hash": "b85334bf2df35c6dd5b294efe92ffc793a78edff75a2ca666fc296ffb04bbba0", + "version": 1, + "inputs": [ + { + "prevTxId": "87c9b0f27571fff14b8c2d69e55614eacedd0f59fcc490b721320f9dae145aad", + "outputIndex": 0, + "sequenceNumber": 4294967295, + "script": "4830450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "scriptString": "72 0x30450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c01 65 0x04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "output": { + "satoshis": 18535505, + "script": "76a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac" + } + }, + { + "prevTxId": "d8a10aaedf3dd33b5ddf8979273f3dbf61e4638d1aa6a93c59ea22bc65ac2196", + "outputIndex": 0, + "sequenceNumber": 4294967295, + "script": "4730440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb31014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "scriptString": "71 0x30440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb3101 65 0x04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "output": { + "satoshis": 16419885, + "script": "76a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac" + } + } + ], + "outputs": [ + { + "satoshis": 21247964, + "script": "76a9144b7b335f978f130269fe661423258ae9642df8a188ac" + }, + { + "satoshis": 13677426, + "script": "76a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac" + } + ], + "nLockTime": 0 + }; + + var todos = { + vin: [ + { + confirmations: 242, + isConfirmed: true, + scriptSig: { + asm: '30450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c01 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307' + }, + unconfirmedInput: false + }, + { + confirmations: 242, + isConfirmed: true, + scriptSig: { + asm: '30440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb3101 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307' + }, + unconfirmedInput: false + } + ], + vout: [ + { + scriptPubKey: { + asm: 'OP_DUP OP_HASH160 4b7b335f978f130269fe661423258ae9642df8a1 OP_EQUALVERIFY OP_CHECKSIG', + reqSigs: 1, + type: 'pubkeyhash' + } + }, + { + scriptPubKey: { + asm: 'OP_DUP OP_HASH160 6efcf883b4b6f9997be9a0600f6c095fe2bd2d92 OP_EQUALVERIFY OP_CHECKSIG', + reqSigs: 1, + type: 'pubkeyhash' + }, + spentIndex: 1, + spentTs: 1440997099, + spentTxId: '614fe1708825f9c21732394e4784cc6808ac1d8b939736bfdead970567561eec' + } + ] + }; + + var bitcoreTx = bitcore.Transaction(bitcoreTxObj); + bitcoreTx.__blockHash = '0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7'; + bitcoreTx.__height = 533974; + bitcoreTx.__timestamp = 1440987503000; + bitcoreTx.populateInputs = sinon.stub().callsArg(2); + bitcoreTx.toObject = sinon.stub().returns(bitcoreTxObj); + + var node = { + getTransactionWithBlockInfo: sinon.stub().callsArgWith(2, null, bitcoreTx), + services: { + db: { + tip: { + __height: 534203 + } + } + }, + network: 'testnet' + }; + + var transactions = new TxController(node); + var req = {}; + var res = {}; + var next = function() { + var merged = _.merge(req.transaction, todos); + should(merged).eql(insight); + done(); + }; + var txid = 'b85334bf2df35c6dd5b294efe92ffc793a78edff75a2ca666fc296ffb04bbba0'; + + transactions.transaction(req, res, next, txid); + }); + }); + + describe('/txs', function() { + it('by block hash', function(done) { + var blockHex = '07000020a491892cca9f143f7f00b8d65bbce0204bb32e17e914325fa5010000000000003e28f0519ecf01f7f01ea8da61084b2e4741a18ce1f3738117b84458353764b06fb9e35567f20c1a78eb626f0301000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2303d6250800feb0aae355fe263600000963676d696e6572343208ae5800000000000000ffffffff01c018824a000000001976a91468bedce8982d25c3b6b03f6238cbad00378b8ead88ac000000000100000002ad5a14ae9d0f3221b790c4fc590fddceea1456e5692d8c4bf1ff7175f2b0c987000000008b4830450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307ffffffff9621ac65bc22ea593ca9a61a8d63e461bf3d3f277989df5d3bd33ddfae0aa1d8000000008a4730440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb31014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307ffffffff02dc374401000000001976a9144b7b335f978f130269fe661423258ae9642df8a188ac72b3d000000000001976a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac000000000100000002060d3cb6dfb7ffe85e2908010fea63190c9707e96fc7448128eb895b5e222771030000006b483045022100f67cffc0ae23adb236ff3edb4a9736e277605db30cc7708dfab8cf1e1483bbce022052396aa5d664ec1cb65992c423fd9a17e94dc7af328d2d559e90746dd195ca5901210346134da14907581d8190d3980caaf46d95e4eb9c1ca8e70f1fc6007fefb1909dfeffffff7b2d8a8263cffbdb722e2a5c74166e6f2258634e277c0b08f51b578b667e2fba000000006a473044022077222a91cda23af69179377c62d84a176fb12caff6c5cbf6ae9e5957ff3b1afe0220768edead76819228dcba18cca3c9a5a5d4c32919720f21df21a297ba375bbe5c012103371ea5a4dfe356b3ea4042a537d7ab7ee0faabd43e21b6cc076fda2240629eeefeffffff02209a1d00000000001976a9148e451eec7ca0a1764b4ab119274efdd2727b3c8588ac40420f00000000001976a914d0fce8f064cd1059a6a11501dd66fe42368572b088accb250800'; + var blockIndex = { + "hash": "0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7", + "chainWork": "0000000000000000000000000000000000000000000000054626b1839ade284a", + "prevHash": "00000000000001a55f3214e9172eb34b20e0bc5bd6b8007f3f149fca2c8991a4", + "height": 533974 + }; + + var block = bitcore.Block.fromBuffer(new Buffer(blockHex, 'hex')); + + var node = { + getBlock: sinon.stub().callsArgWith(1, null, block), + services: { + bitcoind: { + getBlockIndex: sinon.stub().returns(blockIndex) + }, + db: { + tip: { + __height: 534209 + } + } + }, + network: 'testnet' + }; + + bitcore.Transaction.prototype.populateInputs = function(db, pool, callback) { + if(this.hash === 'b85334bf2df35c6dd5b294efe92ffc793a78edff75a2ca666fc296ffb04bbba0') { + this.inputs[0].output = new bitcore.Transaction.Output({ + satoshis: 18535505, + script: '76a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac' + }); + + this.inputs[1].output = new bitcore.Transaction.Output({ + satoshis: 16419885, + script: '76a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac' + }); + } else if(this.hash === '2e01c7a4a0e335112236b711c4aaddd02e8dc59ba2cda416e8f80ff06dddd7e1') { + this.inputs[0].output = new bitcore.Transaction.Output({ + satoshis: 990000, + script: '76a9140b6a5b76fab66d809e0f9e9336c79011880ba96188ac' + }); + this.inputs[1].output = new bitcore.Transaction.Output({ + satoshis: 1960000, + script: '76a914ff6498e8c2498cbad016e1bf3a28cfb178995dbd88ac' + }); + } + + callback(); + }; + + var transactions = new TxController(node); + + var insight = { + "pagesTotal": 1, + "txs": [ + { + "txid": "25a988e54b02e0e5df146a0f8fa7b9db56210533a9f04bdfda5f4ceb6f77aadd", + "version": 1, + "locktime": 0, + "vin": [ + { + "coinbase": "03d6250800feb0aae355fe263600000963676d696e6572343208ae5800000000000000", + "sequence": 4294967295, + "n": 0 + } + ], + "vout": [ + { + "value": "12.50040000", + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 68bedce8982d25c3b6b03f6238cbad00378b8ead OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91468bedce8982d25c3b6b03f6238cbad00378b8ead88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mq4oDPjmNWnBxbzx7qouzhpCSTMePUtYDF" + ] + } + } + ], + "blockhash": "0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7", + "confirmations": 236, + "time": 1440987503, + "blocktime": 1440987503, + "isCoinBase": true, + "valueOut": 12.5004, + "size": 120 + }, + { + "txid": "b85334bf2df35c6dd5b294efe92ffc793a78edff75a2ca666fc296ffb04bbba0", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "87c9b0f27571fff14b8c2d69e55614eacedd0f59fcc490b721320f9dae145aad", + "vout": 0, + "scriptSig": { + "asm": "30450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c01 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "hex": "4830450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307" + }, + "sequence": 4294967295, + "n": 0, + "addr": "mqdofsXHpePPGBFXuwwypAqCcXi48Xhb2f", + "valueSat": 18535505, + "value": 0.18535505, + "doubleSpentTxID": null + }, + { + "txid": "d8a10aaedf3dd33b5ddf8979273f3dbf61e4638d1aa6a93c59ea22bc65ac2196", + "vout": 0, + "scriptSig": { + "asm": "30440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb3101 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307", + "hex": "4730440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb31014104eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307" + }, + "sequence": 4294967295, + "n": 1, + "addr": "mqdofsXHpePPGBFXuwwypAqCcXi48Xhb2f", + "valueSat": 16419885, + "value": 0.16419885, + "doubleSpentTxID": null + } + ], + "vout": [ + { + "value": "0.21247964", + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 4b7b335f978f130269fe661423258ae9642df8a1 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9144b7b335f978f130269fe661423258ae9642df8a188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mnQ4ZaGessNgdxmWPxbTHcfx4b8R6eUr1X" + ] + } + }, + { + "value": "0.13677426", + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6efcf883b4b6f9997be9a0600f6c095fe2bd2d92 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146efcf883b4b6f9997be9a0600f6c095fe2bd2d9288ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mqdofsXHpePPGBFXuwwypAqCcXi48Xhb2f" + ] + }, + "spentTxId": "614fe1708825f9c21732394e4784cc6808ac1d8b939736bfdead970567561eec", + "spentIndex": 1, + "spentTs": 1440997099 + } + ], + "blockhash": "0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7", + "confirmations": 236, + "time": 1440987503, + "blocktime": 1440987503, + "valueOut": 0.3492539, + "size": 437, + "valueIn": 0.3495539, + "fees": 0.0003 + }, + { + "txid": "2e01c7a4a0e335112236b711c4aaddd02e8dc59ba2cda416e8f80ff06dddd7e1", + "version": 1, + "locktime": 533963, + "vin": [ + { + "txid": "7127225e5b89eb288144c76fe907970c1963ea0f0108295ee8ffb7dfb63c0d06", + "vout": 3, + "scriptSig": { + "asm": "3045022100f67cffc0ae23adb236ff3edb4a9736e277605db30cc7708dfab8cf1e1483bbce022052396aa5d664ec1cb65992c423fd9a17e94dc7af328d2d559e90746dd195ca5901 0346134da14907581d8190d3980caaf46d95e4eb9c1ca8e70f1fc6007fefb1909d", + "hex": "483045022100f67cffc0ae23adb236ff3edb4a9736e277605db30cc7708dfab8cf1e1483bbce022052396aa5d664ec1cb65992c423fd9a17e94dc7af328d2d559e90746dd195ca5901210346134da14907581d8190d3980caaf46d95e4eb9c1ca8e70f1fc6007fefb1909d" + }, + "sequence": 4294967294, + "n": 0, + "addr": "mgZK8zpudWoAaAwpLQSgc9t9PJJyEBpBdJ", + "valueSat": 990000, + "value": 0.0099, + "doubleSpentTxID": null + }, + { + "txid": "ba2f7e668b571bf5080b7c274e6358226f6e16745c2a2e72dbfbcf63828a2d7b", + "vout": 0, + "scriptSig": { + "asm": "3044022077222a91cda23af69179377c62d84a176fb12caff6c5cbf6ae9e5957ff3b1afe0220768edead76819228dcba18cca3c9a5a5d4c32919720f21df21a297ba375bbe5c01 03371ea5a4dfe356b3ea4042a537d7ab7ee0faabd43e21b6cc076fda2240629eee", + "hex": "473044022077222a91cda23af69179377c62d84a176fb12caff6c5cbf6ae9e5957ff3b1afe0220768edead76819228dcba18cca3c9a5a5d4c32919720f21df21a297ba375bbe5c012103371ea5a4dfe356b3ea4042a537d7ab7ee0faabd43e21b6cc076fda2240629eee" + }, + "sequence": 4294967294, + "n": 1, + "addr": "n4oM7bPuC4ZPdCEDvtw9xGYQC7jmi5S6F4", + "valueSat": 1960000, + "value": 0.0196, + "doubleSpentTxID": null + } + ], + "vout": [ + { + "value": "0.01940000", + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8e451eec7ca0a1764b4ab119274efdd2727b3c85 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148e451eec7ca0a1764b4ab119274efdd2727b3c8588ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mtVD3tdifBNujYzZ5N7PgXfKk4Bc85tDKA" + ] + }, + "spentTxId": "9a213b879da9073a9a30606f9046f35f36f268cbf03f6242993a97c4c07c00b9", + "spentIndex": 1, + "spentTs": 1440992946 + }, + { + "value": "0.01000000", + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 d0fce8f064cd1059a6a11501dd66fe42368572b0 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914d0fce8f064cd1059a6a11501dd66fe42368572b088ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mzZypShcs1B35udnkqeYeJy8rUdgHDDvKG" + ] + }, + "spentTxId": "418d3eb60275957b3456b96902e908abf962e71be4c4f09486564254664951bc", + "spentIndex": 34, + "spentTs": 1440999118 + } + ], + "blockhash": "0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7", + "confirmations": 236, + "time": 1440987503, + "blocktime": 1440987503, + "valueOut": 0.0294, + "size": 373, + "valueIn": 0.0295, + "fees": 0.0001 + } + ] + }; + + var todos = { + txs: [ + { + vout: [ + { + scriptPubKey: { + asm: 'OP_DUP OP_HASH160 68bedce8982d25c3b6b03f6238cbad00378b8ead OP_EQUALVERIFY OP_CHECKSIG', + reqSigs: 1, + type: 'pubkeyhash' + } + } + ] + }, + { + vin: [ + { + scriptSig: { + asm: '30450221008e5df62719cd92d7b137d00bbd27f153f2909bcad3a300960bc1020ec6d5e961022039df51600ff4fb5da5a794d1648c6b47c1f7d277fd5877fb5e52a730a3595f8c01 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307' + } + }, + { + scriptSig: { + asm: '30440220761464d7bab9515d92260762a97af82a9b25d202d8f7197b1aaec81b6fed541f022059f99606de6b06e17b2cd102dceb3807ebdd9e777a5b77c9a0b3672f5eabcb3101 04eb1e0ccd9afcac42229348dd776e991c69551ae3474340fada12e787e51758397e1d3afdba360d6374261125ea3b6ea079a5f202c150dfd729e1062d9176a307' + } + } + ], + vout: [ + { + scriptPubKey: { + asm: 'OP_DUP OP_HASH160 4b7b335f978f130269fe661423258ae9642df8a1 OP_EQUALVERIFY OP_CHECKSIG', + reqSigs: 1, + type: 'pubkeyhash' + } + }, + { + scriptPubKey: { + asm: 'OP_DUP OP_HASH160 6efcf883b4b6f9997be9a0600f6c095fe2bd2d92 OP_EQUALVERIFY OP_CHECKSIG', + reqSigs: 1, + type: 'pubkeyhash' + }, + spentIndex: 1, + spentTs: 1440997099, + spentTxId: '614fe1708825f9c21732394e4784cc6808ac1d8b939736bfdead970567561eec' + } + ] + }, + { + vin: [ + { + scriptSig: { + asm: '3045022100f67cffc0ae23adb236ff3edb4a9736e277605db30cc7708dfab8cf1e1483bbce022052396aa5d664ec1cb65992c423fd9a17e94dc7af328d2d559e90746dd195ca5901 0346134da14907581d8190d3980caaf46d95e4eb9c1ca8e70f1fc6007fefb1909d' + } + }, + { + scriptSig: { + asm: '3044022077222a91cda23af69179377c62d84a176fb12caff6c5cbf6ae9e5957ff3b1afe0220768edead76819228dcba18cca3c9a5a5d4c32919720f21df21a297ba375bbe5c01 03371ea5a4dfe356b3ea4042a537d7ab7ee0faabd43e21b6cc076fda2240629eee' + } + } + ], + vout: [ + { + scriptPubKey: { + asm: 'OP_DUP OP_HASH160 8e451eec7ca0a1764b4ab119274efdd2727b3c85 OP_EQUALVERIFY OP_CHECKSIG', + reqSigs: 1, + type: 'pubkeyhash' + }, + spentIndex: 1, + spentTs: 1440992946, + spentTxId: '9a213b879da9073a9a30606f9046f35f36f268cbf03f6242993a97c4c07c00b9' + }, + { + scriptPubKey: { + asm: 'OP_DUP OP_HASH160 d0fce8f064cd1059a6a11501dd66fe42368572b0 OP_EQUALVERIFY OP_CHECKSIG', + reqSigs: 1, + type: 'pubkeyhash' + }, + spentIndex: 34, + spentTs: 1440999118, + spentTxId: '418d3eb60275957b3456b96902e908abf962e71be4c4f09486564254664951bc' + } + ] + } + ] + } + + var req = { + query: { + block: '0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7' + } + }; + + var res = { + jsonp: function(data) { + var merged = _.merge(data, todos); + should(data).eql(insight); + done(); + } + }; + + transactions.list(req, res); + }); + it('by address', function(done) { + + var txinfos = [ + { + tx: bitcore.Transaction().fromObject({ + "hash": "bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7", + "version": 1, + "inputs": [ + { + "prevTxId": "ea5e5bafbf29cdf6f6097ab344128477e67889d4d6203cb43594836daa6cc425", + "outputIndex": 1, + "sequenceNumber": 4294967294, + "script": "483045022100f4d169783bef70e3943d2a617cce55d9fe4e33fc6f9880b8277265e2f619a97002201238648abcdf52960500664e969046d41755f7fc371971ebc78002fc418465a6012103acdcd31d51272403ce0829447e59e2ac9e08ed0bf92011cbf7420addf24534e6", + "scriptString": "72 0x3045022100f4d169783bef70e3943d2a617cce55d9fe4e33fc6f9880b8277265e2f619a97002201238648abcdf52960500664e969046d41755f7fc371971ebc78002fc418465a601 33 0x03acdcd31d51272403ce0829447e59e2ac9e08ed0bf92011cbf7420addf24534e6", + "output": { + "satoshis": 2796764565, + "script": "76a91488b1fe8aec5ae4358a11447a2f22b2781faedb9b88ac" + } + } + ], + "outputs": [ + { + "satoshis": 2782729129, + "script": "76a9143583efb5e64a4668c6c54bb5fcc30af4417b4f2d88ac" + }, + { + "satoshis": 14000000, + "script": "76a9149713201957f42379e574d7c70d506ee49c2c8ad688ac" + } + ], + "nLockTime": 534089 + }) + }, + { + tx: bitcore.Transaction().fromObject({ + "hash": "01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3", + "version": 1, + "inputs": [ + { + "prevTxId": "bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7", + "outputIndex": 0, + "sequenceNumber": 4294967294, + "script": "47304402201ee69281db6b95bb1aa3074059b67581635b719e8f64e4c2694db6ec56ad9447022011e91528996ea459b1fb2c0b59363fecbefe4bc2ca90f7b2382bdaa358f2d5640121034cc057b12a68ee79df998004b9a1341bbb18b17ea4939bebaa3bac001e940f24", + "scriptString": "71 0x304402201ee69281db6b95bb1aa3074059b67581635b719e8f64e4c2694db6ec56ad9447022011e91528996ea459b1fb2c0b59363fecbefe4bc2ca90f7b2382bdaa358f2d56401 33 0x034cc057b12a68ee79df998004b9a1341bbb18b17ea4939bebaa3bac001e940f24", + "output": { + "satoshis": 2782729129, + "script": "76a9143583efb5e64a4668c6c54bb5fcc30af4417b4f2d88ac" + } + } + ], + "outputs": [ + { + "satoshis": 2764693692, + "script": "76a91456e446bc3489543d8324c6d0271524c0bd0506dd88ac" + }, + { + "satoshis": 18000000, + "script": "76a914011d2963b619186a318f768dddfd98cd553912a088ac" + } + ], + "nLockTime": 534099 + }) + } + ]; + + txinfos[0].tx.__blockHash = '00000000000001001aba15de213648f370607fb048288dd27b96f7e833a73520'; + txinfos[0].tx.__timestamp = 1441068774000; + txinfos[0].tx.__height = 534105; + + txinfos[1].tx.__blockHash = '0000000000000a3acc1f7fe72917eb48bb319ed96c125a6dfcc0ba6acab3c4d0'; + txinfos[1].tx.__timestamp = 1441072817000; + txinfos[1].tx.__height = 534110; + + var node = { + getAddressHistory: sinon.stub().callsArgWith(2, null, txinfos), + services: { + db: { + tip: { + __height: 534223 + } + } + }, + network: 'testnet' + }; + + var insight = { + "pagesTotal": 1, + "txs": [ + { + "txid": "bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7", + "version": 1, + "locktime": 534089, + "vin": [ + { + "txid": "ea5e5bafbf29cdf6f6097ab344128477e67889d4d6203cb43594836daa6cc425", + "vout": 1, + "scriptSig": { + "asm": "3045022100f4d169783bef70e3943d2a617cce55d9fe4e33fc6f9880b8277265e2f619a97002201238648abcdf52960500664e969046d41755f7fc371971ebc78002fc418465a601 03acdcd31d51272403ce0829447e59e2ac9e08ed0bf92011cbf7420addf24534e6", + "hex": "483045022100f4d169783bef70e3943d2a617cce55d9fe4e33fc6f9880b8277265e2f619a97002201238648abcdf52960500664e969046d41755f7fc371971ebc78002fc418465a6012103acdcd31d51272403ce0829447e59e2ac9e08ed0bf92011cbf7420addf24534e6" + }, + "sequence": 4294967294, + "n": 0, + "addr": "msyjRQQ88MabQmyafpKCjBHUwuJ49tVjcb", + "valueSat": 2796764565, + "value": 27.96764565, + "doubleSpentTxID": null + } + ], + "vout": [ + { + "value": "27.82729129", + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 3583efb5e64a4668c6c54bb5fcc30af4417b4f2d OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9143583efb5e64a4668c6c54bb5fcc30af4417b4f2d88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er" + ] + }, + "spentTxId": "01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3", + "spentIndex": 0, + "spentTs": 1441072817 + }, + { + "value": "0.14000000", + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 9713201957f42379e574d7c70d506ee49c2c8ad6 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9149713201957f42379e574d7c70d506ee49c2c8ad688ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "muHmEsjhjmATf9i3T9gHyeQoce9LXe2dWz" + ] + } + } + ], + "blockhash": "00000000000001001aba15de213648f370607fb048288dd27b96f7e833a73520", + "confirmations": 119, + "time": 1441068774, + "blocktime": 1441068774, + "valueOut": 27.96729129, + "size": 226, + "valueIn": 27.96764565, + "fees": 0.00035436 + }, + { + "txid": "01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3", + "version": 1, + "locktime": 534099, + "vin": [ + { + "txid": "bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7", + "vout": 0, + "scriptSig": { + "asm": "304402201ee69281db6b95bb1aa3074059b67581635b719e8f64e4c2694db6ec56ad9447022011e91528996ea459b1fb2c0b59363fecbefe4bc2ca90f7b2382bdaa358f2d56401 034cc057b12a68ee79df998004b9a1341bbb18b17ea4939bebaa3bac001e940f24", + "hex": "47304402201ee69281db6b95bb1aa3074059b67581635b719e8f64e4c2694db6ec56ad9447022011e91528996ea459b1fb2c0b59363fecbefe4bc2ca90f7b2382bdaa358f2d5640121034cc057b12a68ee79df998004b9a1341bbb18b17ea4939bebaa3bac001e940f24" + }, + "sequence": 4294967294, + "n": 0, + "addr": "mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er", + "valueSat": 2782729129, + "value": 27.82729129, + "doubleSpentTxID": null + } + ], + "vout": [ + { + "value": "27.64693692", + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 56e446bc3489543d8324c6d0271524c0bd0506dd OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91456e446bc3489543d8324c6d0271524c0bd0506dd88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "moSPsU4p2C2gssiniJ1JNH4fB9xs633tLv" + ] + }, + "spentTxId": "661194e5533a395ce9076f292b7e0fb28fe94cd8832a81b4aa0517ff58c1ddd2", + "spentIndex": 0, + "spentTs": 1441077236 + }, + { + "value": "0.18000000", + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 011d2963b619186a318f768dddfd98cd553912a0 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914011d2963b619186a318f768dddfd98cd553912a088ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mfcquSAitCkUKXaYRZTRZQDfUegnL3kDew" + ] + }, + "spentTxId": "71a9e60c0341c9c258367f1a6d4253276f16e207bf84f41ff7412d8958a81bed", + "spentIndex": 0, + "spentTs": 1441069523 + } + ], + "blockhash": "0000000000000a3acc1f7fe72917eb48bb319ed96c125a6dfcc0ba6acab3c4d0", + "confirmations": 114, + "time": 1441072817, + "blocktime": 1441072817, + "valueOut": 27.82693692, + "size": 225, + "valueIn": 27.82729129, + "fees": 0.00035437 + } + ] + }; + + var todos = { + "txs": [ + { + "vin": [ + { + "scriptSig": { + "asm": "3045022100f4d169783bef70e3943d2a617cce55d9fe4e33fc6f9880b8277265e2f619a97002201238648abcdf52960500664e969046d41755f7fc371971ebc78002fc418465a601 03acdcd31d51272403ce0829447e59e2ac9e08ed0bf92011cbf7420addf24534e6" + } + } + ], + "vout": [ + { + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 3583efb5e64a4668c6c54bb5fcc30af4417b4f2d OP_EQUALVERIFY OP_CHECKSIG", + "reqSigs": 1, + "type": "pubkeyhash" + }, + "spentTxId": "01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3", + "spentIndex": 0, + "spentTs": 1441072817 + }, + { + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 9713201957f42379e574d7c70d506ee49c2c8ad6 OP_EQUALVERIFY OP_CHECKSIG", + "reqSigs": 1, + "type": "pubkeyhash" + } + } + ] + }, + { + "vin": [ + { + "scriptSig": { + "asm": "304402201ee69281db6b95bb1aa3074059b67581635b719e8f64e4c2694db6ec56ad9447022011e91528996ea459b1fb2c0b59363fecbefe4bc2ca90f7b2382bdaa358f2d56401 034cc057b12a68ee79df998004b9a1341bbb18b17ea4939bebaa3bac001e940f24" + } + } + ], + "vout": [ + { + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 56e446bc3489543d8324c6d0271524c0bd0506dd OP_EQUALVERIFY OP_CHECKSIG", + "reqSigs": 1, + "type": "pubkeyhash" + }, + "spentTxId": "661194e5533a395ce9076f292b7e0fb28fe94cd8832a81b4aa0517ff58c1ddd2", + "spentIndex": 0, + "spentTs": 1441077236 + }, + { + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 011d2963b619186a318f768dddfd98cd553912a0 OP_EQUALVERIFY OP_CHECKSIG", + "reqSigs": 1, + "type": "pubkeyhash" + }, + "spentTxId": "71a9e60c0341c9c258367f1a6d4253276f16e207bf84f41ff7412d8958a81bed", + "spentIndex": 0, + "spentTs": 1441069523 + } + ] + } + ] + }; + + var req = { + query: { + address: 'mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er' + } + }; + + var res = { + jsonp: function(data) { + var d = diff(insight, data); + var merged = _.merge(data, todos); + should(merged).eql(insight); + done(); + } + }; + + var transactions = new TxController(node); + transactions.list(req, res); + }); + }); + + describe('/rawtx/:txid', function() { + it('should give the correct data', function(done) { + var hex = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2303d6250800feb0aae355fe263600000963676d696e6572343208ae5800000000000000ffffffff01c018824a000000001976a91468bedce8982d25c3b6b03f6238cbad00378b8ead88ac00000000'; + + var node = { + getTransaction: sinon.stub().callsArgWith(2, null, bitcore.Transaction().fromBuffer(new Buffer(hex, 'hex'))) + }; + + var transactions = new TxController(node); + + var res = {}; + var req = {}; + var next = function() { + should(req.rawTransaction.rawtx).eql(hex); + done(); + }; + var txid = '25a988e54b02e0e5df146a0f8fa7b9db56210533a9f04bdfda5f4ceb6f77aadd'; + transactions.rawTransaction(req, res, next, txid); + }); + }); +}); \ No newline at end of file