lnwallet: add regression test TestChannelUnsignedAckedFailure
This commit includes a regression test that checks that a force close won't occur and that unsigned acked updates are properly restored.
This commit is contained in:
parent
8c002a08a7
commit
b6eff5b0ec
@ -9096,3 +9096,119 @@ func TestProcessAddRemoveEntry(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestChannelUnsignedAckedFailure tests that unsigned acked updates are
|
||||
// properly restored after signing for them and disconnecting.
|
||||
//
|
||||
// The full state transition of this test is:
|
||||
//
|
||||
// Alice Bob
|
||||
// -----add----->
|
||||
// -----sig----->
|
||||
// <----rev------
|
||||
// <----sig------
|
||||
// -----rev----->
|
||||
// <----fail-----
|
||||
// <----sig------
|
||||
// -----rev----->
|
||||
// -----sig-----X (does not reach Bob! Alice dies!)
|
||||
//
|
||||
// -----sig----->
|
||||
// <----rev------
|
||||
// <----add------
|
||||
// <----sig------
|
||||
//
|
||||
// The last sig was rejected with the old behavior of deleting unsigned
|
||||
// acked updates from the database after signing for them. The current
|
||||
// behavior of filtering them for deletion upon receiving a revocation
|
||||
// causes Alice to accept the signature as valid.
|
||||
func TestChannelUnsignedAckedFailure(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create a test channel so that we can test the buggy behavior.
|
||||
aliceChannel, bobChannel, cleanUp, err := CreateTestChannels(
|
||||
channeldb.SingleFunderTweaklessBit,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer cleanUp()
|
||||
|
||||
// First we create an HTLC that Alice sends to Bob.
|
||||
htlc, _ := createHTLC(0, lnwire.MilliSatoshi(500000))
|
||||
|
||||
// -----add----->
|
||||
_, err = aliceChannel.AddHTLC(htlc, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = bobChannel.ReceiveHTLC(htlc)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Force a state transition to lock in this add on both commitments.
|
||||
// -----sig----->
|
||||
// <----rev------
|
||||
// <----sig------
|
||||
// -----rev----->
|
||||
err = ForceStateTransition(aliceChannel, bobChannel)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Now Bob should fail the htlc back to Alice.
|
||||
// <----fail-----
|
||||
err = bobChannel.FailHTLC(0, []byte("failreason"), nil, nil, nil)
|
||||
require.NoError(t, err)
|
||||
err = aliceChannel.ReceiveFailHTLC(0, []byte("bad"))
|
||||
require.NoError(t, err)
|
||||
|
||||
// Bob should send a commitment signature to Alice.
|
||||
// <----sig------
|
||||
bobSig, bobHtlcSigs, _, err := bobChannel.SignNextCommitment()
|
||||
require.NoError(t, err)
|
||||
err = aliceChannel.ReceiveNewCommitment(bobSig, bobHtlcSigs)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Alice should reply with a revocation.
|
||||
// -----rev----->
|
||||
aliceRevocation, _, err := aliceChannel.RevokeCurrentCommitment()
|
||||
require.NoError(t, err)
|
||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Alice should sign the next commitment and go down before
|
||||
// sending it.
|
||||
// -----sig-----X
|
||||
aliceSig, aliceHtlcSigs, _, err := aliceChannel.SignNextCommitment()
|
||||
require.NoError(t, err)
|
||||
|
||||
newAliceChannel, err := NewLightningChannel(
|
||||
aliceChannel.Signer, aliceChannel.channelState,
|
||||
aliceChannel.sigPool,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Bob receives Alice's signature.
|
||||
// -----sig----->
|
||||
err = bobChannel.ReceiveNewCommitment(aliceSig, aliceHtlcSigs)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Bob revokes his current commitment and sends a revocation
|
||||
// to Alice.
|
||||
// <----rev------
|
||||
bobRevocation, _, err := bobChannel.RevokeCurrentCommitment()
|
||||
require.NoError(t, err)
|
||||
_, _, _, _, err = newAliceChannel.ReceiveRevocation(bobRevocation)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Now Bob sends an HTLC to Alice.
|
||||
htlc2, _ := createHTLC(0, lnwire.MilliSatoshi(500000))
|
||||
|
||||
// <----add------
|
||||
_, err = bobChannel.AddHTLC(htlc2, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = newAliceChannel.ReceiveHTLC(htlc2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Bob sends the final signature to Alice and Alice should not
|
||||
// reject it, given that we properly restore the unsigned acked
|
||||
// updates and therefore our update log is structured correctly.
|
||||
bobSig, bobHtlcSigs, _, err = bobChannel.SignNextCommitment()
|
||||
require.NoError(t, err)
|
||||
err = newAliceChannel.ReceiveNewCommitment(bobSig, bobHtlcSigs)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user