Fix rct::h2d call (upstream change) (#252)
What changed, and why it matters
This commit updates a single function that decodes hidden Monero transaction amounts to match a recent upstream Monero library change. The old code called rct::h2d(copy.amount) directly and assumed it always succeeded. The new code creates a local output variable, calls rct::h2d(out, copy.amount), and only returns the decoded amount if the function reports success. This is a defensive fix that prevents the wallet server from returning potentially invalid or garbage decoded amounts if the conversion fails. It is unlikely to be a critical remote-exploitable vulnerability on its own, but it removes a correctness bug that could affect balance or transaction reporting.
Apply the patch. After applying, verify that the build links against the upstream Monero version whose rct::h2d signature uses the bool+out-parameter form, and run tests that exercise decode_amount with both valid and malformed RingCT amount fields. Consider auditing other call sites of rct::h2d in the codebase for the same pattern.
Security signals we found
API adaptation to upstream cryptographic conversion routine
Unchecked return value now checked before using decoded amount
Potential for invalid amount to be returned as valid before patch
Defensive correctness fix in transaction amount decoding
Evidence from the diff
In src/util/transactions.cpp, lws::decode_amount previously returned rct::h2d(copy.amount) as an xmr_amount without checking whether the hex-to-decimal conversion succeeded. An upstream Monero change altered rct::h2d’s signature to return bool and write the result into an out-parameter. The patch adapts to that API: it declares rct::xmr_amount out = 0, invokes rct::h2d(out, copy.amount), and returns the decoded pair only when h2d returns true. If h2d fails, the function now returns boost::none instead of an undefined or incorrect amount. The change is small and API-driven, but it closes a hole where a malformed amount encoding could propagate as a valid value.
Changed components
src/util/transactions.cpplws::decode_amountRingCT amount decoding pathInspect captured patch +5 / −1
diff --git a/src/util/transactions.cpp b/src/util/transactions.cpp
index 197563c..768b4d3 100644
--- a/src/util/transactions.cpp
+++ b/src/util/transactions.cpp
@@ -56,6 +56,10 @@ boost::optional<std::pair<std::uint64_t, rct::key>> lws::decode_amount(const rct
rct::key Ctmp;
rct::addKeys2(Ctmp, copy.mask, copy.amount, rct::H);
if (rct::equalKeys(commitment, Ctmp))
- return {{rct::h2d(copy.amount), copy.mask}};
+ {
+ rct::xmr_amount out = 0;
+ if (rct::h2d(out, copy.amount))
+ return {{out, copy.mask}};
+ }
return boost::none;
}
Why this scored 42/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.