feebumper.cpp raw

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