Skip to content

Commit fae7776

Browse files
author
MarcoFalke
committed
wallet: Avoid translating RPC errors when creating txs
Also, mark feebumper bilingual_str as Untranslated They are technical and have previously not been translated either. It is questionable whether they can even appear in the GUI.
1 parent fae51a5 commit fae7776

File tree

9 files changed

+95
-90
lines changed

9 files changed

+95
-90
lines changed

src/interfaces/wallet.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class WalletImpl : public Wallet
219219
bool sign,
220220
int& change_pos,
221221
CAmount& fee,
222-
std::string& fail_reason) override
222+
bilingual_str& fail_reason) override
223223
{
224224
LOCK(m_wallet->cs_wallet);
225225
CTransactionRef tx;
@@ -248,7 +248,7 @@ class WalletImpl : public Wallet
248248
}
249249
bool createBumpTransaction(const uint256& txid,
250250
const CCoinControl& coin_control,
251-
std::vector<std::string>& errors,
251+
std::vector<bilingual_str>& errors,
252252
CAmount& old_fee,
253253
CAmount& new_fee,
254254
CMutableTransaction& mtx) override
@@ -258,7 +258,7 @@ class WalletImpl : public Wallet
258258
bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(*m_wallet.get(), mtx); }
259259
bool commitBumpTransaction(const uint256& txid,
260260
CMutableTransaction&& mtx,
261-
std::vector<std::string>& errors,
261+
std::vector<bilingual_str>& errors,
262262
uint256& bumped_txid) override
263263
{
264264
return feebumper::CommitTransaction(*m_wallet.get(), txid, std::move(mtx), errors, bumped_txid) ==

src/interfaces/wallet.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ enum class TransactionError;
3131
enum isminetype : unsigned int;
3232
struct CRecipient;
3333
struct PartiallySignedTransaction;
34+
struct bilingual_str;
3435
typedef uint8_t isminefilter;
3536

3637
namespace interfaces {
@@ -136,7 +137,7 @@ class Wallet
136137
bool sign,
137138
int& change_pos,
138139
CAmount& fee,
139-
std::string& fail_reason) = 0;
140+
bilingual_str& fail_reason) = 0;
140141

141142
//! Commit transaction.
142143
virtual void commitTransaction(CTransactionRef tx,
@@ -155,7 +156,7 @@ class Wallet
155156
//! Create bump transaction.
156157
virtual bool createBumpTransaction(const uint256& txid,
157158
const CCoinControl& coin_control,
158-
std::vector<std::string>& errors,
159+
std::vector<bilingual_str>& errors,
159160
CAmount& old_fee,
160161
CAmount& new_fee,
161162
CMutableTransaction& mtx) = 0;
@@ -166,7 +167,7 @@ class Wallet
166167
//! Commit bump transaction.
167168
virtual bool commitBumpTransaction(const uint256& txid,
168169
CMutableTransaction&& mtx,
169-
std::vector<std::string>& errors,
170+
std::vector<bilingual_str>& errors,
170171
uint256& bumped_txid) = 0;
171172

172173
//! Get a transaction.

src/qt/walletmodel.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <psbt.h>
2525
#include <ui_interface.h>
2626
#include <util/system.h> // for GetBoolArg
27+
#include <util/translation.h>
2728
#include <wallet/coincontrol.h>
2829
#include <wallet/wallet.h> // for CRecipient
2930

@@ -185,10 +186,10 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
185186
{
186187
CAmount nFeeRequired = 0;
187188
int nChangePosRet = -1;
188-
std::string strFailReason;
189+
bilingual_str error;
189190

190191
auto& newTx = transaction.getWtx();
191-
newTx = m_wallet->createTransaction(vecSend, coinControl, !wallet().privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, strFailReason);
192+
newTx = m_wallet->createTransaction(vecSend, coinControl, !wallet().privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, error);
192193
transaction.setTransactionFee(nFeeRequired);
193194
if (fSubtractFeeFromAmount && newTx)
194195
transaction.reassignAmounts(nChangePosRet);
@@ -199,8 +200,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
199200
{
200201
return SendCoinsReturn(AmountWithFeeExceedsBalance);
201202
}
202-
Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
203-
CClientUIInterface::MSG_ERROR);
203+
Q_EMIT message(tr("Send Coins"), QString::fromStdString(error.translated),
204+
CClientUIInterface::MSG_ERROR);
204205
return TransactionCreationFailed;
205206
}
206207

