Skip to content

Commit 0a1f87f

Browse files
committed
lnwallet: expand chan sync tests to cover taproot channels
In this commit, we expand some of the existing chan sync tests to cover taproot channels (the others already did). Along the way, we always assert that the `PartialSig` is populated on retransmission. In addition, we now send the new commit sig rather than the existing in-memory one to test the new logic that re-signs the commitment.
1 parent d40f440 commit 0a1f87f

File tree

1 file changed

+169
-25
lines changed

1 file changed

+169
-25
lines changed

lnwallet/channel_test.go

Lines changed: 169 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,19 +3024,11 @@ func restartChannel(channelOld *LightningChannel) (*LightningChannel, error) {
30243024
return channelNew, nil
30253025
}
30263026

3027-
// TestChanSyncOweCommitment tests that if Bob restarts (and then Alice) before
3028-
// he receives Alice's CommitSig message, then Alice concludes that she needs
3029-
// to re-send the CommitDiff. After the diff has been sent, both nodes should
3030-
// resynchronize and be able to complete the dangling commit.
3031-
func TestChanSyncOweCommitment(t *testing.T) {
3032-
t.Parallel()
3033-
3027+
func testChanSyncOweCommitment(t *testing.T, chanType channeldb.ChannelType) {
30343028
// Create a test channel which will be used for the duration of this
30353029
// unittest. The channel will be funded evenly with Alice having 5 BTC,
30363030
// and Bob having 5 BTC.
3037-
aliceChannel, bobChannel, err := CreateTestChannels(
3038-
t, channeldb.SingleFunderTweaklessBit,
3039-
)
3031+
aliceChannel, bobChannel, err := CreateTestChannels(t, chanType)
30403032
require.NoError(t, err, "unable to create test channels")
30413033

30423034
var fakeOnionBlob [lnwire.OnionPacketSize]byte
@@ -3111,6 +3103,15 @@ func TestChanSyncOweCommitment(t *testing.T) {
31113103
aliceNewCommit, err := aliceChannel.SignNextCommitment()
31123104
require.NoError(t, err, "unable to sign commitment")
31133105

3106+
// If this is a taproot channel, then we'll generate fresh verification
3107+
// nonce for both sides.
3108+
if chanType.IsTaproot() {
3109+
_, err = aliceChannel.GenMusigNonces()
3110+
require.NoError(t, err)
3111+
_, err = bobChannel.GenMusigNonces()
3112+
require.NoError(t, err)
3113+
}
3114+
31143115
// Bob doesn't get this message so upon reconnection, they need to
31153116
// synchronize. Alice should conclude that she owes Bob a commitment,
31163117
// while Bob should think he's properly synchronized.
@@ -3122,7 +3123,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
31223123
// This is a helper function that asserts Alice concludes that she
31233124
// needs to retransmit the exact commitment that we failed to send
31243125
// above.
3125-
assertAliceCommitRetransmit := func() {
3126+
assertAliceCommitRetransmit := func() *lnwire.CommitSig {
31263127
aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg(
31273128
bobSyncMsg,
31283129
)
@@ -3187,12 +3188,25 @@ func TestChanSyncOweCommitment(t *testing.T) {
31873188
len(commitSigMsg.HtlcSigs))
31883189
}
31893190
for i, htlcSig := range commitSigMsg.HtlcSigs {
3190-
if htlcSig != aliceNewCommit.HtlcSigs[i] {
3191+
if !bytes.Equal(htlcSig.RawBytes(),
3192+
aliceNewCommit.HtlcSigs[i].RawBytes()) {
3193+
31913194
t.Fatalf("htlc sig msgs don't match: "+
3192-
"expected %x got %x",
3193-
aliceNewCommit.HtlcSigs[i], htlcSig)
3195+
"expected %v got %v",
3196+
spew.Sdump(aliceNewCommit.HtlcSigs[i]),
3197+
spew.Sdump(htlcSig))
31943198
}
31953199
}
3200+
3201+
// If this is a taproot channel, then partial sig information
3202+
// should be present in the commit sig sent over. This
3203+
// signature will be re-regenerated, so we can't compare it
3204+
// with the old one.
3205+
if chanType.IsTaproot() {
3206+
require.True(t, commitSigMsg.PartialSig.IsSome())
3207+
}
3208+
3209+
return commitSigMsg
31963210
}
31973211

31983212
// Alice should detect that she needs to re-send 5 messages: the 3
@@ -3213,14 +3227,19 @@ func TestChanSyncOweCommitment(t *testing.T) {
32133227
// send the exact same set of messages.
32143228
aliceChannel, err = restartChannel(aliceChannel)
32153229
require.NoError(t, err, "unable to restart alice")
3216-
assertAliceCommitRetransmit()
32173230

3218-
// TODO(roasbeef): restart bob as well???
3231+
// To properly simulate a restart, we'll use the *new* signature that
3232+
// would send in an actual p2p setting.
3233+
aliceReCommitSig := assertAliceCommitRetransmit()
32193234

32203235
// At this point, we should be able to resume the prior state update
32213236
// without any issues, resulting in Alice settling the 3 htlc's, and
32223237
// adding one of her own.
3223-
err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs)
3238+
err = bobChannel.ReceiveNewCommitment(&CommitSigs{
3239+
CommitSig: aliceReCommitSig.CommitSig,
3240+
HtlcSigs: aliceReCommitSig.HtlcSigs,
3241+
PartialSig: aliceReCommitSig.PartialSig,
3242+
})
32243243
require.NoError(t, err, "bob unable to process alice's commitment")
32253244
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
32263245
require.NoError(t, err, "unable to revoke bob commitment")
@@ -3307,16 +3326,53 @@ func TestChanSyncOweCommitment(t *testing.T) {
33073326
}
33083327
}
33093328

3310-
// TestChanSyncOweCommitmentPendingRemote asserts that local updates are applied
3311-
// to the remote commit across restarts.
3312-
func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
3329+
// TestChanSyncOweCommitment tests that if Bob restarts (and then Alice) before
3330+
// he receives Alice's CommitSig message, then Alice concludes that she needs
3331+
// to re-send the CommitDiff. After the diff has been sent, both nodes should
3332+
// resynchronize and be able to complete the dangling commit.
3333+
func TestChanSyncOweCommitment(t *testing.T) {
33133334
t.Parallel()
33143335

3336+
testCases := []struct {
3337+
name string
3338+
chanType channeldb.ChannelType
3339+
}{
3340+
{
3341+
name: "tweakless",
3342+
chanType: channeldb.SingleFunderTweaklessBit,
3343+
},
3344+
{
3345+
name: "anchors",
3346+
chanType: channeldb.SingleFunderTweaklessBit |
3347+
channeldb.AnchorOutputsBit,
3348+
},
3349+
{
3350+
name: "taproot",
3351+
chanType: channeldb.SingleFunderTweaklessBit |
3352+
channeldb.AnchorOutputsBit |
3353+
channeldb.SimpleTaprootFeatureBit,
3354+
},
3355+
{
3356+
name: "taproot with tapscript root",
3357+
chanType: channeldb.SingleFunderTweaklessBit |
3358+
channeldb.AnchorOutputsBit |
3359+
channeldb.SimpleTaprootFeatureBit |
3360+
channeldb.TapscriptRootBit,
3361+
},
3362+
}
3363+
for _, tc := range testCases {
3364+
t.Run(tc.name, func(t *testing.T) {
3365+
testChanSyncOweCommitment(t, tc.chanType)
3366+
})
3367+
}
3368+
}
3369+
3370+
func testChanSyncOweCommitmentPendingRemote(t *testing.T,
3371+
chanType channeldb.ChannelType) {
3372+
33153373
// Create a test channel which will be used for the duration of this
33163374
// unittest.
3317-
aliceChannel, bobChannel, err := CreateTestChannels(
3318-
t, channeldb.SingleFunderTweaklessBit,
3319-
)
3375+
aliceChannel, bobChannel, err := CreateTestChannels(t, chanType)
33203376
require.NoError(t, err, "unable to create test channels")
33213377

33223378
var fakeOnionBlob [lnwire.OnionPacketSize]byte
@@ -3399,6 +3455,12 @@ func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
33993455
bobChannel, err = restartChannel(bobChannel)
34003456
require.NoError(t, err, "unable to restart bob")
34013457

3458+
// If this is a taproot channel, then since Bob just restarted, we need
3459+
// to exchange nonces once again.
3460+
if chanType.IsTaproot() {
3461+
require.NoError(t, initMusigNonce(aliceChannel, bobChannel))
3462+
}
3463+
34023464
// Bob signs the commitment he owes.
34033465
bobNewCommit, err := bobChannel.SignNextCommitment()
34043466
require.NoError(t, err, "unable to sign commitment")
@@ -3424,6 +3486,45 @@ func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
34243486
}
34253487
}
34263488

3489+
// TestChanSyncOweCommitmentPendingRemote asserts that local updates are applied
3490+
// to the remote commit across restarts.
3491+
func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
3492+
t.Parallel()
3493+
3494+
testCases := []struct {
3495+
name string
3496+
chanType channeldb.ChannelType
3497+
}{
3498+
{
3499+
name: "tweakless",
3500+
chanType: channeldb.SingleFunderTweaklessBit,
3501+
},
3502+
{
3503+
name: "anchors",
3504+
chanType: channeldb.SingleFunderTweaklessBit |
3505+
channeldb.AnchorOutputsBit,
3506+
},
3507+
{
3508+
name: "taproot",
3509+
chanType: channeldb.SingleFunderTweaklessBit |
3510+
channeldb.AnchorOutputsBit |
3511+
channeldb.SimpleTaprootFeatureBit,
3512+
},
3513+
{
3514+
name: "taproot with tapscript root",
3515+
chanType: channeldb.SingleFunderTweaklessBit |
3516+
channeldb.AnchorOutputsBit |
3517+
channeldb.SimpleTaprootFeatureBit |
3518+
channeldb.TapscriptRootBit,
3519+
},
3520+
}
3521+
for _, tc := range testCases {
3522+
t.Run(tc.name, func(t *testing.T) {
3523+
testChanSyncOweCommitmentPendingRemote(t, tc.chanType)
3524+
})
3525+
}
3526+
}
3527+
34273528
// testChanSyncOweRevocation is the internal version of
34283529
// TestChanSyncOweRevocation that is parameterized based on the type of channel
34293530
// being used in the test.
@@ -3573,8 +3674,6 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) {
35733674

35743675
assertAliceOwesRevoke()
35753676

3576-
// TODO(roasbeef): restart bob too???
3577-
35783677
// We'll continue by then allowing bob to process Alice's revocation
35793678
// message.
35803679
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
@@ -3623,6 +3722,23 @@ func TestChanSyncOweRevocation(t *testing.T) {
36233722

36243723
testChanSyncOweRevocation(t, taprootBits)
36253724
})
3725+
t.Run("taproot", func(t *testing.T) {
3726+
taprootBits := channeldb.SimpleTaprootFeatureBit |
3727+
channeldb.AnchorOutputsBit |
3728+
channeldb.ZeroHtlcTxFeeBit |
3729+
channeldb.SingleFunderTweaklessBit
3730+
3731+
testChanSyncOweRevocation(t, taprootBits)
3732+
})
3733+
t.Run("taproot with tapscript root", func(t *testing.T) {
3734+
taprootBits := channeldb.SimpleTaprootFeatureBit |
3735+
channeldb.AnchorOutputsBit |
3736+
channeldb.ZeroHtlcTxFeeBit |
3737+
channeldb.SingleFunderTweaklessBit |
3738+
channeldb.TapscriptRootBit
3739+
3740+
testChanSyncOweRevocation(t, taprootBits)
3741+
})
36263742
}
36273743

