From 1495cdfc0ee7ef82e4b40900f30e5c79cf0328a7 Mon Sep 17 00:00:00 2001 From: Tom Briar Date: Wed, 28 Jun 2023 16:27:08 -0400 Subject: [PATCH] Working Tests, Bug Fixes --- src/primitives/block.h | 2 +- src/primitives/compression.cpp | 6 +- src/rpc/rawtransaction.cpp | 84 +++++++++++++-------------- test/functional/rpc_rawtransaction.py | 10 ++-- 4 files changed, 50 insertions(+), 52 deletions(-) diff --git a/src/primitives/block.h b/src/primitives/block.h index f71061f24ccf65..0e2912ae21a2da 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -110,7 +110,7 @@ class CBlock : public CBlockHeader return block; } - bool LookupTransactionIndex(uint256 txid, uint32_t& index) + bool LookupTransactionIndex(uint256 txid, uint32_t& index) const { for (size_t vindex = 0; vindex < this->vtx.size(); vindex++) { if ((*vtx.at(vindex)).GetHash() == txid) { diff --git a/src/primitives/compression.cpp b/src/primitives/compression.cpp index 6cc2c4a30d43f1..da513bbfb2a8a0 100644 --- a/src/primitives/compression.cpp +++ b/src/primitives/compression.cpp @@ -56,11 +56,11 @@ CCompressedTxIn::CCompressedTxIn(secp256k1_context* ctx, const CTxIn& txin, cons CDataStream stream(SER_DISK, 0); stream << VARINT(txin.scriptSig.size()); if (txin.scriptSig.size()) - stream << txin.scriptSig; + stream.write(MakeByteSpan(txin.scriptSig)); stream << VARINT(txin.scriptWitness.stack.size()); for (size_t index = 0; index < txin.scriptWitness.stack.size(); index++) { stream << VARINT(txin.scriptWitness.stack.at(index).size()); - stream << txin.scriptWitness.stack.at(index); + stream.write(MakeByteSpan(txin.scriptWitness.stack.at(index))); } m_signature.resize(stream.size()); stream.read(MakeWritableByteSpan(m_signature)); @@ -346,7 +346,7 @@ CMutableTransaction::CMutableTransaction(const secp256k1_context* ctx, const CCo uint64_t witnessCount = std::numeric_limits::max(); stream >> VARINT(witnessCount); std::vector> stack; - for (uint64_t i = 0; witnessCount < i; i++) { + for (uint64_t i = 0; i < witnessCount; i++) { uint64_t witnessLength = std::numeric_limits::max(); stream >> VARINT(witnessLength); std::vector witness(witnessLength); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 7cb0962fd7668b..3798b4ea45e774 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -537,7 +537,6 @@ static RPCHelpMan compressrawtransaction() { const NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); - const BlockManager& blockman = chainman.m_blockman; UniValue r(UniValue::VOBJ); CMutableTransaction mtx; std::string error = ""; @@ -551,40 +550,38 @@ static RPCHelpMan compressrawtransaction() } FindCoins(node, coins); for (size_t index = 0; index < mtx.vin.size(); index++) { - input_scripts.push_back(coins[COutPoint(mtx.vin.at(index).prevout.hash, mtx.vin.at(index).prevout.n)].out.scriptPubKey); + Coin coin = coins[COutPoint(mtx.vin.at(index).prevout.hash, mtx.vin.at(index).prevout.n)]; + input_scripts.push_back(coin.out.scriptPubKey); uint256 block_hash; bool compressed_txid = false; - if (GetTransaction(nullptr, node.mempool.get(), mtx.vin.at(index).prevout.hash, block_hash, blockman)) { - const CBlockIndex* pindex{nullptr}; - { - LOCK(cs_main); - pindex = chainman.m_blockman.LookupBlockIndex(block_hash); - } - uint32_t block_height = pindex->nHeight; - uint32_t block_index; - CBlock block; - //If the transaction was found abovej - if (chainman.m_blockman.ReadBlockFromDisk(block, *pindex)) { - if (block.LookupTransactionIndex(mtx.vin.at(index).prevout.hash, block_index)) { - { - LOCK(cs_main); - Chainstate& active_chainstate = chainman.ActiveChainstate(); - - const CBlockIndex& tip{*CHECK_NONFATAL(active_chainstate.m_chain.Tip())}; - const int height{tip.nHeight}; - if ((height-100) >= int(block_height)) { - txids.push_back(CCompressedTxId(block_height, block_index)); - compressed_txid = true; - } else { - error = strprintf("UTXO (%u): Is not older then one hundred blocks and so we will not compress the TXID", index); - } + const CBlockIndex* pindex{nullptr}; + { + LOCK(cs_main); + pindex = chainman.ActiveChain()[coin.nHeight]; + } + uint32_t block_height = pindex->nHeight; + uint32_t block_index; + CBlock block; + if (chainman.m_blockman.ReadBlockFromDisk(block, *pindex)) { + if (block.LookupTransactionIndex(mtx.vin.at(index).prevout.hash, block_index)) { + { + LOCK(cs_main); + Chainstate& active_chainstate = chainman.ActiveChainstate(); + + const CBlockIndex& tip{*CHECK_NONFATAL(active_chainstate.m_chain.Tip())}; + const int height{tip.nHeight}; + if ((height-100) >= int(block_height)) { + txids.push_back(CCompressedTxId(block_height, block_index)); + compressed_txid = true; + } else { + error = strprintf("UTXO (%u): Is not older then one hundred blocks and so we will not compress the TXID", index); } } } } if (!compressed_txid) { txids.push_back(CCompressedTxId(mtx.vin.at(index).prevout.hash)); - error = strprintf("UTXO (%u): Could not find Transaction Index to Compress", index); + if (error == "") error = strprintf("UTXO (%u): Could not find Transaction Index to Compress", index); } } } else throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); @@ -592,7 +589,9 @@ static RPCHelpMan compressrawtransaction() CCompressedTransaction ctx = CCompressedTransaction(secp_context.GetContext(), CTransaction(mtx), txids, input_scripts); CDataStream stream(SER_DISK, 0); ctx.Serialize(stream); - r.pushKV("result", stream.str()); + std::vector hex(stream.size()); + stream.read(MakeWritableByteSpan(hex)); + r.pushKV("result", HexStr(hex)); r.pushKV("error", error); return r; }, @@ -617,7 +616,6 @@ static RPCHelpMan decompressrawtransaction() { const NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); - const BlockManager& blockman = chainman.m_blockman; UniValue r(UniValue::VOBJ); try { CDataStream ssData(ParseHex(request.params[0].get_str()), SER_NETWORK, PROTOCOL_VERSION); @@ -626,23 +624,24 @@ static RPCHelpMan decompressrawtransaction() if (ctx.vin().size() > 0) { std::vector blocks; blocks = chainman.m_blockman.GetAllBlockIndices(); - int blocks_length = blocks.size(); for (size_t index = 0; index < ctx.vin().size(); index++) { if (ctx.vin().at(index).prevout().txid().IsCompressed()) { - for (int blocks_index = 0; blocks_index < blocks_length; blocks_index++) { - const CBlockIndex* pindex{nullptr}; - pindex = blocks.at(blocks_index); - uint32_t height = pindex->nHeight; - if (height == ctx.vin().at(index).prevout().txid().block_height()) { - CBlock block; - chainman.m_blockman.ReadBlockFromDisk(block, *pindex); - uint256 txid = (*block.vtx.at(ctx.vin().at(index).prevout().txid().block_index())).GetHash(); - CTransactionRef tr = GetTransaction(nullptr, nullptr, txid, txid, blockman); - if (tr == nullptr) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Couldn't find TxId"); + uint256 txid; + const CBlockIndex* pindex{nullptr}; + { + LOCK(cs_main); + pindex = chainman.ActiveChain()[ctx.vin().at(index).prevout().txid().block_height()]; + } + if (pindex != nullptr) { + CBlock block; + chainman.m_blockman.ReadBlockFromDisk(block, *pindex); + if (ctx.vin().at(index).prevout().txid().block_index() < block.vtx.size()) { + txid = (*block.vtx.at(ctx.vin().at(index).prevout().txid().block_index())).GetHash(); txids.push_back(txid); - } + } } + if (txid.IsNull()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Couldn't find TxId"); } else txids.push_back(ctx.vin().at(index).prevout().txid().txid()); } } @@ -656,7 +655,8 @@ static RPCHelpMan decompressrawtransaction() for (size_t index = 0; index < ctx.vin().size(); index++) { outs.push_back(coins[COutPoint(txids.at(index), ctx.vin().at(index).prevout().n())].out); } - return EncodeHexTx(CTransaction(CMutableTransaction(secp_context.GetContext(), ctx, txids, outs))); + CTransaction tx = CTransaction(CMutableTransaction(secp_context.GetContext(), ctx, txids, outs)); + return EncodeHexTx(tx); } catch (const std::exception& exc) { // Fall through. } diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 1bc41faa299edd..d0585aace16d36 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -252,9 +252,8 @@ def compressrawtransaction_tests(self): self.log.info("Test compressrawtransaction") tx = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000102616100000000" compressed_transaction = self.nodes[0].compressrawtransaction(tx) - self.log.info("Compressed_Transaction = "+compressed_transaction) - compressed_tx_target = "" - assert_equal(compressed_tx_target, compressed_transaction) + compressed_tx_target = "1580690000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000005000102616100aed6c100" + assert_equal(compressed_tx_target, compressed_transaction["result"]) def createrawtransaction_tests(self): self.log.info("Test createrawtransaction") @@ -465,9 +464,8 @@ def decoderawtransaction_tests(self): def decompressrawtransaction_tests(self): self.log.info("Test decompressrawtransaction") - tx = "" - decompressed_transaction = self.nodes[0].compressrawtransaction(tx) - self.log.info("Compressed_Transaction = "+compressed_transaction) + tx = "1580690000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000005000102616100aed6c100" + decompressed_transaction = self.nodes[0].decompressrawtransaction(tx) decompressed_tx_target = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000102616100000000" assert_equal(decompressed_transaction, decompressed_tx_target)