lnwallet/channel: use FullySynced to check chanSync special case

We check if the channel is FullySynced instead of comparing the local
and remote commit chain heights, as the heights might not be in sync.
Instead we call FullySynced which recently was modified to use compare
the message indexes instead, which is _should_ really be in sync between
the chains.

The test TestChanSyncOweRevocationAndCommitForceTransition is altered to
ensure the two chains at different heights before the test is started, to
trigger the case that would previously fail to resend the commitment
signature.
This commit is contained in:
Johan T. Halseth 2018-06-04 14:29:37 +02:00
parent 2fa2644aec
commit 07629e5da1
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
2 changed files with 49 additions and 6 deletions

@ -3182,8 +3182,7 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
// but died before the signature was sent. We re-transmit our
// revocation, but also initiate a state transition to re-sync
// them.
if lc.localCommitChain.tip().height >
lc.remoteCommitChain.tip().height {
if !lc.FullySynced() {
commitSig, htlcSigs, err := lc.SignNextCommitment()
switch {

@ -3280,16 +3280,17 @@ func TestChanSyncOweRevocationAndCommitForceTransition(t *testing.T) {
var bobPreimage [32]byte
copy(bobPreimage[:], bytes.Repeat([]byte{0xaa}, 32))
rHash := sha256.Sum256(bobPreimage[:])
bobHtlc := &lnwire.UpdateAddHTLC{
var bobHtlc [2]*lnwire.UpdateAddHTLC
bobHtlc[0] = &lnwire.UpdateAddHTLC{
PaymentHash: rHash,
Amount: htlcAmt,
Expiry: uint32(10),
}
bobHtlcIndex, err := bobChannel.AddHTLC(bobHtlc, nil)
bobHtlcIndex, err := bobChannel.AddHTLC(bobHtlc[0], nil)
if err != nil {
t.Fatalf("unable to add bob's htlc: %v", err)
}
aliceHtlcIndex, err := aliceChannel.ReceiveHTLC(bobHtlc)
aliceHtlcIndex, err := aliceChannel.ReceiveHTLC(bobHtlc[0])
if err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
@ -3297,6 +3298,49 @@ func TestChanSyncOweRevocationAndCommitForceTransition(t *testing.T) {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
// To ensure the channel sync logic handles the case where the two
// commit chains are at different heights, we'll add another HTLC from
// Bob to Alice, but let Alice skip the commitment for this state
// update.
rHash = sha256.Sum256(bytes.Repeat([]byte{0xbb}, 32))
bobHtlc[1] = &lnwire.UpdateAddHTLC{
PaymentHash: rHash,
Amount: htlcAmt,
Expiry: uint32(10),
ID: 1,
}
_, err = bobChannel.AddHTLC(bobHtlc[1], nil)
if err != nil {
t.Fatalf("unable to add bob's htlc: %v", err)
}
_, err = aliceChannel.ReceiveHTLC(bobHtlc[1])
if err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
// Bob signs the new state update, and sends the signature to Alice.
bobSig, bobHtlcSigs, err := bobChannel.SignNextCommitment()
if err != nil {
t.Fatalf("bob unable to sign commitment: %v", err)
}
err = aliceChannel.ReceiveNewCommitment(bobSig, bobHtlcSigs)
if err != nil {
t.Fatalf("alice unable to rev bob's commitment: %v", err)
}
// Alice revokes her current state, but doesn't immediately send a
// signature for Bob's updated state. Instead she will issue a new
// update before sending a new CommitSig. This will lead to Alice's
// local commit chain getting height > remote commit chain.
aliceRevocation, _, err := aliceChannel.RevokeCurrentCommitment()
if err != nil {
t.Fatalf("alice unable to revoke commitment: %v", err)
}
if _, _, _, err := bobChannel.ReceiveRevocation(aliceRevocation); err != nil {
t.Fatalf("bob unable to recv revocation: %v", err)
}
// Next, Alice will settle that incoming HTLC, then we'll start the
// core of the test itself.
err = aliceChannel.SettleHTLC(bobPreimage, aliceHtlcIndex, nil, nil, nil)
@ -3433,7 +3477,7 @@ func TestChanSyncOweRevocationAndCommitForceTransition(t *testing.T) {
if err != nil {
t.Fatalf("alice unable to rev bob's commitment: %v", err)
}
aliceRevocation, _, err := aliceChannel.RevokeCurrentCommitment()
aliceRevocation, _, err = aliceChannel.RevokeCurrentCommitment()
if err != nil {
t.Fatalf("alice unable to revoke commitment: %v", err)
}