@@ -482,14 +483,14 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
482483
{
483484
CCoinControl coin_control;
484485
coin_control.m_signal_bip125_rbf = true;
485-
std::vector<std::string> errors;
486+
std::vector<bilingual_str> errors;
486487
CAmount old_fee;
487488
CAmount new_fee;
488489
CMutableTransaction mtx;
489490
if (!m_wallet->createBumpTransaction(hash, coin_control, errors, old_fee, new_fee, mtx)) {
490491
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Increasing transaction fee failed") + "<br />(" +
491-
(errors.size() ? QString::fromStdString(errors[0]) : "") +")");
492-
return false;
492+
(errors.size() ? QString::fromStdString(errors[0].translated) : "") +")");
493+
return false;
493494
}
494495

495496
const bool create_psbt = m_wallet->privateKeysDisabled();
@@ -551,8 +552,8 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
551552
// commit the bumped transaction
552553
if(!m_wallet->commitBumpTransaction(hash, std::move(mtx), errors, new_hash)) {
553554
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Could not commit transaction") + "<br />(" +
554-
QString::fromStdString(errors[0])+")");
555-
return false;
555+
QString::fromStdString(errors[0].translated)+")");
556+
return false;
556557
}
557558
return true;
558559
}

src/wallet/feebumper.cpp

+27-25
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,53 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <interfaces/chain.h>
6-
#include <wallet/coincontrol.h>
7-
#include <wallet/feebumper.h>
8-
#include <wallet/fees.h>
9-
#include <wallet/wallet.h>
106
#include <policy/fees.h>
117
#include <policy/policy.h>
128
#include <util/moneystr.h>
139
#include <util/rbf.h>
1410
#include <util/system.h>
11+
#include <util/translation.h>
12+
#include <wallet/coincontrol.h>
13+
#include <wallet/feebumper.h>
14+
#include <wallet/fees.h>
15+
#include <wallet/wallet.h>
1516

1617
//! Check whether transaction has descendant in wallet or mempool, or has been
1718
//! mined, or conflicts with a mined transaction. Return a feebumper::Result.
18-
static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
19+
static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWalletTx& wtx, std::vector<bilingual_str>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
1920
{
2021
if (wallet.HasWalletSpend(wtx.GetHash())) {
21-
errors.push_back("Transaction has descendants in the wallet");
22+
errors.push_back(Untranslated("Transaction has descendants in the wallet"));
2223
return feebumper::Result::INVALID_PARAMETER;
2324
}
2425

2526
{
2627
if (wallet.chain().hasDescendantsInMempool(wtx.GetHash())) {
27-
errors.push_back("Transaction has descendants in the mempool");
28+
errors.push_back(Untranslated("Transaction has descendants in the mempool"));
2829
return feebumper::Result::INVALID_PARAMETER;
2930
}
3031
}
3132

3233
if (wtx.GetDepthInMainChain() != 0) {
33-
errors.push_back("Transaction has been mined, or is conflicted with a mined transaction");
34+
errors.push_back(Untranslated("Transaction has been mined, or is conflicted with a mined transaction"));
3435
return feebumper::Result::WALLET_ERROR;
3536
}
3637

3738
if (!SignalsOptInRBF(*wtx.tx)) {
38-
errors.push_back("Transaction is not BIP 125 replaceable");
39+
errors.push_back(Untranslated("Transaction is not BIP 125 replaceable"));
3940
return feebumper::Result::WALLET_ERROR;
4041
}
4142

4243
if (wtx.mapValue.count("replaced_by_txid")) {
43-
errors.push_back(strprintf("Cannot bump transaction %s which was already bumped by transaction %s", wtx.GetHash().ToString(), wtx.mapValue.at("replaced_by_txid")));
44+
errors.push_back(strprintf(Untranslated("Cannot bump transaction %s which was already bumped by transaction %s"), wtx.GetHash().ToString(), wtx.mapValue.at("replaced_by_txid")));
4445
return feebumper::Result::WALLET_ERROR;
4546
}
4647

4748
// check that original tx consists entirely of our inputs
4849
// if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee)
4950
isminefilter filter = wallet.GetLegacyScriptPubKeyMan() && wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE;
5051
if (!wallet.IsAllFromMe(*wtx.tx, filter)) {
51-
errors.push_back("Transaction contains inputs that don't belong to this wallet");
52+
errors.push_back(Untranslated("Transaction contains inputs that don't belong to this wallet"));
5253
return feebumper::Result::WALLET_ERROR;
5354
}
5455

@@ -57,7 +58,8 @@ static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWallet
5758
}
5859

