mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-05-21 17:20:03 +02:00
htlcswitch: check for signature owed in link
Previously the channel method FullySynced was used to decide whether to send a new commit sig message. However, it could happen that FullySynced was false, but that we didn't owe a commitment signature. Instead we were waiting on the other party to send us a signature. If that happened, we'd send out an empty commit sig. This commit modifies the condition that triggers a new commit sig and fixes this deviation from the spec.
This commit is contained in:
parent
64f4421d6c
commit
f59b4d62bf
@ -1103,7 +1103,7 @@ out:
|
|||||||
// update in some time, check to see if we have any
|
// update in some time, check to see if we have any
|
||||||
// pending updates we need to commit due to our
|
// pending updates we need to commit due to our
|
||||||
// commitment chains being desynchronized.
|
// commitment chains being desynchronized.
|
||||||
if l.channel.FullySynced() {
|
if !l.channel.OweCommitment(true) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1808,7 +1808,7 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
|
|||||||
// If both commitment chains are fully synced from our PoV,
|
// If both commitment chains are fully synced from our PoV,
|
||||||
// then we don't need to reply with a signature as both sides
|
// then we don't need to reply with a signature as both sides
|
||||||
// already have a commitment with the latest accepted.
|
// already have a commitment with the latest accepted.
|
||||||
if l.channel.FullySynced() {
|
if !l.channel.OweCommitment(true) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4699,11 +4699,10 @@ func TestChannelLinkNoEmptySig(t *testing.T) {
|
|||||||
ctx.receiveRevAndAckAliceToBob()
|
ctx.receiveRevAndAckAliceToBob()
|
||||||
ctx.sendRevAndAckBobToAlice()
|
ctx.sendRevAndAckBobToAlice()
|
||||||
|
|
||||||
// The situation now is that Alice still doesn't have her two htlcs on
|
// The commit txes are not in sync, but it is Bob's turn to send a new
|
||||||
// the local commit tx. Bob needs to send a new signature and Alice can
|
// signature. We don't expect Alice to send out any message. This check
|
||||||
// only wait for that. However, Alice's log commit timer fires and Alice
|
// allows some time for the log commit ticker to trigger for Alice.
|
||||||
// sends a commitment tx containing no updates. THIS SHOULD NOT HAPPEN!
|
ctx.assertNoMsgFromAlice(time.Second)
|
||||||
ctx.receiveCommitSigAliceToBob(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestChannelLinkBatchPreimageWrite asserts that a link will batch preimage
|
// TestChannelLinkBatchPreimageWrite asserts that a link will batch preimage
|
||||||
@ -6109,9 +6108,8 @@ func TestChannelLinkReceiveEmptySig(t *testing.T) {
|
|||||||
// Send RevokeAndAck Bob->Alice to ack the added htlc.
|
// Send RevokeAndAck Bob->Alice to ack the added htlc.
|
||||||
ctx.sendRevAndAckBobToAlice()
|
ctx.sendRevAndAckBobToAlice()
|
||||||
|
|
||||||
// No new updates to sign, Alice still sends out an empty sig. THIS
|
// We received an empty commit sig, we accepted it, but there is nothing
|
||||||
// SHOULD NOT HAPPEN!
|
// new to sign for us.
|
||||||
ctx.receiveCommitSigAliceToBob(1)
|
|
||||||
|
|
||||||
// No other messages are expected.
|
// No other messages are expected.
|
||||||
ctx.assertNoMsgFromAlice(time.Second)
|
ctx.assertNoMsgFromAlice(time.Second)
|
||||||
|
@ -3535,7 +3535,7 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
|
|||||||
// but died before the signature was sent. We re-transmit our
|
// but died before the signature was sent. We re-transmit our
|
||||||
// revocation, but also initiate a state transition to re-sync
|
// revocation, but also initiate a state transition to re-sync
|
||||||
// them.
|
// them.
|
||||||
if !lc.FullySynced() {
|
if lc.OweCommitment(true) {
|
||||||
commitSig, htlcSigs, _, err := lc.SignNextCommitment()
|
commitSig, htlcSigs, _, err := lc.SignNextCommitment()
|
||||||
switch {
|
switch {
|
||||||
|
|
||||||
@ -4225,26 +4225,6 @@ func (lc *LightningChannel) oweCommitment(local bool) bool {
|
|||||||
return oweCommitment
|
return oweCommitment
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullySynced returns a boolean value reflecting if both commitment chains
|
|
||||||
// (remote+local) are fully in sync. Both commitment chains are fully in sync
|
|
||||||
// if the tip of each chain includes the latest committed changes from both
|
|
||||||
// sides.
|
|
||||||
func (lc *LightningChannel) FullySynced() bool {
|
|
||||||
lc.RLock()
|
|
||||||
defer lc.RUnlock()
|
|
||||||
|
|
||||||
lastLocalCommit := lc.localCommitChain.tip()
|
|
||||||
lastRemoteCommit := lc.remoteCommitChain.tip()
|
|
||||||
|
|
||||||
localUpdatesSynced := (lastLocalCommit.ourMessageIndex ==
|
|
||||||
lastRemoteCommit.ourMessageIndex)
|
|
||||||
|
|
||||||
remoteUpdatesSynced := (lastLocalCommit.theirMessageIndex ==
|
|
||||||
lastRemoteCommit.theirMessageIndex)
|
|
||||||
|
|
||||||
return localUpdatesSynced && remoteUpdatesSynced
|
|
||||||
}
|
|
||||||
|
|
||||||
// RevokeCurrentCommitment revokes the next lowest unrevoked commitment
|
// RevokeCurrentCommitment revokes the next lowest unrevoked commitment
|
||||||
// transaction in the local commitment chain. As a result the edge of our
|
// transaction in the local commitment chain. As a result the edge of our
|
||||||
// revocation window is extended by one, and the tail of our local commitment
|
// revocation window is extended by one, and the tail of our local commitment
|
||||||
|
Loading…
x
Reference in New Issue
Block a user