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:
2 files changed
+45
-3
No files matched your search
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user