5960
//! Check if the user provided a valid feeRate
60-
static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<std::string>& errors) {
61+
static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<bilingual_str>& errors)
62+
{
6163
// check that fee rate is higher than mempool's minimum fee
6264
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
6365
// This may occur if the user set fee_rate or paytxfee too low, if fallbackfee is too low, or, perhaps,
@@ -67,7 +69,7 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wt
6769

6870
if (newFeerate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) {
6971
errors.push_back(strprintf(
70-
"New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- ",
72+
Untranslated("New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- "),
7173
FormatMoney(newFeerate.GetFeePerK()),
7274
FormatMoney(minMempoolFeeRate.GetFeePerK())));
7375
return feebumper::Result::WALLET_ERROR;
@@ -86,23 +88,23 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wt
8688
CAmount minTotalFee = nOldFeeRate.GetFee(maxTxSize) + incrementalRelayFee.GetFee(maxTxSize);
8789

8890
if (new_total_fee < minTotalFee) {
89-
errors.push_back(strprintf("Insufficient total fee %s, must be at least %s (oldFee %s + incrementalFee %s)",
91+
errors.push_back(strprintf(Untranslated("Insufficient total fee %s, must be at least %s (oldFee %s + incrementalFee %s)"),
9092
FormatMoney(new_total_fee), FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxTxSize)), FormatMoney(incrementalRelayFee.GetFee(maxTxSize))));
9193
return feebumper::Result::INVALID_PARAMETER;
9294
}
9395

9496
CAmount requiredFee = GetRequiredFee(wallet, maxTxSize);
9597
if (new_total_fee < requiredFee) {
96-
errors.push_back(strprintf("Insufficient total fee (cannot be less than required fee %s)",
98+
errors.push_back(strprintf(Untranslated("Insufficient total fee (cannot be less than required fee %s)"),
9799
FormatMoney(requiredFee)));
98100
return feebumper::Result::INVALID_PARAMETER;
99101
}
100102

101103
// Check that in all cases the new fee doesn't violate maxTxFee
102104
const CAmount max_tx_fee = wallet.m_default_max_tx_fee;
103105
if (new_total_fee > max_tx_fee) {
104-
errors.push_back(strprintf("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)",
105-
FormatMoney(new_total_fee), FormatMoney(max_tx_fee)));
106+
errors.push_back(strprintf(Untranslated("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)"),
107+
FormatMoney(new_total_fee), FormatMoney(max_tx_fee)));
106108
return feebumper::Result::WALLET_ERROR;
107109
}
108110

@@ -144,12 +146,12 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid)
144146
const CWalletTx* wtx = wallet.GetWalletTx(txid);
145147
if (wtx == nullptr) return false;
146148

147-
std::vector<std::string> errors_dummy;
149+
std::vector<bilingual_str> errors_dummy;
148150
feebumper::Result res = PreconditionChecks(wallet, *wtx, errors_dummy);
149151
return res == feebumper::Result::OK;
150152
}
151153

152-
Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
154+
Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<bilingual_str>& errors,
153155
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
154156
{
155157
// We are going to modify coin control later, copy to re-use
@@ -159,7 +161,7 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
159161
errors.clear();
160162
auto it = wallet.mapWallet.find(txid);
161163
if (it == wallet.mapWallet.end()) {
162-
errors.push_back("Invalid or non-wallet transaction id");
164+
errors.push_back(Untranslated("Invalid or non-wallet transaction id"));
163165
return Result::INVALID_ADDRESS_OR_KEY;
164166
}
165167
const CWalletTx& wtx = it->second;
@@ -216,9 +218,9 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
216218
CTransactionRef tx_new = MakeTransactionRef();
217219
CAmount fee_ret;
218220
int change_pos_in_out = -1; // No requested location for change
219-
std::string fail_reason;
221+
bilingual_str fail_reason;
220222
if (!wallet.CreateTransaction(recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false)) {
221-
errors.push_back("Unable to create transaction: " + fail_reason);
223+
errors.push_back(Untranslated("Unable to create transaction: ") + Untranslated(" ") + fail_reason);
222224
return Result::WALLET_ERROR;
223225
}
224226

@@ -242,15 +244,15 @@ bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx) {
242244
return wallet.SignTransaction(mtx);
243245
}
244246

245-
Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid)
247+
Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<bilingual_str>& errors, uint256& bumped_txid)
246248
{
247249
LOCK(wallet.cs_wallet);
248250
if (!errors.empty()) {
249251
return Result::MISC_ERROR;
250252
}
251253
auto it = txid.IsNull() ? wallet.mapWallet.end() : wallet.mapWallet.find(txid);
252254
if (it == wallet.mapWallet.end()) {
253-
errors.push_back("Invalid or non-wallet transaction id");
255+
errors.push_back(Untranslated("Invalid or non-wallet transaction id"));
254256
return Result::MISC_ERROR;
255257
}
256258
CWalletTx& oldWtx = it->second;
@@ -275,7 +277,7 @@ Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransacti
275277
// along with an exception. It would be good to return information about
276278
// wtxBumped to the caller even if marking the original transaction
277279
// replaced does not succeed for some reason.
278-
errors.push_back("Created new bumpfee transaction but could not mark the original transaction as replaced");
280+
errors.push_back(Untranslated("Created new bumpfee transaction but could not mark the original transaction as replaced"));
279281
}
280282
return Result::OK;
281283
}

