Skip to content

Commit 4d335bb

Browse files
committed
wallet: Set preset input sequence through coin control
1 parent 596642c commit 4d335bb

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

src/wallet/coincontrol.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ std::optional<int64_t> CCoinControl::GetInputWeight(const COutPoint& outpoint) c
7272
return it != m_selected.end() ? it->second.GetInputWeight() : std::nullopt;
7373
}
7474

75+
std::optional<uint32_t> CCoinControl::GetSequence(const COutPoint& outpoint) const
76+
{
77+
const auto it = m_selected.find(outpoint);
78+
return it != m_selected.end() ? it->second.GetSequence() : std::nullopt;
79+
}
80+
7581
void PreselectedInput::SetTxOut(const CTxOut& txout)
7682
{
7783
m_txout = txout;
@@ -97,4 +103,14 @@ std::optional<int64_t> PreselectedInput::GetInputWeight() const
97103
{
98104
return m_weight;
99105
}
106+
107+
void PreselectedInput::SetSequence(uint32_t sequence)
108+
{
109+
m_sequence = sequence;
110+
}
111+
112+
std::optional<uint32_t> PreselectedInput::GetSequence() const
113+
{
114+
return m_sequence;
115+
}
100116
} // namespace wallet

src/wallet/coincontrol.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class PreselectedInput
3131
std::optional<CTxOut> m_txout;
3232
//! The input weight for spending this input
3333
std::optional<int64_t> m_weight;
34+
//! The sequence number for this input
35+
std::optional<uint32_t> m_sequence;
3436

3537
public:
3638
/**
@@ -47,6 +49,11 @@ class PreselectedInput
4749
void SetInputWeight(int64_t weight);
4850
/** Retrieve the input weight for this input. */
4951
std::optional<int64_t> GetInputWeight() const;
52+
53+
/** Set the sequence for this input. */
54+
void SetSequence(uint32_t sequence);
55+
/** Retrieve the sequence for this input. */
56+
std::optional<uint32_t> GetSequence() const;
5057
};
5158

5259
/** Coin Control Features. */
@@ -128,6 +135,8 @@ class CCoinControl
128135
* Returns the input weight.
129136
*/
130137
std::optional<int64_t> GetInputWeight(const COutPoint& outpoint) const;
138+
/** Retrieve the sequence for an input */
139+
std::optional<uint32_t> GetSequence(const COutPoint& outpoint) const;
131140

132141
private:
133142
//! Selected inputs (inputs that will be used, regardless of whether they're optimal or not)

src/wallet/spend.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,11 +1150,19 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
11501150
// to avoid conflicting with other possible uses of nSequence,
11511151
// and in the spirit of "smallest possible change from prior
11521152
// behavior."
1153-
const uint32_t nSequence{coin_control.m_signal_bip125_rbf.value_or(wallet.m_signal_rbf) ? MAX_BIP125_RBF_SEQUENCE : CTxIn::MAX_SEQUENCE_NONFINAL};
1153+
bool use_anti_fee_sniping = true;
1154+
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};
11541155
for (const auto& coin : selected_coins) {
1155-
txNew.vin.emplace_back(coin->outpoint, CScript(), nSequence);
1156+
std::optional<uint32_t> sequence = coin_control.GetSequence(coin->outpoint);
1157+
if (sequence) {
1158+
// If an input has a preset sequence, we can't do anti-fee-sniping
1159+
use_anti_fee_sniping = false;
1160+
}
1161+
txNew.vin.emplace_back(coin->outpoint, CScript(), sequence.value_or(default_sequence));
1162+
}
1163+
if (use_anti_fee_sniping) {
1164+
DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetLastBlockHash(), wallet.GetLastBlockHeight());
11561165
}
1157-
DiscourageFeeSniping(txNew, rng_fast, wallet.chain(), wallet.GetLastBlockHash(), wallet.GetLastBlockHeight());
11581166

11591167
// Calculate the transaction fee
11601168
TxSize tx_sizes = CalculateMaximumSignedTxSize(CTransaction(txNew), &wallet, &coin_control);
@@ -1357,6 +1365,7 @@ bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet,
13571365
// The input was not in the wallet, but is in the UTXO set, so select as external
13581366
preset_txin.SetTxOut(coins[outPoint].out);
13591367
}
1368+
preset_txin.SetSequence(txin.nSequence);
13601369
}
13611370

13621371
auto res = CreateTransaction(wallet, vecSend, nChangePosInOut, coinControl, false);

0 commit comments

Comments
 (0)