Skip to content

Commit 3999aad

Browse files
committed
wallet/tests: Enable Silent Payments in wallet unit tests
1 parent dfc1c1c commit 3999aad

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

src/wallet/test/util.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cc
2727
{
2828
LOCK(wallet->cs_wallet);
2929
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
30+
wallet->SetWalletFlag(WALLET_FLAG_SILENT_PAYMENTS);
3031
wallet->SetupDescriptorScriptPubKeyMans();
3132

3233
FlatSigningProvider provider;

src/wallet/test/wallet_tests.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ class ListCoinsTestingSetup : public TestChain100Setup
376376
{
377377
CTransactionRef tx;
378378
CCoinControl dummy;
379+
if (std::holds_alternative<V0SilentPaymentDestination>(recipient.dest)) {
380+
dummy.m_silent_payment = true;
381+
}
379382
{
380383
auto res = CreateTransaction(*wallet, {recipient}, /*change_pos=*/std::nullopt, dummy);
381384
BOOST_CHECK(res);
@@ -492,10 +495,28 @@ BOOST_FIXTURE_TEST_CASE(BasicOutputTypesTest, ListCoinsTest)
492495
// 2. One UTXO from the change, due to payment address matching logic
493496

494497
for (const auto& out_type : OUTPUT_TYPES) {
495-
if (out_type == OutputType::UNKNOWN || out_type == OutputType::SILENT_PAYMENTS) continue;
498+
if (out_type == OutputType::UNKNOWN) continue;
499+
if (out_type == OutputType::SILENT_PAYMENTS) continue;
496500
expected_coins_sizes[out_type] = 2U;
497501
TestCoinsResult(*this, out_type, 1 * COIN, expected_coins_sizes);
498502
}
503+
504+
// Add a taproot UTXO to be used for creating a silent payment
505+
util::Result<CTxDestination> dest = Assert(wallet->GetNewDestination(OutputType::BECH32M, ""));
506+
AddTx(CRecipient{*dest, 1 * COIN, /*fSubtractFeeFromAmount=*/true});
507+
CoinFilterParams filter;
508+
filter.skip_locked = true;
509+
available_coins = WITH_LOCK(wallet->cs_wallet, return AvailableCoins(*wallet, nullptr, std::nullopt, filter));
510+
BOOST_CHECK_EQUAL(available_coins.coins[OutputType::BECH32M].size(), 2U);
511+
// Expect 4 OutputType::BECH32M UTXOs
512+
// 1. One UTXO as the recipient because Silent Payments produce taproot scriptPubKeys
513+
// 3. Two locked UTXOs from previous OutputType::BECH32M test
514+
expected_coins_sizes[OutputType::BECH32M] = 3U;
515+
// Expect 2 OutputType::BECH32M UTXOs
516+
// 1. One UTXO from mining the previous block
517+
// 1. One UTXO from mining the block used in the test
518+
expected_coins_sizes[OutputType::UNKNOWN] = 2U;
519+
TestCoinsResult(*this, OutputType::SILENT_PAYMENTS, 1 * COIN, expected_coins_sizes);
499520
}
500521

501522
BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup)

src/wallet/wallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ bool CWallet::IsMine(const CTransaction& tx, const std::map<COutPoint, Coin>& sp
16431643
AssertLockHeld(cs_wallet);
16441644

16451645
// Scan for silent payments first
1646-
if (IsWalletFlagSet(WALLET_FLAG_SILENT_PAYMENTS) && !tx.IsCoinBase()) {
1646+
if (IsWalletFlagSet(WALLET_FLAG_SILENT_PAYMENTS) && !tx.IsCoinBase() && !spent_coins.empty()) {
16471647
auto sp_data = GetSilentPaymentsData(tx, spent_coins);
16481648
if (sp_data.has_value()) {
16491649
bool found{false};

test/functional/wallet_silentpayments_receiving.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,34 @@ def test_rbf(self):
211211
self.generate(self.nodes[0], 1)
212212
assert_approx(wallet.getbalance(), 49.99, 0.0001)
213213

214+
def test_conflict(self):
215+
self.log.info("Check Silent Payments wallet handles conflicts")
216+
217+
self.nodes[0].createwallet(wallet_name="conflict", silent_payments=True)
218+
wallet = self.nodes[0].get_wallet_rpc("conflict")
219+
address = wallet.getnewaddress(address_type="bech32m")
220+
unspents = self.def_wallet.listunspent()
221+
# walletcreatefundedpsbt fails when receipients include silent-payment addresses
222+
# use bech32m instead
223+
psbt = self.def_wallet.walletcreatefundedpsbt(inputs=[unspents[0]], outputs=[{address : 49.99}])["psbt"]
224+
tx1 = self.def_wallet.walletprocesspsbt(psbt=psbt, finalize=True)['hex']
225+
226+
# Create tx2 to spend the same input as tx1
227+
psbt = self.def_wallet.walletcreatefundedpsbt(inputs=[unspents[0]], outputs=[{self.def_wallet.getnewaddress() : 49.99}])["psbt"]
228+
tx2 = self.def_wallet.walletprocesspsbt(psbt=psbt, finalize=True)['hex']
229+
230+
self.nodes[0].sendrawtransaction(tx1)
231+
232+
# Mine conflicting transaction on node 1
233+
self.disconnect_nodes(0, 1)
234+
self.nodes[1].sendrawtransaction(tx2)
235+
self.generate(self.nodes[1], 1, sync_fun=self.no_op)
236+
237+
self.connect_nodes(0, 1)
238+
self.sync_blocks()
239+
240+
assert_equal(wallet.getbalance(), 0)
241+
214242
def test_createwallet_descriptor(self):
215243
self.log.info("Check createwalletdescriptor works with silent payments descriptor")
216244

@@ -277,6 +305,7 @@ def run_test(self):
277305
self.test_import_rescan()
278306
self.test_createwallet_descriptor()
279307
self.test_getaddressinfo()
308+
self.test_conflict()
280309

281310

282311

0 commit comments

Comments
 (0)