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. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/wallet/test/spend_tests.cpp
CHANGED
|
@@ -105,6 +105,61 @@ BOOST_FIXTURE_TEST_CASE(sweep_transaction_failure_atomicity, TestChain100Setup)
|
|
| 105 |
BOOST_CHECK(committed_authorization.BroadcastStarted());
|
| 106 |
}
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
|
| 109 |
{
|
| 110 |
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
|
|
|
| 105 |
BOOST_CHECK(committed_authorization.BroadcastStarted());
|
| 106 |
}
|
| 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 |
+
|
| 163 |
BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
|
| 164 |
{
|
| 165 |
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|