/ src / wallet / feebumper.cpp
feebumper.cpp
  1  // Copyright (c) 2017-present The Bitcoin Core developers
  2  // Distributed under the MIT software license, see the accompanying
  3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4  
  5  #include <common/system.h>
  6  #include <consensus/validation.h>
  7  #include <interfaces/chain.h>
  8  #include <policy/fees/block_policy_estimator.h>
  9  #include <policy/policy.h>
 10  #include <util/moneystr.h>
 11  #include <util/rbf.h>
 12  #include <util/translation.h>
 13  #include <wallet/coincontrol.h>
 14  #include <wallet/feebumper.h>
 15  #include <wallet/fees.h>
 16  #include <wallet/receive.h>
 17  #include <wallet/spend.h>
 18  #include <wallet/wallet.h>
 19  
 20  namespace wallet {
 21  //! Check whether transaction has descendant in wallet or mempool, or has been
 22  //! mined, or conflicts with a mined transaction. Return a feebumper::Result.
 23  static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWalletTx& wtx, bool require_mine, std::vector<bilingual_str>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
 24  {
 25      if (wallet.HasWalletSpend(wtx.tx)) {
 26          errors.emplace_back(Untranslated("Transaction has descendants in the wallet"));
 27          return feebumper::Result::INVALID_PARAMETER;
 28      }
 29  
 30      {
 31          if (wallet.chain().hasDescendantsInMempool(wtx.GetHash())) {
 32              errors.emplace_back(Untranslated("Transaction has descendants in the mempool"));
 33              return feebumper::Result::INVALID_PARAMETER;
 34          }
 35      }
 36  
 37      if (wallet.GetTxDepthInMainChain(wtx) != 0) {
 38          errors.emplace_back(Untranslated("Transaction has been mined, or is conflicted with a mined transaction"));
 39          return feebumper::Result::WALLET_ERROR;
 40      }
 41  
 42      if (wtx.mapValue.contains("replaced_by_txid")) {
 43          errors.push_back(Untranslated(strprintf("Cannot bump transaction %s which was already bumped by transaction %s", wtx.GetHash().ToString(), wtx.mapValue.at("replaced_by_txid"))));
 44          return feebumper::Result::WALLET_ERROR;
 45      }
 46  
 47      if (require_mine) {
 48          // check that original tx consists entirely of our inputs
 49          // 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)
 50          if (!AllInputsMine(wallet, *wtx.tx)) {
 51              errors.emplace_back(Untranslated("Transaction contains inputs that don't belong to this wallet"));
 52              return feebumper::Result::WALLET_ERROR;
 53          }
 54      }
 55  
 56      return feebumper::Result::OK;
 57  }
 58  
 59  //! Check if the user provided a valid feeRate
 60  static feebumper::Result CheckFeeRate(const CWallet& wallet, const CMutableTransaction& mtx, const CFeeRate& newFeerate, const int64_t maxTxSize, CAmount old_fee, std::vector<bilingual_str>& errors)
 61  {
 62      // check that fee rate is higher than mempool's minimum fee
 63      // (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
 64      // This may occur if fallbackfee is too low, or, perhaps,
 65      // in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
 66      // moment earlier. In this case, we report an error to the user, who may adjust the fee.
 67      CFeeRate minMempoolFeeRate = wallet.chain().mempoolMinFee();
 68  
 69      if (newFeerate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) {
 70          errors.push_back(Untranslated(
 71              strprintf("New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- ",
 72              FormatMoney(newFeerate.GetFeePerK()),
 73              FormatMoney(minMempoolFeeRate.GetFeePerK()))));
 74          return feebumper::Result::WALLET_ERROR;
 75      }
 76  
 77      std::vector<COutPoint> reused_inputs;
 78      reused_inputs.reserve(mtx.vin.size());
 79      for (const CTxIn& txin : mtx.vin) {
 80          reused_inputs.push_back(txin.prevout);
 81      }
 82  
 83      const std::optional<CAmount> combined_bump_fee = wallet.chain().calculateCombinedBumpFee(reused_inputs, newFeerate);
 84      if (!combined_bump_fee.has_value()) {
 85          errors.push_back(Untranslated(strprintf("Failed to calculate bump fees, because unconfirmed UTXOs depend on an enormous cluster of unconfirmed transactions.")));
 86          return feebumper::Result::WALLET_ERROR;
 87      }
 88      CAmount new_total_fee = newFeerate.GetFee(maxTxSize) + combined_bump_fee.value();
 89  
 90      CFeeRate incrementalRelayFee = wallet.chain().relayIncrementalFee();
 91  
 92      // Min total fee is old fee + relay fee
 93      CAmount minTotalFee = old_fee + incrementalRelayFee.GetFee(maxTxSize);
 94  
 95      if (new_total_fee < minTotalFee) {
 96          errors.push_back(Untranslated(strprintf("Insufficient total fee %s, must be at least %s (oldFee %s + incrementalFee %s)",
 97              FormatMoney(new_total_fee), FormatMoney(minTotalFee), FormatMoney(old_fee), FormatMoney(incrementalRelayFee.GetFee(maxTxSize)))));
 98          return feebumper::Result::INVALID_PARAMETER;
 99      }
100  
101      CAmount requiredFee = GetRequiredFee(wallet, maxTxSize);
102      if (new_total_fee < requiredFee) {
103          errors.push_back(Untranslated(strprintf("Insufficient total fee (cannot be less than required fee %s)",
104              FormatMoney(requiredFee))));
105          return feebumper::Result::INVALID_PARAMETER;
106      }
107  
108      // Check that in all cases the new fee doesn't violate maxTxFee
109      const CAmount max_tx_fee = wallet.m_default_max_tx_fee;
110      if (new_total_fee > max_tx_fee) {
111          errors.push_back(Untranslated(strprintf("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)",
112              FormatMoney(new_total_fee), FormatMoney(max_tx_fee))));
113          return feebumper::Result::WALLET_ERROR;
114      }
115  
116      return feebumper::Result::OK;
117  }
118  
119  static CFeeRate EstimateFeeRate(const CWallet& wallet, const CWalletTx& wtx, const CAmount old_fee, const CCoinControl& coin_control)
120  {
121      // Get the fee rate of the original transaction. This is calculated from
122      // the tx fee/vsize, so it may have been rounded down. Add 1 satoshi to the
123      // result.
124      int64_t txSize = GetVirtualTransactionSize(*(wtx.tx));
125      CFeeRate feerate(old_fee, txSize);
126      feerate += CFeeRate(1);
127  
128      // The node has a configurable incremental relay fee. Increment the fee by
129      // the minimum of that and the wallet's conservative
130      // WALLET_INCREMENTAL_RELAY_FEE value to future proof against changes to
131      // network wide policy for incremental relay fee that our node may not be
132      // aware of. This ensures we're over the required relay fee rate
133      // (Rule 4).  The replacement tx will be at least as large as the
134      // original tx, so the total fee will be greater (Rule 3)
135      CFeeRate node_incremental_relay_fee = wallet.chain().relayIncrementalFee();
136      CFeeRate wallet_incremental_relay_fee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE);
137      feerate += std::max(node_incremental_relay_fee, wallet_incremental_relay_fee);
138  
139      // Fee rate must also be at least the wallet's GetMinimumFeeRate
140      CFeeRate min_feerate(GetMinimumFeeRate(wallet, coin_control, /*feeCalc=*/nullptr));
141  
142      // Set the required fee rate for the replacement transaction in coin control.
143      return std::max(feerate, min_feerate);
144  }
145  
146  namespace feebumper {
147  
148  bool TransactionCanBeBumped(const CWallet& wallet, const Txid& txid)
149  {
150      LOCK(wallet.cs_wallet);
151      const CWalletTx* wtx = wallet.GetWalletTx(txid);
152      if (wtx == nullptr) return false;
153  
154      std::vector<bilingual_str> errors_dummy;
155      feebumper::Result res = PreconditionChecks(wallet, *wtx, /* require_mine=*/ true, errors_dummy);
156      return res == feebumper::Result::OK;
157  }
158  
159  Result CreateRateBumpTransaction(CWallet& wallet, const Txid& txid, const CCoinControl& coin_control, std::vector<bilingual_str>& errors,
160                                   CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx, bool require_mine, const std::vector<CTxOut>& outputs, std::optional<uint32_t> original_change_index)
161  {
162      // For now, cannot specify both new outputs to use and an output index to send change
163      if (!outputs.empty() && original_change_index.has_value()) {
164          errors.emplace_back(Untranslated("The options 'outputs' and 'original_change_index' are incompatible. You can only either specify a new set of outputs, or designate a change output to be recycled."));
165          return Result::INVALID_PARAMETER;
166      }
167  
168      // We are going to modify coin control later, copy to reuse
169      CCoinControl new_coin_control(coin_control);
170  
171      LOCK(wallet.cs_wallet);
172      errors.clear();
173      auto it = wallet.mapWallet.find(txid);
174      if (it == wallet.mapWallet.end()) {
175          errors.emplace_back(Untranslated("Invalid or non-wallet transaction id"));
176          return Result::INVALID_ADDRESS_OR_KEY;
177      }
178      const CWalletTx& wtx = it->second;
179  
180      // Make sure that original_change_index is valid
181      if (original_change_index.has_value() && original_change_index.value() >= wtx.tx->vout.size()) {
182          errors.emplace_back(Untranslated("Change position is out of range"));
183          return Result::INVALID_PARAMETER;
184      }
185  
186      // Retrieve all of the UTXOs and add them to coin control
187      // While we're here, calculate the input amount
188      std::map<COutPoint, Coin> coins;
189      CAmount input_value = 0;
190      std::vector<CTxOut> spent_outputs;
191      for (const CTxIn& txin : wtx.tx->vin) {
192          coins[txin.prevout]; // Create empty map entry keyed by prevout.
193      }
194      wallet.chain().findCoins(coins);
195      for (const CTxIn& txin : wtx.tx->vin) {
196          const Coin& coin = coins.at(txin.prevout);
197          if (coin.out.IsNull()) {
198              errors.emplace_back(Untranslated(strprintf("%s:%u is already spent", txin.prevout.hash.GetHex(), txin.prevout.n)));
199              return Result::MISC_ERROR;
200          }
201          PreselectedInput& preset_txin = new_coin_control.Select(txin.prevout);
202          if (!wallet.IsMine(txin.prevout)) {
203              preset_txin.SetTxOut(coin.out);
204          }
205          input_value += coin.out.nValue;
206          spent_outputs.push_back(coin.out);
207      }
208  
209      // Figure out if we need to compute the input weight, and do so if necessary
210      PrecomputedTransactionData txdata;
211      txdata.Init(*wtx.tx, std::move(spent_outputs), /* force=*/ true);
212      for (unsigned int i = 0; i < wtx.tx->vin.size(); ++i) {
213          const CTxIn& txin = wtx.tx->vin.at(i);
214          const Coin& coin = coins.at(txin.prevout);
215  
216          if (new_coin_control.IsExternalSelected(txin.prevout)) {
217              // For external inputs, we estimate the size using the size of this input
218              int64_t input_weight = GetTransactionInputWeight(txin);
219              // Because signatures can have different sizes, we need to figure out all of the
220              // signature sizes and replace them with the max sized signature.
221              // In order to do this, we verify the script with a special SignatureChecker which
222              // will observe the signatures verified and record their sizes.
223              SignatureWeights weights;
224              TransactionSignatureChecker tx_checker(wtx.tx.get(), i, coin.out.nValue, txdata, MissingDataBehavior::FAIL);
225              SignatureWeightChecker size_checker(weights, tx_checker);
226              VerifyScript(txin.scriptSig, coin.out.scriptPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, size_checker);
227              // Add the difference between max and current to input_weight so that it represents the largest the input could be
228              input_weight += weights.GetWeightDiffToMax();
229              new_coin_control.SetInputWeight(txin.prevout, input_weight);
230          }
231      }
232  
233      Result result = PreconditionChecks(wallet, wtx, require_mine, errors);
234      if (result != Result::OK) {
235          return result;
236      }
237  
238      // Calculate the old output amount.
239      CAmount output_value = 0;
240      for (const auto& old_output : wtx.tx->vout) {
241          output_value += old_output.nValue;
242      }
243  
244      old_fee = input_value - output_value;
245  
246      // Fill in recipients (and preserve a single change key if there
247      // is one). If outputs vector is non-empty, replace original
248      // outputs with its contents, otherwise use original outputs.
249      std::vector<CRecipient> recipients;
250      CAmount new_outputs_value = 0;
251      const auto& txouts = outputs.empty() ? wtx.tx->vout : outputs;
252      for (size_t i = 0; i < txouts.size(); ++i) {
253          const CTxOut& output = txouts.at(i);
254          CTxDestination dest;
255          ExtractDestination(output.scriptPubKey, dest);
256          if (original_change_index.has_value() ?  original_change_index.value() == i : OutputIsChange(wallet, output)) {
257              new_coin_control.destChange = dest;
258          } else {
259              CRecipient recipient = {dest, output.nValue, false};
260              recipients.push_back(recipient);
261          }
262          new_outputs_value += output.nValue;
263      }
264  
265      // If no recipients, means that we are sending coins to a change address
266      if (recipients.empty()) {
267          // Just as a sanity check, ensure that the change address exist
268          if (std::get_if<CNoDestination>(&new_coin_control.destChange)) {
269              errors.emplace_back(Untranslated("Unable to create transaction. Transaction must have at least one recipient"));
270              return Result::INVALID_PARAMETER;
271          }
272  
273          // Add change as recipient with SFFO flag enabled, so fees are deduced from it.
274          // If the output differs from the original tx output (because the user customized it) a new change output will be created.
275          recipients.emplace_back(CRecipient{new_coin_control.destChange, new_outputs_value, /*fSubtractFeeFromAmount=*/true});
276          new_coin_control.destChange = CNoDestination();
277      }
278  
279      if (coin_control.m_feerate) {
280          // The user provided a feeRate argument.
281          // We calculate this here to avoid compiler warning on the cs_wallet lock
282          // We need to make a temporary transaction with no input witnesses as the dummy signer expects them to be empty for external inputs
283          CMutableTransaction temp_mtx{*wtx.tx};
284          for (auto& txin : temp_mtx.vin) {
285              txin.scriptSig.clear();
286              txin.scriptWitness.SetNull();
287          }
288          temp_mtx.vout = txouts;
289          const int64_t maxTxSize{CalculateMaximumSignedTxSize(CTransaction(temp_mtx), &wallet, &new_coin_control).vsize};
290          Result res = CheckFeeRate(wallet, temp_mtx, *new_coin_control.m_feerate, maxTxSize, old_fee, errors);
291          if (res != Result::OK) {
292              return res;
293          }
294      } else {
295          // The user did not provide a feeRate argument
296          new_coin_control.m_feerate = EstimateFeeRate(wallet, wtx, old_fee, new_coin_control);
297      }
298  
299      // Fill in required inputs we are double-spending(all of them)
300      // N.B.: bip125 doesn't require all the inputs in the replaced transaction to be
301      // used in the replacement transaction, but it's very important for wallets to make
302      // sure that happens. If not, it would be possible to bump a transaction A twice to
303      // A2 and A3 where A2 and A3 don't conflict (or alternatively bump A to A2 and A2
304      // to A3 where A and A3 don't conflict). If both later get confirmed then the sender
305      // has accidentally double paid.
306      for (const auto& inputs : wtx.tx->vin) {
307          new_coin_control.Select(COutPoint(inputs.prevout));
308      }
309      new_coin_control.m_allow_other_inputs = true;
310  
311      // We cannot source new unconfirmed inputs(bip125 rule 2)
312      new_coin_control.m_min_depth = 1;
313  
314      auto res = CreateTransaction(wallet, recipients, /*change_pos=*/std::nullopt, new_coin_control, false);
315      if (!res) {
316          errors.emplace_back(Untranslated("Unable to create transaction.") + Untranslated(" ") + util::ErrorString(res));
317          return Result::WALLET_ERROR;
318      }
319  
320      const auto& txr = *res;
321      // Write back new fee if successful
322      new_fee = txr.fee;
323  
324      // Write back transaction
325      mtx = CMutableTransaction(*txr.tx);
326  
327      return Result::OK;
328  }
329  
330  bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx) {
331      LOCK(wallet.cs_wallet);
332  
333      if (wallet.IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) {
334          // Make a blank psbt
335          PartiallySignedTransaction psbtx(mtx);
336  
337          // First fill transaction with our data without signing,
338          // so external signers are not asked to sign more than once.
339          bool complete;
340          wallet.FillPSBT(psbtx, {.sign = false, .bip32_derivs = true}, complete);
341          auto err{wallet.FillPSBT(psbtx, {.sign = true, .bip32_derivs = false}, complete)};
342          if (err) return false;
343          complete = FinalizeAndExtractPSBT(psbtx, mtx);
344          return complete;
345      } else {
346          return wallet.SignTransaction(mtx);
347      }
348  }
349  
350  Result CommitTransaction(CWallet& wallet, const Txid& txid, CMutableTransaction&& mtx, std::vector<bilingual_str>& errors, Txid& bumped_txid)
351  {
352      LOCK(wallet.cs_wallet);
353      if (!errors.empty()) {
354          return Result::MISC_ERROR;
355      }
356      auto it = txid.IsNull() ? wallet.mapWallet.end() : wallet.mapWallet.find(txid);
357      if (it == wallet.mapWallet.end()) {
358          errors.emplace_back(Untranslated("Invalid or non-wallet transaction id"));
359          return Result::MISC_ERROR;
360      }
361      const CWalletTx& oldWtx = it->second;
362  
363      // make sure the transaction still has no descendants and hasn't been mined in the meantime
364      Result result = PreconditionChecks(wallet, oldWtx, /* require_mine=*/ false, errors);
365      if (result != Result::OK) {
366          return result;
367      }
368  
369      // commit/broadcast the tx
370      CTransactionRef tx = MakeTransactionRef(std::move(mtx));
371      mapValue_t mapValue = oldWtx.mapValue;
372      mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
373  
374      wallet.CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm);
375  
376      // mark the original tx as bumped
377      bumped_txid = tx->GetHash();
378      if (!wallet.MarkReplaced(oldWtx.GetHash(), bumped_txid)) {
379          errors.emplace_back(Untranslated("Created new bumpfee transaction but could not mark the original transaction as replaced"));
380      }
381      return Result::OK;
382  }
383  
384  } // namespace feebumper
385  } // namespace wallet