From ed3db3bab2fb4474dcb79326bcca4b628796856e Mon Sep 17 00:00:00 2001 From: Boris Nagaev Date: Wed, 7 Aug 2024 22:52:02 -0300 Subject: [PATCH] client: fill LastHop in FetchSwaps Loop used to "forget" last_hop of swaps created before its restart. The commit fixes this. Added test TestFetchSwapsLastHop for this. Filled field abandonChans in test utility function newSwapClient because the field is used in new test. Fixes https://github.com/lightninglabs/loop/issues/798 --- client.go | 1 + client_test.go | 74 +++++++++++++++++++++++++++++++++++++++++++++ testcontext_test.go | 1 + 3 files changed, 76 insertions(+) diff --git a/client.go b/client.go index 504fcb67..f116f6b3 100644 --- a/client.go +++ b/client.go @@ -283,6 +283,7 @@ func (s *Client) FetchSwaps(ctx context.Context) ([]*SwapInfo, error) { SwapStateData: swp.State(), SwapHash: swp.Hash, LastUpdate: swp.LastUpdateTime(), + LastHop: swp.Contract.LastHop, } htlc, err := utils.GetHtlc( diff --git a/client_test.go b/client_test.go index 9283fdd9..1f851d47 100644 --- a/client_test.go +++ b/client_test.go @@ -16,6 +16,7 @@ import ( "github.com/lightninglabs/loop/utils" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntypes" + "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -45,6 +46,23 @@ var ( defaultConfirmations = int32(loopdb.DefaultLoopOutHtlcConfirmations) ) +var htlcKeys = func() loopdb.HtlcKeys { + var senderKey, receiverKey [33]byte + + // Generate keys. + _, senderPubKey := test.CreateKey(1) + copy(senderKey[:], senderPubKey.SerializeCompressed()) + _, receiverPubKey := test.CreateKey(2) + copy(receiverKey[:], receiverPubKey.SerializeCompressed()) + + return loopdb.HtlcKeys{ + SenderScriptKey: senderKey, + ReceiverScriptKey: receiverKey, + SenderInternalPubKey: senderKey, + ReceiverInternalPubKey: receiverKey, + } +}() + // TestLoopOutSuccess tests the loop out happy flow, using a custom htlc // confirmation target. func TestLoopOutSuccess(t *testing.T) { @@ -437,3 +455,59 @@ func TestWrapGrpcError(t *testing.T) { }) } } + +// TestFetchSwapsLastHop asserts that FetchSwaps loads LastHop for LoopIn's. +func TestFetchSwapsLastHop(t *testing.T) { + defer test.Guard(t)() + + ctx := createClientTestContext(t, nil) + + lastHop := route.Vertex{1, 2, 3} + + // Create a loop in swap. + swapHash := lntypes.Hash{1, 1, 1} + swap := &loopdb.LoopInContract{ + SwapContract: loopdb.SwapContract{ + CltvExpiry: 111, + AmountRequested: 111, + ProtocolVersion: loopdb.ProtocolVersionMuSig2, + HtlcKeys: htlcKeys, + }, + LastHop: &lastHop, + } + err := ctx.store.CreateLoopIn(context.Background(), swapHash, swap) + require.NoError(t, err, "CreateLoopOut failed") + + // Now read all the swaps from the store + swapInfos, err := ctx.swapClient.FetchSwaps(context.Background()) + require.NoError(t, err, "FetchSwaps failed") + + // Find the loop-in and compare with the expected value. + require.Len(t, swapInfos, 1) + loopInInfo := swapInfos[0] + wantLoopInInfo := &SwapInfo{ + SwapHash: swapHash, + SwapContract: loopdb.SwapContract{ + CltvExpiry: 111, + AmountRequested: 111, + ProtocolVersion: loopdb.ProtocolVersionMuSig2, + HtlcKeys: htlcKeys, + }, + + // Make sure LastHop is filled. + LastHop: &lastHop, + } + + // Calculate HtlcAddressP2TR. + htlc, err := utils.GetHtlc( + swapHash, &wantLoopInInfo.SwapContract, + &chaincfg.TestNet3Params, + ) + require.NoError(t, err) + wantLoopInInfo.HtlcAddressP2TR = htlc.Address + + require.Equal(t, wantLoopInInfo, loopInInfo) + + // Shutdown the client not to leak goroutines. + ctx.finish() +} diff --git a/testcontext_test.go b/testcontext_test.go index 617666ce..e9fe20cb 100644 --- a/testcontext_test.go +++ b/testcontext_test.go @@ -108,6 +108,7 @@ func newSwapClient(t *testing.T, config *clientConfig) *Client { sweeper: sweeper, executor: executor, resumeReady: make(chan struct{}), + abandonChans: make(map[lntypes.Hash]chan struct{}), } }