mirror of
https://github.com/aljazceru/breez-lnd.git
synced 2025-12-18 14:44:22 +01:00
Merge pull request #3872 from joostjager/invalid-sig-fix
htlcswitch+lnwallet+channeldb: invalid sig fix
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user