Merge pull request #10035 from ziggie1984/fix-switch-deadlock

fix switch deadlock
This commit is contained in:
Yong
2025-07-04 16:35:20 +03:00
committed by GitHub
2 changed files with 9 additions and 1 deletions

View File

@ -37,6 +37,8 @@
could lead to a memory issues due to a goroutine leak in the peer/gossiper could lead to a memory issues due to a goroutine leak in the peer/gossiper
code. code.
- [Fixed](https://github.com/lightningnetwork/lnd/pull/10035) a deadlock (writer starvation) in the switch.
# New Features # New Features
## Functional Enhancements ## Functional Enhancements

View File

@ -880,7 +880,6 @@ func (s *Switch) getLocalLink(pkt *htlcPacket, htlc *lnwire.UpdateAddHTLC) (
// Try to find links by node destination. // Try to find links by node destination.
s.indexMtx.RLock() s.indexMtx.RLock()
link, err := s.getLinkByShortID(pkt.outgoingChanID) link, err := s.getLinkByShortID(pkt.outgoingChanID)
defer s.indexMtx.RUnlock()
if err != nil { if err != nil {
// If the link was not found for the outgoingChanID, an outside // If the link was not found for the outgoingChanID, an outside
// subsystem may be using the confirmed SCID of a zero-conf // subsystem may be using the confirmed SCID of a zero-conf
@ -892,6 +891,7 @@ func (s *Switch) getLocalLink(pkt *htlcPacket, htlc *lnwire.UpdateAddHTLC) (
// do that upon receiving the packet. // do that upon receiving the packet.
baseScid, ok := s.baseIndex[pkt.outgoingChanID] baseScid, ok := s.baseIndex[pkt.outgoingChanID]
if !ok { if !ok {
s.indexMtx.RUnlock()
log.Errorf("Link %v not found", pkt.outgoingChanID) log.Errorf("Link %v not found", pkt.outgoingChanID)
return nil, NewLinkError(&lnwire.FailUnknownNextPeer{}) return nil, NewLinkError(&lnwire.FailUnknownNextPeer{})
} }
@ -900,10 +900,15 @@ func (s *Switch) getLocalLink(pkt *htlcPacket, htlc *lnwire.UpdateAddHTLC) (
// link. // link.
link, err = s.getLinkByShortID(baseScid) link, err = s.getLinkByShortID(baseScid)
if err != nil { if err != nil {
s.indexMtx.RUnlock()
log.Errorf("Link %v not found", baseScid) log.Errorf("Link %v not found", baseScid)
return nil, NewLinkError(&lnwire.FailUnknownNextPeer{}) return nil, NewLinkError(&lnwire.FailUnknownNextPeer{})
} }
} }
// We finished looking up the indexes, so we can unlock the mutex before
// performing the link operations which might also acquire the lock
// in case e.g. failAliasUpdate is called.
s.indexMtx.RUnlock()
if !link.EligibleToForward() { if !link.EligibleToForward() {
log.Errorf("Link %v is not available to forward", log.Errorf("Link %v is not available to forward",
@ -928,6 +933,7 @@ func (s *Switch) getLocalLink(pkt *htlcPacket, htlc *lnwire.UpdateAddHTLC) (
"satisfied", pkt.outgoingChanID) "satisfied", pkt.outgoingChanID)
return nil, htlcErr return nil, htlcErr
} }
return link, nil return link, nil
} }