routing: implement capacity in getEdge

This commit adds the maximal capacity between two nodes to the unified
edge data. We use MaxHTLC as a replacement if the channel capacity is
not available.

In tests we use larger maxHTLC values to be able to convert to a
non-zero sat capacity.
This commit is contained in:
bitromortac committed 2022-12-12 13:22:28 +01:00
1 parent 99273cc5e1
commit 2b6308a61f
2 files changed
+45 -3

No files matched your search

+14
View File
@@ -207,6 +207,7 @@ func (u *edgeUnifier) getEdgeNetwork(amt lnwire.MilliSatoshi) *unifiedEdge {
bestPolicy *channeldb.CachedEdgePolicy
maxFee lnwire.MilliSatoshi
maxTimelock uint16
maxCapMsat lnwire.MilliSatoshi
)
for _, edge := range u.edges {
@@ -222,6 +223,18 @@ func (u *edgeUnifier) getEdgeNetwork(amt lnwire.MilliSatoshi) *unifiedEdge {
continue
}
// Track the maximal capacity for usable channels. If we don't
// know the capacity, we fall back to MaxHTLC.
capMsat := lnwire.NewMSatFromSatoshis(edge.capacity)
if capMsat == 0 && edge.policy.MessageFlags.HasMaxHtlc() {
log.Tracef("No capacity available for channel %v, "+
"using MaxHtlcMsat (%v) as a fallback.",
edge.policy.ChannelID, edge.policy.MaxHTLC)
capMsat = edge.policy.MaxHTLC
}
maxCapMsat = lntypes.Max(capMsat, maxCapMsat)
// Track the maximum time lock of all channels that are
// candidate for non-strict forwarding at the routing node.
maxTimelock = lntypes.Max(
@@ -257,6 +270,7 @@ func (u *edgeUnifier) getEdgeNetwork(amt lnwire.MilliSatoshi) *unifiedEdge {
policyCopy := *bestPolicy
modifiedEdge := unifiedEdge{policy: &policyCopy}
modifiedEdge.policy.TimeLockDelta = maxTimelock
modifiedEdge.capacity = maxCapMsat.ToSatoshis()
return &modifiedEdge
}
+31 -3
View File
@@ -26,7 +26,7 @@ func TestNodeEdgeUnifier(t *testing.T) {
FeeBaseMSat: 30,
TimeLockDelta: 60,
MessageFlags: lnwire.ChanUpdateOptionMaxHtlc,
MaxHTLC: 500,
MaxHTLC: 5000,
MinHTLC: 100,
}
p2 := channeldb.CachedEdgePolicy{
@@ -34,7 +34,7 @@ func TestNodeEdgeUnifier(t *testing.T) {
FeeBaseMSat: 10,
TimeLockDelta: 40,
MessageFlags: lnwire.ChanUpdateOptionMaxHtlc,
MaxHTLC: 400,
MaxHTLC: 4000,
MinHTLC: 100,
}
c1 := btcutil.Amount(7)
@@ -44,6 +44,13 @@ func TestNodeEdgeUnifier(t *testing.T) {
unifierFilled.addPolicy(fromNode, &p1, c1)
unifierFilled.addPolicy(fromNode, &p2, c2)
unifierNoCapacity := newNodeEdgeUnifier(source, toNode, nil)
unifierNoCapacity.addPolicy(fromNode, &p1, 0)
unifierNoCapacity.addPolicy(fromNode, &p2, 0)
unifierNoInfo := newNodeEdgeUnifier(source, toNode, nil)
unifierNoInfo.addPolicy(fromNode, &channeldb.CachedEdgePolicy{}, 0)
tests := []struct {
name string
unifier *nodeEdgeUnifier
@@ -52,6 +59,7 @@ func TestNodeEdgeUnifier(t *testing.T) {
expectedFeeRate lnwire.MilliSatoshi
expectedTimeLock uint16
expectNoPolicy bool
expectedCapacity btcutil.Amount
}{
{
name: "amount below min htlc",
@@ -62,7 +70,7 @@ func TestNodeEdgeUnifier(t *testing.T) {
{
name: "amount above max htlc",
unifier: unifierFilled,
amount: 550,
amount: 5500,
expectNoPolicy: true,
},
// For 200 msat, p1 yields the highest fee. Use that policy to
@@ -75,6 +83,7 @@ func TestNodeEdgeUnifier(t *testing.T) {
expectedFeeBase: p1.FeeBaseMSat,
expectedFeeRate: p1.FeeProportionalMillionths,
expectedTimeLock: p1.TimeLockDelta,
expectedCapacity: c2,
},
// For 400 sat, p2 yields the highest fee. Use that policy to
// forward, because it will also match p1 in case p2 does not
@@ -87,6 +96,23 @@ func TestNodeEdgeUnifier(t *testing.T) {
expectedFeeBase: p2.FeeBaseMSat,
expectedFeeRate: p2.FeeProportionalMillionths,
expectedTimeLock: p1.TimeLockDelta,
expectedCapacity: c2,
},
// If there's no capacity info present, we fall back to the max
// maxHTLC value.
{
name: "no capacity info",
unifier: unifierNoCapacity,
amount: 400,
expectedFeeBase: p2.FeeBaseMSat,
expectedFeeRate: p2.FeeProportionalMillionths,
expectedTimeLock: p1.TimeLockDelta,
expectedCapacity: p1.MaxHTLC.ToSatoshis(),
},
{
name: "no info",
unifier: unifierNoInfo,
expectedCapacity: 0,
},
}
@@ -113,6 +139,8 @@ func TestNodeEdgeUnifier(t *testing.T) {
policy.FeeProportionalMillionths, "fee rate")
require.Equal(t, test.expectedTimeLock,
policy.TimeLockDelta, "timelock")
require.Equal(t, test.expectedCapacity, edge.capacity,
"capacity")
})
}
}