@@ -3024,19 +3024,11 @@ func restartChannel(channelOld *LightningChannel) (*LightningChannel, error) {
3024
3024
return channelNew , nil
3025
3025
}
3026
3026
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 ) {
3034
3028
// Create a test channel which will be used for the duration of this
3035
3029
// unittest. The channel will be funded evenly with Alice having 5 BTC,
3036
3030
// and Bob having 5 BTC.
3037
- aliceChannel , bobChannel , err := CreateTestChannels (
3038
- t , channeldb .SingleFunderTweaklessBit ,
3039
- )
3031
+ aliceChannel , bobChannel , err := CreateTestChannels (t , chanType )
3040
3032
require .NoError (t , err , "unable to create test channels" )
3041
3033
3042
3034
var fakeOnionBlob [lnwire .OnionPacketSize ]byte
@@ -3111,6 +3103,15 @@ func TestChanSyncOweCommitment(t *testing.T) {
3111
3103
aliceNewCommit , err := aliceChannel .SignNextCommitment ()
3112
3104
require .NoError (t , err , "unable to sign commitment" )
3113
3105
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
+
3114
3115
// Bob doesn't get this message so upon reconnection, they need to
3115
3116
// synchronize. Alice should conclude that she owes Bob a commitment,
3116
3117
// while Bob should think he's properly synchronized.
@@ -3122,7 +3123,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
3122
3123
// This is a helper function that asserts Alice concludes that she
3123
3124
// needs to retransmit the exact commitment that we failed to send
3124
3125
// above.
3125
- assertAliceCommitRetransmit := func () {
3126
+ assertAliceCommitRetransmit := func () * lnwire. CommitSig {
3126
3127
aliceMsgsToSend , _ , _ , err := aliceChannel .ProcessChanSyncMsg (
3127
3128
bobSyncMsg ,
3128
3129
)
@@ -3187,12 +3188,25 @@ func TestChanSyncOweCommitment(t *testing.T) {
3187
3188
len (commitSigMsg .HtlcSigs ))
3188
3189
}
3189
3190
for i , htlcSig := range commitSigMsg .HtlcSigs {
3190
- if htlcSig != aliceNewCommit .HtlcSigs [i ] {
3191
+ if ! bytes .Equal (htlcSig .RawBytes (),
3192
+ aliceNewCommit .HtlcSigs [i ].RawBytes ()) {
3193
+
3191
3194
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 ))
3194
3198
}
3195
3199
}
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
3196
3210
}
3197
3211
3198
3212
// Alice should detect that she needs to re-send 5 messages: the 3
@@ -3213,14 +3227,19 @@ func TestChanSyncOweCommitment(t *testing.T) {
3213
3227
// send the exact same set of messages.
3214
3228
aliceChannel , err = restartChannel (aliceChannel )
3215
3229
require .NoError (t , err , "unable to restart alice" )
3216
- assertAliceCommitRetransmit ()
3217
3230
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 ()
3219
3234
3220
3235
// At this point, we should be able to resume the prior state update
3221
3236
// without any issues, resulting in Alice settling the 3 htlc's, and
3222
3237
// 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
+ })
3224
3243
require .NoError (t , err , "bob unable to process alice's commitment" )
3225
3244
bobRevocation , _ , _ , err := bobChannel .RevokeCurrentCommitment ()
3226
3245
require .NoError (t , err , "unable to revoke bob commitment" )
@@ -3307,16 +3326,53 @@ func TestChanSyncOweCommitment(t *testing.T) {
3307
3326
}
3308
3327
}
3309
3328
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 ) {
3313
3334
t .Parallel ()
3314
3335
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
+
3315
3373
// Create a test channel which will be used for the duration of this
3316
3374
// unittest.
3317
- aliceChannel , bobChannel , err := CreateTestChannels (
3318
- t , channeldb .SingleFunderTweaklessBit ,
3319
- )
3375
+ aliceChannel , bobChannel , err := CreateTestChannels (t , chanType )
3320
3376
require .NoError (t , err , "unable to create test channels" )
3321
3377
3322
3378
var fakeOnionBlob [lnwire .OnionPacketSize ]byte
@@ -3399,6 +3455,12 @@ func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
3399
3455
bobChannel , err = restartChannel (bobChannel )
3400
3456
require .NoError (t , err , "unable to restart bob" )
3401
3457
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
+
3402
3464
// Bob signs the commitment he owes.
3403
3465
bobNewCommit , err := bobChannel .SignNextCommitment ()
3404
3466
require .NoError (t , err , "unable to sign commitment" )
@@ -3424,6 +3486,45 @@ func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
3424
3486
}
3425
3487
}
3426
3488
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
+
3427
3528
// testChanSyncOweRevocation is the internal version of
3428
3529
// TestChanSyncOweRevocation that is parameterized based on the type of channel
3429
3530
// being used in the test.
@@ -3573,8 +3674,6 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) {
3573
3674
3574
3675
assertAliceOwesRevoke ()
3575
3676
3576
- // TODO(roasbeef): restart bob too???
3577
-
3578
3677
// We'll continue by then allowing bob to process Alice's revocation
3579
3678
// message.
3580
3679
_ , _ , _ , _ , err = bobChannel .ReceiveRevocation (aliceRevocation )
@@ -3623,6 +3722,23 @@ func TestChanSyncOweRevocation(t *testing.T) {
3623
3722
3624
3723
testChanSyncOweRevocation (t , taprootBits )
3625
3724
})
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
+ })
3626
3742
}
3627
3743
3628
3744
func testChanSyncOweRevocationAndCommit (t * testing.T ,
@@ -3752,6 +3868,14 @@ func testChanSyncOweRevocationAndCommit(t *testing.T,
3752
3868
bobNewCommit .HtlcSigs [i ])
3753
3869
}
3754
3870
}
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
+ }
3755
3879
}
3756
3880
3757
3881
// We expect Bob to send exactly two messages: first his revocation
@@ -3808,6 +3932,15 @@ func TestChanSyncOweRevocationAndCommit(t *testing.T) {
3808
3932
3809
3933
testChanSyncOweRevocationAndCommit (t , taprootBits )
3810
3934
})
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
+ })
3811
3944
}
3812
3945
3813
3946
func testChanSyncOweRevocationAndCommitForceTransition (t * testing.T ,
@@ -4039,6 +4172,17 @@ func TestChanSyncOweRevocationAndCommitForceTransition(t *testing.T) {
4039
4172
t , taprootBits ,
4040
4173
)
4041
4174
})
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
+ })
4042
4186
}
4043
4187
4044
4188
// TestChanSyncFailure tests the various scenarios during channel sync where we
0 commit comments