36283744
func testChanSyncOweRevocationAndCommit(t *testing.T,
@@ -3752,6 +3868,14 @@ func testChanSyncOweRevocationAndCommit(t *testing.T,
37523868
bobNewCommit.HtlcSigs[i])
37533869
}
37543870
}
3871+
3872+
// If this is a taproot channel, then partial sig information
3873+
// should be present in the commit sig sent over. This
3874+
// signature will be re-regenerated, so we can't compare it
3875+
// with the old one.
3876+
if chanType.IsTaproot() {
3877+
require.True(t, bobReCommitSigMsg.PartialSig.IsSome())
3878+
}
37553879
}
37563880

37573881
// We expect Bob to send exactly two messages: first his revocation
@@ -3808,6 +3932,15 @@ func TestChanSyncOweRevocationAndCommit(t *testing.T) {
38083932

38093933
testChanSyncOweRevocationAndCommit(t, taprootBits)
38103934
})
3935+
t.Run("taproot with tapscript root", func(t *testing.T) {
3936+
taprootBits := channeldb.SimpleTaprootFeatureBit |
3937+
channeldb.AnchorOutputsBit |
3938+
channeldb.ZeroHtlcTxFeeBit |
3939+
channeldb.SingleFunderTweaklessBit |
3940+
channeldb.TapscriptRootBit
3941+
3942+
testChanSyncOweRevocationAndCommit(t, taprootBits)
3943+
})
38113944
}
38123945

38133946
func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T,
@@ -4039,6 +4172,17 @@ func TestChanSyncOweRevocationAndCommitForceTransition(t *testing.T) {
40394172
t, taprootBits,
40404173
)
40414174
})
4175+
t.Run("taproot with tapscript root", func(t *testing.T) {
4176+
taprootBits := channeldb.SimpleTaprootFeatureBit |
4177+
channeldb.AnchorOutputsBit |
4178+
channeldb.ZeroHtlcTxFeeBit |
4179+
channeldb.SingleFunderTweaklessBit |
4180+
channeldb.TapscriptRootBit
4181+
4182+
testChanSyncOweRevocationAndCommitForceTransition(
4183+
t, taprootBits,
4184+
)
4185+
})
40424186
}
40434187

40444188
// TestChanSyncFailure tests the various scenarios during channel sync where we

0 commit comments

Comments
 (0)