src/wallet/feebumper.h

+11-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class CWalletTx;
1212
class uint256;
1313
class CCoinControl;
1414
enum class FeeEstimateMode;
15+
struct bilingual_str;
1516

1617
namespace feebumper {
1718

@@ -30,12 +31,12 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid);
3031

3132
//! Create bumpfee transaction based on feerate estimates.
3233
Result CreateRateBumpTransaction(CWallet& wallet,
33-
const uint256& txid,
34-
const CCoinControl& coin_control,
35-
std::vector<std::string>& errors,
36-
CAmount& old_fee,
37-
CAmount& new_fee,
38-
CMutableTransaction& mtx);
34+
const uint256& txid,
35+
const CCoinControl& coin_control,
36+
std::vector<bilingual_str>& errors,
37+
CAmount& old_fee,
38+
CAmount& new_fee,
39+
CMutableTransaction& mtx);
3940

4041
//! Sign the new transaction,
4142
//! @return false if the tx couldn't be found or if it was
@@ -47,10 +48,10 @@ bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx);
4748
//! but sets errors if the tx could not be added to the mempool (will try later)
4849
//! or if the old transaction could not be marked as replaced.
4950
Result CommitTransaction(CWallet& wallet,
50-
const uint256& txid,
51-
CMutableTransaction&& mtx,
52-
std::vector<std::string>& errors,
53-
uint256& bumped_txid);
51+
const uint256& txid,
52+
CMutableTransaction&& mtx,
53+
std::vector<bilingual_str>& errors,
54+
uint256& bumped_txid);
5455

5556
} // namespace feebumper
5657

0 commit comments

Comments
 (0)