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