From 5dc8aae3a0c56880d430b78525417bb975f8280b Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 2 Oct 2014 15:14:23 -0700 Subject: [PATCH] Revert "start using conversions properly." This reverts commit 0261a6face73b0315f68acc71ab928a2098350da. Temporarily reverting this until I write some tests. --- src/bitcoindjs.cc | 208 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 189 insertions(+), 19 deletions(-) diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index e8d18d04..9bc01fd7 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -284,7 +284,7 @@ struct async_tx_data { std::string err_msg; std::string txHash; std::string blockHash; - CTransaction ctx; + CTransaction result_tx; Persistent callback; }; @@ -321,8 +321,7 @@ struct async_poll_mempool_data { struct async_broadcast_tx_data { std::string err_msg; - Persistent jstx; - CTransaction ctx; + std::string tx_hex; std::string tx_hash; bool override_fees; bool own_only; @@ -781,7 +780,7 @@ async_get_tx(uv_work_t *req) { CTransaction ctx; if (GetTransaction(hash, ctx, block_hash, true)) { - data->ctx = ctx; + data->result_tx = ctx; } else { data->err_msg = std::string("get_tx(): failed."); } @@ -794,7 +793,7 @@ async_get_tx_after(uv_work_t *req) { std::string txHash = data->txHash; std::string blockHash = data->blockHash; - CTransaction ctx = data->ctx; + CTransaction ctx = data->result_tx; uint256 hash(txHash); uint256 block_hash(blockHash); @@ -809,7 +808,12 @@ async_get_tx_after(uv_work_t *req) { node::FatalException(try_catch); } } else { + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << ctx; + std::string strHex = HexStr(ssTx.begin(), ssTx.end()); + Local jstx = NanNew(); + jstx->Set(NanNew("hex"), NanNew(strHex)); ctx_to_jstx(ctx, block_hash, jstx); const unsigned argc = 2; @@ -1078,18 +1082,16 @@ NAN_METHOD(BroadcastTx) { Local jstx = Local::Cast(args[0]); Local callback = Local::Cast(args[3]); + String::Utf8Value tx_hex_(jstx->Get(NanNew("hex"))->ToString()); + std::string tx_hex = std::string(*tx_hex_); + async_broadcast_tx_data *data = new async_broadcast_tx_data(); + data->tx_hex = tx_hex; data->override_fees = args[1]->ToBoolean()->IsTrue(); data->own_only = args[2]->ToBoolean()->IsTrue(); data->err_msg = std::string(""); data->callback = Persistent::New(callback); - data->jstx = Persistent::New(jstx); - - CTransaction ctx; - jstx_to_ctx(jstx, ctx); - data->ctx = ctx; - uv_work_t *req = new uv_work_t(); req->data = data; @@ -1106,6 +1108,9 @@ static void async_broadcast_tx(uv_work_t *req) { async_broadcast_tx_data* data = static_cast(req->data); + CDataStream ssData(ParseHex(data->tx_hex), SER_NETWORK, PROTOCOL_VERSION); + CTransaction ctx; + bool fOverrideFees = false; bool fOwnOnly = false; @@ -1117,7 +1122,14 @@ async_broadcast_tx(uv_work_t *req) { fOwnOnly = true; } - CTransaction ctx = data->ctx; + // jstx_to_ctx(jstx, ctx); + + try { + ssData >> ctx; + } catch (std::exception &e) { + data->err_msg = std::string("TX decode failed"); + return; + } uint256 hashTx = ctx.GetHash(); @@ -1164,11 +1176,18 @@ async_broadcast_tx_after(uv_work_t *req) { node::FatalException(try_catch); } } else { + // jstx_to_ctx(jstx, ctx); + CDataStream ssData(ParseHex(data->tx_hex), SER_NETWORK, PROTOCOL_VERSION); + CTransaction ctx; + ssData >> ctx; + Local jstx = NanNew(); + ctx_to_jstx(ctx, 0, jstx); + const unsigned argc = 3; Local argv[argc] = { Local::New(Null()), Local::New(NanNew(data->tx_hash)), - Local::New(data->jstx) + Local::New(jstx) }; TryCatch try_catch; data->callback->Call(Context::GetCurrent()->Global(), argc, argv); @@ -1200,8 +1219,10 @@ NAN_METHOD(VerifyBlock) { String::Utf8Value block_hex_(jsblock->Get(NanNew("hex"))->ToString()); std::string block_hex = std::string(*block_hex_); + // jsblock_to_cblock(jsblock, cblock); CBlock cblock; - jsblock_to_cblock(jsblock, cblock); + CDataStream ssData(ParseHex(block_hex), SER_NETWORK, PROTOCOL_VERSION); + ssData >> cblock; CValidationState state; bool valid = CheckBlock(cblock, state); @@ -1226,8 +1247,10 @@ NAN_METHOD(VerifyTransaction) { String::Utf8Value tx_hex_(jstx->Get(NanNew("hex"))->ToString()); std::string tx_hex = std::string(*tx_hex_); + // jstx_to_ctx(jstx, ctx); CTransaction ctx; - jstx_to_ctx(jstx, ctx); + CDataStream ssData(ParseHex(tx_hex), SER_NETWORK, PROTOCOL_VERSION); + ssData >> ctx; CValidationState state; bool valid = CheckTransaction(ctx, state); @@ -1252,8 +1275,10 @@ NAN_METHOD(FillTransaction) { String::Utf8Value tx_hex_(jstx->Get(NanNew("hex"))->ToString()); std::string tx_hex = std::string(*tx_hex_); + // jstx_to_ctx(jstx, ctx); CTransaction ctx; - jstx_to_ctx(jstx, ctx); + CDataStream ssData(ParseHex(tx_hex), SER_NETWORK, PROTOCOL_VERSION); + ssData >> ctx; // Get total value of outputs // Get the scriptPubKey of the first output (presumably our destination) @@ -2424,8 +2449,98 @@ cblock_to_jsblock(const CBlock& cblock, const CBlockIndex* cblock_index, Local jstx = NanNew(); - const uint256 block_hash = cblock.GetHash(); - ctx_to_jstx(ctx, block_hash, jstx); + + // const uint256 block_hash = cblock.GetHash(); + // ctx_to_jstx(ctx, block_hash, jstx); + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << ctx; + std::string strHex = HexStr(ssTx.begin(), ssTx.end()); + jstx->Set(NanNew("hex"), NanNew(strHex)); + + jstx->Set(NanNew("txid"), NanNew(ctx.GetHash().GetHex())); + jstx->Set(NanNew("version"), NanNew(ctx.nVersion)); + jstx->Set(NanNew("locktime"), NanNew(ctx.nLockTime)); + + Local vin = NanNew(); + int vi = 0; + BOOST_FOREACH(const CTxIn& txin, ctx.vin) { + Local in = NanNew(); + if (ctx.IsCoinBase()) { + in->Set(NanNew("coinbase"), NanNew(HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + } else { + in->Set(NanNew("txid"), NanNew(txin.prevout.hash.GetHex())); + in->Set(NanNew("vout"), NanNew((boost::int64_t)txin.prevout.n)); + Local o = NanNew(); + o->Set(NanNew("asm"), NanNew(txin.scriptSig.ToString())); + o->Set(NanNew("hex"), NanNew(HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in->Set(NanNew("scriptSig"), o); + } + in->Set(NanNew("sequence"), NanNew((boost::int64_t)txin.nSequence)); + vin->Set(vi, in); + vi++; + } + jstx->Set(NanNew("vin"), vin); + + Local vout = NanNew(); + for (unsigned int vo = 0; vo < ctx.vout.size(); vo++) { + const CTxOut& txout = ctx.vout[vo]; + Local out = NanNew(); + out->Set(NanNew("value"), NanNew(txout.nValue)); + out->Set(NanNew("n"), NanNew((boost::int64_t)vo)); + + Local o = NanNew(); + { + const CScript& scriptPubKey = txout.scriptPubKey; + Local out = o; + bool fIncludeHex = true; + + txnouttype type; + vector addresses; + int nRequired; + out->Set(NanNew("asm"), NanNew(scriptPubKey.ToString())); + if (fIncludeHex) { + out->Set(NanNew("hex"), NanNew(HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + } + if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) { + out->Set(NanNew("type"), NanNew(GetTxnOutputType(type))); + } else { + out->Set(NanNew("reqSigs"), NanNew(nRequired)); + out->Set(NanNew("type"), NanNew(GetTxnOutputType(type))); + Local a = NanNew(); + int ai = 0; + BOOST_FOREACH(const CTxDestination& addr, addresses) { + a->Set(ai, NanNew(CBitcoinAddress(addr).ToString())); + ai++; + } + out->Set(NanNew("addresses"), a); + } + } + out->Set(NanNew("scriptPubKey"), o); + + vout->Set(vo, out); + } + jstx->Set(NanNew("vout"), vout); + + { + const uint256 block_hash = cblock.GetHash(); + if (block_hash != 0) { + jstx->Set(NanNew("blockhash"), NanNew(block_hash.GetHex())); + map::iterator mi = mapBlockIndex.find(block_hash); + if (mi != mapBlockIndex.end() && (*mi).second) { + CBlockIndex* cblock_index = (*mi).second; + if (chainActive.Contains(cblock_index)) { + jstx->Set(NanNew("confirmations"), + NanNew(1 + chainActive.Height() - cblock_index->nHeight)); + jstx->Set(NanNew("time"), NanNew((boost::int64_t)cblock_index->nTime)); + jstx->Set(NanNew("blocktime"), NanNew((boost::int64_t)cblock_index->nTime)); + } else { + jstx->Set(NanNew("confirmations"), NanNew(0)); + } + } + } + } + txs->Set(ti, jstx); ti++; } @@ -2563,7 +2678,62 @@ jsblock_to_cblock(const Local jsblock, CBlock& cblock) { for (unsigned int ti = 0; ti < txs->Length(); ti++) { Local jstx = Local::Cast(txs->Get(ti)); CTransaction ctx; - jstx_to_ctx(jstx, ctx); + + // jstx_to_ctx(jstx, ctx); + + ctx.nVersion = jstx->Get(NanNew("version"))->IntegerValue(); + ctx.nLockTime = jstx->Get(NanNew("locktime"))->IntegerValue(); + + Local vin = Local::Cast(jstx->Get(NanNew("vin"))); + for (unsigned int vi = 0; vi < vin->Length(); vi++) { + CTxIn txin; + Local in = Local::Cast(vin->Get(vi)); + + std::string shash_; + if (in->Get(NanNew("coinbase"))->IsString()) { + String::AsciiValue shash__(in->Get(NanNew("coinbase"))->ToString()); + shash_ = *shash__; + } else { + String::AsciiValue shash__(in->Get(NanNew("scriptSig"))->ToString()); + shash_ = *shash__; + } + if (shash_[1] != 'x') shash_ = "0x" + shash_; + uint256 shash(shash_); + CScript scriptSig(shash); + + txin.scriptSig = scriptSig; + + String::AsciiValue phash__(in->Get(NanNew("txid"))->ToString()); + std::string phash_ = *phash__; + if (phash_[1] != 'x') phash_ = "0x" + phash_; + uint256 phash(phash_); + + txin.prevout.hash = phash; + txin.prevout.n = (boost::int64_t)in->Get(NanNew("vout"))->IntegerValue(); + txin.nSequence = (boost::int64_t)in->Get(NanNew("sequence"))->IntegerValue(); + + ctx.vin.push_back(txin); + } + + Local vout = Local::Cast(jstx->Get(NanNew("vout"))); + for (unsigned int vo = 0; vo < vout->Length(); vo++) { + CTxOut txout; + Local out = Local::Cast(vout->Get(vo)); + + txout.nValue = (int64_t)out->Get(NanNew("value"))->IntegerValue(); + + Local spk = Local::Cast(out->Get(NanNew("scriptPubKey"))); + String::AsciiValue phash__(spk->Get(NanNew("hex"))); + std::string phash_ = *phash__; + if (phash_[1] != 'x') phash_ = "0x" + phash_; + uint256 phash(phash_); + CScript scriptPubKey(phash); + + txout.scriptPubKey = scriptPubKey; + + ctx.vout.push_back(txout); + } + cblock.vtx.push_back(ctx); } }