From 08afe5bb3be48b6c5024cbd3c630845dc3515098 Mon Sep 17 00:00:00 2001 From: DanS Date: Fri, 9 Oct 2026 13:31:01 -0500 Subject: [PATCH] wallet: read wallet txs and note data by reference in more RPCs z_listreceivedbyaddress copied a whole CWalletTx per returned note to call GetTxTime(). z_viewtransaction copied the previous tx of each own spend, CWalletTx::DecryptSaplingNote copied the output and the note data (witness list included) to read one field, and zsTxSpendsToJSON copied the note data. All of them now bind const references to the same elements. The lookups that throw or assert still do, and output is unchanged. Co-Authored-By: Claude Opus 5.5 --- src/wallet/rpchushwallet.cpp | 2 +- src/wallet/rpcwallet.cpp | 4 ++-- src/wallet/wallet.cpp | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/wallet/rpchushwallet.cpp b/src/wallet/rpchushwallet.cpp index cdcb08f2d..85574b7c7 100644 --- a/src/wallet/rpchushwallet.cpp +++ b/src/wallet/rpchushwallet.cpp @@ -153,7 +153,7 @@ void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpen if (pwalletMain->IsSaplingNullifierFromMe(spendDesc.nullifier)) { const CWalletTx* parent = pwalletMain->GetWalletTx(pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash); const OutputDescription& output = parent->vShieldedOutput[op.n]; - auto nd = pwalletMain->mapWallet[pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash].mapSaplingNoteData[op]; + const SaplingNoteData& nd = pwalletMain->mapWallet[pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash].mapSaplingNoteData[op]; auto pt = libzcash::SaplingNotePlaintext::decrypt(output.encCiphertext,nd.ivk,output.ephemeralKey,output.cm); if (pt) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5fa5c5fd9..d71f35d98 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4696,7 +4696,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK } obj.push_back(Pair("outindex", (int)entry.op.n)); obj.push_back(Pair("rawconfirmations", entry.confirmations)); - auto wtx = pwalletMain->mapWallet.at(entry.op.hash); //.ToString()); + const CWalletTx& wtx = pwalletMain->mapWallet.at(entry.op.hash); //.ToString()); obj.push_back(Pair("time", wtx.GetTxTime())); obj.push_back(Pair("confirmations", dpowconfs)); @@ -4949,7 +4949,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp, const CPubKey& my continue; } auto op = res->second; - auto wtxPrev = pwalletMain->mapWallet.at(op.hash); + const CWalletTx& wtxPrev = pwalletMain->mapWallet.at(op.hash); auto decrypted = wtxPrev.DecryptSaplingNote(op).get(); auto notePt = decrypted.first; auto pa = decrypted.second; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dec4fb598..1e8a22cb8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2935,12 +2935,13 @@ boost::optional> CWalletTx::DecryptSaplingNote(SaplingOutPoint op) const { // Check whether we can decrypt this SaplingOutPoint - if (this->mapSaplingNoteData.count(op) == 0) { + mapSaplingNoteData_t::const_iterator ndIt = this->mapSaplingNoteData.find(op); + if (ndIt == this->mapSaplingNoteData.end()) { return boost::none; } - auto output = this->vShieldedOutput[op.n]; - auto nd = this->mapSaplingNoteData.at(op); + const OutputDescription& output = this->vShieldedOutput[op.n]; + const SaplingNoteData& nd = ndIt->second; auto maybe_pt = SaplingNotePlaintext::decrypt( output.encCiphertext,