refactor: Convert RPCs and `merkleblock` from uint256 to Txid
What changed, and why it matters
This commit is a code cleanup that replaces the generic uint256 type with a more specific Txid type when handling transaction identifiers in RPC commands and merkle block processing. It does not change program behavior, fix a bug, or introduce a security feature. It is a type-safety refactor intended to make the code clearer and harder to misuse in the future.
No security action required. Treat as ordinary code-quality/maintenance change. Reviewers may verify that all uint256-to-Txid conversions are explicit and that no implicit conversion paths were introduced.
Security signals we found
Type-hardening refactor: replaces general-purpose uint256 with semantically specific Txid
No functional change to serialization, hashing, or validation
No bounds-checking, input-validation, or cryptography changes
No vendor disclosure of security relevance
Evidence from the diff
The change converts RPC handlers (mempool, mining, rawtransaction, txoutproof, wallet backup) and merkleblock classes from using uint256 to the dedicated Txid type for transaction identifiers. The conversions are explicit (Txid::FromUint256 / ToUint256) and the wire/serialization behavior remains unchanged. No logic, validation, or consensus rules are modified.
Changed components
src/merkleblock.cppsrc/merkleblock.hsrc/net_processing.cppsrc/rpc/mempool.cppsrc/rpc/mining.cppsrc/rpc/rawtransaction.cppsrc/rpc/txoutproof.cppsrc/wallet/rpc/backup.cpprelated unit and fuzz testsInspect captured patch +78 / −80
diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp
index 669c6e3b..34ff06e5 100644
--- a/src/merkleblock.cpp
+++ b/src/merkleblock.cpp
@@ -32,7 +32,7 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std:
header = block.GetBlockHeader();
std::vector<bool> vMatch;
- std::vector<uint256> vHashes;
+ std::vector<Txid> vHashes;
vMatch.reserve(block.vtx.size());
vHashes.reserve(block.vtx.size());
@@ -55,13 +55,13 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std:
}
// NOLINTNEXTLINE(misc-no-recursion)
-uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
+uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<Txid> &vTxid) {
//we can never have zero txs in a merkle block, we always need the coinbase tx
//if we do not have this assert, we can hit a memory access violation when indexing into vTxid
assert(vTxid.size() != 0);
if (height == 0) {
// hash at height 0 is the txids themselves
- return vTxid[pos];
+ return vTxid[pos].ToUint256();
} else {
// calculate left hash
uint256 left = CalcHash(height-1, pos*2, vTxid), right;
@@ -76,7 +76,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve
}
// NOLINTNEXTLINE(misc-no-recursion)
-void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) {
+void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch) {
// determine whether this node is the parent of at least one matched txid
bool fParentOfMatch = false;
for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++)
@@ -95,7 +95,7 @@ void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const st
}
// NOLINTNEXTLINE(misc-no-recursion)
-uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex) {
+uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex) {
if (nBitsUsed >= vBits.size()) {
// overflowed the bits array - failure
fBad = true;
@@ -111,7 +111,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
}
const uint256 &hash = vHash[nHashUsed++];
if (height==0 && fParentOfMatch) { // in case of height 0, we have a matched txid
- vMatch.push_back(hash);
+ vMatch.push_back(Txid::FromUint256(hash));
vnIndex.push_back(pos);
}
return hash;
@@ -133,7 +133,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns
}
}
-CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
+CPartialMerkleTree::CPartialMerkleTree(const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
// reset state
vBits.clear();
vHash.clear();
@@ -149,7 +149,7 @@ CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const
CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {}
-uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex) {
+uint256 CPartialMerkleTree::ExtractMatches(std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex) {
vMatch.clear();
// An empty set will not work
if (nTransactions == 0)
diff --git a/src/merkleblock.h b/src/merkleblock.h
index 945b7d33..8f1d45a3 100644
--- a/src/merkleblock.h
+++ b/src/merkleblock.h
@@ -10,6 +10,7 @@
#include <primitives/block.h>
#include <serialize.h>
#include <uint256.h>
+#include <util/transaction_identifier.h>
#include <set>
#include <vector>
@@ -73,16 +74,16 @@ protected:
}
/** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */
- uint256 CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid);
+ uint256 CalcHash(int height, unsigned int pos, const std::vector<Txid> &vTxid);
/** recursive function that traverses tree nodes, storing the data as bits and hashes */
- void TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
+ void TraverseAndBuild(int height, unsigned int pos, const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch);
/**
* recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild.
* it returns the hash of the respective node and its respective index.
*/
- uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex);
+ uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex);
public:
@@ -97,7 +98,7 @@ public:
}
/** Construct a partial merkle tree from a list of transaction ids, and a mask that selects a subset of them */
- CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
+ CPartialMerkleTree(const std::vector<Txid> &vTxid, const std::vector<bool> &vMatch);
CPartialMerkleTree();
@@ -106,7 +107,7 @@ public:
* and their respective indices within the partial tree.
* returns the merkle root, or 0 in case of failure
*/
- uint256 ExtractMatches(std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex);
+ uint256 ExtractMatches(std::vector<Txid> &vMatch, std::vector<unsigned int> &vnIndex);
/** Get number of transactions the merkle proof is indicating for cross-reference with
* local blockchain knowledge.
@@ -135,7 +136,7 @@ public:
* Used only when a bloom filter is specified to allow
* testing the transactions which matched the bloom filter.
*/
- std::vector<std::pair<unsigned int, uint256> > vMatchedTxn;
+ std::vector<std::pair<unsigned int, Txid> > vMatchedTxn;
/**
* Create from a CBlock, filtering transactions according to filter
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 28e6cc7b..ba919fac 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -2352,9 +2352,8 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
// they must either disconnect and retry or request the full block.
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
// however we MUST always provide at least what the remote peer needs
- typedef std::pair<unsigned int, uint256> PairType;
- for (PairType& pair : merkleBlock.vMatchedTxn)
- MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[pair.first]));
+ for (const auto& [tx_idx, _] : merkleBlock.vMatchedTxn)
+ MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[tx_idx]));
}
// else
// no response
diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
index df5d2282..919c3046 100644
--- a/src/rpc/mempool.cpp
+++ b/src/rpc/mempool.cpp
@@ -461,12 +461,12 @@ static RPCHelpMan getmempoolancestors()
if (!request.params[1].isNull())
fVerbose = request.params[1].get_bool();
- uint256 hash = ParseHashV(request.params[0], "parameter 1");
+ auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
LOCK(mempool.cs);
- const auto entry{mempool.GetEntry(Txid::FromUint256(hash))};
+ const auto entry{mempool.GetEntry(txid)};
if (entry == nullptr) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
}
@@ -483,10 +483,9 @@ static RPCHelpMan getmempoolancestors()
UniValue o(UniValue::VOBJ);
for (CTxMemPool::txiter ancestorIt : ancestors) {
const CTxMemPoolEntry &e = *ancestorIt;
- const uint256& _hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
entryToJSON(mempool, info, e);
- o.pushKV(_hash.ToString(), std::move(info));
+ o.pushKV(e.GetTx().GetHash().ToString(), std::move(info));
}
return o;
}
@@ -523,7 +522,7 @@ static RPCHelpMan getmempooldescendants()
if (!request.params[1].isNull())
fVerbose = request.params[1].get_bool();
- Txid txid{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))};
+ auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
LOCK(mempool.cs);
@@ -549,10 +548,9 @@ static RPCHelpMan getmempooldescendants()
UniValue o(UniValue::VOBJ);
for (CTxMemPool::txiter descendantIt : setDescendants) {
const CTxMemPoolEntry &e = *descendantIt;
- const uint256& _hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
entryToJSON(mempool, info, e);
- o.pushKV(_hash.ToString(), std::move(info));
+ o.pushKV(e.GetTx().GetHash().ToString(), std::move(info));
}
return o;
}
@@ -576,12 +574,12 @@ static RPCHelpMan getmempoolentry()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- uint256 hash = ParseHashV(request.params[0], "parameter 1");
+ auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
LOCK(mempool.cs);
- const auto entry{mempool.GetEntry(Txid::FromUint256(hash))};
+ const auto entry{mempool.GetEntry(txid)};
if (entry == nullptr) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
}
@@ -1080,7 +1078,7 @@ static RPCHelpMan submitpackage()
UniValue rpc_result{UniValue::VOBJ};
rpc_result.pushKV("package_msg", package_msg);
UniValue tx_result_map{UniValue::VOBJ};
- std::set<uint256> replaced_txids;
+ std::set<Txid> replaced_txids;
for (const auto& tx : txns) {
UniValue result_inner{UniValue::VOBJ};
result_inner.pushKV("txid", tx->GetHash().GetHex());
@@ -1124,7 +1122,7 @@ static RPCHelpMan submitpackage()
}
rpc_result.pushKV("tx-results", std::move(tx_result_map));
UniValue replaced_list(UniValue::VARR);
- for (const uint256& hash : replaced_txids) replaced_list.push_back(hash.ToString());
+ for (const auto& txid : replaced_txids) replaced_list.push_back(txid.ToString());
rpc_result.pushKV("replaced-transactions", std::move(replaced_list));
return rpc_result;
},
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index f11305f1..c66b6c19 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -353,8 +353,8 @@ static RPCHelpMan generateblock()
const auto& str{raw_txs_or_txids[i].get_str()};
CMutableTransaction mtx;
- if (auto hash{uint256::FromHex(str)}) {
- const auto tx{mempool.get(*hash)};
+ if (auto txid{Txid::FromHex(str)}) {
+ const auto tx{mempool.get(*txid)};
if (!tx) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Transaction %s not in mempool.", str));
}
@@ -517,7 +517,7 @@ static RPCHelpMan prioritisetransaction()
{
LOCK(cs_main);
- uint256 hash(ParseHashV(request.params[0], "txid"));
+ auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
const auto dummy{self.MaybeArg<double>("dummy")};
CAmount nAmount = request.params[2].getInt<int64_t>();
@@ -528,12 +528,12 @@ static RPCHelpMan prioritisetransaction()
CTxMemPool& mempool = EnsureAnyMemPool(request.context);
// Non-0 fee dust transactions are not allowed for entry, and modification not allowed afterwards
- const auto& tx = mempool.get(hash);
+ const auto& tx = mempool.get(txid);
if (mempool.m_opts.require_standard && tx && !GetDust(*tx, mempool.m_opts.dust_relay_feerate).empty()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is not supported for transactions with dust outputs.");
}
- mempool.PrioritiseTransaction(hash, nAmount);
+ mempool.PrioritiseTransaction(txid, nAmount);
return true;
},
};
@@ -887,14 +887,14 @@ static RPCHelpMan getblocktemplate()
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
UniValue transactions(UniValue::VARR);
- std::map<uint256, int64_t> setTxIndex;
+ std::map<Txid, int64_t> setTxIndex;
std::vector<CAmount> tx_fees{block_template->getTxFees()};
std::vector<CAmount> tx_sigops{block_template->getTxSigops()};
int i = 0;
for (const auto& it : block.vtx) {
const CTransaction& tx = *it;
- uint256 txHash = tx.GetHash();
+ Txid txHash = tx.GetHash();
setTxIndex[txHash] = i++;
if (tx.IsCoinBase())
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 9c26e5c7..c87741a5 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -322,10 +322,10 @@ static RPCHelpMan getrawtransaction()
const NodeContext& node = EnsureAnyNodeContext(request.context);
ChainstateManager& chainman = EnsureChainman(node);
- uint256 hash = ParseHashV(request.params[0], "parameter 1");
+ auto txid{Txid::FromUint256(ParseHashV(request.params[0], "parameter 1"))};
const CBlockIndex* blockindex = nullptr;
- if (hash == chainman.GetParams().GenesisBlock().hashMerkleRoot) {
+ if (txid.ToUint256() == chainman.GetParams().GenesisBlock().hashMerkleRoot) {
// Special exception for the genesis block coinbase transaction
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "The genesis block coinbase is not considered an ordinary transaction and cannot be retrieved");
}
@@ -348,7 +348,7 @@ static RPCHelpMan getrawtransaction()
}
uint256 hash_block;
- const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), hash, hash_block, chainman.m_blockman);
+ const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), txid, hash_block, chainman.m_blockman);
if (!tx) {
std::string errmsg;
if (blockindex) {
diff --git a/src/rpc/txoutproof.cpp b/src/rpc/txoutproof.cpp
index a45e4381..2d98053d 100644
--- a/src/rpc/txoutproof.cpp
+++ b/src/rpc/txoutproof.cpp
@@ -150,7 +150,7 @@ static RPCHelpMan verifytxoutproof()
UniValue res(UniValue::VARR);
- std::vector<uint256> vMatch;
+ std::vector<Txid> vMatch;
std::vector<unsigned int> vIndex;
if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot)
return res;
@@ -165,8 +165,8 @@ static RPCHelpMan verifytxoutproof()
// Check if proof is valid, only add results if so
if (pindex->nTx == merkleBlock.txn.GetNumTransactions()) {
- for (const uint256& hash : vMatch) {
- res.push_back(hash.GetHex());
+ for (const auto& txid : vMatch) {
+ res.push_back(txid.GetHex());
}
}
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 1c732a82..584c970e 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -181,12 +181,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex());
BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1U);
- std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+ std::pair<unsigned int, Txid> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8);
- std::vector<uint256> vMatched;
+ std::vector<Txid> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
@@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1)
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"dd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"dd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
@@ -229,12 +229,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_2)
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
- std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+ std::pair<unsigned int, Txid> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
- std::vector<uint256> vMatched;
+ std::vector<Txid> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
@@ -253,13 +253,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2)
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
- BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == Txid::FromUint256(uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256{"6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == Txid::FromUint256(uint256{"6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2);
- BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == Txid::FromUint256(uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
@@ -286,12 +286,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
- std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+ std::pair<unsigned int, Txid> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"e980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
- std::vector<uint256> vMatched;
+ std::vector<Txid> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
@@ -310,10 +310,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
- BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == Txid::FromUint256(uint256{"28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == Txid::FromUint256(uint256{"3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
@@ -341,10 +341,10 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
- std::vector<uint256> vMatched;
+ std::vector<Txid> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
@@ -376,12 +376,12 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
- std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+ std::pair<unsigned int, Txid> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6);
- std::vector<uint256> vMatched;
+ std::vector<Txid> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
@@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4)
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256{"02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"});
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == Txid::FromUint256(uint256{"02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"}));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3);
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
diff --git a/src/test/fuzz/merkleblock.cpp b/src/test/fuzz/merkleblock.cpp
index e03e6284..b203acb0 100644
--- a/src/test/fuzz/merkleblock.cpp
+++ b/src/test/fuzz/merkleblock.cpp
@@ -43,7 +43,7 @@ FUZZ_TARGET(merkleblock)
partial_merkle_tree = merkle_block.txn;
});
(void)partial_merkle_tree.GetNumTransactions();
- std::vector<uint256> matches;
+ std::vector<Txid> matches;
std::vector<unsigned int> indices;
(void)partial_merkle_tree.ExtractMatches(matches, indices);
}
diff --git a/src/test/merkleblock_tests.cpp b/src/test/merkleblock_tests.cpp
index 73dbe337..48a61a3f 100644
--- a/src/test/merkleblock_tests.cpp
+++ b/src/test/merkleblock_tests.cpp
@@ -39,17 +39,17 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_found)
// vMatchedTxn is only used when bloom filter is specified.
BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U);
- std::vector<uint256> vMatched;
+ std::vector<Txid> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex());
BOOST_CHECK_EQUAL(vMatched.size(), 2U);
// Ordered by occurrence in depth-first tree traversal.
- BOOST_CHECK_EQUAL(vMatched[0].ToString(), txhash2.ToString());
+ BOOST_CHECK_EQUAL(vMatched[0], txhash2);
BOOST_CHECK_EQUAL(vIndex[0], 1U);
- BOOST_CHECK_EQUAL(vMatched[1].ToString(), txhash1.ToString());
+ BOOST_CHECK_EQUAL(vMatched[1], txhash1);
BOOST_CHECK_EQUAL(vIndex[1], 8U);
}
@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_not_found)
BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex());
BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U);
- std::vector<uint256> vMatched;
+ std::vector<Txid> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex());
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index 2ba48d71..b7bf5062 100644
--- a/src/test/pmt_tests.cpp
+++ b/src/test/pmt_tests.cpp
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
// calculate actual merkle root and height
uint256 merkleRoot1 = BlockMerkleRoot(block);
- std::vector<uint256> vTxid(nTx, uint256());
+ std::vector<Txid> vTxid(nTx);
for (unsigned int j=0; j<nTx; j++)
vTxid[j] = block.vtx[j]->GetHash();
int nHeight = 1, nTx_ = nTx;
@@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
for (int att = 1; att < 15; att++) {
// build random subset of txid's
std::vector<bool> vMatch(nTx, false);
- std::vector<uint256> vMatchTxid1;
+ std::vector<Txid> vMatchTxid1;
for (unsigned int j=0; j<nTx; j++) {
bool fInclude = m_rng.randbits(att / 2) == 0;
vMatch[j] = fInclude;
@@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
ss >> pmt2;
// extract merkle root and matched txids from copy
- std::vector<uint256> vMatchTxid2;
+ std::vector<Txid> vMatchTxid2;
std::vector<unsigned int> vIndex;
uint256 merkleRoot2 = pmt2.ExtractMatches(vMatchTxid2, vIndex);
@@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
for (int j=0; j<4; j++) {
CPartialMerkleTreeTester pmt3(pmt2);
pmt3.Damage();
- std::vector<uint256> vMatchTxid3;
+ std::vector<Txid> vMatchTxid3;
uint256 merkleRoot3 = pmt3.ExtractMatches(vMatchTxid3, vIndex);
BOOST_CHECK(merkleRoot3 != merkleRoot1);
}
@@ -110,13 +110,13 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
BOOST_AUTO_TEST_CASE(pmt_malleability)
{
- std::vector<uint256> vTxid{
- uint256{1}, uint256{2},
- uint256{3}, uint256{4},
- uint256{5}, uint256{6},
- uint256{7}, uint256{8},
- uint256{9}, uint256{10},
- uint256{9}, uint256{10},
+ std::vector<Txid> vTxid{
+ Txid::FromUint256(uint256{1}), Txid::FromUint256(uint256{2}),
+ Txid::FromUint256(uint256{3}), Txid::FromUint256(uint256{4}),
+ Txid::FromUint256(uint256{5}), Txid::FromUint256(uint256{6}),
+ Txid::FromUint256(uint256{7}), Txid::FromUint256(uint256{8}),
+ Txid::FromUint256(uint256{9}), Txid::FromUint256(uint256{10}),
+ Txid::FromUint256(uint256{9}), Txid::FromUint256(uint256{10}),
};
std::vector<bool> vMatch = {false, false, false, false, false, false, false, false, false, true, true, false};
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index edd1fb86..e8109214 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -60,7 +60,7 @@ RPCHelpMan importprunedfunds()
ssMB >> merkleBlock;
//Search partial merkle tree in proof for our transaction and index in valid block
- std::vector<uint256> vMatch;
+ std::vector<Txid> vMatch;
std::vector<unsigned int> vIndex;
if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Something wrong with merkleblock");
@@ -72,7 +72,7 @@ RPCHelpMan importprunedfunds()
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
}
- std::vector<uint256>::const_iterator it;
+ std::vector<Txid>::const_iterator it;
if ((it = std::find(vMatch.begin(), vMatch.end(), tx.GetHash())) == vMatch.end()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof");
}
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.