multi: add ChanEdgePolicyFromWire constructor for ChannelEdgePolicy
What changed, and why it matters
This commit is a straightforward code cleanup: it creates a single helper function that builds an internal data structure from two different kinds of channel update messages, and updates three places to use that helper. There is no change to security behavior, no bug fix, and no disclosed vulnerability.
No security action required; treat as normal refactoring review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces ChanEdgePolicyFromWire in graph/db/models/channel_edge_policy.go to centralize conversion of lnwire.ChannelUpdate (v1 and v2) into models.ChannelEdgePolicy. It refactors discovery/gossiper.handleChanUpdate, graph/builder.ApplyChannelUpdate, and a test helper in routing/router_test.go to call this constructor. The logic for v1 updates is identical to the previous inline construction; v2 support is added in the constructor but the commit only changes call sites that previously handled v1. No validation, authorization, or cryptographic logic is altered.
Changed components
discovery/gossiper.gograph/builder.gograph/db/models/channel_edge_policy.gorouting/router_test.goInspect captured patch +69 / −42
diff --git a/discovery/gossiper.go b/discovery/gossiper.go
index 3e72f8a..d2375cb 100644
--- a/discovery/gossiper.go
+++ b/discovery/gossiper.go
@@ -3422,20 +3422,12 @@ func (d *AuthenticatedGossiper) handleChanUpdate(ctx context.Context,
// different alias. This might mean that SigBytes is incorrect as it
// signs a different SCID than the database SCID, but since there will
// only be a difference if AuthProof == nil, this is fine.
- update := &models.ChannelEdgePolicy{
- Version: upd.GossipVersion(),
- SigBytes: upd.Signature.ToSignatureBytes(),
- ChannelID: chanInfo.ChannelID,
- LastUpdate: timestamp,
- MessageFlags: upd.MessageFlags,
- ChannelFlags: upd.ChannelFlags,
- TimeLockDelta: upd.TimeLockDelta,
- MinHTLC: upd.HtlcMinimumMsat,
- MaxHTLC: upd.HtlcMaximumMsat,
- FeeBaseMSat: lnwire.MilliSatoshi(upd.BaseFee),
- FeeProportionalMillionths: lnwire.MilliSatoshi(upd.FeeRate),
- InboundFee: upd.InboundFee.ValOpt(),
- ExtraOpaqueData: upd.ExtraOpaqueData,
+ update, err := models.ChanEdgePolicyFromWire(
+ chanInfo.ChannelID, upd,
+ )
+ if err != nil {
+ nMsg.err <- err
+ return nil, false
}
if err := d.cfg.Graph.UpdateEdge(ctx, update, ops...); err != nil {
diff --git a/graph/builder.go b/graph/builder.go
index 10d0b29..fa8b0b4 100644
--- a/graph/builder.go
+++ b/graph/builder.go
@@ -952,20 +952,12 @@ func (b *Builder) ApplyChannelUpdate(msg *lnwire.ChannelUpdate1) bool {
return false
}
- update := &models.ChannelEdgePolicy{
- Version: msg.GossipVersion(),
- SigBytes: msg.Signature.ToSignatureBytes(),
- ChannelID: msg.ShortChannelID.ToUint64(),
- LastUpdate: time.Unix(int64(msg.Timestamp), 0),
- MessageFlags: msg.MessageFlags,
- ChannelFlags: msg.ChannelFlags,
- TimeLockDelta: msg.TimeLockDelta,
- MinHTLC: msg.HtlcMinimumMsat,
- MaxHTLC: msg.HtlcMaximumMsat,
- FeeBaseMSat: lnwire.MilliSatoshi(msg.BaseFee),
- FeeProportionalMillionths: lnwire.MilliSatoshi(msg.FeeRate),
- InboundFee: msg.InboundFee.ValOpt(),
- ExtraOpaqueData: msg.ExtraOpaqueData,
+ update, err := models.ChanEdgePolicyFromWire(
+ msg.ShortChannelID.ToUint64(), msg,
+ )
+ if err != nil {
+ log.Errorf("Unable to parse channel update: %v", err)
+ return false
}
err = b.UpdateEdge(ctx, update)
diff --git a/graph/db/models/channel_edge_policy.go b/graph/db/models/channel_edge_policy.go
index dd93c21..067c786 100644
--- a/graph/db/models/channel_edge_policy.go
+++ b/graph/db/models/channel_edge_policy.go
@@ -99,6 +99,56 @@ type ChannelEdgePolicy struct {
ExtraSignedFields map[uint64][]byte
}
+// ChanEdgePolicyFromWire constructs a ChannelEdgePolicy from a channel update
+// message.
+func ChanEdgePolicyFromWire(scid uint64,
+ update lnwire.ChannelUpdate) (*ChannelEdgePolicy, error) {
+
+ switch upd := update.(type) {
+ case *lnwire.ChannelUpdate1:
+ //nolint:ll
+ return &ChannelEdgePolicy{
+ Version: lnwire.GossipVersion1,
+ SigBytes: upd.Signature.ToSignatureBytes(),
+ ChannelID: scid,
+ LastUpdate: time.Unix(int64(upd.Timestamp), 0),
+ MessageFlags: upd.MessageFlags,
+ ChannelFlags: upd.ChannelFlags,
+ TimeLockDelta: upd.TimeLockDelta,
+ MinHTLC: upd.HtlcMinimumMsat,
+ MaxHTLC: upd.HtlcMaximumMsat,
+ FeeBaseMSat: lnwire.MilliSatoshi(upd.BaseFee),
+ FeeProportionalMillionths: lnwire.MilliSatoshi(upd.FeeRate),
+ InboundFee: upd.InboundFee.ValOpt(),
+ ExtraOpaqueData: upd.ExtraOpaqueData,
+ }, nil
+
+ case *lnwire.ChannelUpdate2:
+ return &ChannelEdgePolicy{
+ Version: lnwire.GossipVersion2,
+ SigBytes: upd.Signature.Val.ToSignatureBytes(),
+ ChannelID: scid,
+ LastBlockHeight: upd.BlockHeight.Val,
+ SecondPeer: upd.SecondPeer.IsSome(),
+ DisableFlags: upd.DisabledFlags.Val,
+ TimeLockDelta: upd.CLTVExpiryDelta.Val,
+ MinHTLC: upd.HTLCMinimumMsat.Val,
+ MaxHTLC: upd.HTLCMaximumMsat.Val,
+ FeeBaseMSat: lnwire.MilliSatoshi(
+ upd.FeeBaseMsat.Val,
+ ),
+ FeeProportionalMillionths: lnwire.MilliSatoshi(
+ upd.FeeProportionalMillionths.Val,
+ ),
+ InboundFee: upd.InboundFee.ValOpt(),
+ ExtraSignedFields: upd.ExtraSignedFields,
+ }, nil
+ }
+
+ return nil, fmt.Errorf("unknown channel update version: %v",
+ update.MsgType())
+}
+
// IsNode1 returns true if this policy was announced by the channel's node_1.
func (c *ChannelEdgePolicy) IsNode1() bool {
if c.Version == lnwire.GossipVersion1 {
diff --git a/routing/router_test.go b/routing/router_test.go
index 12c4adb..115c02c 100644
--- a/routing/router_test.go
+++ b/routing/router_test.go
@@ -2968,20 +2968,13 @@ func (m *mockGraphBuilder) ApplyChannelUpdate(msg *lnwire.ChannelUpdate1) bool {
return false
}
- err := m.updateEdge(&models.ChannelEdgePolicy{
- Version: msg.GossipVersion(),
- SigBytes: msg.Signature.ToSignatureBytes(),
- ChannelID: msg.ShortChannelID.ToUint64(),
- LastUpdate: time.Unix(int64(msg.Timestamp), 0),
- MessageFlags: msg.MessageFlags,
- ChannelFlags: msg.ChannelFlags,
- TimeLockDelta: msg.TimeLockDelta,
- MinHTLC: msg.HtlcMinimumMsat,
- MaxHTLC: msg.HtlcMaximumMsat,
- FeeBaseMSat: lnwire.MilliSatoshi(msg.BaseFee),
- FeeProportionalMillionths: lnwire.MilliSatoshi(msg.FeeRate),
- ExtraOpaqueData: msg.ExtraOpaqueData,
- })
+ update, err := models.ChanEdgePolicyFromWire(
+ msg.ShortChannelID.ToUint64(), msg,
+ )
+ if err != nil {
+ return false
+ }
+ err = m.updateEdge(update)
return err == nil
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.