diff --git a/app/controllers/transactions.js b/app/controllers/transactions.js index a86f71e3..cda2868a 100644 --- a/app/controllers/transactions.js +++ b/app/controllers/transactions.js @@ -10,6 +10,7 @@ var common = require('./common'); var TransactionDb = require('../../lib/TransactionDb').class(); var BlockDb = require('../../lib/BlockDb').class(); +var tDb = new TransactionDb(); var bdb = new BlockDb(); @@ -17,7 +18,6 @@ var bdb = new BlockDb(); * Find transaction by hash ... */ exports.transaction = function(req, res, next, txid) { - var tDb = new TransactionDb(); tDb.fromIdWithInfo(txid, function(err, tx) { if (err || ! tx) @@ -42,21 +42,13 @@ exports.show = function(req, res) { var getTransaction = function(txid, cb) { - var tDb = new TransactionDb(); tDb.fromIdWithInfo(txid, function(err, tx) { - if (err) { - console.log(err); - } + if (err) console.log(err); if (!tx || !tx.info) { -console.log('[transactions.js.48]:: TXid %s not found in RPC. CHECK THIS.', txid); //TODO - // not check this. no - tx = { - info: { - txid: txid - } - }; + console.log('[transactions.js.48]:: TXid %s not found in RPC. CHECK THIS.', txid); + return ({ txid: txid }); } return cb(null, tx.info); @@ -71,7 +63,7 @@ exports.list = function(req, res, next) { var bId = req.query.block; var addrStr = req.query.address; var page = req.query.pageNum; - var pageLength = 20; + var pageLength = 10; var pagesTotal = 1; var txLength; var txs; diff --git a/lib/Rpc.js b/lib/Rpc.js index fe8735b9..cefc075b 100644 --- a/lib/Rpc.js +++ b/lib/Rpc.js @@ -5,7 +5,6 @@ require('classtool'); function spec(b) { var RpcClient = require('bitcore/RpcClient').class(), - BitcoreTransaction = require('bitcore/Transaction').class(), BitcoreBlock = require('bitcore/Block').class(), bitcoreUtil = require('bitcore/util/util'), util = require('util'), @@ -16,25 +15,25 @@ function spec(b) { function Rpc() { } - Rpc._parseRpcResult = function(info) { + Rpc._parseTxResult = function(info) { var b = new Buffer(info.hex,'hex'); - var tx = new BitcoreTransaction(); - tx.parse(b); - // Inputs - if (tx.isCoinBase()) { - info.isCoinBase = true; - } + // remove fields we dont need, to speed, and adapt the information + delete info['hex']; + // Inputs => add index + coinBase flag var n =0; info.vin.forEach(function(i) { i.n = n++; + if (i.coinbase) info.isCoinBase = true; + if (i.scriptSig) delete i.scriptSig['hex']; }); - // Outputs + // Outputs => add total var valueOutSat = 0; info.vout.forEach( function(o) { valueOutSat += o.value * bitcoreUtil.COIN; + delete o.scriptPubKey['hex']; }); info.valueOut = parseInt(valueOutSat) / bitcoreUtil.COIN; info.size = b.length; @@ -54,7 +53,7 @@ function spec(b) { return e; }; - Rpc.getRpcInfo = function(txid, cb) { + Rpc.getTxInfo = function(txid, cb) { var self = this; bitcoreRpc.getRawTransaction(txid, 1, function(err, txInfo) { @@ -63,7 +62,7 @@ function spec(b) { if (err && err.code === -5) return cb(); if (err) return cb(self.errMsg(err)); - var info = self._parseRpcResult(txInfo.result); + var info = self._parseTxResult(txInfo.result); return cb(null,info); }); diff --git a/lib/TransactionDb.js b/lib/TransactionDb.js index 5eb7d7cc..70cae4fa 100644 --- a/lib/TransactionDb.js +++ b/lib/TransactionDb.js @@ -24,6 +24,7 @@ function spec(b) { var CONCURRENCY = 10; var MAX_OPEN_FILES = 500; + var CONFIRMATION_NR_TO_NOT_CHECK = 10; /** * Module dependencies. */ @@ -192,7 +193,7 @@ function spec(b) { var incompleteInputs = 0; async.eachLimit(info.vin, CONCURRENCY, function(i, c_in) { - self.fromTxIdN(i.txid, i.vout, function(err, ret) { + self.fromTxIdN(i.txid, i.vout, info.confirmations, function(err, ret) { //console.log('[TransactionDb.js.154:ret:]',ret); //TODO if (!ret || !ret.addr || !ret.valueSat) { console.log('Could not get TXouts in %s,%d from %s ', i.txid, i.vout, info.txid); @@ -206,7 +207,16 @@ function spec(b) { i.addr = ret.addr; i.valueSat = ret.valueSat; i.value = ret.valueSat / util.COIN; + valueIn += i.valueSat; +/* + * If confirmed by bitcoind, we could not check for double spends + * but we prefer to keep the flag of double spend attempt + * + if (info.confirmations + && info.confirmations >= CONFIRMATION_NR_TO_NOT_CHECK) + return c_in(); +*/ // Double spend? if (ret.multipleSpendAttempt || !ret.spendTxId || (ret.spendTxId && ret.spendTxId !== info.txid) @@ -227,8 +237,6 @@ function spec(b) { } else { i.doubleSpendTxID = null; } - - valueIn += i.valueSat; return c_in(); }); }, @@ -246,7 +254,7 @@ function spec(b) { TransactionDb.prototype._getInfo = function(txid, next) { var self = this; - Rpc.getRpcInfo(txid, function(err, info) { + Rpc.getTxInfo(txid, function(err, info) { if (err) return next(err); self._fillOutpoints(info, function() { @@ -271,7 +279,7 @@ function spec(b) { }); }; - TransactionDb.prototype.fromTxIdN = function(txid, n, cb) { + TransactionDb.prototype.fromTxIdN = function(txid, n, confirmations, cb) { var self = this; var k = OUTS_PREFIX + txid + '-' + n; @@ -288,6 +296,18 @@ function spec(b) { valueSat: parseInt(a[1]), }; + /* + * If this TxID comes from an RPC request + * the .confirmations value from bitcoind is available + * so we could avoid checking if the input were double spended + * + * This speed up address calculations by ~30% + * + if (confirmations >= CONFIRMATION_NR_TO_NOT_CHECK) { + return cb(null, ret); + } + */ + // Spend? var k = SPEND_PREFIX + txid + '-' + n; db.createReadStream({ @@ -677,7 +697,7 @@ function spec(b) { // TODO: parse it from networks.genesisTX? if (t === genesisTXID) return each_cb(); - Rpc.getRpcInfo(t, function(err, inInfo) { + Rpc.getTxInfo(t, function(err, inInfo) { if (!inInfo) return each_cb(err); return self.add(inInfo, blockHash, each_cb);