diff options
Diffstat (limited to 'src/wallet/feebumper.cpp')
-rw-r--r-- | src/wallet/feebumper.cpp | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index dafa022ded..cacf306891 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -3,44 +3,45 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <interfaces/chain.h> -#include <wallet/coincontrol.h> -#include <wallet/feebumper.h> -#include <wallet/fees.h> -#include <wallet/wallet.h> #include <policy/fees.h> #include <policy/policy.h> #include <util/moneystr.h> #include <util/rbf.h> #include <util/system.h> +#include <util/translation.h> +#include <wallet/coincontrol.h> +#include <wallet/feebumper.h> +#include <wallet/fees.h> +#include <wallet/wallet.h> //! Check whether transaction has descendant in wallet or mempool, or has been //! mined, or conflicts with a mined transaction. Return a feebumper::Result. -static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) +static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWalletTx& wtx, std::vector<bilingual_str>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) { if (wallet.HasWalletSpend(wtx.GetHash())) { - errors.push_back("Transaction has descendants in the wallet"); + errors.push_back(Untranslated("Transaction has descendants in the wallet")); return feebumper::Result::INVALID_PARAMETER; } { if (wallet.chain().hasDescendantsInMempool(wtx.GetHash())) { - errors.push_back("Transaction has descendants in the mempool"); + errors.push_back(Untranslated("Transaction has descendants in the mempool")); return feebumper::Result::INVALID_PARAMETER; } } if (wtx.GetDepthInMainChain() != 0) { - errors.push_back("Transaction has been mined, or is conflicted with a mined transaction"); + errors.push_back(Untranslated("Transaction has been mined, or is conflicted with a mined transaction")); return feebumper::Result::WALLET_ERROR; } if (!SignalsOptInRBF(*wtx.tx)) { - errors.push_back("Transaction is not BIP 125 replaceable"); + errors.push_back(Untranslated("Transaction is not BIP 125 replaceable")); return feebumper::Result::WALLET_ERROR; } if (wtx.mapValue.count("replaced_by_txid")) { - errors.push_back(strprintf("Cannot bump transaction %s which was already bumped by transaction %s", wtx.GetHash().ToString(), wtx.mapValue.at("replaced_by_txid"))); + 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"))); return feebumper::Result::WALLET_ERROR; } @@ -48,7 +49,7 @@ static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWallet // 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) isminefilter filter = wallet.GetLegacyScriptPubKeyMan() && wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE; if (!wallet.IsAllFromMe(*wtx.tx, filter)) { - errors.push_back("Transaction contains inputs that don't belong to this wallet"); + errors.push_back(Untranslated("Transaction contains inputs that don't belong to this wallet")); return feebumper::Result::WALLET_ERROR; } @@ -57,7 +58,8 @@ static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWallet } //! Check if the user provided a valid feeRate -static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<std::string>& errors) { +static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<bilingual_str>& errors) +{ // check that fee rate is higher than mempool's minimum fee // (no point in bumping fee if we know that the new tx won't be accepted to the mempool) // 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 if (newFeerate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) { errors.push_back(strprintf( - "New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- ", + Untranslated("New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- "), FormatMoney(newFeerate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFeePerK()))); return feebumper::Result::WALLET_ERROR; @@ -86,14 +88,14 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wt CAmount minTotalFee = nOldFeeRate.GetFee(maxTxSize) + incrementalRelayFee.GetFee(maxTxSize); if (new_total_fee < minTotalFee) { - errors.push_back(strprintf("Insufficient total fee %s, must be at least %s (oldFee %s + incrementalFee %s)", + errors.push_back(strprintf(Untranslated("Insufficient total fee %s, must be at least %s (oldFee %s + incrementalFee %s)"), FormatMoney(new_total_fee), FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxTxSize)), FormatMoney(incrementalRelayFee.GetFee(maxTxSize)))); return feebumper::Result::INVALID_PARAMETER; } CAmount requiredFee = GetRequiredFee(wallet, maxTxSize); if (new_total_fee < requiredFee) { - errors.push_back(strprintf("Insufficient total fee (cannot be less than required fee %s)", + errors.push_back(strprintf(Untranslated("Insufficient total fee (cannot be less than required fee %s)"), FormatMoney(requiredFee))); return feebumper::Result::INVALID_PARAMETER; } @@ -101,8 +103,8 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wt // Check that in all cases the new fee doesn't violate maxTxFee const CAmount max_tx_fee = wallet.m_default_max_tx_fee; if (new_total_fee > max_tx_fee) { - errors.push_back(strprintf("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)", - FormatMoney(new_total_fee), FormatMoney(max_tx_fee))); + errors.push_back(strprintf(Untranslated("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)"), + FormatMoney(new_total_fee), FormatMoney(max_tx_fee))); return feebumper::Result::WALLET_ERROR; } @@ -140,28 +142,26 @@ namespace feebumper { bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid) { - auto locked_chain = wallet.chain().lock(); LOCK(wallet.cs_wallet); const CWalletTx* wtx = wallet.GetWalletTx(txid); if (wtx == nullptr) return false; - std::vector<std::string> errors_dummy; + std::vector<bilingual_str> errors_dummy; feebumper::Result res = PreconditionChecks(wallet, *wtx, errors_dummy); return res == feebumper::Result::OK; } -Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors, +Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<bilingual_str>& errors, CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx) { // We are going to modify coin control later, copy to re-use CCoinControl new_coin_control(coin_control); - auto locked_chain = wallet.chain().lock(); LOCK(wallet.cs_wallet); errors.clear(); auto it = wallet.mapWallet.find(txid); if (it == wallet.mapWallet.end()) { - errors.push_back("Invalid or non-wallet transaction id"); + errors.push_back(Untranslated("Invalid or non-wallet transaction id")); return Result::INVALID_ADDRESS_OR_KEY; } const CWalletTx& wtx = it->second; @@ -218,9 +218,9 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo CTransactionRef tx_new = MakeTransactionRef(); CAmount fee_ret; int change_pos_in_out = -1; // No requested location for change - std::string fail_reason; - if (!wallet.CreateTransaction(*locked_chain, recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false)) { - errors.push_back("Unable to create transaction: " + fail_reason); + bilingual_str fail_reason; + if (!wallet.CreateTransaction(recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false)) { + errors.push_back(Untranslated("Unable to create transaction.") + Untranslated(" ") + fail_reason); return Result::WALLET_ERROR; } @@ -240,21 +240,19 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo } bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx) { - auto locked_chain = wallet.chain().lock(); LOCK(wallet.cs_wallet); return wallet.SignTransaction(mtx); } -Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid) +Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<bilingual_str>& errors, uint256& bumped_txid) { - auto locked_chain = wallet.chain().lock(); LOCK(wallet.cs_wallet); if (!errors.empty()) { return Result::MISC_ERROR; } auto it = txid.IsNull() ? wallet.mapWallet.end() : wallet.mapWallet.find(txid); if (it == wallet.mapWallet.end()) { - errors.push_back("Invalid or non-wallet transaction id"); + errors.push_back(Untranslated("Invalid or non-wallet transaction id")); return Result::MISC_ERROR; } CWalletTx& oldWtx = it->second; @@ -279,7 +277,7 @@ Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransacti // along with an exception. It would be good to return information about // wtxBumped to the caller even if marking the original transaction // replaced does not succeed for some reason. - errors.push_back("Created new bumpfee transaction but could not mark the original transaction as replaced"); + errors.push_back(Untranslated("Created new bumpfee transaction but could not mark the original transaction as replaced")); } return Result::OK; } |