v30.3-roots.1 · Commit 49: [PATCH 49/68] wallet: snapshot sweep fee settings under lock
src/wallet/test/spend_tests.cpp
Before: src/wallet/test/spend_tests.cpp · After: src/wallet/test/spend_tests.cpp
File metadata
index dd1ac13a193f2c3d88b9992dc9d407d2887a1093..67e535d15990592dcd99ac606d04d9d85d73ca33 100644
Download original patch · Release notes
Diff rows 1–61 of 61. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
src/wallet/test/spend_tests.cpp
CHANGED
|
@@ -105,6 +105,61 @@ BOOST_FIXTURE_TEST_CASE(sweep_transaction_failure_atomicity, TestChain100Setup)
|
|
|
105
105
|
BOOST_CHECK(committed_authorization.BroadcastStarted());
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
BOOST_FIXTURE_TEST_CASE(sweep_transaction_uses_one_fee_snapshot, TestChain100Setup)
|
|
109
|
+
{
|
|
110
|
+
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
|
111
|
+
auto wallet = CreateSyncedWallet(*m_node.chain, WITH_LOCK(Assert(m_node.chainman)->GetMutex(), return m_node.chainman->ActiveChain()), coinbaseKey);
|
|
112
|
+
const CKey key{GenerateRandomKey()};
|
|
113
|
+
const CScript script{GetScriptForDestination(PKHash{key.GetPubKey()})};
|
|
114
|
+
const std::map<COutPoint, Coin> coins{{COutPoint{Txid{}, 1}, Coin{CTxOut{COIN, script}, 1, false}}};
|
|
115
|
+
const CFeeRate initial_rate{1000};
|
|
116
|
+
const CFeeRate changed_rate{10000};
|
|
117
|
+
WITH_LOCK(wallet->cs_wallet, wallet->m_pay_tx_fee = initial_rate);
|
|
118
|
+
|
|
119
|
+
// Change the wallet setting when signing the fee-adjusted transaction,
|
|
120
|
+
// after the operation has selected its fee rate. This deterministically
|
|
121
|
+
// models a concurrent settxfee without timing-sensitive threads.
|
|
122
|
+
class FeeChangingProvider final : public SigningProvider
|
|
123
|
+
{
|
|
124
|
+
CWallet& m_wallet;
|
|
125
|
+
FlatSigningProvider m_provider;
|
|
126
|
+
CFeeRate m_changed_rate;
|
|
127
|
+
|
|
128
|
+
public:
|
|
129
|
+
mutable int key_requests{0};
|
|
130
|
+
FeeChangingProvider(CWallet& wallet, const CKey& key, CFeeRate changed_rate)
|
|
131
|
+
: m_wallet{wallet}, m_changed_rate{changed_rate}
|
|
132
|
+
{
|
|
133
|
+
m_provider.keys.emplace(key.GetPubKey().GetID(), key);
|
|
134
|
+
m_provider.pubkeys.emplace(key.GetPubKey().GetID(), key.GetPubKey());
|
|
135
|
+
}
|
|
136
|
+
bool GetKey(const CKeyID& id, CKey& key_out) const override
|
|
137
|
+
{
|
|
138
|
+
AssertLockNotHeld(m_wallet.cs_wallet);
|
|
139
|
+
if (++key_requests == 2) {
|
|
140
|
+
WITH_LOCK(m_wallet.cs_wallet, m_wallet.m_pay_tx_fee = m_changed_rate);
|
|
141
|
+
}
|
|
142
|
+
return m_provider.GetKey(id, key_out);
|
|
143
|
+
}
|
|
144
|
+
bool GetPubKey(const CKeyID& id, CPubKey& pubkey) const override
|
|
145
|
+
{
|
|
146
|
+
return m_provider.GetPubKey(id, pubkey);
|
|
147
|
+
}
|
|
148
|
+
} provider{*wallet, key, changed_rate};
|
|
149
|
+
|
|
150
|
+
interfaces::SweepAuthorization authorization;
|
|
151
|
+
auto result{CreateSweepTransaction(*wallet, provider, coins, script, [&](const CTransactionRef&, std::string&) {
|
|
152
|
+
AssertLockNotHeld(wallet->cs_wallet);
|
|
153
|
+
return true;
|
|
154
|
+
}, authorization)};
|
|
155
|
+
BOOST_REQUIRE(result);
|
|
156
|
+
BOOST_CHECK_GE(provider.key_requests, 2);
|
|
157
|
+
BOOST_CHECK(WITH_LOCK(wallet->cs_wallet, return wallet->m_pay_tx_fee == changed_rate));
|
|
158
|
+
const auto vsize{GetVirtualTransactionSize(*result->tx)};
|
|
159
|
+
BOOST_CHECK_GE(result->fee, initial_rate.GetFee(vsize));
|
|
160
|
+
BOOST_CHECK_LT(result->fee, changed_rate.GetFee(vsize));
|
|
161
|
+
}
|
|
162
|
+
|
|
108
163
|
BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
|
|
109
164
|
{
|
|
110
165
|
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|