mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
routing: account for blinded routes in fee calculation
When we introduce blinded routes, some of our hops are expected to have zero amounts to forward in their hop payload. This commit updates our hop fee logic to attribute the full blinded route's fees to the introduction node. We can't actually know where/how these fees are distributed, so we collect them all at the introduction node.
This commit is contained in:
parent
940b491051
commit
11a007dc16
@ -408,6 +408,42 @@ func (r *Route) Copy() *Route {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HopFee returns the fee charged by the route hop indicated by hopIndex.
|
// HopFee returns the fee charged by the route hop indicated by hopIndex.
|
||||||
|
//
|
||||||
|
// This calculation takes into account the possibility that the route contains
|
||||||
|
// some blinded hops, that will not have the amount to forward set. We take
|
||||||
|
// note of various points in the blinded route.
|
||||||
|
//
|
||||||
|
// Given the following route where Carol is the introduction node and B2 is
|
||||||
|
// the recipient, Carol and B1's hops will not have an amount to forward set:
|
||||||
|
// Alice --- Bob ---- Carol (introduction) ----- B1 ----- B2
|
||||||
|
//
|
||||||
|
// We locate ourselves in the route as follows:
|
||||||
|
// * Regular Hop (eg Alice - Bob):
|
||||||
|
//
|
||||||
|
// incomingAmt !=0
|
||||||
|
// outgoingAmt !=0
|
||||||
|
// -> Fee = incomingAmt - outgoingAmt
|
||||||
|
//
|
||||||
|
// * Introduction Hop (eg Bob - Carol):
|
||||||
|
//
|
||||||
|
// incomingAmt !=0
|
||||||
|
// outgoingAmt = 0
|
||||||
|
// -> Fee = incomingAmt - receiverAmt
|
||||||
|
//
|
||||||
|
// This has the impact of attributing the full fees for the blinded route to
|
||||||
|
// the introduction node.
|
||||||
|
//
|
||||||
|
// * Blinded Intermediate Hop (eg Carol - B1):
|
||||||
|
//
|
||||||
|
// incomingAmt = 0
|
||||||
|
// outgoingAmt = 0
|
||||||
|
// -> Fee = 0
|
||||||
|
//
|
||||||
|
// * Final Blinded Hop (B1 - B2):
|
||||||
|
//
|
||||||
|
// incomingAmt = 0
|
||||||
|
// outgoingAmt !=0
|
||||||
|
// -> Fee = 0
|
||||||
func (r *Route) HopFee(hopIndex int) lnwire.MilliSatoshi {
|
func (r *Route) HopFee(hopIndex int) lnwire.MilliSatoshi {
|
||||||
var incomingAmt lnwire.MilliSatoshi
|
var incomingAmt lnwire.MilliSatoshi
|
||||||
if hopIndex == 0 {
|
if hopIndex == 0 {
|
||||||
@ -416,8 +452,25 @@ func (r *Route) HopFee(hopIndex int) lnwire.MilliSatoshi {
|
|||||||
incomingAmt = r.Hops[hopIndex-1].AmtToForward
|
incomingAmt = r.Hops[hopIndex-1].AmtToForward
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fee is calculated as difference between incoming and outgoing amount.
|
outgoingAmt := r.Hops[hopIndex].AmtToForward
|
||||||
return incomingAmt - r.Hops[hopIndex].AmtToForward
|
|
||||||
|
switch {
|
||||||
|
// If both incoming and outgoing amounts are set, we're in a normal
|
||||||
|
// hop
|
||||||
|
case incomingAmt != 0 && outgoingAmt != 0:
|
||||||
|
return incomingAmt - outgoingAmt
|
||||||
|
|
||||||
|
// If the incoming amount is zero, we're at an intermediate hop in
|
||||||
|
// a blinded route, so the fee is zero.
|
||||||
|
case incomingAmt == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
// If we have a non-zero incoming amount and a zero outgoing amount,
|
||||||
|
// we're at the introduction hop so we express the fees for the full
|
||||||
|
// blinded route at this hop.
|
||||||
|
default:
|
||||||
|
return incomingAmt - r.ReceiverAmt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalFees is the sum of the fees paid at each hop within the final route. In
|
// TotalFees is the sum of the fees paid at each hop within the final route. In
|
||||||
|
@ -296,3 +296,42 @@ func testPayloadSize(t *testing.T, hops []*Hop) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestBlindedHopFee tests calculation of hop fees for blinded routes.
|
||||||
|
func TestBlindedHopFee(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
route := &Route{
|
||||||
|
TotalAmount: 1500,
|
||||||
|
Hops: []*Hop{
|
||||||
|
// Start with two un-blinded hops.
|
||||||
|
{
|
||||||
|
AmtToForward: 1450,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AmtToForward: 1300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Our introduction node will have a zero
|
||||||
|
// forward amount.
|
||||||
|
AmtToForward: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// An intermediate blinded hop will also have
|
||||||
|
// a zero forward amount.
|
||||||
|
AmtToForward: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Our final blinded hop should have a forward
|
||||||
|
// amount set.
|
||||||
|
AmtToForward: 1000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, lnwire.MilliSatoshi(50), route.HopFee(0))
|
||||||
|
require.Equal(t, lnwire.MilliSatoshi(150), route.HopFee(1))
|
||||||
|
require.Equal(t, lnwire.MilliSatoshi(300), route.HopFee(2))
|
||||||
|
require.Equal(t, lnwire.MilliSatoshi(0), route.HopFee(3))
|
||||||
|
require.Equal(t, lnwire.MilliSatoshi(0), route.HopFee(4))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user