From cc1747c596a60d48e7ab2d5ed0b598d194a24af8 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Thu, 16 Jul 2015 11:21:47 -0400 Subject: [PATCH 1/3] Update test data with unspent output. --- integration/livenet-spents.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration/livenet-spents.json b/integration/livenet-spents.json index 8c1eed28..35e57234 100644 --- a/integration/livenet-spents.json +++ b/integration/livenet-spents.json @@ -5,8 +5,8 @@ "outputIndex": 0 }, { - "txid": "64b2da257d93ab44d19ef9b374788d82b6885bc3fb3c17704f42f09b1096e982", - "outputIndex": 0 + "txid": "8131ffb0a2c945ecaf9b9063e59558784f9c3a74741ce6ae2a18d0571dac15bb", + "outputIndex": 1 }, { "txid": "226bbc4b1f851857f37aa96e9eb702946fc128b055e4decc684740005f5044cf", From 9020ddb85ca3622486c67f42a72c4330bb63279a Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Thu, 16 Jul 2015 14:31:58 -0400 Subject: [PATCH 2/3] Add queryMempool option to getTransaction --- integration/index.js | 2 +- lib/bitcoind.js | 31 +++------------------ src/bitcoindjs.cc | 65 ++++++++++++++++++++++++++++++-------------- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/integration/index.js b/integration/index.js index b018f3c1..bd2c2f22 100644 --- a/integration/index.js +++ b/integration/index.js @@ -54,7 +54,7 @@ describe('Basic Functionality', function() { var tx = bitcore.Transaction(); tx.fromString(data); it('for tx ' + tx.hash, function(done) { - bitcoind.getTransaction(tx.hash, function(err, response) { + bitcoind.getTransaction(tx.hash, true, function(err, response) { if (err) { throw err; } diff --git a/lib/bitcoind.js b/lib/bitcoind.js index bb022a84..27149c8c 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -327,34 +327,11 @@ Bitcoin.prototype.isSpent = function(txid, outputIndex) { return bitcoindjs.isSpent(txid, outputIndex); }; -Bitcoin.prototype.getTransaction = -Bitcoin.prototype.getTx = function(txid, blockhash, callback) { - if (bitcoin.stopping) return []; - if (typeof txid === 'object' && txid) { - var options = txid; - callback = blockhash; - txid = options.txid || options.tx || options.txhash || options.id || options.hash; - blockhash = options.blockhash || options.block; - } - - if (typeof blockhash === 'function') { - callback = blockhash; - blockhash = ''; - } - - if (typeof blockhash !== 'string') { - if (blockhash) { - blockhash = blockhash.hash - || blockhash.blockhash - || (blockhash.getHash && blockhash.getHash()) - || ''; - } else { - blockhash = ''; +Bitcoin.prototype.getTransaction = function(txid, queryMempool, callback) { + return bitcoindjs.getTransaction(txid, queryMempool, function(err, tx) { + if (err) { + return callback(err); } - } - - return bitcoindjs.getTransaction(txid, blockhash, function(err, tx) { - if (err) return callback(err); return callback(null, tx); }); }; diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index b4fb8467..61d748ed 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -132,6 +132,7 @@ struct async_tx_data { std::string err_msg; std::string txid; std::string blockhash; + bool queryMempool; CTransaction ctx; Eternal callback; }; @@ -425,10 +426,8 @@ start_node_thread(void) { argc++; } - if (g_txindex) { - argv[argc] = (char *)"-txindex"; - argc++; - } + argv[argc] = (char *)"-txindex"; + argc++; argv[argc] = NULL; @@ -754,7 +753,7 @@ async_get_block_after(uv_work_t *req) { /** * GetTransaction() - * bitcoind.getTransaction(txid, [blockhash], callback) + * bitcoind.getTransaction(txid, callback) * Read any transaction from disk asynchronously. */ @@ -763,14 +762,14 @@ NAN_METHOD(GetTransaction) { HandleScope scope(isolate); if (args.Length() < 3 || !args[0]->IsString() - || !args[1]->IsString() + || !args[1]->IsBoolean() || !args[2]->IsFunction()) { return NanThrowError( - "Usage: bitcoindjs.getTransaction(txid, [blockhash], callback)"); + "Usage: bitcoindjs.getTransaction(txid, callback)"); } String::Utf8Value txid_(args[0]->ToString()); - String::Utf8Value blockhash_(args[1]->ToString()); + bool queryMempool = args[1]->BooleanValue(); Local callback = Local::Cast(args[2]); async_tx_data *data = new async_tx_data(); @@ -779,16 +778,12 @@ NAN_METHOD(GetTransaction) { data->txid = std::string(""); std::string txid = std::string(*txid_); - std::string blockhash = std::string(*blockhash_); data->txid = txid; + data->queryMempool = queryMempool; Eternal eternal(isolate, callback); data->callback = eternal; - if (blockhash == "") { - data->blockhash = uint256().GetHex(); - } - uv_work_t *req = new uv_work_t(); req->data = data; @@ -808,12 +803,42 @@ async_get_tx(uv_work_t *req) { uint256 hash = uint256S(data->txid); uint256 blockhash; CTransaction ctx; - - if (!GetTransaction(hash, ctx, blockhash, true)) { - data->err_msg = std::string("Transaction not found."); - } else { - data->ctx = ctx; - data->blockhash = blockhash.GetHex(); + + { + + if (data->queryMempool) { + LOCK(cs_main); + { + if (mempool.lookup(hash, ctx)) + { + return; + } + } + } + + CDiskTxPos postx; + if (pblocktree->ReadTxIndex(hash, postx)) { + + CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); + + if (file.IsNull()) { + data->err_msg = std::string("%s: OpenBlockFile failed", __func__); + return; + } + + const int HEADER_SIZE = sizeof(int32_t) + sizeof(uint32_t) * 3 + sizeof(char) * 64; + + try { + fseek(file.Get(), postx.nTxOffset + HEADER_SIZE, SEEK_CUR); + file >> ctx; + data->ctx = ctx; + } catch (const std::exception& e) { + data->err_msg = std::string("Deserialize or I/O error - %s", __func__); + return; + } + + } + } } @@ -842,7 +867,7 @@ async_get_tx_after(uv_work_t *req) { ssTx << ctx; std::string stx = ssTx.str(); Local rawNodeBuffer = node::Buffer::New(isolate, stx.c_str(), stx.size()); - + const unsigned argc = 2; Local argv[argc] = { Local::New(isolate, NanNull()), From b738a5fb849c390e0e881774b202f98ca7769c4c Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Thu, 16 Jul 2015 16:09:30 -0400 Subject: [PATCH 3/3] Remove braces, fix benchmark and pass callback. --- benchmarks/index.js | 2 +- lib/bitcoind.js | 7 +------ src/bitcoindjs.cc | 46 +++++++++++++++++++++------------------------ 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/benchmarks/index.js b/benchmarks/index.js index a6b7ecf4..be32186b 100644 --- a/benchmarks/index.js +++ b/benchmarks/index.js @@ -90,7 +90,7 @@ bitcoind.on('ready', function() { c = 0; } var hash = fixtureData.txHashes[c]; - bitcoind.getTransaction(hash, function(err, tx) { + bitcoind.getTransaction(hash, true, function(err, tx) { if (err) { throw err; } diff --git a/lib/bitcoind.js b/lib/bitcoind.js index 27149c8c..9d1c0b5f 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -328,12 +328,7 @@ Bitcoin.prototype.isSpent = function(txid, outputIndex) { }; Bitcoin.prototype.getTransaction = function(txid, queryMempool, callback) { - return bitcoindjs.getTransaction(txid, queryMempool, function(err, tx) { - if (err) { - return callback(err); - } - return callback(null, tx); - }); + return bitcoindjs.getTransaction(txid, queryMempool, callback); }; Bitcoin.prototype.getTransactionWithBlock = function(txid, blockhash, callback) { diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index 61d748ed..fcf700a9 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -804,39 +804,35 @@ async_get_tx(uv_work_t *req) { uint256 blockhash; CTransaction ctx; - { - - if (data->queryMempool) { - LOCK(cs_main); + if (data->queryMempool) { + LOCK(cs_main); + { + if (mempool.lookup(hash, ctx)) { - if (mempool.lookup(hash, ctx)) - { - return; - } + return; } } + } - CDiskTxPos postx; - if (pblocktree->ReadTxIndex(hash, postx)) { + CDiskTxPos postx; + if (pblocktree->ReadTxIndex(hash, postx)) { - CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); + CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); - if (file.IsNull()) { - data->err_msg = std::string("%s: OpenBlockFile failed", __func__); - return; - } + if (file.IsNull()) { + data->err_msg = std::string("%s: OpenBlockFile failed", __func__); + return; + } - const int HEADER_SIZE = sizeof(int32_t) + sizeof(uint32_t) * 3 + sizeof(char) * 64; - - try { - fseek(file.Get(), postx.nTxOffset + HEADER_SIZE, SEEK_CUR); - file >> ctx; - data->ctx = ctx; - } catch (const std::exception& e) { - data->err_msg = std::string("Deserialize or I/O error - %s", __func__); - return; - } + const int HEADER_SIZE = sizeof(int32_t) + sizeof(uint32_t) * 3 + sizeof(char) * 64; + try { + fseek(file.Get(), postx.nTxOffset + HEADER_SIZE, SEEK_CUR); + file >> ctx; + data->ctx = ctx; + } catch (const std::exception& e) { + data->err_msg = std::string("Deserialize or I/O error - %s", __func__); + return; } }