diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 7f36692c427..ce1c69b033b 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -393,6 +393,8 @@ struct WalletTx int64_t time; std::optional from; // Deprecated std::optional message; // Deprecated + std::optional comment; + std::optional comment_to; std::map value_map; bool is_coinbase; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index d16e280883f..4d1be8c7621 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -155,10 +155,9 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall // // To // - if (wtx.value_map.contains("to") && !wtx.value_map["to"].empty()) - { + if (wtx.comment_to) { // Online transaction - std::string strAddress = wtx.value_map["to"]; + std::string strAddress = *wtx.comment_to; strHTML += "" + tr("To") + ": "; CTxDestination dest = DecodeDestination(strAddress); std::string name; @@ -210,8 +209,7 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall if (toSelf && all_from_me) continue; - if (!wtx.value_map.contains("to") || wtx.value_map["to"].empty()) - { + if (!wtx.comment_to) { // Offline transaction CTxDestination address; if (ExtractDestination(txout.scriptPubKey, address)) @@ -274,8 +272,9 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall if (wtx.message) { strHTML += "
" + tr("Message") + ":
" + GUIUtil::HtmlEscape(*wtx.message, true) + "
"; } - if (wtx.value_map.count("comment") && !wtx.value_map["comment"].empty()) - strHTML += "
" + tr("Comment") + ":
" + GUIUtil::HtmlEscape(wtx.value_map["comment"], true) + "
"; + if (wtx.comment) { + strHTML += "
" + tr("Comment") + ":
" + GUIUtil::HtmlEscape(*wtx.comment, true) + "
"; + } strHTML += "" + tr("Transaction ID") + ": " + rec->getTxHash() + "
"; strHTML += "" + tr("Transaction total size") + ": " + QString::number(wtx.tx->ComputeTotalSize()) + " bytes
"; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index a06736bb3bd..1f323590471 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -77,7 +77,7 @@ QList TransactionRecord::decomposeTransaction(const interface { // Sent to IP, or other non-address transaction like OP_EVAL sub.type = TransactionRecord::SendToOther; - sub.address = mapValue["to"]; + sub.address = wtx.comment_to.value_or(""); } CAmount nValue = txout.nValue; diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 5ccaf896eac..84eb022e7e1 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -370,9 +370,7 @@ Result CommitTransaction(CWallet& wallet, const Txid& txid, CMutableTransaction& // commit/broadcast the tx CTransactionRef tx = MakeTransactionRef(std::move(mtx)); - std::optional comment = oldWtx.mapValue.contains("comment") ? std::optional(oldWtx.mapValue.at("comment")) : std::nullopt; - std::optional comment_to = oldWtx.mapValue.contains("to") ? std::optional(oldWtx.mapValue.at("to")) : std::nullopt; - wallet.CommitTransaction(tx, oldWtx.vOrderForm, oldWtx.GetHash(), comment, comment_to); + wallet.CommitTransaction(tx, oldWtx.vOrderForm, oldWtx.GetHash(), oldWtx.m_comment, oldWtx.m_comment_to); // mark the original tx as bumped bumped_txid = tx->GetHash(); diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index 49271648a3e..d95e057422a 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -81,6 +81,8 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) result.time = wtx.GetTxTime(); result.from = wtx.m_from; result.message = wtx.m_message; + result.comment = wtx.m_comment; + result.comment_to = wtx.m_comment_to; result.value_map = wtx.mapValue; result.is_coinbase = wtx.IsCoinBase(); return result; diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp index 77af932ea68..8d7b8019e4e 100644 --- a/src/wallet/rpc/transactions.cpp +++ b/src/wallet/rpc/transactions.cpp @@ -62,6 +62,9 @@ static void WalletTxToJSON(const CWallet& wallet, const CWalletTx& wtx, UniValue entry.pushKV("bip125-replaceable", rbfStatus); } + if (wtx.m_comment) entry.pushKV("comment", *wtx.m_comment); + if (wtx.m_comment_to) entry.pushKV("to", *wtx.m_comment_to); + for (const std::pair& item : wtx.mapValue) entry.pushKV(item.first, item.second); } diff --git a/src/wallet/transaction.h b/src/wallet/transaction.h index 32236aaf638..5ea686b7a28 100644 --- a/src/wallet/transaction.h +++ b/src/wallet/transaction.h @@ -199,14 +199,15 @@ public: // These fields are kept to avoid losing metadata. std::optional m_from; std::optional m_message; + // Comment strings provided by the user + std::optional m_comment; + std::optional m_comment_to; /** * Key/value map with information about the transaction. * * The following keys can be read and written through the map and are * serialized in the wallet database: * - * "comment", "to" - comment strings provided to sendtoaddress, - * and sendmany wallet RPCs * "replaces_txid" - txid (as HexStr) of transaction replaced by * bumpfee on transaction created by bumpfee * "replaced_by_txid" - txid (as HexStr) of transaction created by @@ -223,6 +224,8 @@ public: * 2014 (removed in commit 93a18a3) * "from", "message" - obsolete fields that could be set in UI prior to * 2011 (removed in commit 4d9b223) + * "comment", "to" - comment strings provided to sendtoaddress, + * and sendmany wallet RPCs */ mapValue_t mapValue; std::vector > vOrderForm; @@ -292,6 +295,8 @@ public: mapValue_t mapValueCopy = mapValue; if (m_from) mapValueCopy["from"] = *m_from; if (m_message) mapValueCopy["message"] = *m_message; + if (m_comment) mapValueCopy["comment"] = *m_comment; + if (m_comment_to) mapValueCopy["to"] = *m_comment_to; mapValueCopy["fromaccount"] = ""; if (nOrderPos != -1) { @@ -330,6 +335,8 @@ public: else if (key == "timesmart") nTimeSmart = LocaleIndependentAtoi(value); else if (key == "from") m_from = value; else if (key == "message") m_message = value; + else if (key == "comment") m_comment = value; + else if (key == "to") m_comment_to = value; } mapValue.erase("fromaccount"); @@ -338,6 +345,8 @@ public: mapValue.erase("timesmart"); mapValue.erase("from"); mapValue.erase("message"); + mapValue.erase("comment"); + mapValue.erase("to"); } void SetTx(CTransactionRef arg) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b9980428fdd..095bb285aaf 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -744,6 +744,8 @@ void CWallet::SyncMetaData(std::pair ran if (!copyFrom->IsEquivalentTo(*copyTo)) continue; copyTo->m_from = copyFrom->m_from; copyTo->m_message = copyFrom->m_message; + copyTo->m_comment = copyFrom->m_comment; + copyTo->m_comment_to = copyFrom->m_comment_to; copyTo->mapValue = copyFrom->mapValue; copyTo->vOrderForm = copyFrom->vOrderForm; // nTimeReceived not copied on purpose @@ -2343,8 +2345,8 @@ void CWallet::CommitTransaction( CHECK_NONFATAL(wtx.mapValue.empty()); CHECK_NONFATAL(wtx.vOrderForm.empty()); if (replaces_txid) wtx.mapValue["replaces_txid"] = replaces_txid->ToString(); - if (comment) wtx.mapValue["comment"] = *comment; - if (comment_to) wtx.mapValue["to"] = *comment_to; + if (comment) wtx.m_comment = comment; + if (comment_to) wtx.m_comment_to = comment_to; wtx.vOrderForm = std::move(orderForm); return true; });