Merge pull request #343 from matiu/feature/refactor-rpc-txs
Feature/refactor rpc txs
This commit is contained in:
commit
944d5a7051
|
@ -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;
|
||||||
|
|
21
lib/Rpc.js
21
lib/Rpc.js
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue