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