uint256
to Txid
.
uint256
to Txid
.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
For detailed information about the code coverage, see the test coverage report.
See the guideline for information on the review process.
Type | Reviewers |
---|---|
ACK | Sjors, stickies-v, TheCharlatan |
Concept ACK | ismaelsadeeq, pablomartin4btc |
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
42@@ -43,8 +43,7 @@ class COutPoint
43
44 friend bool operator<(const COutPoint& a, const COutPoint& b)
45 {
46- int cmp = a.hash.Compare(b.hash);
47- return cmp < 0 || (cmp == 0 && a.n < b.n);
48+ return a.hash < b.hash || (a.hash == b.hash && a.n < b.n);
0 return std::tie(a.hash, a.n) < std::tie(b.hash, b.n);
nit: This should compile, is shorter, and is recommended in https://en.cppreference.com/w/cpp/language/operators#Comparison_operators
2013@@ -2014,7 +2014,7 @@ bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>&
2014 }
2015 if (count % 256 == 0) {
2016 // update progress reference every 256 item
2017- uint32_t high = 0x100 * *key.hash.begin() + *(key.hash.begin() + 1);
2018+ uint32_t high = 0x100 * static_cast<const uint8_t>(*key.hash.begin()) + *(reinterpret_cast<const uint8_t*>(key.hash.begin()) + 1);
UCharCast
wrapper?
42@@ -43,7 +43,9 @@ struct PrecomputedData
43 for (uint32_t i = 0; i < NUM_OUTPOINTS; ++i) {
44 uint32_t idx = (i * 1200U) >> 12; /* Map 3 or 4 entries to same txid. */
45 const uint8_t ser[4] = {uint8_t(idx), uint8_t(idx >> 8), uint8_t(idx >> 16), uint8_t(idx >> 24)};
46- CSHA256().Write(PREFIX_O, 1).Write(ser, sizeof(ser)).Finalize(outpoints[i].hash.begin());
47+ uint256 txid;
48+ CSHA256().Write(PREFIX_O, 1).Write(ser, sizeof(ser)).Finalize(txid.begin());
49+ outpoints[i].hash = Txid::FromUint256(txid);
Finalize(UCharCast(outpoints[i].hash.data())
?
data
const. I don’t think there is any good reason to support mutating a txid.
const
.
64@@ -65,4 +65,9 @@ using Txid = transaction_identifier<false>;
65 /** Wtxid commits to all transaction fields including the witness. */
66 using Wtxid = transaction_identifier<true>;
67
68+inline Txid TxidFromString(const std::string& str)
Actually, string_view::data in this context may be UB, according to the standard, because a NUL char is not guaranteed to come at the string_view::end position, but the constructor requires a NUL at the end char to function.
I’ll try to fix this in a follow-up.
797 if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
798 return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
799
800- txid.SetHex(strTxid);
801- vOutPoints.emplace_back(txid, (uint32_t)nOutput);
802+ vOutPoints.emplace_back(TxidFromString(strTxid), (uint32_t)nOutput);
632@@ -633,7 +633,7 @@ static RPCHelpMan gettxspendingprevout()
633 {"vout", UniValueType(UniValue::VNUM)},
634 }, /*fAllowNull=*/false, /*fStrict=*/true);
635
636- const uint256 txid(ParseHashO(o, "txid"));
637+ const Txid txid = Txid::FromUint256(ParseHashO(o, "txid"));
ParseHashO
has a length check internally?
ParseHashV
which indeed checks that it’s 64 characters. So then only the rest.cpp
line above doesn’t check the length (and it’s terribly documented).
2013@@ -2014,7 +2014,7 @@ bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>&
2014 }
2015 if (count % 256 == 0) {
2016 // update progress reference every 256 item
2017- uint32_t high = 0x100 * *key.hash.begin() + *(key.hash.begin() + 1);
2018+ uint32_t high = 0x100 * *UCharCast(key.hash.begin()) + *(UCharCast(key.hash.begin()) + 1);
Txid::begin
etc. return std::byte*
which can’t be used for arithmetic operations.
Txid
comes to play here. But I see key
is a COutPoint
.
33@@ -34,7 +34,7 @@ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, std::optio
34 const UniValue& input = inputs[idx];
35 const UniValue& o = input.get_obj();
36
37- uint256 txid = ParseHashO(o, "txid");
38+ Txid txid = Txid::FromUint256(ParseHashO(o, "txid"));
ParseHashV
- deleting the other comments below
320@@ -321,7 +321,7 @@ CoinsResult AvailableCoins(const CWallet& wallet,
321 std::set<uint256> trusted_parents;
322 for (const auto& entry : wallet.mapWallet)
323 {
324- const uint256& wtxid = entry.first;
325+ const uint256& txid = entry.first;
entry.first
is a uint256
.
nit: Would simplify this to
0for (const auto& [txid, wtx] : wallet.mapWallet)
0diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
1index 35583642a5..0e72efe0ba 100644
2--- a/src/wallet/spend.cpp
3+++ b/src/wallet/spend.cpp
4@@ -319,11 +319,8 @@ CoinsResult AvailableCoins(const CWallet& wallet,
5 std::vector<COutPoint> outpoints;
6
7 std::set<uint256> trusted_parents;
8- for (const auto& entry : wallet.mapWallet)
9+ for (const auto& [txid, wtx] : wallet.mapWallet)
10 {
11- const uint256& txid = entry.first;
12- const CWalletTx& wtx = entry.second;
13-
14 if (wallet.IsTxImmatureCoinBase(wtx) && !params.include_immature_coinbase)
15 continue;
16
1056@@ -1057,7 +1057,7 @@ static RPCHelpMan gettxout()
1057
1058 UniValue ret(UniValue::VOBJ);
1059
1060- uint256 hash(ParseHashV(request.params[0], "txid"));
1061+ auto hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
Txid hash
?
nit
0 const auto hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
@maflcko perhaps we should add another RPCArg
type that’s ~32~ 64 characters STR_HEX
?
Update: it already happens in practice, though might still make sense to be more explicit, since there are other hex things users can pass to the RPC like a script or public key.
Are you keeping this and removing it in a follow-up?
Same for the comparisons above those lines (#L18 // TODO
).
Concept ACK
Light CR.
24@@ -25,7 +25,7 @@ void initialize_miner()
25 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
26 g_setup = testing_setup.get();
27 for (uint32_t i = 0; i < uint32_t{100}; ++i) {
28- g_available_coins.emplace_back(uint256::ZERO, i);
29+ g_available_coins.emplace_back(Txid::FromUint256(uint256::ZERO), i);
nit
0 g_available_coins.emplace_back(Txid{}, i);
Txid{}
, like you did in bench/disconnected_transactions
?
375 }
376 for (int i{0}; i <= 3; ++i) {
377 // Add some immature and non-existent outpoints
378 txids.push_back(g_outpoints_coinbase_init_immature.at(i).hash);
379- txids.push_back(ConsumeUInt256(fuzzed_data_provider));
380+ txids.push_back(Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)));
nit
0 txids.emplace_back(Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)));
599+ };
600+
601 // Add chain of size 500
602 TestMemPoolEntryHelper entry;
603- std::vector<uint256> chain_txids;
604+ std::vector<Txid> chain_txids;
std::vector<uint256> chain_txids;
for now?