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