lnd/itest/lnd_coop_close_external_delivery_test.go
yyforyongyu 2913f6e4c9
itest: fix flake in testCoopCloseWithExternalDeliveryImpl
The response from `ClosedChannels` may not be up-to-date, so we wrap it
inside a wait closure.
2024-12-20 19:38:15 +08:00

135 lines
3.8 KiB
Go

package itest
import (
"fmt"
"testing"
"github.com/btcsuite/btcd/btcutil"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/stretchr/testify/require"
)
func testCoopCloseWithExternalDelivery(ht *lntest.HarnessTest) {
ok := ht.Run("set P2WPKH delivery address at open", func(t *testing.T) {
tt := ht.Subtest(t)
testCoopCloseWithExternalDeliveryImpl(
tt, true, lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
)
})
// Abort the test if failed.
if !ok {
return
}
ok = ht.Run("set P2WPKH delivery address at close", func(t *testing.T) {
tt := ht.Subtest(t)
testCoopCloseWithExternalDeliveryImpl(
tt, false, lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
)
})
// Abort the test if failed.
if !ok {
return
}
ok = ht.Run("set P2TR delivery address at open", func(t *testing.T) {
tt := ht.Subtest(t)
testCoopCloseWithExternalDeliveryImpl(
tt, true, lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
)
})
// Abort the test if failed.
if !ok {
return
}
ht.Run("set P2TR delivery address at close", func(t *testing.T) {
tt := ht.Subtest(t)
testCoopCloseWithExternalDeliveryImpl(
tt, false, lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
)
})
}
// testCoopCloseWithExternalDeliveryImpl ensures that we have a valid settled
// balance irrespective of whether the delivery address is in LND's wallet or
// not. Some users set this value to be an address in a different wallet and
// this should not affect our ability to accurately report the settled balance.
func testCoopCloseWithExternalDeliveryImpl(ht *lntest.HarnessTest,
upfrontShutdown bool, deliveryAddressType lnrpc.AddressType) {
alice := ht.NewNodeWithCoins("Alice", nil)
bob := ht.NewNodeWithCoins("bob", nil)
ht.ConnectNodes(alice, bob)
// Here we generate a final delivery address in bob's wallet but set by
// alice. We do this to ensure that the address is not in alice's LND
// wallet. We already correctly track settled balances when the address
// is in the LND wallet.
addr := bob.RPC.NewAddress(&lnrpc.NewAddressRequest{
Type: deliveryAddressType,
})
// Prepare for channel open.
openParams := lntest.OpenChannelParams{
Amt: btcutil.Amount(1000000),
}
// If we are testing the case where we set it on open then we'll set the
// upfront shutdown script in the channel open parameters.
if upfrontShutdown {
openParams.CloseAddress = addr.Address
}
// Open the channel!
chanPoint := ht.OpenChannel(alice, bob, openParams)
// Prepare for channel close.
closeParams := lnrpc.CloseChannelRequest{
ChannelPoint: chanPoint,
TargetConf: 6,
}
// If we are testing the case where we set the delivery address on
// channel close then we will set it in the channel close parameters.
if !upfrontShutdown {
closeParams.DeliveryAddress = addr.Address
}
// Close the channel!
closeClient := alice.RPC.CloseChannel(&closeParams)
// Assert that we got a channel update when we get a closing txid.
_, err := closeClient.Recv()
require.NoError(ht, err)
// Mine the closing transaction.
ht.MineClosingTx(chanPoint)
// Assert that we got a channel update when the closing tx was mined.
_, err = closeClient.Recv()
require.NoError(ht, err)
// Here we query our closed channels to conduct the final test
// assertion. We want to ensure that even though alice's delivery
// address is set to an address in bob's wallet, we should still show
// the balance as settled.
err = wait.NoError(func() error {
closed := alice.RPC.ClosedChannels(&lnrpc.ClosedChannelsRequest{
Cooperative: true,
})
if len(closed.Channels) == 0 {
return fmt.Errorf("expected closed channel not found")
}
if closed.Channels[0].SettledBalance == 0 {
return fmt.Errorf("expected settled balance to be zero")
}
return nil
}, defaultTimeout)
require.NoError(ht, err, "timeout checking closed channels")
}