mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
wallet: remove CreateTotalBumpTransaction()
This commit is contained in:
parent
4a0b27bb01
commit
c3857c5fcb
2 changed files with 0 additions and 136 deletions
|
@ -150,132 +150,6 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid)
|
|||
return res == feebumper::Result::OK;
|
||||
}
|
||||
|
||||
Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, CAmount total_fee, std::vector<std::string>& errors,
|
||||
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
|
||||
{
|
||||
new_fee = total_fee;
|
||||
|
||||
auto locked_chain = wallet->chain().lock();
|
||||
LOCK(wallet->cs_wallet);
|
||||
errors.clear();
|
||||
auto it = wallet->mapWallet.find(txid);
|
||||
if (it == wallet->mapWallet.end()) {
|
||||
errors.push_back("Invalid or non-wallet transaction id");
|
||||
return Result::INVALID_ADDRESS_OR_KEY;
|
||||
}
|
||||
const CWalletTx& wtx = it->second;
|
||||
|
||||
Result result = PreconditionChecks(*wallet, wtx, errors);
|
||||
if (result != Result::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// figure out which output was change
|
||||
// if there was no change output or multiple change outputs, fail
|
||||
int nOutput = -1;
|
||||
for (size_t i = 0; i < wtx.tx->vout.size(); ++i) {
|
||||
if (wallet->IsChange(wtx.tx->vout[i])) {
|
||||
if (nOutput != -1) {
|
||||
errors.push_back("Transaction has multiple change outputs");
|
||||
return Result::WALLET_ERROR;
|
||||
}
|
||||
nOutput = i;
|
||||
}
|
||||
}
|
||||
if (nOutput == -1) {
|
||||
errors.push_back("Transaction does not have a change output");
|
||||
return Result::WALLET_ERROR;
|
||||
}
|
||||
|
||||
// Calculate the expected size of the new transaction.
|
||||
int64_t txSize = GetVirtualTransactionSize(*(wtx.tx));
|
||||
const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx, wallet);
|
||||
if (maxNewTxSize < 0) {
|
||||
errors.push_back("Transaction contains inputs that cannot be signed");
|
||||
return Result::INVALID_ADDRESS_OR_KEY;
|
||||
}
|
||||
|
||||
// calculate the old fee and fee-rate
|
||||
isminefilter filter = wallet->GetLegacyScriptPubKeyMan() && wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE;
|
||||
old_fee = wtx.GetDebit(filter) - wtx.tx->GetValueOut();
|
||||
CFeeRate nOldFeeRate(old_fee, txSize);
|
||||
// The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to
|
||||
// future proof against changes to network wide policy for incremental relay
|
||||
// fee that our node may not be aware of.
|
||||
CFeeRate nodeIncrementalRelayFee = wallet->chain().relayIncrementalFee();
|
||||
CFeeRate walletIncrementalRelayFee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE);
|
||||
if (nodeIncrementalRelayFee > walletIncrementalRelayFee) {
|
||||
walletIncrementalRelayFee = nodeIncrementalRelayFee;
|
||||
}
|
||||
|
||||
CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + nodeIncrementalRelayFee.GetFee(maxNewTxSize);
|
||||
if (total_fee < minTotalFee) {
|
||||
errors.push_back(strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)",
|
||||
FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(nodeIncrementalRelayFee.GetFee(maxNewTxSize))));
|
||||
return Result::INVALID_PARAMETER;
|
||||
}
|
||||
CAmount requiredFee = GetRequiredFee(*wallet, maxNewTxSize);
|
||||
if (total_fee < requiredFee) {
|
||||
errors.push_back(strprintf("Insufficient totalFee (cannot be less than required fee %s)",
|
||||
FormatMoney(requiredFee)));
|
||||
return Result::INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Check that in all cases the new fee doesn't violate maxTxFee
|
||||
const CAmount max_tx_fee = wallet->m_default_max_tx_fee;
|
||||
if (new_fee > max_tx_fee) {
|
||||
errors.push_back(strprintf("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)",
|
||||
FormatMoney(new_fee), FormatMoney(max_tx_fee)));
|
||||
return Result::WALLET_ERROR;
|
||||
}
|
||||
|
||||
// check that fee rate is higher than mempool's minimum fee
|
||||
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
|
||||
// This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps,
|
||||
// in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
|
||||
// moment earlier. In this case, we report an error to the user, who may use total_fee to make an adjustment.
|
||||
CFeeRate minMempoolFeeRate = wallet->chain().mempoolMinFee();
|
||||
CFeeRate nNewFeeRate = CFeeRate(total_fee, maxNewTxSize);
|
||||
if (nNewFeeRate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) {
|
||||
errors.push_back(strprintf(
|
||||
"New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- "
|
||||
"the totalFee value should be at least %s to add transaction",
|
||||
FormatMoney(nNewFeeRate.GetFeePerK()),
|
||||
FormatMoney(minMempoolFeeRate.GetFeePerK()),
|
||||
FormatMoney(minMempoolFeeRate.GetFee(maxNewTxSize))));
|
||||
return Result::WALLET_ERROR;
|
||||
}
|
||||
|
||||
// Now modify the output to increase the fee.
|
||||
// If the output is not large enough to pay the fee, fail.
|
||||
CAmount nDelta = new_fee - old_fee;
|
||||
assert(nDelta > 0);
|
||||
mtx = CMutableTransaction{*wtx.tx};
|
||||
CTxOut* poutput = &(mtx.vout[nOutput]);
|
||||
if (poutput->nValue < nDelta) {
|
||||
errors.push_back("Change output is too small to bump the fee");
|
||||
return Result::WALLET_ERROR;
|
||||
}
|
||||
|
||||
// If the output would become dust, discard it (converting the dust to fee)
|
||||
poutput->nValue -= nDelta;
|
||||
if (poutput->nValue <= GetDustThreshold(*poutput, GetDiscardRate(*wallet))) {
|
||||
wallet->WalletLogPrintf("Bumping fee and discarding dust output\n");
|
||||
new_fee += poutput->nValue;
|
||||
mtx.vout.erase(mtx.vout.begin() + nOutput);
|
||||
}
|
||||
|
||||
// Mark new tx not replaceable, if requested.
|
||||
if (!coin_control.m_signal_bip125_rbf.get_value_or(wallet->m_signal_rbf)) {
|
||||
for (auto& input : mtx.vin) {
|
||||
if (input.nSequence < 0xfffffffe) input.nSequence = 0xfffffffe;
|
||||
}
|
||||
}
|
||||
|
||||
return Result::OK;
|
||||
}
|
||||
|
||||
|
||||
Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
|
||||
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
|
||||
{
|
||||
|
|
|
@ -28,16 +28,6 @@ enum class Result
|
|||
//! Return whether transaction can be bumped.
|
||||
bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid);
|
||||
|
||||
//! Create bumpfee transaction based on total amount.
|
||||
Result CreateTotalBumpTransaction(const CWallet* wallet,
|
||||
const uint256& txid,
|
||||
const CCoinControl& coin_control,
|
||||
CAmount total_fee,
|
||||
std::vector<std::string>& errors,
|
||||
CAmount& old_fee,
|
||||
CAmount& new_fee,
|
||||
CMutableTransaction& mtx);
|
||||
|
||||
//! Create bumpfee transaction based on feerate estimates.
|
||||
Result CreateRateBumpTransaction(CWallet& wallet,
|
||||
const uint256& txid,
|
||||
|
|
Loading…
Reference in a new issue