@@ -108,8 +108,10 @@ type ChannelLinkConfig struct {
108
108
// blobs, which are then used to inform how to forward an HTLC.
109
109
//
110
110
// NOTE: This function assumes the same set of readers and preimages
111
- // are always presented for the same identifier.
112
- DecodeHopIterators func ([]byte , []hop.DecodeHopIteratorRequest ) (
111
+ // are always presented for the same identifier. The last boolean is
112
+ // used to decide whether this is a reforwarding or not - when it's
113
+ // reforwarding, we skip the replay check enforced in our decay log.
114
+ DecodeHopIterators func ([]byte , []hop.DecodeHopIteratorRequest , bool ) (
113
115
[]hop.DecodeHopIteratorResponse , error )
114
116
115
117
// ExtractErrorEncrypter function is responsible for decoding HTLC
@@ -3630,6 +3632,13 @@ func (l *channelLink) processRemoteSettleFails(fwdPkg *channeldb.FwdPkg) {
3630
3632
return
3631
3633
}
3632
3634
3635
+ // Exit early if the fwdPkg is already processed.
3636
+ if fwdPkg .State == channeldb .FwdStateCompleted {
3637
+ l .log .Debugf ("skipped processing completed fwdPkg %v" , fwdPkg )
3638
+
3639
+ return
3640
+ }
3641
+
3633
3642
l .log .Debugf ("settle-fail-filter: %v" , fwdPkg .SettleFailFilter )
3634
3643
3635
3644
var switchPackets []* htlcPacket
@@ -3738,13 +3747,36 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
3738
3747
return
3739
3748
}
3740
3749
3750
+ // Exit early if the fwdPkg is already processed.
3751
+ if fwdPkg .State == channeldb .FwdStateCompleted {
3752
+ l .log .Debugf ("skipped processing completed fwdPkg %v" , fwdPkg )
3753
+
3754
+ return
3755
+ }
3756
+
3741
3757
l .log .Tracef ("processing %d remote adds for height %d" ,
3742
3758
len (fwdPkg .Adds ), fwdPkg .Height )
3743
3759
3744
- decodeReqs := make (
3745
- []hop.DecodeHopIteratorRequest , 0 , len (fwdPkg .Adds ),
3746
- )
3747
- for _ , update := range fwdPkg .Adds {
3760
+ // decodeReqs is a list of requests sent to the onion decoder. We expect
3761
+ // the same length of responses to be returned.
3762
+ decodeReqs := make ([]hop.DecodeHopIteratorRequest , 0 , len (fwdPkg .Adds ))
3763
+
3764
+ // unackedAdds is a list of ADDs that's waiting for the remote's
3765
+ // settle/fail update.
3766
+ unackedAdds := make ([]* lnwire.UpdateAddHTLC , 0 , len (fwdPkg .Adds ))
3767
+
3768
+ for i , update := range fwdPkg .Adds {
3769
+ // If this index is already found in the ack filter, the
3770
+ // response to this forwarding decision has already been
3771
+ // committed by one of our commitment txns. ADDs in this state
3772
+ // are waiting for the rest of the fwding package to get acked
3773
+ // before being garbage collected.
3774
+ if fwdPkg .State == channeldb .FwdStateProcessed &&
3775
+ fwdPkg .AckFilter .Contains (uint16 (i )) {
3776
+
3777
+ continue
3778
+ }
3779
+
3748
3780
if msg , ok := update .UpdateMsg .(* lnwire.UpdateAddHTLC ); ok {
3749
3781
// Before adding the new htlc to the state machine,
3750
3782
// parse the onion object in order to obtain the
@@ -3761,15 +3793,20 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
3761
3793
}
3762
3794
3763
3795
decodeReqs = append (decodeReqs , req )
3796
+ unackedAdds = append (unackedAdds , msg )
3764
3797
}
3765
3798
}
3766
3799
3800
+ // If the fwdPkg has already been processed, it means we are
3801
+ // reforwarding the packets again, which happens only on a restart.
3802
+ reforward := fwdPkg .State == channeldb .FwdStateProcessed
3803
+
3767
3804
// Atomically decode the incoming htlcs, simultaneously checking for
3768
3805
// replay attempts. A particular index in the returned, spare list of
3769
3806
// channel iterators should only be used if the failure code at the
3770
3807
// same index is lnwire.FailCodeNone.
3771
3808
decodeResps , sphinxErr := l .cfg .DecodeHopIterators (
3772
- fwdPkg .ID (), decodeReqs ,
3809
+ fwdPkg .ID (), decodeReqs , reforward ,
3773
3810
)
3774
3811
if sphinxErr != nil {
3775
3812
l .failf (LinkFailureError {code : ErrInternalError },
@@ -3779,23 +3816,10 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
3779
3816
3780
3817
var switchPackets []* htlcPacket
3781
3818
3782
- for i , update := range fwdPkg . Adds {
3819
+ for i , update := range unackedAdds {
3783
3820
idx := uint16 (i )
3784
-
3785
- //nolint:forcetypeassert
3786
- add := * update .UpdateMsg .(* lnwire.UpdateAddHTLC )
3787
3821
sourceRef := fwdPkg .SourceRef (idx )
3788
-
3789
- if fwdPkg .State == channeldb .FwdStateProcessed &&
3790
- fwdPkg .AckFilter .Contains (idx ) {
3791
-
3792
- // If this index is already found in the ack filter,
3793
- // the response to this forwarding decision has already
3794
- // been committed by one of our commitment txns. ADDs
3795
- // in this state are waiting for the rest of the fwding
3796
- // package to get acked before being garbage collected.
3797
- continue
3798
- }
3822
+ add := * update
3799
3823
3800
3824
// An incoming HTLC add has been full-locked in. As a result we
3801
3825
// can now examine the forwarding details of the HTLC, and the
@@ -3815,8 +3839,10 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
3815
3839
add .ID , failureCode , add .OnionBlob , & sourceRef ,
3816
3840
)
3817
3841
3818
- l .log .Errorf ("unable to decode onion hop " +
3819
- "iterator: %v" , failureCode )
3842
+ l .log .Errorf ("unable to decode onion hop iterator " +
3843
+ "for htlc(id=%v, hash=%x): %v" , add .ID ,
3844
+ add .PaymentHash , failureCode )
3845
+
3820
3846
continue
3821
3847
}
3822
3848
@@ -4120,17 +4146,15 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
4120
4146
return
4121
4147
}
4122
4148
4123
- replay := fwdPkg .State != channeldb .FwdStateLockedIn
4124
-
4125
- l .log .Debugf ("forwarding %d packets to switch: replay=%v" ,
4126
- len (switchPackets ), replay )
4149
+ l .log .Debugf ("forwarding %d packets to switch: reforward=%v" ,
4150
+ len (switchPackets ), reforward )
4127
4151
4128
4152
// NOTE: This call is made synchronous so that we ensure all circuits
4129
4153
// are committed in the exact order that they are processed in the link.
4130
4154
// Failing to do this could cause reorderings/gaps in the range of
4131
4155
// opened circuits, which violates assumptions made by the circuit
4132
4156
// trimming.
4133
- l .forwardBatch (replay , switchPackets ... )
4157
+ l .forwardBatch (reforward , switchPackets ... )
4134
4158
}
4135
4159
4136
4160
// experimentalEndorsement returns the value to set for our outgoing
0 commit comments