htlcswitch: drop the connection when receiving an invalid add

When the link is flushing in the incoming direction, it means
adds are invalid. The best chance we have at dealing with this
is to drop the connection. This should roll back the channel
state to the last CommitSig. If the remote has already sent a
CommitSig we haven't received yet, channel state will be
re-synchronized with a ChannelReestablish message upon
reconnection and the protocol state that caused us to flush
the link will be rolled back. In the event that there was some
non-deterministic behavior in the remote that caused them to
violate the protocol, we have a decent shot at correcting it
this way, since reconnecting will put us in the cleanest
possible state to try again.
This commit is contained in:
Keagan McClelland 2023-12-08 15:10:30 -08:00
parent a9d5235c62
commit 891b00d473

View File

@ -1786,6 +1786,39 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
switch msg := msg.(type) { switch msg := msg.(type) {
case *lnwire.UpdateAddHTLC: case *lnwire.UpdateAddHTLC:
if l.IsFlushing(Incoming) {
// This is forbidden by the protocol specification.
// The best chance we have to deal with this is to drop
// the connection. This should roll back the channel
// state to the last CommitSig. If the remote has
// already sent a CommitSig we haven't received yet,
// channel state will be re-synchronized with a
// ChannelReestablish message upon reconnection and the
// protocol state that caused us to flush the link will
// be rolled back. In the event that there was some
// non-deterministic behavior in the remote that caused
// them to violate the protocol, we have a decent shot
// at correcting it this way, since reconnecting will
// put us in the cleanest possible state to try again.
//
// In addition to the above, it is possible for us to
// hit this case in situations where we improperly
// handle message ordering due to concurrency choices.
// An issue has been filed to address this here:
// https://github.com/lightningnetwork/lnd/issues/8393
l.fail(
LinkFailureError{
code: ErrInvalidUpdate,
FailureAction: LinkFailureDisconnect,
PermanentFailure: false,
Warning: true,
},
"received add while link is flushing",
)
return
}
// We just received an add request from an upstream peer, so we // We just received an add request from an upstream peer, so we
// add it to our state machine, then add the HTLC to our // add it to our state machine, then add the HTLC to our
// "settle" list in the event that we know the preimage. // "settle" list in the event that we know the preimage.