MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / CheckFeeRate

Function CheckFeeRate

src/wallet/feebumper.cpp:62–119  ·  view source on GitHub ↗

Check if the user provided a valid feeRate

Source from the content-addressed store, hash-verified

60
61//! Check if the user provided a valid feeRate
62static 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}

Callers 3

PreChecksMethod · 0.85

Calls 13

UntranslatedFunction · 0.85
FormatMoneyFunction · 0.85
GetRequiredFeeFunction · 0.85
mempoolMinFeeMethod · 0.80
GetFeePerKMethod · 0.80
relayIncrementalFeeMethod · 0.80
push_backMethod · 0.45
reserveMethod · 0.45
sizeMethod · 0.45
has_valueMethod · 0.45
GetFeeMethod · 0.45

Tested by

no test coverage detected