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