Merge pull request #3872 from joostjager/invalid-sig-fix

htlcswitch+lnwallet+channeldb: invalid sig fix
This commit is contained in:
Joost Jager
2020-01-23 21:08:07 +01:00
committed by GitHub
5 changed files with 553 additions and 39 deletions

View File

@@ -19,6 +19,7 @@ import (
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
"github.com/lightningnetwork/lnd/lnwire"
)
@@ -3050,6 +3051,112 @@ func TestChanSyncOweCommitment(t *testing.T) {
}
}
// TestChanSyncOweCommitmentPendingRemote asserts that local updates are applied
// to the remote commit across restarts.
func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
t.Parallel()
// Create a test channel which will be used for the duration of this
// unittest.
aliceChannel, bobChannel, cleanUp, err := CreateTestChannels(true)
if err != nil {
t.Fatalf("unable to create test channels: %v", err)
}
defer cleanUp()
var fakeOnionBlob [lnwire.OnionPacketSize]byte
copy(fakeOnionBlob[:], bytes.Repeat([]byte{0x05}, lnwire.OnionPacketSize))
// We'll start off the scenario where Bob send two htlcs to Alice in a
// single state update.
var preimages []lntypes.Preimage
const numHtlcs = 2
for id := byte(0); id < numHtlcs; id++ {
htlcAmt := lnwire.NewMSatFromSatoshis(20000)
var bobPreimage [32]byte
copy(bobPreimage[:], bytes.Repeat([]byte{id}, 32))
rHash := sha256.Sum256(bobPreimage[:])
h := &lnwire.UpdateAddHTLC{
PaymentHash: rHash,
Amount: htlcAmt,
Expiry: uint32(10),
OnionBlob: fakeOnionBlob,
}
htlcIndex, err := bobChannel.AddHTLC(h, nil)
if err != nil {
t.Fatalf("unable to add bob's htlc: %v", err)
}
h.ID = htlcIndex
if _, err := aliceChannel.ReceiveHTLC(h); err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
preimages = append(preimages, bobPreimage)
}
// With the HTLCs applied to both update logs, we'll initiate a state
// transition from Bob.
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
// Next, Alice settles the HTLCs from Bob in distinct state updates.
for i := 0; i < numHtlcs; i++ {
err = aliceChannel.SettleHTLC(preimages[i], uint64(i), nil, nil, nil)
if err != nil {
t.Fatalf("unable to settle htlc: %v", err)
}
err = bobChannel.ReceiveHTLCSettle(preimages[i], uint64(i))
if err != nil {
t.Fatalf("unable to settle htlc: %v", err)
}
aliceSig, aliceHtlcSigs, _, err := aliceChannel.SignNextCommitment()
if err != nil {
t.Fatalf("unable to sign commitment: %v", err)
}
err = bobChannel.ReceiveNewCommitment(aliceSig, aliceHtlcSigs)
if err != nil {
t.Fatalf("unable to receive commitment: %v", err)
}
// Bob revokes his current commitment. After this call
// completes, the htlc is settled on the local commitment
// transaction. Bob still owes Alice a signature to also settle
// the htlc on her local commitment transaction.
bobRevoke, _, err := bobChannel.RevokeCurrentCommitment()
if err != nil {
t.Fatalf("unable to revoke commitment: %v", err)
}
_, _, _, _, err = aliceChannel.ReceiveRevocation(bobRevoke)
if err != nil {
t.Fatalf("unable to revoke commitment: %v", err)
}
}
// We restart Bob. This should have no impact on further message that
// are generated.
bobChannel, err = restartChannel(bobChannel)
if err != nil {
t.Fatalf("unable to restart bob: %v", err)
}
// Bob signs the commitment he owes.
_, bobHtlcSigs, _, err := bobChannel.SignNextCommitment()
if err != nil {
t.Fatalf("unable to sign commitment: %v", err)
}
// This commitment is expected to contain no htlcs anymore.
if len(bobHtlcSigs) != 0 {
t.Fatalf("no htlcs expected, but got %v", len(bobHtlcSigs))
}
}
// TestChanSyncOweRevocation tests that if Bob restarts (and then Alice) before
// he receiver's Alice's RevokeAndAck message, then Alice concludes that she
// needs to re-send the RevokeAndAck. After the revocation has been sent, both
@@ -6178,9 +6285,11 @@ func TestChannelRestoreUpdateLogsFailedHTLC(t *testing.T) {
// At this point Alice has advanced her local commitment chain to a
// commitment with no HTLCs left. The current state on her remote
// commitment chain, however, still has the HTLC active, as she hasn't
// sent a new signature yet.
// sent a new signature yet. If we'd now restart and restore, the htlc
// failure update should still be waiting for inclusion in Alice's next
// signature. Otherwise the produced signature would be invalid.
assertInLogs(t, aliceChannel, 1, 0, 0, 1)
restoreAndAssert(t, aliceChannel, 1, 0, 0, 0)
restoreAndAssert(t, aliceChannel, 1, 0, 0, 1)
// Now send a signature from Alice. This will give Bob a new commitment
// where the HTLC is removed.