diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 0b59c8af9..d79fe7a74 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -3260,6 +3260,26 @@ func (d *AuthenticatedGossiper) handleChanUpdate(ctx context.Context, ExtraOpaqueData: upd.ExtraOpaqueData, } + // Extract the inbound fee from the ExtraOpaqueData, if present. + // + // TODO(elle): this can be removed once we define the optional TLV + // field on the lnwire.ChannelUpdate itself. + var inboundFee lnwire.Fee + typeMap, err := upd.ExtraOpaqueData.ExtractRecords(&inboundFee) + if err != nil { + rErr := fmt.Errorf("%w: %w", graphdb.ErrParsingExtraTLVBytes, + err) + + log.Error(rErr) + nMsg.err <- rErr + return nil, false + } + + val, ok := typeMap[lnwire.FeeRecordType] + if ok && val == nil { + update.InboundFee = fn.Some(inboundFee) + } + if err := d.cfg.Graph.UpdateEdge(update, ops...); err != nil { if graph.IsError( err, graph.ErrOutdated, diff --git a/graph/builder.go b/graph/builder.go index 3350eeb33..32aac9434 100644 --- a/graph/builder.go +++ b/graph/builder.go @@ -11,6 +11,7 @@ import ( "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/batch" "github.com/lightningnetwork/lnd/chainntnfs" + "github.com/lightningnetwork/lnd/fn/v2" graphdb "github.com/lightningnetwork/lnd/graph/db" "github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/lnutils" @@ -943,7 +944,7 @@ func (b *Builder) ApplyChannelUpdate(msg *lnwire.ChannelUpdate1) bool { return false } - err = b.UpdateEdge(&models.ChannelEdgePolicy{ + update := &models.ChannelEdgePolicy{ SigBytes: msg.Signature.ToSignatureBytes(), ChannelID: msg.ShortChannelID.ToUint64(), LastUpdate: time.Unix(int64(msg.Timestamp), 0), @@ -955,7 +956,25 @@ func (b *Builder) ApplyChannelUpdate(msg *lnwire.ChannelUpdate1) bool { FeeBaseMSat: lnwire.MilliSatoshi(msg.BaseFee), FeeProportionalMillionths: lnwire.MilliSatoshi(msg.FeeRate), ExtraOpaqueData: msg.ExtraOpaqueData, - }) + } + + // Extract the inbound fee from the ExtraOpaqueData, if present. + // + // TODO(elle): this can be removed once we define the optional TLV + // field on the lnwire.ChannelUpdate itself. + var inboundFee lnwire.Fee + typeMap, err := update.ExtraOpaqueData.ExtractRecords(&inboundFee) + if err != nil { + log.Errorf("%v: %v", graphdb.ErrParsingExtraTLVBytes, err) + return false + } + + val, ok := typeMap[lnwire.FeeRecordType] + if ok && val == nil { + update.InboundFee = fn.Some(inboundFee) + } + + err = b.UpdateEdge(update) if err != nil && !IsError(err, ErrIgnored, ErrOutdated) { log.Errorf("Unable to apply channel update: %v", err) return false diff --git a/graph/notifications_test.go b/graph/notifications_test.go index 71c6f4a34..2f2ec1b4b 100644 --- a/graph/notifications_test.go +++ b/graph/notifications_test.go @@ -121,6 +121,7 @@ func randEdgePolicy(chanID *lnwire.ShortChannelID, FeeBaseMSat: lnwire.MilliSatoshi(prand.Int31()), FeeProportionalMillionths: lnwire.MilliSatoshi(prand.Int31()), ToNode: node.PubKeyBytes, + InboundFee: fn.Some(inboundFee), ExtraOpaqueData: extraOpaqueData, }, nil } diff --git a/routing/localchans/manager.go b/routing/localchans/manager.go index 3beb28525..492f8f18c 100644 --- a/routing/localchans/manager.go +++ b/routing/localchans/manager.go @@ -127,12 +127,10 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy, Edge: edge, }) - // Extract inbound fees from the ExtraOpaqueData. var inboundWireFee lnwire.Fee - _, err = edge.ExtraOpaqueData.ExtractRecords(&inboundWireFee) - if err != nil { - return err - } + edge.InboundFee.WhenSome(func(fee lnwire.Fee) { + inboundWireFee = fee + }) inboundFee := models.NewInboundFeeFromWire(inboundWireFee) // Add updated policy to list of policies to send to switch. @@ -372,6 +370,8 @@ func (r *Manager) updateEdge(chanPoint wire.OutPoint, err = fn.MapOptionZ(newSchema.InboundFee, func(f models.InboundFee) error { inboundWireFee := f.ToWire() + edge.InboundFee = fn.Some(inboundWireFee) + return edge.ExtraOpaqueData.PackRecords( &inboundWireFee, )