From 755bb09a73f9b996951a455f49f598b320e292c2 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 11 Jun 2025 16:36:52 +0800 Subject: [PATCH] htlcswitch: skip decoding hop if the htlc is already acked We now move the check earlier in the loop so we don't even need to decode the hop for already processed ADDs. --- htlcswitch/link.go | 48 ++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 33bf1805d..d2bc4f4bf 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -3757,10 +3757,26 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) { l.log.Tracef("processing %d remote adds for height %d", len(fwdPkg.Adds), fwdPkg.Height) - decodeReqs := make( - []hop.DecodeHopIteratorRequest, 0, len(fwdPkg.Adds), - ) - for _, update := range fwdPkg.Adds { + // decodeReqs is a list of requests sent to the onion decoder. We expect + // the same length of responses to be returned. + decodeReqs := make([]hop.DecodeHopIteratorRequest, 0, len(fwdPkg.Adds)) + + // unackedAdds is a list of ADDs that's waiting for the remote's + // settle/fail update. + unackedAdds := make([]*lnwire.UpdateAddHTLC, 0, len(fwdPkg.Adds)) + + for i, update := range fwdPkg.Adds { + // If this index is already found in the ack filter, the + // response to this forwarding decision has already been + // committed by one of our commitment txns. ADDs in this state + // are waiting for the rest of the fwding package to get acked + // before being garbage collected. + if fwdPkg.State == channeldb.FwdStateProcessed && + fwdPkg.AckFilter.Contains(uint16(i)) { + + continue + } + if msg, ok := update.UpdateMsg.(*lnwire.UpdateAddHTLC); ok { // Before adding the new htlc to the state machine, // parse the onion object in order to obtain the @@ -3777,6 +3793,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) { } decodeReqs = append(decodeReqs, req) + unackedAdds = append(unackedAdds, msg) } } @@ -3799,23 +3816,10 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) { var switchPackets []*htlcPacket - for i, update := range fwdPkg.Adds { + for i, update := range unackedAdds { idx := uint16(i) - - //nolint:forcetypeassert - add := *update.UpdateMsg.(*lnwire.UpdateAddHTLC) sourceRef := fwdPkg.SourceRef(idx) - - if fwdPkg.State == channeldb.FwdStateProcessed && - fwdPkg.AckFilter.Contains(idx) { - - // If this index is already found in the ack filter, - // the response to this forwarding decision has already - // been committed by one of our commitment txns. ADDs - // in this state are waiting for the rest of the fwding - // package to get acked before being garbage collected. - continue - } + add := *update // An incoming HTLC add has been full-locked in. As a result we // can now examine the forwarding details of the HTLC, and the @@ -3835,8 +3839,10 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) { add.ID, failureCode, add.OnionBlob, &sourceRef, ) - l.log.Errorf("unable to decode onion hop "+ - "iterator: %v", failureCode) + l.log.Errorf("unable to decode onion hop iterator "+ + "for htlc(id=%v, hash=%x): %v", add.ID, + add.PaymentHash, failureCode) + continue }