@@ -2780,28 +2780,43 @@ func (l *channelLink) UpdateForwardingPolicy(
2780
2780
func (l * channelLink ) CheckHtlcForward (payHash [32 ]byte ,
2781
2781
incomingHtlcAmt , amtToForward lnwire.MilliSatoshi ,
2782
2782
incomingTimeout , outgoingTimeout uint32 ,
2783
+ inboundFee models.InboundFee ,
2783
2784
heightNow uint32 , originalScid lnwire.ShortChannelID ) * LinkError {
2784
2785
2785
2786
l .RLock ()
2786
2787
policy := l .cfg .FwrdingPolicy
2787
2788
l .RUnlock ()
2788
2789
2789
- // Using the amount of the incoming HTLC, we'll calculate the expected
2790
- // fee this incoming HTLC must carry in order to satisfy the
2791
- // constraints of the outgoing link.
2792
- expectedFee := ExpectedFee (policy , amtToForward )
2790
+ // Using the outgoing HTLC amount, we'll calculate the outgoing
2791
+ // fee this incoming HTLC must carry in order to satisfy the constraints
2792
+ // of the outgoing link.
2793
+ outFee := ExpectedFee (policy , amtToForward )
2794
+
2795
+ // Then calculate the inbound fee that we charge based on the sum of
2796
+ // outgoing HTLC amount and outgoing fee.
2797
+ inFee := inboundFee .CalcFee (amtToForward + outFee )
2798
+
2799
+ // Add up both fee components. It is important to calculate both fees
2800
+ // separately. An alternative way of calculating is to first determine
2801
+ // an aggregate fee and apply that to the outgoing HTLC amount. However,
2802
+ // rounding may cause the result to be slightly higher than in the case
2803
+ // of separately rounded fee components. This potentially causes failed
2804
+ // forwards for senders and is something to be avoided.
2805
+ expectedFee := inFee + int64 (outFee )
2793
2806
2794
2807
// If the actual fee is less than our expected fee, then we'll reject
2795
2808
// this HTLC as it didn't provide a sufficient amount of fees, or the
2796
2809
// values have been tampered with, or the send used incorrect/dated
2797
2810
// information to construct the forwarding information for this hop. In
2798
- // any case, we'll cancel this HTLC. We're checking for this case first
2799
- // to leak as little information as possible.
2800
- actualFee := incomingHtlcAmt - amtToForward
2811
+ // any case, we'll cancel this HTLC.
2812
+ actualFee := int64 (incomingHtlcAmt ) - int64 (amtToForward )
2801
2813
if incomingHtlcAmt < amtToForward || actualFee < expectedFee {
2802
2814
l .log .Warnf ("outgoing htlc(%x) has insufficient fee: " +
2803
- "expected %v, got %v" ,
2804
- payHash [:], int64 (expectedFee ), int64 (actualFee ))
2815
+ "expected %v, got %v: incoming=%v, outgoing=%v, " +
2816
+ "inboundFee=%v" ,
2817
+ payHash [:], expectedFee , actualFee ,
2818
+ incomingHtlcAmt , amtToForward , inboundFee ,
2819
+ )
2805
2820
2806
2821
// As part of the returned error, we'll send our latest routing
2807
2822
// policy so the sending node obtains the most up to date data.
@@ -3330,6 +3345,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3330
3345
// round of processing.
3331
3346
chanIterator .EncodeNextHop (buf )
3332
3347
3348
+ inboundFee := l .cfg .FwrdingPolicy .InboundFee
3349
+
3333
3350
updatePacket := & htlcPacket {
3334
3351
incomingChanID : l .ShortChanID (),
3335
3352
incomingHTLCID : pd .HtlcIndex ,
@@ -3342,6 +3359,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3342
3359
incomingTimeout : pd .Timeout ,
3343
3360
outgoingTimeout : fwdInfo .OutgoingCTLV ,
3344
3361
customRecords : pld .CustomRecords (),
3362
+ inboundFee : inboundFee ,
3345
3363
}
3346
3364
switchPackets = append (
3347
3365
switchPackets , updatePacket ,
@@ -3394,6 +3412,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3394
3412
// have been added to switchPackets at the top of this
3395
3413
// section.
3396
3414
if fwdPkg .State == channeldb .FwdStateLockedIn {
3415
+ inboundFee := l .cfg .FwrdingPolicy .InboundFee
3416
+
3397
3417
updatePacket := & htlcPacket {
3398
3418
incomingChanID : l .ShortChanID (),
3399
3419
incomingHTLCID : pd .HtlcIndex ,
@@ -3406,6 +3426,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3406
3426
incomingTimeout : pd .Timeout ,
3407
3427
outgoingTimeout : fwdInfo .OutgoingCTLV ,
3408
3428
customRecords : pld .CustomRecords (),
3429
+ inboundFee : inboundFee ,
3409
3430
}
3410
3431
3411
3432
fwdPkg .FwdFilter .Set (idx )
0 commit comments