From 7e015258cd36381de13f4685e399a2a8b323add3 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Thu, 10 Jan 2019 12:23:57 +0100 Subject: [PATCH] lnwallet/channel test: add TestUpdateFeeConcurrentSig This tests make sure we don't reset our expected fee upate after signing our next commitment. This test would fail without the previous set of commits. --- lnwallet/channel_test.go | 82 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/lnwallet/channel_test.go b/lnwallet/channel_test.go index 5eba3bc45..7cdb3f7b1 100644 --- a/lnwallet/channel_test.go +++ b/lnwallet/channel_test.go @@ -1999,6 +1999,88 @@ func TestUpdateFeeFail(t *testing.T) { } +// TestUpdateFeeConcurrentSig tests that the channel can properly handle a fee +// update that it receives concurrently with signing its next commitment. +func TestUpdateFeeConcurrentSig(t *testing.T) { + t.Parallel() + + aliceChannel, bobChannel, cleanUp, err := CreateTestChannels() + if err != nil { + t.Fatalf("unable to create test channels: %v", err) + } + defer cleanUp() + + paymentPreimage := bytes.Repeat([]byte{1}, 32) + paymentHash := sha256.Sum256(paymentPreimage) + htlc := &lnwire.UpdateAddHTLC{ + PaymentHash: paymentHash, + Amount: btcutil.SatoshiPerBitcoin, + Expiry: uint32(5), + } + + // First Alice adds the outgoing HTLC to her local channel's state + // update log. Then Alice sends this wire message over to Bob who + // adds this htlc to his remote state update log. + if _, err := aliceChannel.AddHTLC(htlc, nil); err != nil { + t.Fatalf("unable to add htlc: %v", err) + } + if _, err := bobChannel.ReceiveHTLC(htlc); err != nil { + t.Fatalf("unable to recv htlc: %v", err) + } + + // Simulate Alice sending update fee message to bob. + fee := SatPerKWeight(111) + if err := aliceChannel.UpdateFee(fee); err != nil { + t.Fatalf("unable to send fee update") + } + + // Alice signs a commitment, and sends this to bob. + aliceSig, aliceHtlcSigs, err := aliceChannel.SignNextCommitment() + if err != nil { + t.Fatalf("alice unable to sign commitment: %v", err) + } + + // At the same time, Bob signs a commitment. + bobSig, bobHtlcSigs, err := bobChannel.SignNextCommitment() + if err != nil { + t.Fatalf("bob unable to sign alice's commitment: %v", err) + } + + // ...that Alice receives. + err = aliceChannel.ReceiveNewCommitment(bobSig, bobHtlcSigs) + if err != nil { + t.Fatalf("alice unable to process bob's new commitment: %v", err) + } + + // Now let Bob receive the fee update + commitment that Alice sent. + if err := bobChannel.ReceiveUpdateFee(fee); err != nil { + t.Fatalf("unable to receive fee update") + } + + // Bob receives this signature message, and verifies that it is + // consistent with the state he had for Alice, including the received + // HTLC and fee update. + err = bobChannel.ReceiveNewCommitment(aliceSig, aliceHtlcSigs) + if err != nil { + t.Fatalf("bob unable to process alice's new commitment: %v", err) + } + + if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) == fee { + t.Fatalf("bob's feePerKw was unexpectedly locked in") + } + + // Bob can revoke the prior commitment he had. This should lock in the + // fee update for him. + _, _, err = bobChannel.RevokeCurrentCommitment() + if err != nil { + t.Fatalf("unable to generate bob revocation: %v", err) + } + + if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != fee { + t.Fatalf("bob's feePerKw was not locked in") + } +} + // TestUpdateFeeSenderCommits verifies that the state machine progresses as // expected if we send a fee update, and then the sender of the fee update // sends a commitment signature.