From 830b9db69c1dd96df9234eb647db463b0a360c43 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 19 Nov 2025 13:00:31 +0200 Subject: [PATCH] multi: add ToChannelAnnouncement helper on ChannelEdgeInfo So that we have one place that converts from our `models` struct to the `lnwire.ChannelAnnouncement` struct. The commit also refactors netann.CreateChanAnnouncement to only take a ChannelEdgeInfo and get the proof from there instead of needing the proof to be passed in separately. Add ToChannelAnnouncement() method to ChannelEdgeInfo that converts the model struct to a lnwire.ChannelAnnouncement1 message. This: - Centralizes the conversion logic in one place instead of scattered across multiple call sites - Validates that AuthProof is present (can't create announcement without proof) - Currently only supports v1 channels, returning error for v2 Refactor netann.CreateChanAnnouncement to use this helper and remove the separate chanProof parameter since proof is now accessed from within ChannelEdgeInfo. This improves encapsulation and reduces parameter count. --- discovery/chan_series.go | 6 +-- discovery/gossiper.go | 49 ++++++---------------- graph/db/models/channel_edge_info.go | 63 ++++++++++++++++++++++++++++ netann/channel_announcement.go | 40 ++---------------- netann/channel_announcement_test.go | 4 +- 5 files changed, 82 insertions(+), 80 deletions(-) diff --git a/discovery/chan_series.go b/discovery/chan_series.go index 050b82b10..9ba9607e9 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -133,8 +133,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash, //nolint:ll chanAnn, edge1, edge2, err := netann.CreateChanAnnouncement( - channel.Info.AuthProof, channel.Info, - channel.Policy1, channel.Policy2, + channel.Info, channel.Policy1, channel.Policy2, ) if err != nil { if !yield(nil, err) { @@ -281,8 +280,7 @@ func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash, } chanAnn, edge1, edge2, err := netann.CreateChanAnnouncement( - channel.Info.AuthProof, channel.Info, channel.Policy1, - channel.Policy2, + channel.Info, channel.Policy1, channel.Policy2, ) if err != nil { return nil, err diff --git a/discovery/gossiper.go b/discovery/gossiper.go index b26435c56..88ac2418b 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -2096,10 +2096,14 @@ func (d *AuthenticatedGossiper) processRejectedEdge(_ context.Context, return nil, nil } + // Attach the proof to the channel info before creating the + // announcement. + chanInfo.AuthProof = proof + // We'll then create then validate the new fully assembled // announcement. chanAnn, e1Ann, e2Ann, err := netann.CreateChanAnnouncement( - proof, chanInfo, e1, e2, + chanInfo, e1, e2, ) if err != nil { return nil, err @@ -2492,44 +2496,13 @@ func (d *AuthenticatedGossiper) updateChannel(ctx context.Context, // have a full channel announcement for this channel. var chanAnn *lnwire.ChannelAnnouncement1 if info.AuthProof != nil { - chanID := lnwire.NewShortChanIDFromInt(info.ChannelID) - chanAnn = &lnwire.ChannelAnnouncement1{ - ShortChannelID: chanID, - NodeID1: info.NodeKey1Bytes, - NodeID2: info.NodeKey2Bytes, - ChainHash: info.ChainHash, - BitcoinKey1: info.BitcoinKey1Bytes, - Features: lnwire.NewRawFeatureVector(), - BitcoinKey2: info.BitcoinKey2Bytes, - ExtraOpaqueData: info.ExtraOpaqueData, - } - chanAnn.NodeSig1, err = lnwire.NewSigFromECDSARawSignature( - info.AuthProof.NodeSig1(), - ) - if err != nil { - return nil, nil, err - } - chanAnn.NodeSig2, err = lnwire.NewSigFromECDSARawSignature( - info.AuthProof.NodeSig2(), - ) - if err != nil { - return nil, nil, err - } - chanAnn.BitcoinSig1, err = lnwire.NewSigFromECDSARawSignature( - info.AuthProof.BitcoinSig1(), - ) - if err != nil { - return nil, nil, err - } - chanAnn.BitcoinSig2, err = lnwire.NewSigFromECDSARawSignature( - info.AuthProof.BitcoinSig2(), - ) + chanAnn, err = info.ToChannelAnnouncement() if err != nil { return nil, nil, err } } - return chanAnn, chanUpdate, err + return chanAnn, chanUpdate, nil } // SyncManager returns the gossiper's SyncManager instance. @@ -3703,7 +3676,7 @@ func (d *AuthenticatedGossiper) handleAnnSig(ctx context.Context, ann.ChannelID, peerID) ca, _, _, err := netann.CreateChanAnnouncement( - chanInfo.AuthProof, chanInfo, e1, e2, + chanInfo, e1, e2, ) if err != nil { log.Errorf("unable to gen ann: %v", @@ -3782,8 +3755,12 @@ func (d *AuthenticatedGossiper) handleAnnSig(ctx context.Context, ) } + // Attach the proof to the channel info before creating the + // announcement. + chanInfo.AuthProof = dbProof + chanAnn, e1Ann, e2Ann, err := netann.CreateChanAnnouncement( - dbProof, chanInfo, e1, e2, + chanInfo, e1, e2, ) if err != nil { log.Error(err) diff --git a/graph/db/models/channel_edge_info.go b/graph/db/models/channel_edge_info.go index 7e872c5cd..9f9477064 100644 --- a/graph/db/models/channel_edge_info.go +++ b/graph/db/models/channel_edge_info.go @@ -199,3 +199,66 @@ func (c *ChannelEdgeInfo) OtherNodeKeyBytes(thisNodeKey []byte) ( "this channel") } } + +// ToChannelAnnouncement converts the ChannelEdgeInfo to a +// lnwire.ChannelAnnouncement1 message. Returns an error if AuthProof is nil +// or if the version is not v1. +func (c *ChannelEdgeInfo) ToChannelAnnouncement() ( + *lnwire.ChannelAnnouncement1, error) { + + // We currently only support v1 channel announcements. + if c.Version != lnwire.GossipVersion1 { + return nil, fmt.Errorf("unsupported channel version: %d", + c.Version) + } + + // If there's no auth proof, we can't create a full channel + // announcement. + if c.AuthProof == nil { + return nil, fmt.Errorf("cannot create channel announcement " + + "without auth proof") + } + + chanID := lnwire.NewShortChanIDFromInt(c.ChannelID) + chanAnn := &lnwire.ChannelAnnouncement1{ + ShortChannelID: chanID, + NodeID1: c.NodeKey1Bytes, + NodeID2: c.NodeKey2Bytes, + ChainHash: c.ChainHash, + BitcoinKey1: c.BitcoinKey1Bytes, + BitcoinKey2: c.BitcoinKey2Bytes, + Features: c.Features.RawFeatureVector, + ExtraOpaqueData: c.ExtraOpaqueData, + } + + var err error + chanAnn.NodeSig1, err = lnwire.NewSigFromECDSARawSignature( + c.AuthProof.NodeSig1(), + ) + if err != nil { + return nil, err + } + + chanAnn.NodeSig2, err = lnwire.NewSigFromECDSARawSignature( + c.AuthProof.NodeSig2(), + ) + if err != nil { + return nil, err + } + + chanAnn.BitcoinSig1, err = lnwire.NewSigFromECDSARawSignature( + c.AuthProof.BitcoinSig1(), + ) + if err != nil { + return nil, err + } + + chanAnn.BitcoinSig2, err = lnwire.NewSigFromECDSARawSignature( + c.AuthProof.BitcoinSig2(), + ) + if err != nil { + return nil, err + } + + return chanAnn, nil +} diff --git a/netann/channel_announcement.go b/netann/channel_announcement.go index fee3c5abf..14f65c3f5 100644 --- a/netann/channel_announcement.go +++ b/netann/channel_announcement.go @@ -34,48 +34,14 @@ const ( // function is used to transform out database structs into the corresponding wire // structs for announcing new channels to other peers, or simply syncing up a // peer's initial routing table upon connect. -func CreateChanAnnouncement(chanProof *models.ChannelAuthProof, - chanInfo *models.ChannelEdgeInfo, +func CreateChanAnnouncement(chanInfo *models.ChannelEdgeInfo, e1, e2 *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement1, *lnwire.ChannelUpdate1, *lnwire.ChannelUpdate1, error) { // First, using the parameters of the channel, along with the channel - // authentication chanProof, we'll create re-create the original + // authentication proof, we'll create re-create the original // authenticated channel announcement. - chanID := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID) - chanAnn := &lnwire.ChannelAnnouncement1{ - ShortChannelID: chanID, - NodeID1: chanInfo.NodeKey1Bytes, - NodeID2: chanInfo.NodeKey2Bytes, - ChainHash: chanInfo.ChainHash, - BitcoinKey1: chanInfo.BitcoinKey1Bytes, - BitcoinKey2: chanInfo.BitcoinKey2Bytes, - Features: chanInfo.Features.RawFeatureVector, - ExtraOpaqueData: chanInfo.ExtraOpaqueData, - } - - var err error - chanAnn.BitcoinSig1, err = lnwire.NewSigFromECDSARawSignature( - chanProof.BitcoinSig1(), - ) - if err != nil { - return nil, nil, nil, err - } - chanAnn.BitcoinSig2, err = lnwire.NewSigFromECDSARawSignature( - chanProof.BitcoinSig2(), - ) - if err != nil { - return nil, nil, nil, err - } - chanAnn.NodeSig1, err = lnwire.NewSigFromECDSARawSignature( - chanProof.NodeSig1(), - ) - if err != nil { - return nil, nil, nil, err - } - chanAnn.NodeSig2, err = lnwire.NewSigFromECDSARawSignature( - chanProof.NodeSig2(), - ) + chanAnn, err := chanInfo.ToChannelAnnouncement() if err != nil { return nil, nil, nil, err } diff --git a/netann/channel_announcement_test.go b/netann/channel_announcement_test.go index c46b90a9d..11e72bb4a 100644 --- a/netann/channel_announcement_test.go +++ b/netann/channel_announcement_test.go @@ -59,9 +59,7 @@ func TestCreateChanAnnouncement(t *testing.T) { models.WithFeatures(features), ) require.NoError(t, err) - chanAnn, _, _, err := CreateChanAnnouncement( - chanProof, chanInfo, nil, nil, - ) + chanAnn, _, _, err := CreateChanAnnouncement(chanInfo, nil, nil) require.NoError(t, err, "unable to create channel announcement") assert.Equal(t, chanAnn, expChanAnn)