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 504fcb6..f116f6b 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 9283fdd..1f851d4 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 617666c..e9fe20c 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{}), } }