Skip to content

Commit fd902a9

Browse files
MarcoFalkedeadalnix
authored andcommitted
wallet: Avoid translating RPC errors when creating txs
Summary: 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. This is a partial backport of Cor [[bitcoin/bitcoin#18699 | PR18699]] : bitcoin/bitcoin@fae7776 Test Plan: ninja all check Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D7703
1 parent 0aad192 commit fd902a9

File tree

7 files changed

+47
-61
lines changed

7 files changed

+47
-61
lines changed

src/interfaces/wallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ namespace {
235235
createTransaction(const std::vector<CRecipient> &recipients,
236236
const CCoinControl &coin_control, bool sign,
237237
int &change_pos, Amount &fee,
238-
std::string &fail_reason) override {
238+
bilingual_str &fail_reason) override {
239239
auto locked_chain = m_wallet->chain().lock();
240240
LOCK(m_wallet->cs_wallet);
241241
CTransactionRef tx;

src/interfaces/wallet.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef uint8_t isminefilter;
3535
enum class OutputType;
3636
struct CRecipient;
3737
struct TxId;
38+
struct bilingual_str;
3839

3940
namespace interfaces {
4041

@@ -156,7 +157,7 @@ class Wallet {
156157
createTransaction(const std::vector<CRecipient> &recipients,
157158
const CCoinControl &coin_control, bool sign,
158159
int &change_pos, Amount &fee,
159-
std::string &fail_reason) = 0;
160+
bilingual_str &fail_reason) = 0;
160161

161162
//! Commit transaction.
162163
virtual void commitTransaction(CTransactionRef tx, WalletValueMap value_map,

src/qt/walletmodel.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <qt/transactiontablemodel.h>
1616
#include <ui_interface.h>
1717
#include <util/system.h> // for GetBoolArg
18+
#include <util/translation.h>
1819
#include <wallet/coincontrol.h>
1920
#include <wallet/wallet.h>
2021

@@ -197,12 +198,11 @@ WalletModel::prepareTransaction(WalletModelTransaction &transaction,
197198

198199
Amount nFeeRequired = Amount::zero();
199200
int nChangePosRet = -1;
200-
std::string strFailReason;
201+
bilingual_str error;
201202

202203
auto &newTx = transaction.getWtx();
203-
newTx =
204-
m_wallet->createTransaction(vecSend, coinControl, true /* sign */,
205-
nChangePosRet, nFeeRequired, strFailReason);
204+
newTx = m_wallet->createTransaction(vecSend, coinControl, true /* sign */,
205+
nChangePosRet, nFeeRequired, error);
206206
transaction.setTransactionFee(nFeeRequired);
207207
if (fSubtractFeeFromAmount && newTx) {
208208
transaction.reassignAmounts(nChangePosRet);
@@ -212,7 +212,8 @@ WalletModel::prepareTransaction(WalletModelTransaction &transaction,
212212
if (!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) {
213213
return SendCoinsReturn(AmountWithFeeExceedsBalance);
214214
}
215-
Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
215+
Q_EMIT message(tr("Send Coins"),
216+
QString::fromStdString(error.translated),
216217
CClientUIInterface::MSG_ERROR);
217218
return TransactionCreationFailed;
218219
}

src/wallet/rpcwallet.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ static CTransactionRef SendMoney(interfaces::Chain::Lock &locked_chain,
377377

378378
// Create and send the transaction
379379
Amount nFeeRequired;
380-
std::string strError;
380+
bilingual_str error;
381381
std::vector<CRecipient> vecSend;
382382
int nChangePosRet = -1;
383383
CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
@@ -386,13 +386,13 @@ static CTransactionRef SendMoney(interfaces::Chain::Lock &locked_chain,
386386
CCoinControl coinControl;
387387
CTransactionRef tx;
388388
if (!pwallet->CreateTransaction(locked_chain, vecSend, tx, nFeeRequired,
389-
nChangePosRet, strError, coinControl)) {
389+
nChangePosRet, error, coinControl)) {
390390
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) {
391-
strError = strprintf("Error: This transaction requires a "
392-
"transaction fee of at least %s",
393-
FormatMoney(nFeeRequired));
391+
error = strprintf(Untranslated("Error: This transaction requires a "
392+
"transaction fee of at least %s"),
393+
FormatMoney(nFeeRequired));
394394
}
395-
throw JSONRPCError(RPC_WALLET_ERROR, strError);
395+
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
396396
}
397397
pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
398398
return tx;
@@ -1065,14 +1065,14 @@ static UniValue sendmany(const Config &config, const JSONRPCRequest &request) {
10651065
// Send
10661066
Amount nFeeRequired = Amount::zero();
10671067
int nChangePosRet = -1;
1068-
std::string strFailReason;
1068+
bilingual_str error;
10691069
CTransactionRef tx;
10701070
CCoinControl coinControl;
10711071
bool fCreated =
10721072
pwallet->CreateTransaction(*locked_chain, vecSend, tx, nFeeRequired,
1073-
nChangePosRet, strFailReason, coinControl);
1073+
nChangePosRet, error, coinControl);
10741074
if (!fCreated) {
1075-
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
1075+
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, error.original);
10761076
}
10771077
pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
10781078
return tx->GetId().GetHex();
@@ -3670,12 +3670,12 @@ void FundTransaction(CWallet *const pwallet, CMutableTransaction &tx,
36703670
setSubtractFeeFromOutputs.insert(pos);
36713671
}
36723672

3673-
std::string strFailReason;
3673+
bilingual_str error;
36743674

3675-
if (!pwallet->FundTransaction(tx, fee_out, change_position, strFailReason,
3675+
if (!pwallet->FundTransaction(tx, fee_out, change_position, error,
36763676
lockUnspents, setSubtractFeeFromOutputs,
36773677
coinControl)) {
3678-
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
3678+
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
36793679
}
36803680
}
36813681

src/wallet/test/wallet_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <node/context.h>
1010
#include <policy/policy.h>
1111
#include <rpc/server.h>
12+
#include <util/translation.h>
1213
#include <validation.h>
1314
#include <wallet/coincontrol.h>
1415
#include <wallet/rpcdump.h>
@@ -521,7 +522,7 @@ class ListCoinsTestingSetup : public TestChain100Setup {
521522
CTransactionRef tx;
522523
Amount fee;
523524
int changePos = -1;
524-
std::string error;
525+
bilingual_str error;
525526
CCoinControl dummy;
526527
{
527528
auto locked_chain = m_chain->lock();

src/wallet/wallet.cpp

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <key_io.h>
1717
#include <policy/mempool.h>
1818
#include <policy/policy.h>
19-
#include <primitives/block.h>
2019
#include <primitives/transaction.h>
2120
#include <random.h>
2221
#include <script/descriptor.h>
@@ -2736,7 +2735,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx) {
27362735
}
27372736

27382737
bool CWallet::FundTransaction(CMutableTransaction &tx, Amount &nFeeRet,
2739-
int &nChangePosInOut, std::string &strFailReason,
2738+
int &nChangePosInOut, bilingual_str &error,
27402739
bool lockUnspents,
27412740
const std::set<int> &setSubtractFeeFromOutputs,
27422741
CCoinControl coinControl) {
@@ -2763,8 +2762,7 @@ bool CWallet::FundTransaction(CMutableTransaction &tx, Amount &nFeeRet,
27632762

27642763
CTransactionRef tx_new;
27652764
if (!CreateTransaction(*locked_chain, vecSend, tx_new, nFeeRet,
2766-
nChangePosInOut, strFailReason, coinControl,
2767-
false)) {
2765+
nChangePosInOut, error, coinControl, false)) {
27682766
return false;
27692767
}
27702768

@@ -2879,8 +2877,7 @@ CWallet::TransactionChangeType(OutputType change_type,
28792877
bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
28802878
const std::vector<CRecipient> &vecSend,
28812879
CTransactionRef &tx, Amount &nFeeRet,
2882-
int &nChangePosInOut,
2883-
std::string &strFailReason,
2880+
int &nChangePosInOut, bilingual_str &error,
28842881
const CCoinControl &coinControl, bool sign) {
28852882
Amount nValue = Amount::zero();
28862883
const OutputType change_type = TransactionChangeType(
@@ -2892,8 +2889,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
28922889
unsigned int nSubtractFeeFromAmount = 0;
28932890
for (const auto &recipient : vecSend) {
28942891
if (nValue < Amount::zero() || recipient.nAmount < Amount::zero()) {
2895-
strFailReason =
2896-
_("Transaction amounts must not be negative").translated;
2892+
error = _("Transaction amounts must not be negative");
28972893
return false;
28982894
}
28992895

@@ -2905,8 +2901,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
29052901
}
29062902

29072903
if (vecSend.empty()) {
2908-
strFailReason =
2909-
_("Transaction must have at least one recipient").translated;
2904+
error = _("Transaction must have at least one recipient");
29102905
return false;
29112906
}
29122907

@@ -2946,18 +2941,14 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
29462941

29472942
// Reserve a new key pair from key pool
29482943
if (!CanGetAddresses(true)) {
2949-
strFailReason =
2950-
_("Can't generate a change-address key. No keys in the "
2951-
"internal keypool and can't generate any keys.")
2952-
.translated;
2944+
error = _("Can't generate a change-address key. No keys in the "
2945+
"internal keypool and can't generate any keys.");
29532946
return false;
29542947
}
29552948
CTxDestination dest;
29562949
bool ret = reservedest.GetReservedDestination(dest, true);
29572950
if (!ret) {
2958-
strFailReason =
2959-
_("Keypool ran out, please call keypoolrefill first")
2960-
.translated;
2951+
error = _("Keypool ran out, please call keypoolrefill first");
29612952
return false;
29622953
}
29632954

@@ -3027,18 +3018,14 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
30273018
if (recipient.fSubtractFeeFromAmount &&
30283019
nFeeRet > Amount::zero()) {
30293020
if (txout.nValue < Amount::zero()) {
3030-
strFailReason = _("The transaction amount is too "
3031-
"small to pay the fee")
3032-
.translated;
3021+
error = _("The transaction amount is too small to "
3022+
"pay the fee");
30333023
} else {
3034-
strFailReason =
3035-
_("The transaction amount is too small to "
3036-
"send after the fee has been deducted")
3037-
.translated;
3024+
error = _("The transaction amount is too small to "
3025+
"send after the fee has been deducted");
30383026
}
30393027
} else {
3040-
strFailReason =
3041-
_("Transaction amount too small").translated;
3028+
error = _("Transaction amount too small");
30423029
}
30433030

30443031
return false;
@@ -3065,7 +3052,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
30653052
coin_selection_params.use_bnb = false;
30663053
continue;
30673054
} else {
3068-
strFailReason = _("Insufficient funds").translated;
3055+
error = _("Insufficient funds");
30693056
return false;
30703057
}
30713058
}
@@ -3090,8 +3077,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
30903077
nChangePosInOut = GetRandInt(txNew.vout.size() + 1);
30913078
} else if ((unsigned int)nChangePosInOut >
30923079
txNew.vout.size()) {
3093-
strFailReason =
3094-
_("Change index out of range").translated;
3080+
error = _("Change index out of range");
30953081
return false;
30963082
}
30973083

@@ -3113,7 +3099,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
31133099
int nBytes = CalculateMaximumSignedTxSize(
31143100
txNewConst, this, coinControl.fAllowWatchOnly);
31153101
if (nBytes < 0) {
3116-
strFailReason = _("Signing transaction failed").translated;
3102+
error = _("Signing transaction failed");
31173103
return false;
31183104
}
31193105

@@ -3165,9 +3151,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
31653151
// to pay for the new output and still meet nFeeNeeded.
31663152
// Or we should have just subtracted fee from recipients and
31673153
// nFeeNeeded should not have changed.
3168-
strFailReason =
3169-
_("Transaction fee and change calculation failed")
3170-
.translated;
3154+
error = _("Transaction fee and change calculation failed");
31713155
return false;
31723156
}
31733157

@@ -3230,7 +3214,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
32303214
MutableTransactionSignatureCreator(
32313215
&txNew, nIn, coin.txout.nValue, sigHashType),
32323216
scriptPubKey, sigdata)) {
3233-
strFailReason = _("Signing transaction failed").translated;
3217+
error = _("Signing transaction failed");
32343218
return false;
32353219
}
32363220

@@ -3244,23 +3228,22 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock &locked_chainIn,
32443228

32453229
// Limit size.
32463230
if (tx->GetTotalSize() > MAX_STANDARD_TX_SIZE) {
3247-
strFailReason = _("Transaction too large").translated;
3231+
error = _("Transaction too large");
32483232
return false;
32493233
}
32503234
}
32513235

32523236
if (nFeeRet > m_default_max_tx_fee) {
3253-
strFailReason =
3254-
TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED);
3237+
error = Untranslated(
3238+
TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED));
32553239
return false;
32563240
}
32573241

32583242
if (gArgs.GetBoolArg("-walletrejectlongchains",
32593243
DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
32603244
// Lastly, ensure this tx will pass the mempool's chain limits
32613245
if (!chain().checkChainLimits(tx)) {
3262-
strFailReason =
3263-
_("Transaction has too long of a mempool chain").translated;
3246+
error = _("Transaction has too long of a mempool chain");
32643247
return false;
32653248
}
32663249
}

src/wallet/wallet.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,7 @@ class CWallet final : public WalletStorage,
10541054
* CreateTransaction();
10551055
*/
10561056
bool FundTransaction(CMutableTransaction &tx, Amount &nFeeRet,
1057-
int &nChangePosInOut, std::string &strFailReason,
1057+
int &nChangePosInOut, bilingual_str &error,
10581058
bool lockUnspents,
10591059
const std::set<int> &setSubtractFeeFromOutputs,
10601060
CCoinControl coinControl);
@@ -1070,7 +1070,7 @@ class CWallet final : public WalletStorage,
10701070
bool CreateTransaction(interfaces::Chain::Lock &locked_chain,
10711071
const std::vector<CRecipient> &vecSend,
10721072
CTransactionRef &tx, Amount &nFeeRet,
1073-
int &nChangePosInOut, std::string &strFailReason,
1073+
int &nChangePosInOut, bilingual_str &error,
10741074
const CCoinControl &coin_control, bool sign = true);
10751075
/**
10761076
* Submit the transaction to the node's mempool and then relay to peers.

0 commit comments

Comments
 (0)