aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2022-05-31 23:51:49 -0400
committerAndrew Chow <github@achow101.com>2023-12-08 14:55:14 -0500
commit4d335bb1e00a414a4740007d5a192a73179b2262 (patch)
tree00e59a98e4bd7a010b6651b33cc035047b6dd2e1
parent596642c5a9f52dda2599b0bde424366bb22b3c6e (diff)
downloadbitcoin-4d335bb1e00a414a4740007d5a192a73179b2262.tar.xz
wallet: Set preset input sequence through coin control
-rw-r--r--src/wallet/coincontrol.cpp16
-rw-r--r--src/wallet/coincontrol.h9
-rw-r--r--src/wallet/spend.cpp15
3 files changed, 37 insertions, 3 deletions
diff --git a/src/wallet/coincontrol.cpp b/src/wallet/coincontrol.cpp
index 00852b5f85..f13b7073be 100644
--- a/src/wallet/coincontrol.cpp
+++ b/src/wallet/coincontrol.cpp
@@ -72,6 +72,12 @@ std::optional<int64_t> CCoinControl::GetInputWeight(const COutPoint& outpoint) c
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)
{
m_txout = txout;
@@ -97,4 +103,14 @@ std::optional<int64_t> PreselectedInput::GetInputWeight() const
{
return m_weight;
}
+
+void PreselectedInput::SetSequence(uint32_t sequence)
+{
+ m_sequence = sequence;
+}
+
+std::optional<uint32_t> PreselectedInput::GetSequence() const
+{
+ return m_sequence;
+}
} // namespace wallet
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index e7a16e37df..32595955f0 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -31,6 +31,8 @@ private:
std::optional<CTxOut> m_txout;
//! The input weight for spending this input
std::optional<int64_t> m_weight;
+ //! The sequence number for this input
+ std::optional<uint32_t> m_sequence;
public:
/**
@@ -47,6 +49,11 @@ public:
void SetInputWeight(int64_t weight);
/** Retrieve the input weight for this input. */
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. */
@@ -128,6 +135,8 @@ public:
* Returns the input weight.
*/
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:
//! Selected inputs (inputs that will be used, regardless of whether they're optimal or not)
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index c3fd695eb9..7ec2775fb1 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -1150,11 +1150,19 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
// to avoid conflicting with other possible uses of nSequence,
// and in the spirit of "smallest possible change from prior
// 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) {
- 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
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
preset_txin.SetTxOut(coins[outPoint].out);
}
+ preset_txin.SetSequence(txin.nSequence);
}
auto res = CreateTransaction(wallet, vecSend, nChangePosInOut, coinControl, false);