routing: add inbound fee support to pathfinding

Add sender-side support for inbound fees in pathfinding
and route building.
This commit is contained in:
Joost Jager committed 2024-03-31 18:12:28 +02:00
1 parent d97e7d30fb
commit 0bae781785
13 files changed
+585 -131

No files matched your search

+11
View File
@@ -490,6 +490,16 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(tx kvdb.RTx,
cachedInPolicy.ToNodeFeatures = toNodeFeatures
}
var inboundFee lnwire.Fee
if p1 != nil {
// Extract inbound fee. If there is a decoding error,
// skip this edge.
_, err := p1.ExtraOpaqueData.ExtractRecords(&inboundFee)
if err != nil {
return nil
}
}
directedChannel := &DirectedChannel{
ChannelID: e.ChannelID,
IsNode1: node == e.NodeKey1Bytes,
@@ -497,6 +507,7 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(tx kvdb.RTx,
Capacity: e.Capacity,
OutPolicySet: p1 != nil,
InPolicy: cachedInPolicy,
InboundFee: inboundFee,
}
if node == e.NodeKey2Bytes {
+13
View File
@@ -59,6 +59,9 @@ type DirectedChannel struct {
// source, so we're always interested in the edge that arrives to us
// from the other node.
InPolicy *models.CachedEdgePolicy
// Inbound fees of this node.
InboundFee lnwire.Fee
}
// DeepCopy creates a deep copy of the channel, including the incoming policy.
@@ -220,6 +223,14 @@ func (c *GraphCache) updateOrAddEdge(node route.Vertex, edge *DirectedChannel) {
func (c *GraphCache) UpdatePolicy(policy *models.ChannelEdgePolicy, fromNode,
toNode route.Vertex, edge1 bool) {
// Extract inbound fee if possible and available. If there is a decoding
// error, ignore this policy.
var inboundFee lnwire.Fee
_, err := policy.ExtraOpaqueData.ExtractRecords(&inboundFee)
if err != nil {
return
}
c.mtx.Lock()
defer c.mtx.Unlock()
@@ -240,11 +251,13 @@ func (c *GraphCache) UpdatePolicy(policy *models.ChannelEdgePolicy, fromNode,
// policy for node 1.
case channel.IsNode1 && edge1:
channel.OutPolicySet = true
channel.InboundFee = inboundFee
// This is node 2, and it is edge 2, so this is the outgoing
// policy for node 2.
case !channel.IsNode1 && !edge1:
channel.OutPolicySet = true
channel.InboundFee = inboundFee
// The other two cases left mean it's the inbound policy for the
// node.
+15 -1
View File
@@ -75,6 +75,10 @@ func TestGraphCacheAddNode(t *testing.T) {
ChannelID: 1000,
ChannelFlags: lnwire.ChanUpdateChanFlags(channelFlagA),
ToNode: nodeB,
// Define an inbound fee.
ExtraOpaqueData: []byte{
253, 217, 3, 8, 0, 0, 0, 10, 0, 0, 0, 20,
},
}
inPolicy1 := &models.ChannelEdgePolicy{
ChannelID: 1000,
@@ -124,8 +128,18 @@ func TestGraphCacheAddNode(t *testing.T) {
edges map[uint64]*DirectedChannel) error {
nodes[node] = struct{}{}
for chanID := range edges {
for chanID, directedChannel := range edges {
chans[chanID] = struct{}{}
if node == nodeA {
require.NotZero(
t, directedChannel.InboundFee,
)
} else {
require.Zero(
t, directedChannel.InboundFee,
)
}
}
return nil
+35 -3
View File
@@ -674,7 +674,7 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (
FeeBaseMSat: 4352345,
FeeProportionalMillionths: 3452352,
ToNode: secondNode,
ExtraOpaqueData: []byte("new unknown feature2"),
ExtraOpaqueData: []byte{1, 0},
}
edge2 := &models.ChannelEdgePolicy{
SigBytes: testSig.Serialize(),
@@ -688,7 +688,7 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (
FeeBaseMSat: 4352345,
FeeProportionalMillionths: 90392423,
ToNode: firstNode,
ExtraOpaqueData: []byte("new unknown feature1"),
ExtraOpaqueData: []byte{1, 0},
}
return edgeInfo, edge1, edge2
@@ -3929,7 +3929,17 @@ func TestGraphCacheForEachNodeChannel(t *testing.T) {
require.Nil(t, err)
// Create an edge and add it to the db.
edgeInfo, _, _ := createChannelEdge(graph.db, node1, node2)
edgeInfo, e1, e2 := createChannelEdge(graph.db, node1, node2)
// Because of lexigraphical sorting and the usage of random node keys in
// this test, we need to determine which edge belongs to node 1 at
// runtime.
var edge1 *models.ChannelEdgePolicy
if e1.ToNode == node2.PubKeyBytes {
edge1 = e1
} else {
edge1 = e2
}
// Add the channel, but only insert a single edge into the graph.
require.NoError(t, graph.AddChannelEdge(edgeInfo))
@@ -3952,6 +3962,28 @@ func TestGraphCacheForEachNodeChannel(t *testing.T) {
// We should be able to accumulate the single channel added, even
// though we have a nil edge policy here.
require.NotNil(t, getSingleChannel())
// Set an inbound fee and check that it is properly returned.
edge1.ExtraOpaqueData = []byte{
253, 217, 3, 8, 0, 0, 0, 10, 0, 0, 0, 20,
}
require.NoError(t, graph.UpdateEdgePolicy(edge1))
directedChan := getSingleChannel()
require.NotNil(t, directedChan)
require.Equal(t, directedChan.InboundFee, lnwire.Fee{
BaseFee: 10,
FeeRate: 20,
})
// Set an invalid inbound fee and check that the edge is no longer
// returned.
edge1.ExtraOpaqueData = []byte{
253, 217, 3, 8, 0,
}
require.NoError(t, graph.UpdateEdgePolicy(edge1))
require.Nil(t, getSingleChannel())
}
// TestGraphLoading asserts that the cache is properly reconstructed after a