From a952c3e417b2eaa32569cc69ca22c1a95bef5058 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Mon, 3 Aug 2015 17:41:11 -0400 Subject: [PATCH 1/2] Added regtests for getTransaction --- integration/regtest.js | 36 +++++++++++++++++++++++++++++++++++- src/libbitcoind.cc | 14 +++++++++----- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/integration/regtest.js b/integration/regtest.js index 475e1765..7b632746 100644 --- a/integration/regtest.js +++ b/integration/regtest.js @@ -21,6 +21,7 @@ var should = chai.should(); var assert = chai.assert; var sinon = require('sinon'); var BitcoinRPC = require('bitcoind-rpc'); +var transactionData = []; var blockHashes = []; var utxo; var client; @@ -123,6 +124,10 @@ describe('Daemon Binding Functionality', function() { var unspentTransaction = bitcore.Transaction(); var outputIndex; unspentTransaction.fromString(response.result.hex); + + // add to the list of transactions for testing later + transactionData.push(response.result.hex); + for (var i = 0; i < unspentTransaction.outputs.length; i++) { var output = unspentTransaction.outputs[i]; if (output.script.toAddress(network).toString() === address.toString(network)) { @@ -181,7 +186,7 @@ describe('Daemon Binding Functionality', function() { describe('get blocks by height', function() { - [0,1,2,3,5,6,7,8,9].forEach(function(i) { + [0,1,2,3,4,5,6,7,8,9].forEach(function(i) { it('generated block ' + i, function(done) { // add the genesis block var height = i + 1; @@ -198,6 +203,35 @@ describe('Daemon Binding Functionality', function() { }); }); + describe('get transactions by hash', function() { + [0].forEach(function(i) { + it('for tx ' + i, function(done) { + var txhex = transactionData[i]; + var tx = new bitcore.Transaction(); + tx.fromString(txhex); + bitcoind.getTransaction(tx.hash, true, function(err, response) { + if (err) { + throw err; + } + assert(response.toString('hex') === txhex, 'incorrect tx data result'); + done(); + }); + }); + }); + + it('will return null if the transaction does not exist', function(done) { + var txid = '6226c407d0e9705bdd7158e60983e37d0f5d23529086d6672b07d9238d5aa618'; + bitcoind.getTransaction(txid, true, function(err, response) { + if (err) { + throw err; + } + should.not.exist(response); + done(); + }); + }); + + }); + describe('get block index', function() { var expectedWork = new BN(6); [1,2,3,4,5,6,7,8,9].forEach(function(i) { diff --git a/src/libbitcoind.cc b/src/libbitcoind.cc index ae21910c..c243c763 100644 --- a/src/libbitcoind.cc +++ b/src/libbitcoind.cc @@ -1135,15 +1135,19 @@ async_get_tx_after(uv_work_t *req) { } } else { - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << ctx; - std::string stx = ssTx.str(); - Local rawNodeBuffer = node::Buffer::New(isolate, stx.c_str(), stx.size()); + Local result = Local::New(isolate, NanNull()); + + if (!ctx.IsNull()) { + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << ctx; + std::string stx = ssTx.str(); + result = node::Buffer::New(isolate, stx.c_str(), stx.size()); + } const unsigned argc = 2; Local argv[argc] = { Local::New(isolate, NanNull()), - rawNodeBuffer + result }; TryCatch try_catch; cb->Call(isolate->GetCurrentContext()->Global(), argc, argv); From de77dbf99be4b5649dc5c27af7ccc0f52e5da0a8 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Mon, 3 Aug 2015 18:11:11 -0400 Subject: [PATCH 2/2] Add tests around db.getTransaction and return NotFound error. --- lib/db.js | 5 ++++- lib/errors.js | 3 +++ test/db.unit.js | 44 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/lib/db.js b/lib/db.js index dd0d89b8..ef68db92 100644 --- a/lib/db.js +++ b/lib/db.js @@ -75,6 +75,9 @@ DB.prototype.getTransaction = function(txid, queryMempool, callback) { if(err) { return callback(err); } + if(!txBuffer) { + return callback(new errors.Transaction.NotFound()); + } callback(null, Transaction().fromBuffer(txBuffer)); }); @@ -92,7 +95,7 @@ DB.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, callback callback(null, tx); }); -} +}; DB.prototype.validateBlockData = function(block, callback) { // bitcoind does the validation diff --git a/lib/errors.js b/lib/errors.js index cd6f5334..35e1002d 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -5,4 +5,7 @@ var chainlib = require('chainlib'); var errors = chainlib.errors; +errors.Transaction = createError('Transaction', errors.Error); +errors.Transaction.NotFound = createError('NotFound', errors.Transaction); + module.exports = errors; diff --git a/test/db.unit.js b/test/db.unit.js index 035d23e8..b1790bdb 100644 --- a/test/db.unit.js +++ b/test/db.unit.js @@ -2,13 +2,10 @@ var should = require('chai').should(); var sinon = require('sinon'); -var chainlib = require('chainlib'); -var levelup = chainlib.deps.levelup; var bitcoindjs = require('../'); var DB = bitcoindjs.DB; var blockData = require('./data/livenet-345003.json'); -var bitcore = require('bitcore'); -var EventEmitter = require('events').EventEmitter; +var transactionData = require('./data/bitcoin-transactions.json'); var errors = bitcoindjs.errors; var memdown = require('memdown'); var inherits = require('util').inherits; @@ -17,6 +14,45 @@ var BaseModule = require('../lib/module'); describe('Bitcoin DB', function() { var coinbaseAmount = 50 * 1e8; + describe('#getTransaction', function() { + it('will return a NotFound error', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + getTransaction: sinon.stub().callsArgWith(2, null, null) + }; + var txid = '7426c707d0e9705bdd8158e60983e37d0f5d63529086d6672b07d9238d5aa623'; + db.getTransaction(txid, true, function(err) { + err.should.be.instanceof(errors.Transaction.NotFound); + done(); + }); + }); + it('will return an error from bitcoind', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + getTransaction: sinon.stub().callsArgWith(2, new Error('test error')) + }; + var txid = '7426c707d0e9705bdd8158e60983e37d0f5d63529086d6672b07d9238d5aa623'; + db.getTransaction(txid, true, function(err) { + err.message.should.equal('test error'); + done(); + }); + }); + it('will return an error from bitcoind', function(done) { + var db = new DB({store: memdown}); + db.bitcoind = { + getTransaction: sinon.stub().callsArgWith(2, null, new Buffer(transactionData[0].hex, 'hex')) + }; + var txid = '7426c707d0e9705bdd8158e60983e37d0f5d63529086d6672b07d9238d5aa623'; + db.getTransaction(txid, true, function(err, tx) { + if (err) { + throw err; + } + should.exist(tx); + done(); + }); + }); + }); + describe('#getBlock', function() { var db = new DB({store: memdown}); db.bitcoind = {