From cbfba79f46087bb0be1f40bb729adc0f8ced7bcc Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Thu, 5 Apr 2018 19:17:17 +0200 Subject: [PATCH] fundingmanager test: add test for custom channel parameters This commit adds TestFundingManagerCustomChannelParameters, which checks that custom channel parameters specified at channel creation is preserved and recorded correctly on both sides of the channel. --- fundingmanager_test.go | 156 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/fundingmanager_test.go b/fundingmanager_test.go index 7090a3e6..c8a20e6a 100644 --- a/fundingmanager_test.go +++ b/fundingmanager_test.go @@ -1934,3 +1934,159 @@ func TestFundingManagerPrivateRestart(t *testing.T) { // from the database, as the channel is announced. assertNoChannelState(t, alice, bob, fundingOutPoint) } + +// TestFundingManagerCustomChannelParameters checks that custom requirements we +// specify during the channel funding flow is preserved correcly on both sides. +func TestFundingManagerCustomChannelParameters(t *testing.T) { + alice, bob := setupFundingManagers(t) + defer tearDownFundingManagers(t, alice, bob) + + // This is the custom CSV delay we'll use. + const csvDelay = 67 + + // We will consume the channel updates as we go, so no buffering is + // needed. + updateChan := make(chan *lnrpc.OpenStatusUpdate) + + // Create a funding request with the custom parameters and start the + // workflow. + errChan := make(chan error, 1) + initReq := &openChanReq{ + targetPubkey: bob.privKey.PubKey(), + chainHash: *activeNetParams.GenesisHash, + localFundingAmt: 5000000, + pushAmt: lnwire.NewMSatFromSatoshis(0), + private: false, + remoteCsvDelay: csvDelay, + updates: updateChan, + err: errChan, + } + + alice.fundingMgr.initFundingWorkflow(bobAddr, initReq) + + // Alice should have sent the OpenChannel message to Bob. + var aliceMsg lnwire.Message + select { + case aliceMsg = <-alice.msgChan: + case err := <-initReq.err: + t.Fatalf("error init funding workflow: %v", err) + case <-time.After(time.Second * 5): + t.Fatalf("alice did not send OpenChannel message") + } + + openChannelReq, ok := aliceMsg.(*lnwire.OpenChannel) + if !ok { + errorMsg, gotError := aliceMsg.(*lnwire.Error) + if gotError { + t.Fatalf("expected OpenChannel to be sent "+ + "from bob, instead got error: %v", + lnwire.ErrorCode(errorMsg.Data[0])) + } + t.Fatalf("expected OpenChannel to be sent from "+ + "alice, instead got %T", aliceMsg) + } + + // Check that the custom CSV delay is sent as part of OpenChannel. + if openChannelReq.CsvDelay != csvDelay { + t.Fatalf("expected OpenChannel to have CSV delay %v, got %v", + csvDelay, openChannelReq.CsvDelay) + } + + chanID := openChannelReq.PendingChannelID + + // Let Bob handle the init message. + bob.fundingMgr.processFundingOpen(openChannelReq, aliceAddr) + + // Bob should answer with an AcceptChannel message. + acceptChannelResponse := assertFundingMsgSent( + t, bob.msgChan, "AcceptChannel", + ).(*lnwire.AcceptChannel) + + // Bob should require the default delay of 4. + if acceptChannelResponse.CsvDelay != 4 { + t.Fatalf("expected AcceptChannel to have CSV delay %v, got %v", + 4, acceptChannelResponse.CsvDelay) + } + + // Forward the response to Alice. + alice.fundingMgr.processFundingAccept(acceptChannelResponse, bobAddr) + + // Alice responds with a FundingCreated message. + fundingCreated := assertFundingMsgSent( + t, alice.msgChan, "FundingCreated", + ).(*lnwire.FundingCreated) + + // Give the message to Bob. + bob.fundingMgr.processFundingCreated(fundingCreated, aliceAddr) + + // Finally, Bob should send the FundingSigned message. + fundingSigned := assertFundingMsgSent( + t, bob.msgChan, "FundingSigned", + ).(*lnwire.FundingSigned) + + // Forward the signature to Alice. + alice.fundingMgr.processFundingSigned(fundingSigned, bobAddr) + + // After Alice processes the singleFundingSignComplete message, she will + // broadcast the funding transaction to the network. We expect to get a + // channel update saying the channel is pending. + var pendingUpdate *lnrpc.OpenStatusUpdate + select { + case pendingUpdate = <-updateChan: + case <-time.After(time.Second * 5): + t.Fatalf("alice did not send OpenStatusUpdate_ChanPending") + } + + _, ok = pendingUpdate.Update.(*lnrpc.OpenStatusUpdate_ChanPending) + if !ok { + t.Fatal("OpenStatusUpdate was not OpenStatusUpdate_ChanPending") + } + + // Wait for Alice to published the funding tx to the network. + select { + case <-alice.publTxChan: + case <-time.After(time.Second * 5): + t.Fatalf("alice did not publish funding tx") + } + + // Helper method for checking the CSV delay stored for a reservation. + assertDelay := func(resCtx *reservationWithCtx, + ourDelay, theirDelay uint16) error { + + ourCsvDelay := resCtx.reservation.OurContribution().CsvDelay + if ourCsvDelay != ourDelay { + return fmt.Errorf("expected our CSV delay to be %v, "+ + "was %v", ourDelay, ourCsvDelay) + } + + theirCsvDelay := resCtx.reservation.TheirContribution().CsvDelay + if theirCsvDelay != theirDelay { + return fmt.Errorf("expected their CSV delay to be %v, "+ + "was %v", theirDelay, theirCsvDelay) + } + return nil + } + + // Check that the custom channel parameters were properly set in the + // channel reservation. + resCtx, err := alice.fundingMgr.getReservationCtx(bobPubKey, chanID) + if err != nil { + t.Fatalf("unable to find ctx: %v", err) + } + + // Alice's CSV delay should be 4 since Bob sent the fedault value, and + // Bob's should be 67 since Alice sent the custom value. + if err := assertDelay(resCtx, 4, csvDelay); err != nil { + t.Fatal(err) + } + + // Also make sure the parameters are properly set on Bob's end. + resCtx, err = bob.fundingMgr.getReservationCtx(alicePubKey, chanID) + if err != nil { + t.Fatalf("unable to find ctx: %v", err) + } + + if err := assertDelay(resCtx, csvDelay, 4); err != nil { + t.Fatal(err) + } +}