Merge pull request #343 from matiu/feature/refactor-rpc-txs

Feature/refactor rpc txs
This commit is contained in:
Matias Alejo Garcia 2014-02-15 21:28:17 -02:00
commit 944d5a7051
3 changed files with 41 additions and 30 deletions

View File

@ -10,6 +10,7 @@ var common = require('./common');
var TransactionDb = require('../../lib/TransactionDb').class(); var TransactionDb = require('../../lib/TransactionDb').class();
var BlockDb = require('../../lib/BlockDb').class(); var BlockDb = require('../../lib/BlockDb').class();
var tDb = new TransactionDb();
var bdb = new BlockDb(); var bdb = new BlockDb();
@ -17,7 +18,6 @@ var bdb = new BlockDb();
* Find transaction by hash ... * Find transaction by hash ...
*/ */
exports.transaction = function(req, res, next, txid) { exports.transaction = function(req, res, next, txid) {
var tDb = new TransactionDb();
tDb.fromIdWithInfo(txid, function(err, tx) { tDb.fromIdWithInfo(txid, function(err, tx) {
if (err || ! tx) if (err || ! tx)
@ -42,21 +42,13 @@ exports.show = function(req, res) {
var getTransaction = function(txid, cb) { var getTransaction = function(txid, cb) {
var tDb = new TransactionDb();
tDb.fromIdWithInfo(txid, function(err, tx) { tDb.fromIdWithInfo(txid, function(err, tx) {
if (err) { if (err) console.log(err);
console.log(err);
}
if (!tx || !tx.info) { if (!tx || !tx.info) {
console.log('[transactions.js.48]:: TXid %s not found in RPC. CHECK THIS.', txid); //TODO console.log('[transactions.js.48]:: TXid %s not found in RPC. CHECK THIS.', txid);
// not check this. no return ({ txid: txid });
tx = {
info: {
txid: txid
}
};
} }
return cb(null, tx.info); return cb(null, tx.info);
@ -71,7 +63,7 @@ exports.list = function(req, res, next) {
var bId = req.query.block; var bId = req.query.block;
var addrStr = req.query.address; var addrStr = req.query.address;
var page = req.query.pageNum; var page = req.query.pageNum;
var pageLength = 20; var pageLength = 10;
var pagesTotal = 1; var pagesTotal = 1;
var txLength; var txLength;
var txs; var txs;

View File

@ -5,7 +5,6 @@ require('classtool');
function spec(b) { function spec(b) {
var RpcClient = require('bitcore/RpcClient').class(), var RpcClient = require('bitcore/RpcClient').class(),
BitcoreTransaction = require('bitcore/Transaction').class(),
BitcoreBlock = require('bitcore/Block').class(), BitcoreBlock = require('bitcore/Block').class(),
bitcoreUtil = require('bitcore/util/util'), bitcoreUtil = require('bitcore/util/util'),
util = require('util'), util = require('util'),
@ -16,25 +15,25 @@ function spec(b) {
function Rpc() { function Rpc() {
} }
Rpc._parseRpcResult = function(info) { Rpc._parseTxResult = function(info) {
var b = new Buffer(info.hex,'hex'); var b = new Buffer(info.hex,'hex');
var tx = new BitcoreTransaction();
tx.parse(b);
// Inputs // remove fields we dont need, to speed, and adapt the information
if (tx.isCoinBase()) { delete info['hex'];
info.isCoinBase = true;
}
// Inputs => add index + coinBase flag
var n =0; var n =0;
info.vin.forEach(function(i) { info.vin.forEach(function(i) {
i.n = n++; i.n = n++;
if (i.coinbase) info.isCoinBase = true;
if (i.scriptSig) delete i.scriptSig['hex'];
}); });
// Outputs // Outputs => add total
var valueOutSat = 0; var valueOutSat = 0;
info.vout.forEach( function(o) { info.vout.forEach( function(o) {
valueOutSat += o.value * bitcoreUtil.COIN; valueOutSat += o.value * bitcoreUtil.COIN;
delete o.scriptPubKey['hex'];
}); });
info.valueOut = parseInt(valueOutSat) / bitcoreUtil.COIN; info.valueOut = parseInt(valueOutSat) / bitcoreUtil.COIN;
info.size = b.length; info.size = b.length;
@ -54,7 +53,7 @@ function spec(b) {
return e; return e;
}; };
Rpc.getRpcInfo = function(txid, cb) { Rpc.getTxInfo = function(txid, cb) {
var self = this; var self = this;
bitcoreRpc.getRawTransaction(txid, 1, function(err, txInfo) { bitcoreRpc.getRawTransaction(txid, 1, function(err, txInfo) {
@ -63,7 +62,7 @@ function spec(b) {
if (err && err.code === -5) return cb(); if (err && err.code === -5) return cb();
if (err) return cb(self.errMsg(err)); if (err) return cb(self.errMsg(err));
var info = self._parseRpcResult(txInfo.result); var info = self._parseTxResult(txInfo.result);
return cb(null,info); return cb(null,info);
}); });

View File

@ -24,6 +24,7 @@ function spec(b) {
var CONCURRENCY = 10; var CONCURRENCY = 10;
var MAX_OPEN_FILES = 500; var MAX_OPEN_FILES = 500;
var CONFIRMATION_NR_TO_NOT_CHECK = 10;
/** /**
* Module dependencies. * Module dependencies.
*/ */
@ -192,7 +193,7 @@ function spec(b) {
var incompleteInputs = 0; var incompleteInputs = 0;
async.eachLimit(info.vin, CONCURRENCY, function(i, c_in) { 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 //console.log('[TransactionDb.js.154:ret:]',ret); //TODO
if (!ret || !ret.addr || !ret.valueSat) { if (!ret || !ret.addr || !ret.valueSat) {
console.log('Could not get TXouts in %s,%d from %s ', i.txid, i.vout, info.txid); 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.addr = ret.addr;
i.valueSat = ret.valueSat; i.valueSat = ret.valueSat;
i.value = ret.valueSat / util.COIN; 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? // Double spend?
if (ret.multipleSpendAttempt || !ret.spendTxId || if (ret.multipleSpendAttempt || !ret.spendTxId ||
(ret.spendTxId && ret.spendTxId !== info.txid) (ret.spendTxId && ret.spendTxId !== info.txid)
@ -227,8 +237,6 @@ function spec(b) {
} else { } else {
i.doubleSpendTxID = null; i.doubleSpendTxID = null;
} }
valueIn += i.valueSat;
return c_in(); return c_in();
}); });
}, },
@ -246,7 +254,7 @@ function spec(b) {
TransactionDb.prototype._getInfo = function(txid, next) { TransactionDb.prototype._getInfo = function(txid, next) {
var self = this; var self = this;
Rpc.getRpcInfo(txid, function(err, info) { Rpc.getTxInfo(txid, function(err, info) {
if (err) return next(err); if (err) return next(err);
self._fillOutpoints(info, function() { 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 self = this;
var k = OUTS_PREFIX + txid + '-' + n; var k = OUTS_PREFIX + txid + '-' + n;
@ -288,6 +296,18 @@ function spec(b) {
valueSat: parseInt(a[1]), 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? // Spend?
var k = SPEND_PREFIX + txid + '-' + n; var k = SPEND_PREFIX + txid + '-' + n;
db.createReadStream({ db.createReadStream({
@ -677,7 +697,7 @@ function spec(b) {
// TODO: parse it from networks.genesisTX? // TODO: parse it from networks.genesisTX?
if (t === genesisTXID) return each_cb(); if (t === genesisTXID) return each_cb();
Rpc.getRpcInfo(t, function(err, inInfo) { Rpc.getTxInfo(t, function(err, inInfo) {
if (!inInfo) return each_cb(err); if (!inInfo) return each_cb(err);
return self.add(inInfo, blockHash, each_cb); return self.add(inInfo, blockHash, each_cb);