@@ -2546,28 +2546,43 @@ func (l *channelLink) UpdateForwardingPolicy(
2546
2546
func (l * channelLink ) CheckHtlcForward (payHash [32 ]byte ,
2547
2547
incomingHtlcAmt , amtToForward lnwire.MilliSatoshi ,
2548
2548
incomingTimeout , outgoingTimeout uint32 ,
2549
+ inboundFee models.InboundFee ,
2549
2550
heightNow uint32 , originalScid lnwire.ShortChannelID ) * LinkError {
2550
2551
2551
2552
l .RLock ()
2552
2553
policy := l .cfg .FwrdingPolicy
2553
2554
l .RUnlock ()
2554
2555
2555
- // Using the amount of the incoming HTLC, we'll calculate the expected
2556
- // fee this incoming HTLC must carry in order to satisfy the
2557
- // constraints of the outgoing link.
2558
- expectedFee := ExpectedFee (policy , amtToForward )
2556
+ // Using the outgoing HTLC amount, we'll calculate the outgoing
2557
+ // fee this incoming HTLC must carry in order to satisfy the constraints
2558
+ // of the outgoing link.
2559
+ outFee := ExpectedFee (policy , amtToForward )
2560
+
2561
+ // Then calculate the inbound fee that we charge based on the sum of
2562
+ // outgoing HTLC amount and outgoing fee.
2563
+ inFee := inboundFee .CalcFee (amtToForward + outFee )
2564
+
2565
+ // Add up both fee components. It is important to calculate both fees
2566
+ // separately. An alternative way of calculating is to first determine
2567
+ // an aggregate fee and apply that to the outgoing HTLC amount. However,
2568
+ // rounding may cause the result to be slightly higher than in the case
2569
+ // of separately rounded fee components. This potentially causes failed
2570
+ // forwards for senders and is something to be avoided.
2571
+ expectedFee := inFee + int64 (outFee )
2559
2572
2560
2573
// If the actual fee is less than our expected fee, then we'll reject
2561
2574
// this HTLC as it didn't provide a sufficient amount of fees, or the
2562
2575
// values have been tampered with, or the send used incorrect/dated
2563
2576
// information to construct the forwarding information for this hop. In
2564
- // any case, we'll cancel this HTLC. We're checking for this case first
2565
- // to leak as little information as possible.
2566
- actualFee := incomingHtlcAmt - amtToForward
2577
+ // any case, we'll cancel this HTLC.
2578
+ actualFee := int64 (incomingHtlcAmt ) - int64 (amtToForward )
2567
2579
if incomingHtlcAmt < amtToForward || actualFee < expectedFee {
2568
2580
l .log .Warnf ("outgoing htlc(%x) has insufficient fee: " +
2569
- "expected %v, got %v" ,
2570
- payHash [:], int64 (expectedFee ), int64 (actualFee ))
2581
+ "expected %v, got %v: incoming=%v, outgoing=%v, " +
2582
+ "inboundFee=%v" ,
2583
+ payHash [:], expectedFee , actualFee ,
2584
+ incomingHtlcAmt , amtToForward , inboundFee ,
2585
+ )
2571
2586
2572
2587
// As part of the returned error, we'll send our latest routing
2573
2588
// policy so the sending node obtains the most up to date data.
@@ -3114,6 +3129,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3114
3129
// round of processing.
3115
3130
chanIterator .EncodeNextHop (buf )
3116
3131
3132
+ inboundFee := l .cfg .FwrdingPolicy .InboundFee
3133
+
3117
3134
updatePacket := & htlcPacket {
3118
3135
incomingChanID : l .ShortChanID (),
3119
3136
incomingHTLCID : pd .HtlcIndex ,
@@ -3126,6 +3143,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3126
3143
incomingTimeout : pd .Timeout ,
3127
3144
outgoingTimeout : fwdInfo .OutgoingCTLV ,
3128
3145
customRecords : pld .CustomRecords (),
3146
+ inboundFee : inboundFee ,
3129
3147
}
3130
3148
switchPackets = append (
3131
3149
switchPackets , updatePacket ,
@@ -3178,6 +3196,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3178
3196
// have been added to switchPackets at the top of this
3179
3197
// section.
3180
3198
if fwdPkg .State == channeldb .FwdStateLockedIn {
3199
+ inboundFee := l .cfg .FwrdingPolicy .InboundFee
3200
+
3181
3201
updatePacket := & htlcPacket {
3182
3202
incomingChanID : l .ShortChanID (),
3183
3203
incomingHTLCID : pd .HtlcIndex ,
@@ -3190,6 +3210,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
3190
3210
incomingTimeout : pd .Timeout ,
3191
3211
outgoingTimeout : fwdInfo .OutgoingCTLV ,
3192
3212
customRecords : pld .CustomRecords (),
3213
+ inboundFee : inboundFee ,
3193
3214
}
3194
3215
3195
3216
fwdPkg .FwdFilter .Set (idx )
0 commit comments