mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-08 14:34:53 -05:00
wallet: Set preset input sequence through coin control
This commit is contained in:
parent
596642c5a9
commit
4d335bb1e0
3 changed files with 37 additions and 3 deletions
|
@ -72,6 +72,12 @@ std::optional<int64_t> CCoinControl::GetInputWeight(const COutPoint& outpoint) c
|
||||||
return it != m_selected.end() ? it->second.GetInputWeight() : std::nullopt;
|
return it != m_selected.end() ? it->second.GetInputWeight() : std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<uint32_t> CCoinControl::GetSequence(const COutPoint& outpoint) const
|
||||||
|
{
|
||||||
|
const auto it = m_selected.find(outpoint);
|
||||||
|
return it != m_selected.end() ? it->second.GetSequence() : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
void PreselectedInput::SetTxOut(const CTxOut& txout)
|
void PreselectedInput::SetTxOut(const CTxOut& txout)
|
||||||
{
|
{
|
||||||
m_txout = txout;
|
m_txout = txout;
|
||||||
|
@ -97,4 +103,14 @@ std::optional<int64_t> PreselectedInput::GetInputWeight() const
|
||||||
{
|
{
|
||||||
return m_weight;
|
return m_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PreselectedInput::SetSequence(uint32_t sequence)
|
||||||
|
{
|
||||||
|
m_sequence = sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<uint32_t> PreselectedInput::GetSequence() const
|
||||||
|
{
|
||||||
|
return m_sequence;
|
||||||
|
}
|
||||||
} // namespace wallet
|
} // namespace wallet
|
||||||
|
|
|
@ -31,6 +31,8 @@ private:
|
||||||
std::optional<CTxOut> m_txout;
|
std::optional<CTxOut> m_txout;
|
||||||
//! The input weight for spending this input
|
//! The input weight for spending this input
|
||||||
std::optional<int64_t> m_weight;
|
std::optional<int64_t> m_weight;
|
||||||
|
//! The sequence number for this input
|
||||||
|
std::optional<uint32_t> m_sequence;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -47,6 +49,11 @@ public:
|
||||||
void SetInputWeight(int64_t weight);
|
void SetInputWeight(int64_t weight);
|
||||||
/** Retrieve the input weight for this input. */
|
/** Retrieve the input weight for this input. */
|
||||||
std::optional<int64_t> GetInputWeight() const;
|
std::optional<int64_t> GetInputWeight() const;
|
||||||
|
|
||||||
|
/** Set the sequence for this input. */
|
||||||
|
void SetSequence(uint32_t sequence);
|
||||||
|
/** Retrieve the sequence for this input. */
|
||||||
|
std::optional<uint32_t> GetSequence() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Coin Control Features. */
|
/** Coin Control Features. */
|
||||||
|
@ -128,6 +135,8 @@ public:
|
||||||
* Returns the input weight.
|
* Returns the input weight.
|
||||||
*/
|
*/
|
||||||
std::optional<int64_t> GetInputWeight(const COutPoint& outpoint) const;
|
std::optional<int64_t> GetInputWeight(const COutPoint& outpoint) const;
|
||||||
|
/** Retrieve the sequence for an input */
|
||||||
|
std::optional<uint32_t> GetSequence(const COutPoint& outpoint) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Selected inputs (inputs that will be used, regardless of whether they're optimal or not)
|
//! Selected inputs (inputs that will be used, regardless of whether they're optimal or not)
|
||||||
|
|
|
@ -1150,11 +1150,19 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
|
||||||
// to avoid conflicting with other possible uses of nSequence,
|
// to avoid conflicting with other possible uses of nSequence,
|
||||||
// and in the spirit of "smallest possible change from prior
|
// and in the spirit of "smallest possible change from prior
|
||||||
// behavior."
|
// behavior."
|
||||||
const uint32_t nSequence{coin_control.m_signal_bip125_rbf.value_or(wallet.m_signal_rbf) ? MAX_BIP125_RBF_SEQUENCE : CTxIn::MAX_SEQUENCE_NONFINAL};
|
bool use_anti_fee_sniping = true;
|
||||||
|
const uint32_t default_sequence{coin_control.m_signal_bip125_rbf.value_or(wallet.m_signal_rbf) ? MAX_BIP125_RBF_SEQUENCE : CTxIn::MAX_SEQUENCE_NONFINAL};
|
||||||
for (const auto& coin : selected_coins) {
|
for (const auto& coin : selected_coins) {
|
||||||
txNew.vin.emplace_back(coin->outpoint, CScript(), nSequence);
|
std::optional<uint32_t> sequence = coin_control.GetSequence(coin->outpoint);
|
||||||
|
if (sequence) {
|
||||||
|
// If an input has a preset sequence, we can't do anti-fee-sniping
|
||||||
|
use_anti_fee_sniping = false;
|
||||||
|
}
|
||||||
|
txNew.vin.emplace_back(coin->outpoint, CScript(), sequence.value_or(default_sequence));
|
||||||
|
}
|
||||||
|
if (use_anti_fee_sniping) {
|
||||||
|
DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetLastBlockHash(), wallet.GetLastBlockHeight());
|
||||||
}
|
}
|
||||||
DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetLastBlockHash(), wallet.GetLastBlockHeight());
|
|
||||||
|
|
||||||
// Calculate the transaction fee
|
// Calculate the transaction fee
|
||||||
TxSize tx_sizes = CalculateMaximumSignedTxSize(CTransaction(txNew), &wallet, &coin_control);
|
TxSize tx_sizes = CalculateMaximumSignedTxSize(CTransaction(txNew), &wallet, &coin_control);
|
||||||
|
@ -1357,6 +1365,7 @@ bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet,
|
||||||
// The input was not in the wallet, but is in the UTXO set, so select as external
|
// The input was not in the wallet, but is in the UTXO set, so select as external
|
||||||
preset_txin.SetTxOut(coins[outPoint].out);
|
preset_txin.SetTxOut(coins[outPoint].out);
|
||||||
}
|
}
|
||||||
|
preset_txin.SetSequence(txin.nSequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto res = CreateTransaction(wallet, vecSend, nChangePosInOut, coinControl, false);
|
auto res = CreateTransaction(wallet, vecSend, nChangePosInOut, coinControl, false);
|
||||||
|
|
Loading…
Add table
Reference in a new issue