Skip to content

Commit 65d7c31

Browse files
committed
Merge bitcoin/bitcoin#25789: test: clean and extend availablecoins_tests coverage
9622fe6 test: move coins result test to wallet_tests.cpp (furszy) f69347d test: extend and simplify availablecoins_tests (furszy) 212ccdf wallet: AvailableCoins, add arg to include/skip locked coins (furszy) Pull request description: Negative PR with extended test coverage :). 1) Cleaned duplicated code and added coverage for the 'AvailableCoins' incremental result. 2) The class `AvailableCoinsTestingSetup` inside `availablecoins_tests.cpp` is a plain copy of `ListCoinsTestingSetup` that is inside `wallet_tests.cpp`. So, deleted the file and moved the `BasicOutputTypesTest` test case to `wallet_tests.cpp`. 3) Added arg to include/skip locked coins from the `AvailableCoins` result. This is needed for point (1) as otherwise the wallet will spend the coins that we recently created due its closeness to the recipient amount. Note: this last point comes from #25659 where I'm using the same functionality to clean/speedup another flow as well. ACKs for top commit: achow101: ACK 9622fe6 theStack: ACK 9622fe6 aureleoules: reACK 9622fe6, nice cleanup! Tree-SHA512: 1ed9133120bfe8815455d1ad317bb0ff96e11a0cc34ee8098716ab9b001749168fa649212b2fa14b330c1686cb1f29039ff1f88ae306db68881b0428c038f388
2 parents 7bb07bf + 9622fe6 commit 65d7c31

File tree

5 files changed

+43
-109
lines changed

5 files changed

+43
-109
lines changed

src/Makefile.test.include

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ BITCOIN_TESTS += \
174174
wallet/test/wallet_crypto_tests.cpp \
175175
wallet/test/wallet_transaction_tests.cpp \
176176
wallet/test/coinselector_tests.cpp \
177-
wallet/test/availablecoins_tests.cpp \
178177
wallet/test/init_tests.cpp \
179178
wallet/test/ismine_tests.cpp \
180179
wallet/test/rpc_util_tests.cpp \

src/wallet/spend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ CoinsResult AvailableCoins(const CWallet& wallet,
287287
if (coinControl && coinControl->HasSelected() && coinControl->IsSelected(outpoint))
288288
continue;
289289

290-
if (wallet.IsLockedCoin(outpoint))
290+
if (wallet.IsLockedCoin(outpoint) && params.skip_locked)
291291
continue;
292292

293293
if (wallet.IsSpent(outpoint))

src/wallet/spend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ struct CoinFilterParams {
7676
bool only_spendable{true};
7777
// By default, do not include immature coinbase outputs
7878
bool include_immature_coinbase{false};
79+
// By default, skip locked UTXOs
80+
bool skip_locked{true};
7981
};
8082

8183
/**

src/wallet/test/availablecoins_tests.cpp

Lines changed: 0 additions & 107 deletions
This file was deleted.

src/wallet/test/wallet_tests.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,46 @@ BOOST_FIXTURE_TEST_CASE(ListCoinsTest, ListCoinsTestingSetup)
622622
BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
623623
}
624624

625+
void TestCoinsResult(ListCoinsTest& context, OutputType out_type, CAmount amount,
626+
std::map<OutputType, size_t>& expected_coins_sizes)
627+
{
628+
LOCK(context.wallet->cs_wallet);
629+
util::Result<CTxDestination> dest = Assert(context.wallet->GetNewDestination(out_type, ""));
630+
CWalletTx& wtx = context.AddTx(CRecipient{{GetScriptForDestination(*dest)}, amount, /*fSubtractFeeFromAmount=*/true});
631+
CoinFilterParams filter;
632+
filter.skip_locked = false;
633+
CoinsResult available_coins = AvailableCoins(*context.wallet, nullptr, std::nullopt, filter);
634+
// Lock outputs so they are not spent in follow-up transactions
635+
for (uint32_t i = 0; i < wtx.tx->vout.size(); i++) context.wallet->LockCoin({wtx.GetHash(), i});
636+
for (const auto& [type, size] : expected_coins_sizes) BOOST_CHECK_EQUAL(size, available_coins.coins[type].size());
637+
}
638+
639+
BOOST_FIXTURE_TEST_CASE(BasicOutputTypesTest, ListCoinsTest)
640+
{
641+
std::map<OutputType, size_t> expected_coins_sizes;
642+
for (const auto& out_type : OUTPUT_TYPES) { expected_coins_sizes[out_type] = 0U; }
643+
644+
// Verify our wallet has one usable coinbase UTXO before starting
645+
// This UTXO is a P2PK, so it should show up in the Other bucket
646+
expected_coins_sizes[OutputType::UNKNOWN] = 1U;
647+
CoinsResult available_coins = WITH_LOCK(wallet->cs_wallet, return AvailableCoins(*wallet));
648+
BOOST_CHECK_EQUAL(available_coins.Size(), expected_coins_sizes[OutputType::UNKNOWN]);
649+
BOOST_CHECK_EQUAL(available_coins.coins[OutputType::UNKNOWN].size(), expected_coins_sizes[OutputType::UNKNOWN]);
650+
651+
// We will create a self transfer for each of the OutputTypes and
652+
// verify it is put in the correct bucket after running GetAvailablecoins
653+
//
654+
// For each OutputType, We expect 2 UTXOs in our wallet following the self transfer:
655+
// 1. One UTXO as the recipient
656+
// 2. One UTXO from the change, due to payment address matching logic
657+
658+
for (const auto& out_type : OUTPUT_TYPES) {
659+
if (out_type == OutputType::UNKNOWN) continue;
660+
expected_coins_sizes[out_type] = 2U;
661+
TestCoinsResult(*this, out_type, 1 * COIN, expected_coins_sizes);
662+
}
663+
}
664+
625665
BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup)
626666
{
627667
{

0 commit comments

Comments
 (0)