diff --git a/docs/release-notes/release-notes-0.18.0.md b/docs/release-notes/release-notes-0.18.0.md index 7628726ef0..3b130b9832 100644 --- a/docs/release-notes/release-notes-0.18.0.md +++ b/docs/release-notes/release-notes-0.18.0.md @@ -314,6 +314,9 @@ maintain a healthy connection to the network by checking the number of outbound peers if they are below 6. +* [Add inbound fees](https://github.com/lightningnetwork/lnd/pull/8723) to + `subscribeChannelGraph`. + ### Logging * [Add the htlc amount](https://github.com/lightningnetwork/lnd/pull/8156) to contract court logs in case of timed-out HTLCs in order to easily spot dust @@ -549,6 +552,7 @@ * BitcoinerCoderBob * bitromortac * bota87 +* Bufo * Calvin Zachman * Carla Kirk-Cohen * cristiantroy diff --git a/routing/notifications.go b/routing/notifications.go index 9d6c4b51f9..3afbb15330 100644 --- a/routing/notifications.go +++ b/routing/notifications.go @@ -301,6 +301,11 @@ type ChannelEdgeUpdate struct { // Disabled, if true, signals that the channel is unavailable to relay // payments. Disabled bool + + // ExtraOpaqueData is the set of data that was appended to this message + // to fill out the full maximum transport message size. These fields can + // be used to specify optional data such as custom TLV fields. + ExtraOpaqueData lnwire.ExtraOpaqueData } // appendTopologyChange appends the passed update message to the passed @@ -379,6 +384,7 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange, AdvertisingNode: aNode, ConnectingNode: cNode, Disabled: m.ChannelFlags&lnwire.ChanUpdateDisabled != 0, + ExtraOpaqueData: m.ExtraOpaqueData, } // TODO(roasbeef): add bit to toggle diff --git a/routing/notifications_test.go b/routing/notifications_test.go index 48b0a2766d..4e095649b5 100644 --- a/routing/notifications_test.go +++ b/routing/notifications_test.go @@ -75,7 +75,18 @@ func createTestNode() (*channeldb.LightningNode, error) { } func randEdgePolicy(chanID *lnwire.ShortChannelID, - node *channeldb.LightningNode) *models.ChannelEdgePolicy { + node *channeldb.LightningNode) (*models.ChannelEdgePolicy, error) { + + InboundFee := models.InboundFee{ + Base: prand.Int31() * -1, + Rate: prand.Int31() * -1, + } + inboundFee := InboundFee.ToWire() + + var extraOpaqueData lnwire.ExtraOpaqueData + if err := extraOpaqueData.PackRecords(&inboundFee); err != nil { + return nil, err + } return &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), @@ -87,7 +98,8 @@ func randEdgePolicy(chanID *lnwire.ShortChannelID, FeeBaseMSat: lnwire.MilliSatoshi(prand.Int31()), FeeProportionalMillionths: lnwire.MilliSatoshi(prand.Int31()), ToNode: node.PubKeyBytes, - } + ExtraOpaqueData: extraOpaqueData, + }, nil } func createChannelEdge(ctx *testCtx, bitcoinKey1, bitcoinKey2 []byte, @@ -457,9 +469,12 @@ func TestEdgeUpdateNotification(t *testing.T) { // Create random policy edges that are stemmed to the channel id // created above. - edge1 := randEdgePolicy(chanID, node1) + edge1, err := randEdgePolicy(chanID, node1) + require.NoError(t, err, "unable to create a random chan policy") edge1.ChannelFlags = 0 - edge2 := randEdgePolicy(chanID, node2) + + edge2, err := randEdgePolicy(chanID, node2) + require.NoError(t, err, "unable to create a random chan policy") edge2.ChannelFlags = 1 if err := ctx.router.UpdateEdge(edge1); err != nil { @@ -511,6 +526,9 @@ func TestEdgeUpdateNotification(t *testing.T) { "expected %v, got %v", edgeAnn.TimeLockDelta, edgeUpdate.TimeLockDelta) } + require.Equal( + t, edgeAnn.ExtraOpaqueData, edgeUpdate.ExtraOpaqueData, + ) } // Create lookup map for notifications we are intending to receive. Entries diff --git a/rpcserver.go b/rpcserver.go index e4e8f50ee2..1e9f0be080 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -6691,6 +6691,14 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol channelUpdates := make([]*lnrpc.ChannelEdgeUpdate, len(topChange.ChannelEdgeUpdates)) for i, channelUpdate := range topChange.ChannelEdgeUpdates { + + customRecords := marshalExtraOpaqueData( + channelUpdate.ExtraOpaqueData, + ) + inboundFee := extractInboundFeeSafe( + channelUpdate.ExtraOpaqueData, + ) + channelUpdates[i] = &lnrpc.ChannelEdgeUpdate{ ChanId: channelUpdate.ChanID, ChanPoint: &lnrpc.ChannelPoint{ @@ -6701,12 +6709,25 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol }, Capacity: int64(channelUpdate.Capacity), RoutingPolicy: &lnrpc.RoutingPolicy{ - TimeLockDelta: uint32(channelUpdate.TimeLockDelta), - MinHtlc: int64(channelUpdate.MinHTLC), - MaxHtlcMsat: uint64(channelUpdate.MaxHTLC), - FeeBaseMsat: int64(channelUpdate.BaseFee), - FeeRateMilliMsat: int64(channelUpdate.FeeRate), - Disabled: channelUpdate.Disabled, + TimeLockDelta: uint32( + channelUpdate.TimeLockDelta, + ), + MinHtlc: int64( + channelUpdate.MinHTLC, + ), + MaxHtlcMsat: uint64( + channelUpdate.MaxHTLC, + ), + FeeBaseMsat: int64( + channelUpdate.BaseFee, + ), + FeeRateMilliMsat: int64( + channelUpdate.FeeRate, + ), + Disabled: channelUpdate.Disabled, + InboundFeeBaseMsat: inboundFee.BaseFee, + InboundFeeRateMilliMsat: inboundFee.FeeRate, + CustomRecords: customRecords, }, AdvertisingNode: encodeKey(channelUpdate.AdvertisingNode), ConnectingNode: encodeKey(channelUpdate.ConnectingNode),