From efabd2fbc788dce3eadd3ede161d90a6d93632a1 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 12:03:20 +0200 Subject: [PATCH 01/20] multi: rename AnnounceSignatures to AnnounceSignatures1 In preparation for adding a new message, AnnounceSignatures2 along with an AnnounceSignatures interface, we rename the existing message to AnnounceSignatures1. --- channeldb/migration/lnwire21/message.go | 2 +- channeldb/waitingproof.go | 21 ++++++++++----------- channeldb/waitingproof_test.go | 2 +- discovery/gossiper.go | 10 +++++----- discovery/gossiper_test.go | 16 ++++++++-------- discovery/message_store.go | 2 +- discovery/message_store_test.go | 8 ++++---- discovery/reliable_sender.go | 2 +- discovery/reliable_sender_test.go | 2 +- funding/manager.go | 6 +++--- funding/manager_test.go | 4 ++-- lnwire/announcement_signatures.go | 18 +++++++++--------- lnwire/lnwire_test.go | 4 ++-- lnwire/message.go | 4 ++-- lnwire/message_test.go | 4 ++-- peer/brontide.go | 4 ++-- routing/validation_barrier.go | 6 +++--- 17 files changed, 57 insertions(+), 58 deletions(-) diff --git a/channeldb/migration/lnwire21/message.go b/channeldb/migration/lnwire21/message.go index cf88e48a6f..a7be3f98c5 100644 --- a/channeldb/migration/lnwire21/message.go +++ b/channeldb/migration/lnwire21/message.go @@ -100,7 +100,7 @@ func (t MessageType) String() string { case MsgPing: return "Ping" case MsgAnnounceSignatures: - return "AnnounceSignatures" + return "AnnounceSignatures1" case MsgPong: return "Pong" case MsgUpdateFee: diff --git a/channeldb/waitingproof.go b/channeldb/waitingproof.go index c6b2b9df52..71f69ad7f2 100644 --- a/channeldb/waitingproof.go +++ b/channeldb/waitingproof.go @@ -191,15 +191,17 @@ type WaitingProofKey [9]byte // needed to make channel proof exchange persistent, so that after client // restart we may receive remote/local half proof and process it. type WaitingProof struct { - *lnwire.AnnounceSignatures + *lnwire.AnnounceSignatures1 isRemote bool } // NewWaitingProof constructs a new waiting prof instance. -func NewWaitingProof(isRemote bool, proof *lnwire.AnnounceSignatures) *WaitingProof { +func NewWaitingProof(isRemote bool, + proof *lnwire.AnnounceSignatures1) *WaitingProof { + return &WaitingProof{ - AnnounceSignatures: proof, - isRemote: isRemote, + AnnounceSignatures1: proof, + isRemote: isRemote, } } @@ -238,11 +240,7 @@ func (p *WaitingProof) Encode(w io.Writer) error { return fmt.Errorf("expect io.Writer to be *bytes.Buffer") } - if err := p.AnnounceSignatures.Encode(buf, 0); err != nil { - return err - } - - return nil + return p.AnnounceSignatures1.Encode(buf, 0) } // Decode reads the data from the byte stream and initializes the @@ -252,11 +250,12 @@ func (p *WaitingProof) Decode(r io.Reader) error { return err } - msg := &lnwire.AnnounceSignatures{} + msg := &lnwire.AnnounceSignatures1{} if err := msg.Decode(r, 0); err != nil { return err } - (*p).AnnounceSignatures = msg + p.AnnounceSignatures1 = msg + return nil } diff --git a/channeldb/waitingproof_test.go b/channeldb/waitingproof_test.go index 1a00c829e0..d7113d9e75 100644 --- a/channeldb/waitingproof_test.go +++ b/channeldb/waitingproof_test.go @@ -18,7 +18,7 @@ func TestWaitingProofStore(t *testing.T) { db, err := MakeTestDB(t) require.NoError(t, err, "failed to make test database") - proof1 := NewWaitingProof(true, &lnwire.AnnounceSignatures{ + proof1 := NewWaitingProof(true, &lnwire.AnnounceSignatures1{ NodeSignature: wireSig, BitcoinSignature: wireSig, ExtraOpaqueData: make([]byte, 0), diff --git a/discovery/gossiper.go b/discovery/gossiper.go index d2d2fb993f..8b5bfd6a1d 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -1386,7 +1386,7 @@ func (d *AuthenticatedGossiper) networkHandler() { switch announcement.msg.(type) { // Channel announcement signatures are amongst the only // messages that we'll process serially. - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: emittedAnnouncements, _ := d.processNetworkAnnouncement( announcement, ) @@ -2010,7 +2010,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement( // A new signature announcement has been received. This indicates // willingness of nodes involved in the funding of a channel to // announce this new channel to the rest of the world. - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: return d.handleAnnSig(nMsg, msg) default: @@ -2086,7 +2086,7 @@ func (d *AuthenticatedGossiper) fetchNodeAnn( // MessageStore is seen as stale by the current graph. func (d *AuthenticatedGossiper) isMsgStale(msg lnwire.Message) bool { switch msg := msg.(type) { - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: chanInfo, _, _, err := d.cfg.Router.GetChannelByID( msg.ShortChannelID, ) @@ -3027,7 +3027,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, // handleAnnSig processes a new announcement signatures message. func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg, - ann *lnwire.AnnounceSignatures) ([]networkMsg, bool) { + ann *lnwire.AnnounceSignatures1) ([]networkMsg, bool) { needBlockHeight := ann.ShortChannelID.BlockHeight + d.cfg.ProofMatureDelta @@ -3143,7 +3143,7 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg, // proof yet. So be kind and send them the full proof. if nMsg.isRemote { peerID := nMsg.source.SerializeCompressed() - log.Debugf("Got AnnounceSignatures for channel with " + + log.Debugf("Got AnnounceSignatures1 for channel with " + "full proof.") d.wg.Add(1) diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index a47d98bb95..ee3b421634 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -465,8 +465,8 @@ type annBatch struct { chanUpdAnn1 *lnwire.ChannelUpdate chanUpdAnn2 *lnwire.ChannelUpdate - localProofAnn *lnwire.AnnounceSignatures - remoteProofAnn *lnwire.AnnounceSignatures + localProofAnn *lnwire.AnnounceSignatures1 + remoteProofAnn *lnwire.AnnounceSignatures1 } func createLocalAnnouncements(blockHeight uint32) (*annBatch, error) { @@ -497,7 +497,7 @@ func createAnnouncements(blockHeight uint32, key1, key2 *btcec.PrivateKey) (*ann return nil, err } - batch.remoteProofAnn = &lnwire.AnnounceSignatures{ + batch.remoteProofAnn = &lnwire.AnnounceSignatures1{ ShortChannelID: lnwire.ShortChannelID{ BlockHeight: blockHeight, }, @@ -505,7 +505,7 @@ func createAnnouncements(blockHeight uint32, key1, key2 *btcec.PrivateKey) (*ann BitcoinSignature: batch.chanAnn.BitcoinSig2, } - batch.localProofAnn = &lnwire.AnnounceSignatures{ + batch.localProofAnn = &lnwire.AnnounceSignatures1{ ShortChannelID: lnwire.ShortChannelID{ BlockHeight: blockHeight, }, @@ -1327,7 +1327,7 @@ func TestOrphanSignatureAnnouncement(t *testing.T) { } // TestSignatureAnnouncementRetryAtStartup tests that if we restart the -// gossiper, it will retry sending the AnnounceSignatures to the peer if it did +// gossiper, it will retry sending the AnnounceSignatures1 to the peer if it did // not succeed before shutting down, and the full channel proof is not yet // assembled. func TestSignatureAnnouncementRetryAtStartup(t *testing.T) { @@ -1511,7 +1511,7 @@ out: case msg := <-sentToPeer: // Since the ChannelUpdate will also be resent as it is // sent reliably, we'll need to filter it out. - if _, ok := msg.(*lnwire.AnnounceSignatures); !ok { + if _, ok := msg.(*lnwire.AnnounceSignatures1); !ok { continue } @@ -3248,7 +3248,7 @@ func TestSendChannelUpdateReliably(t *testing.T) { peerChan <- remotePeer - // At this point, we should have sent both the AnnounceSignatures and + // At this point, we should have sent both the AnnounceSignatures1 and // stale ChannelUpdate. for i := 0; i < 2; i++ { var msg lnwire.Message @@ -3261,7 +3261,7 @@ func TestSendChannelUpdateReliably(t *testing.T) { switch msg := msg.(type) { case *lnwire.ChannelUpdate: assertMessage(t, staleChannelUpdate, msg) - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: assertMessage(t, batch.localProofAnn, msg) default: t.Fatalf("send unexpected %v message", msg.MsgType()) diff --git a/discovery/message_store.go b/discovery/message_store.go index cf228eee71..e89a65eefa 100644 --- a/discovery/message_store.go +++ b/discovery/message_store.go @@ -83,7 +83,7 @@ func NewMessageStore(db kvdb.Backend) (*MessageStore, error) { func msgShortChanID(msg lnwire.Message) (lnwire.ShortChannelID, error) { var shortChanID lnwire.ShortChannelID switch msg := msg.(type) { - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: shortChanID = msg.ShortChannelID case *lnwire.ChannelUpdate: shortChanID = msg.ShortChannelID diff --git a/discovery/message_store_test.go b/discovery/message_store_test.go index e812c3f1a3..9027c68611 100644 --- a/discovery/message_store_test.go +++ b/discovery/message_store_test.go @@ -52,8 +52,8 @@ func randCompressedPubKey(t *testing.T) [33]byte { return compressedPubKey } -func randAnnounceSignatures() *lnwire.AnnounceSignatures { - return &lnwire.AnnounceSignatures{ +func randAnnounceSignatures() *lnwire.AnnounceSignatures1 { + return &lnwire.AnnounceSignatures1{ ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), ExtraOpaqueData: make([]byte, 0), } @@ -116,7 +116,7 @@ func TestMessageStoreMessages(t *testing.T) { for _, msg := range peerMsgs { var shortChanID uint64 switch msg := msg.(type) { - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: shortChanID = msg.ShortChannelID.ToUint64() case *lnwire.ChannelUpdate: shortChanID = msg.ShortChannelID.ToUint64() @@ -281,7 +281,7 @@ func TestMessageStoreDeleteMessage(t *testing.T) { } } - // An AnnounceSignatures message should exist within the store after + // An AnnounceSignatures1 message should exist within the store after // adding it, and should no longer exists after deleting it. peer := randCompressedPubKey(t) annSig := randAnnounceSignatures() diff --git a/discovery/reliable_sender.go b/discovery/reliable_sender.go index b4d32e73fd..2a0fca9ed2 100644 --- a/discovery/reliable_sender.go +++ b/discovery/reliable_sender.go @@ -250,7 +250,7 @@ out: // Now that the message has at least been sent once, we can // check whether it's stale. This guarantees that - // AnnounceSignatures are sent at least once if we happen to + // AnnounceSignatures1 are sent at least once if we happen to // already have signatures for both parties. if s.cfg.IsMsgStale(msg) { err := s.cfg.MessageStore.DeleteMessage(msg, peerPubKey) diff --git a/discovery/reliable_sender_test.go b/discovery/reliable_sender_test.go index d1e69b11fb..8835af42f4 100644 --- a/discovery/reliable_sender_test.go +++ b/discovery/reliable_sender_test.go @@ -283,7 +283,7 @@ func TestReliableSenderStaleMessages(t *testing.T) { // Finally, notifying the peer is online should prompt the message to be // sent. Only the ChannelUpdate will be sent in this case since the - // AnnounceSignatures message above was seen as stale. + // AnnounceSignatures1 message above was seen as stale. peerChan <- peer assertMsgsSent(t, peer.sentMsgs, msg2) diff --git a/funding/manager.go b/funding/manager.go index f87db443d2..70b7910936 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -4052,7 +4052,7 @@ func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID, type chanAnnouncement struct { chanAnn *lnwire.ChannelAnnouncement chanUpdateAnn *lnwire.ChannelUpdate - chanProof *lnwire.AnnounceSignatures + chanProof *lnwire.AnnounceSignatures1 } // newChanAnnouncement creates the authenticated channel announcement messages @@ -4244,7 +4244,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, // Finally, we'll generate the announcement proof which we'll use to // provide the other side with the necessary signatures required to // allow them to reconstruct the full channel announcement. - proof := &lnwire.AnnounceSignatures{ + proof := &lnwire.AnnounceSignatures1{ ChannelID: chanID, ShortChannelID: shortChanID, } @@ -4304,7 +4304,7 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey, routing.ErrIgnored) { log.Debugf("Router rejected "+ - "AnnounceSignatures: %v", err) + "AnnounceSignatures1: %v", err) } else { log.Errorf("Unable to send channel "+ "proof: %v", err) diff --git a/funding/manager_test.go b/funding/manager_test.go index d6a0a4427d..2320c99b36 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -1284,7 +1284,7 @@ func assertAnnouncementSignatures(t *testing.T, alice, bob *testNode) { gotNodeAnnouncement := false for _, msg := range announcements { switch msg.(type) { - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: gotAnnounceSignatures = true case *lnwire.NodeAnnouncement: gotNodeAnnouncement = true @@ -1292,7 +1292,7 @@ func assertAnnouncementSignatures(t *testing.T, alice, bob *testNode) { } if !gotAnnounceSignatures { - t.Fatalf("did not get AnnounceSignatures from node %d", + t.Fatalf("did not get AnnounceSignatures1 from node %d", j) } if !gotNodeAnnouncement { diff --git a/lnwire/announcement_signatures.go b/lnwire/announcement_signatures.go index 49b6106119..3f0e72803d 100644 --- a/lnwire/announcement_signatures.go +++ b/lnwire/announcement_signatures.go @@ -5,11 +5,11 @@ import ( "io" ) -// AnnounceSignatures is a direct message between two endpoints of a +// AnnounceSignatures1 is a direct message between two endpoints of a // channel and serves as an opt-in mechanism to allow the announcement of // the channel to the rest of the network. It contains the necessary // signatures by the sender to construct the channel announcement message. -type AnnounceSignatures struct { +type AnnounceSignatures1 struct { // ChannelID is the unique description of the funding transaction. // Channel id is better for users and debugging and short channel id is // used for quick test on existence of the particular utxo inside the @@ -43,15 +43,15 @@ type AnnounceSignatures struct { ExtraOpaqueData ExtraOpaqueData } -// A compile time check to ensure AnnounceSignatures implements the +// A compile time check to ensure AnnounceSignatures1 implements the // lnwire.Message interface. -var _ Message = (*AnnounceSignatures)(nil) +var _ Message = (*AnnounceSignatures1)(nil) -// Decode deserializes a serialized AnnounceSignatures stored in the passed +// Decode deserializes a serialized AnnounceSignatures1 stored in the passed // io.Reader observing the specified protocol version. // // This is part of the lnwire.Message interface. -func (a *AnnounceSignatures) Decode(r io.Reader, pver uint32) error { +func (a *AnnounceSignatures1) Decode(r io.Reader, pver uint32) error { return ReadElements(r, &a.ChannelID, &a.ShortChannelID, @@ -61,11 +61,11 @@ func (a *AnnounceSignatures) Decode(r io.Reader, pver uint32) error { ) } -// Encode serializes the target AnnounceSignatures into the passed io.Writer +// Encode serializes the target AnnounceSignatures1 into the passed io.Writer // observing the protocol version specified. // // This is part of the lnwire.Message interface. -func (a *AnnounceSignatures) Encode(w *bytes.Buffer, pver uint32) error { +func (a *AnnounceSignatures1) Encode(w *bytes.Buffer, pver uint32) error { if err := WriteChannelID(w, a.ChannelID); err != nil { return err } @@ -89,6 +89,6 @@ func (a *AnnounceSignatures) Encode(w *bytes.Buffer, pver uint32) error { // wire. // // This is part of the lnwire.Message interface. -func (a *AnnounceSignatures) MsgType() MessageType { +func (a *AnnounceSignatures1) MsgType() MessageType { return MsgAnnounceSignatures } diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index f5c028581b..8c204d9dd2 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -934,7 +934,7 @@ func TestLightningWireProtocol(t *testing.T) { }, MsgAnnounceSignatures: func(v []reflect.Value, r *rand.Rand) { var err error - req := AnnounceSignatures{ + req := AnnounceSignatures1{ ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), ExtraOpaqueData: make([]byte, 0), } @@ -1222,7 +1222,7 @@ func TestLightningWireProtocol(t *testing.T) { }, { msgType: MsgAnnounceSignatures, - scenario: func(m AnnounceSignatures) bool { + scenario: func(m AnnounceSignatures1) bool { return mainScenario(&m) }, }, diff --git a/lnwire/message.go b/lnwire/message.go index 02447b806c..7eb6a2de26 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -119,7 +119,7 @@ func (t MessageType) String() string { case MsgPing: return "Ping" case MsgAnnounceSignatures: - return "AnnounceSignatures" + return "AnnounceSignatures1" case MsgPong: return "Pong" case MsgUpdateFee: @@ -223,7 +223,7 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { case MsgPing: msg = &Ping{} case MsgAnnounceSignatures: - msg = &AnnounceSignatures{} + msg = &AnnounceSignatures1{} case MsgPong: msg = &Pong{} case MsgQueryShortChanIDs: diff --git a/lnwire/message_test.go b/lnwire/message_test.go index bbb434785f..1a3c61ac21 100644 --- a/lnwire/message_test.go +++ b/lnwire/message_test.go @@ -727,11 +727,11 @@ func newMsgChannelUpdate(t testing.TB, r *rand.Rand) *lnwire.ChannelUpdate { } func newMsgAnnounceSignatures(t testing.TB, - r *rand.Rand) *lnwire.AnnounceSignatures { + r *rand.Rand) *lnwire.AnnounceSignatures1 { t.Helper() - msg := &lnwire.AnnounceSignatures{ + msg := &lnwire.AnnounceSignatures1{ ShortChannelID: lnwire.NewShortChanIDFromInt( uint64(r.Int63()), ), diff --git a/peer/brontide.go b/peer/brontide.go index 4c7694085a..6dc2f8634f 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -1733,7 +1733,7 @@ out: case *lnwire.ChannelUpdate, *lnwire.ChannelAnnouncement, *lnwire.NodeAnnouncement, - *lnwire.AnnounceSignatures, + *lnwire.AnnounceSignatures1, *lnwire.GossipTimestampRange, *lnwire.QueryShortChanIDs, *lnwire.QueryChannelRange, @@ -1980,7 +1980,7 @@ func messageSummary(msg lnwire.Message) string { case *lnwire.Error: return fmt.Sprintf("%v", msg.Error()) - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: return fmt.Sprintf("chan_id=%v, short_chan_id=%v", msg.ChannelID, msg.ShortChannelID.ToUint64()) diff --git a/routing/validation_barrier.go b/routing/validation_barrier.go index aeef3d4b81..52b7399da8 100644 --- a/routing/validation_barrier.go +++ b/routing/validation_barrier.go @@ -153,7 +153,7 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) { return case *channeldb.LightningNode: return - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: // TODO(roasbeef): need to wait on chan ann? return } @@ -216,7 +216,7 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { // Other types of jobs can be executed immediately, so we'll just // return directly. - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: // TODO(roasbeef): need to wait on chan ann? case *models.ChannelEdgeInfo: case *lnwire.ChannelAnnouncement: @@ -301,7 +301,7 @@ func (v *ValidationBarrier) SignalDependants(job interface{}, allow bool) { shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID) delete(v.chanEdgeDependencies, shortID) - case *lnwire.AnnounceSignatures: + case *lnwire.AnnounceSignatures1: return } } From a94a23c9ea8c144a325f8ea0ac5784704172ab96 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 12:05:52 +0200 Subject: [PATCH 02/20] multi: rename ChannelAnnouncement to ChannelAnnouncment1 In preparation for adding the new ChannelAnnouncement2 message along with a ChannelAnnouncement interface, we rename the existing message to ChannelAnnouncement1. --- discovery/gossiper.go | 40 ++++++++++++++--------------- discovery/gossiper_test.go | 29 +++++++++++---------- discovery/syncer.go | 2 +- discovery/syncer_test.go | 10 ++++---- funding/manager.go | 16 ++++++------ funding/manager_test.go | 12 ++++----- lnwire/channel_announcement.go | 20 +++++++-------- lnwire/lnwire_test.go | 4 +-- lnwire/message.go | 4 +-- lnwire/message_test.go | 4 +-- netann/channel_announcement.go | 4 +-- netann/channel_announcement_test.go | 2 +- netann/sign.go | 2 +- peer/brontide.go | 4 +-- routing/ann_validation.go | 2 +- routing/router.go | 2 +- routing/validation_barrier.go | 16 ++++++------ routing/validation_barrier_test.go | 4 +-- 18 files changed, 89 insertions(+), 88 deletions(-) diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 8b5bfd6a1d..eeb979606e 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -421,7 +421,7 @@ type AuthenticatedGossiper struct { // prematureChannelUpdates is a map of ChannelUpdates we have received // that wasn't associated with any channel we know about. We store // them temporarily, such that we can reprocess them when a - // ChannelAnnouncement for the channel is received. + // ChannelAnnouncement1 for the channel is received. prematureChannelUpdates *lru.Cache[uint64, *cachedNetworkMsg] // networkMsgs is a channel that carries new network broadcasted @@ -819,9 +819,9 @@ func (d *AuthenticatedGossiper) ProcessRemoteAnnouncement(msg lnwire.Message, // To avoid inserting edges in the graph for our own channels that we // have already closed, we ignore such channel announcements coming // from the remote. - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: ownKey := d.selfKey.SerializeCompressed() - ownErr := fmt.Errorf("ignoring remote ChannelAnnouncement " + + ownErr := fmt.Errorf("ignoring remote ChannelAnnouncement1 " + "for own channel") if bytes.Equal(m.NodeID1[:], ownKey) || @@ -981,7 +981,7 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) { switch msg := message.msg.(type) { // Channel announcements are identified by the short channel id field. - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: deDupKey := msg.ShortChannelID sender := route.NewVertex(message.source) @@ -1555,7 +1555,7 @@ func (d *AuthenticatedGossiper) isRecentlyRejectedMsg(msg lnwire.Message, case *lnwire.ChannelUpdate: scid = m.ShortChannelID.ToUint64() - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: scid = m.ShortChannelID.ToUint64() default: @@ -1811,9 +1811,9 @@ func remotePubFromChanInfo(chanInfo *models.ChannelEdgeInfo, // contains a proof, we can add this proof to our edge. We can end up in this // situation in the case where we create a channel, but for some reason fail // to receive the remote peer's proof, while the remote peer is able to fully -// assemble the proof and craft the ChannelAnnouncement. +// assemble the proof and craft the ChannelAnnouncement1. func (d *AuthenticatedGossiper) processRejectedEdge( - chanAnnMsg *lnwire.ChannelAnnouncement, + chanAnnMsg *lnwire.ChannelAnnouncement1, proof *models.ChannelAuthProof) ([]networkMsg, error) { // First, we'll fetch the state of the channel as we know if from the @@ -1998,7 +1998,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement( // *creation* of a new channel within the network. This only advertises // the existence of a channel and not yet the routing policies in // either direction of the channel. - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: return d.handleChanAnnouncement(nMsg, msg, schedulerOp) // A new authenticated channel edge update has arrived. This indicates @@ -2152,7 +2152,7 @@ func (d *AuthenticatedGossiper) isMsgStale(msg lnwire.Message) bool { // updateChannel creates a new fully signed update for the channel, and updates // the underlying graph with the new state. func (d *AuthenticatedGossiper) updateChannel(info *models.ChannelEdgeInfo, - edge *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, + edge *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement1, *lnwire.ChannelUpdate, error) { // Parse the unsigned edge into a channel update. @@ -2189,10 +2189,10 @@ func (d *AuthenticatedGossiper) updateChannel(info *models.ChannelEdgeInfo, // We'll also create the original channel announcement so the two can // be broadcast along side each other (if necessary), but only if we // have a full channel announcement for this channel. - var chanAnn *lnwire.ChannelAnnouncement + var chanAnn *lnwire.ChannelAnnouncement1 if info.AuthProof != nil { chanID := lnwire.NewShortChanIDFromInt(info.ChannelID) - chanAnn = &lnwire.ChannelAnnouncement{ + chanAnn = &lnwire.ChannelAnnouncement1{ ShortChannelID: chanID, NodeID1: info.NodeKey1Bytes, NodeID2: info.NodeKey2Bytes, @@ -2364,16 +2364,16 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(nMsg *networkMsg, // handleChanAnnouncement processes a new channel announcement. func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, - ann *lnwire.ChannelAnnouncement, + ann *lnwire.ChannelAnnouncement1, ops []batch.SchedulerOption) ([]networkMsg, bool) { - log.Debugf("Processing ChannelAnnouncement: peer=%v, short_chan_id=%v", + log.Debugf("Processing ChannelAnnouncement1: peer=%v, short_chan_id=%v", nMsg.peer, ann.ShortChannelID.ToUint64()) // We'll ignore any channel announcements that target any chain other // than the set of chains we know of. if !bytes.Equal(ann.ChainHash[:], d.cfg.ChainHash[:]) { - err := fmt.Errorf("ignoring ChannelAnnouncement from chain=%v"+ + err := fmt.Errorf("ignoring ChannelAnnouncement1 from chain=%v"+ ", gossiper on chain=%v", ann.ChainHash, d.cfg.ChainHash) log.Errorf(err.Error()) @@ -2388,7 +2388,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, return nil, false } - // If this is a remote ChannelAnnouncement with an alias SCID, we'll + // If this is a remote ChannelAnnouncement1 with an alias SCID, we'll // reject the announcement. Since the router accepts alias SCIDs, // not erroring out would be a DoS vector. if nMsg.isRemote && d.cfg.IsAlias(ann.ShortChannelID) { @@ -2631,7 +2631,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, nMsg.err <- nil - log.Debugf("Processed ChannelAnnouncement: peer=%v, short_chan_id=%v", + log.Debugf("Processed ChannelAnnouncement1: peer=%v, short_chan_id=%v", nMsg.peer, ann.ShortChannelID.ToUint64()) return announcements, true @@ -2739,7 +2739,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, } // We'll fallthrough to ensure we stash the update until we - // receive its corresponding ChannelAnnouncement. This is + // receive its corresponding ChannelAnnouncement1. This is // needed to ensure the edge exists in the graph before // applying the update. fallthrough @@ -2751,15 +2751,15 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, // If the edge corresponding to this ChannelUpdate was not // found in the graph, this might be a channel in the process // of being opened, and we haven't processed our own - // ChannelAnnouncement yet, hence it is not not found in the + // ChannelAnnouncement1 yet, hence it is not found in the // graph. This usually gets resolved after the channel proofs // are exchanged and the channel is broadcasted to the rest of // the network, but in case this is a private channel this // won't ever happen. This can also happen in the case of a // zombie channel with a fresh update for which we don't have a - // ChannelAnnouncement for since we reject them. Because of + // ChannelAnnouncement1 for since we reject them. Because of // this, we temporarily add it to a map, and reprocess it after - // our own ChannelAnnouncement has been processed. + // our own ChannelAnnouncement1 has been processed. // // The shortChanID may be an alias, but it is fine to use here // since we don't have an edge in the graph and if the peer is diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index ee3b421634..09f2eaab38 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -460,7 +460,7 @@ type annBatch struct { nodeAnn1 *lnwire.NodeAnnouncement nodeAnn2 *lnwire.NodeAnnouncement - chanAnn *lnwire.ChannelAnnouncement + chanAnn *lnwire.ChannelAnnouncement1 chanUpdAnn1 *lnwire.ChannelUpdate chanUpdAnn2 *lnwire.ChannelUpdate @@ -619,9 +619,9 @@ func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate) error { func createAnnouncementWithoutProof(blockHeight uint32, key1, key2 *btcec.PublicKey, - extraBytes ...[]byte) *lnwire.ChannelAnnouncement { + extraBytes ...[]byte) *lnwire.ChannelAnnouncement1 { - a := &lnwire.ChannelAnnouncement{ + a := &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.ShortChannelID{ BlockHeight: blockHeight, TxIndex: 0, @@ -641,13 +641,13 @@ func createAnnouncementWithoutProof(blockHeight uint32, } func createRemoteChannelAnnouncement(blockHeight uint32, - extraBytes ...[]byte) (*lnwire.ChannelAnnouncement, error) { + extraBytes ...[]byte) (*lnwire.ChannelAnnouncement1, error) { return createChannelAnnouncement(blockHeight, remoteKeyPriv1, remoteKeyPriv2, extraBytes...) } func createChannelAnnouncement(blockHeight uint32, key1, key2 *btcec.PrivateKey, - extraBytes ...[]byte) (*lnwire.ChannelAnnouncement, error) { + extraBytes ...[]byte) (*lnwire.ChannelAnnouncement1, error) { a := createAnnouncementWithoutProof(blockHeight, key1.PubKey(), key2.PubKey(), extraBytes...) @@ -1562,7 +1562,7 @@ out: // TestSignatureAnnouncementFullProofWhenRemoteProof tests that if a remote // proof is received when we already have the full proof, the gossiper will send -// the full proof (ChannelAnnouncement) to the remote peer. +// the full proof (ChannelAnnouncement1) to the remote peer. func TestSignatureAnnouncementFullProofWhenRemoteProof(t *testing.T) { t.Parallel() @@ -1724,7 +1724,7 @@ func TestSignatureAnnouncementFullProofWhenRemoteProof(t *testing.T) { } // Now give the gossiper the remote proof yet again. This should - // trigger a send of the full ChannelAnnouncement. + // trigger a send of the full ChannelAnnouncement1. select { case err = <-ctx.gossiper.ProcessRemoteAnnouncement( batch.remoteProofAnn, remotePeer, @@ -1737,9 +1737,10 @@ func TestSignatureAnnouncementFullProofWhenRemoteProof(t *testing.T) { // We expect the gossiper to send this message to the remote peer. select { case msg := <-sentToPeer: - _, ok := msg.(*lnwire.ChannelAnnouncement) + _, ok := msg.(*lnwire.ChannelAnnouncement1) if !ok { - t.Fatalf("expected ChannelAnnouncement, instead got %T", msg) + t.Fatalf("expected ChannelAnnouncement1, instead got "+ + "%T", msg) } case <-time.After(2 * time.Second): t.Fatal("did not send local proof to peer") @@ -2054,7 +2055,7 @@ func TestForwardPrivateNodeAnnouncement(t *testing.T) { // Now, we'll attempt to forward the NodeAnnouncement for the same node // by opening a public channel on the network. We'll create a - // ChannelAnnouncement and hand it off to the gossiper in order to + // ChannelAnnouncement1 and hand it off to the gossiper in order to // process it. remoteChanAnn, err := createRemoteChannelAnnouncement(startingHeight - 1) require.NoError(t, err, "unable to create remote channel announcement") @@ -2356,8 +2357,8 @@ func TestProcessZombieEdgeNowLive(t *testing.T) { } // TestReceiveRemoteChannelUpdateFirst tests that if we receive a ChannelUpdate -// from the remote before we have processed our own ChannelAnnouncement, it will -// be reprocessed later, after our ChannelAnnouncement. +// from the remote before we have processed our own ChannelAnnouncement1, it will +// be reprocessed later, after our ChannelAnnouncement1. func TestReceiveRemoteChannelUpdateFirst(t *testing.T) { t.Parallel() @@ -2553,7 +2554,7 @@ func TestReceiveRemoteChannelUpdateFirst(t *testing.T) { } // TestExtraDataChannelAnnouncementValidation tests that we're able to properly -// validate a ChannelAnnouncement that includes opaque bytes that we don't +// validate a ChannelAnnouncement1 that includes opaque bytes that we don't // currently know of. func TestExtraDataChannelAnnouncementValidation(t *testing.T) { t.Parallel() @@ -2772,7 +2773,7 @@ func TestRetransmit(t *testing.T) { var chanAnn, chanUpd, nodeAnn int for _, msg := range anns { switch msg.(type) { - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: chanAnn++ case *lnwire.ChannelUpdate: chanUpd++ diff --git a/discovery/syncer.go b/discovery/syncer.go index 722519fb08..72174ea666 100644 --- a/discovery/syncer.go +++ b/discovery/syncer.go @@ -1314,7 +1314,7 @@ func (g *GossipSyncer) FilterGossipMsgs(msgs ...msgWithSenders) { // For each channel announcement message, we'll only send this // message if the channel updates for the channel are between // our time range. - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: // First, we'll check if the channel updates are in // this message batch. chanUpdates, ok := chanUpdateIndex[msg.ShortChannelID] diff --git a/discovery/syncer_test.go b/discovery/syncer_test.go index a7b514db8c..1fe94441b2 100644 --- a/discovery/syncer_test.go +++ b/discovery/syncer_test.go @@ -283,7 +283,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { }, { // Ann tuple below horizon. - msg: &lnwire.ChannelAnnouncement{ + msg: &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(10), }, }, @@ -295,7 +295,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { }, { // Ann tuple above horizon. - msg: &lnwire.ChannelAnnouncement{ + msg: &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(15), }, }, @@ -307,7 +307,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { }, { // Ann tuple beyond horizon. - msg: &lnwire.ChannelAnnouncement{ + msg: &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(20), }, }, @@ -320,7 +320,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { { // Ann w/o an update at all, the update in the DB will // be below the horizon. - msg: &lnwire.ChannelAnnouncement{ + msg: &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(25), }, }, @@ -683,7 +683,7 @@ func TestGossipSyncerReplyShortChanIDs(t *testing.T) { } queryReply := []lnwire.Message{ - &lnwire.ChannelAnnouncement{ + &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(20), }, &lnwire.ChannelUpdate{ diff --git a/funding/manager.go b/funding/manager.go index 70b7910936..56f63545c4 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -3295,7 +3295,7 @@ func (f *Manager) receivedChannelReady(node *btcec.PublicKey, } // extractAnnounceParams extracts the various channel announcement and update -// parameters that will be needed to construct a ChannelAnnouncement and a +// parameters that will be needed to construct a ChannelAnnouncement1 and a // ChannelUpdate. func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) ( lnwire.MilliSatoshi, lnwire.MilliSatoshi) { @@ -3324,7 +3324,7 @@ func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) ( return fwdMinHTLC, fwdMaxHTLC } -// addToRouterGraph sends a ChannelAnnouncement and a ChannelUpdate to the +// addToRouterGraph sends a ChannelAnnouncement1 and a ChannelUpdate to the // gossiper so that the channel is added to the Router's internal graph. // These announcement messages are NOT broadcasted to the greater network, // only to the channel counter party. The proofs required to announce the @@ -3353,7 +3353,7 @@ func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel, "announcement: %v", err) } - // Send ChannelAnnouncement and ChannelUpdate to the gossiper to add + // Send ChannelAnnouncement1 and ChannelUpdate to the gossiper to add // to the Router's topology. errChan := f.cfg.SendAnnouncement( ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity), @@ -3366,7 +3366,7 @@ func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel, routing.ErrIgnored) { log.Debugf("Router rejected "+ - "ChannelAnnouncement: %v", err) + "ChannelAnnouncement1: %v", err) } else { return fmt.Errorf("error sending channel "+ "announcement: %v", err) @@ -4050,7 +4050,7 @@ func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID, // chanAnnouncement encapsulates the two authenticated announcements that we // send out to the network after a new channel has been created locally. type chanAnnouncement struct { - chanAnn *lnwire.ChannelAnnouncement + chanAnn *lnwire.ChannelAnnouncement1 chanUpdateAnn *lnwire.ChannelUpdate chanProof *lnwire.AnnounceSignatures1 } @@ -4075,7 +4075,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, // The unconditional section of the announcement is the ShortChannelID // itself which compactly encodes the location of the funding output // within the blockchain. - chanAnn := &lnwire.ChannelAnnouncement{ + chanAnn := &lnwire.ChannelAnnouncement1{ ShortChannelID: shortChanID, Features: lnwire.NewRawFeatureVector(), ChainHash: chainHash, @@ -4088,7 +4088,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, // TODO(roasbeef): temp, remove after gossip 1.5 if chanType.IsTaproot() { log.Debugf("Applying taproot feature bit to "+ - "ChannelAnnouncement for %v", chanID) + "ChannelAnnouncement1 for %v", chanID) chanAnn.Features.Set( lnwire.SimpleTaprootChannelsRequiredStaging, @@ -4293,7 +4293,7 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey, } // We only send the channel proof announcement and the node announcement - // because addToRouterGraph previously sent the ChannelAnnouncement and + // because addToRouterGraph previously sent the ChannelAnnouncement1 and // the ChannelUpdate announcement messages. The channel proof and node // announcements are broadcast to the greater network. errChan := f.cfg.SendAnnouncement(ann.chanProof) diff --git a/funding/manager_test.go b/funding/manager_test.go index 2320c99b36..a51e40c15d 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -1144,7 +1144,7 @@ func assertAddedToRouterGraph(t *testing.T, alice, bob *testNode, } // assertChannelAnnouncements checks that alice and bob both sends the expected -// announcements (ChannelAnnouncement, ChannelUpdate) after the funding tx has +// announcements (ChannelAnnouncement1, ChannelUpdate) after the funding tx has // confirmed. The last arguments can be set if we expect the nodes to advertise // custom min_htlc values as part of their ChannelUpdate. We expect Alice to // advertise the value required by Bob and vice versa. If they are not set the @@ -1175,9 +1175,9 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, // After the ChannelReady message is sent, Alice and Bob will each send // the following messages to their gossiper: - // 1) ChannelAnnouncement + // 1) ChannelAnnouncement1 // 2) ChannelUpdate - // The ChannelAnnouncement is kept locally, while the ChannelUpdate is + // The ChannelAnnouncement1 is kept locally, while the ChannelUpdate is // sent directly to the other peer, so the edge policies are known to // both peers. nodes := []*testNode{alice, bob} @@ -1195,7 +1195,7 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, gotChannelUpdate := false for _, msg := range announcements { switch m := msg.(type) { - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: gotChannelAnnouncement = true case *lnwire.ChannelUpdate: @@ -1244,7 +1244,7 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, require.Truef( t, gotChannelAnnouncement, - "ChannelAnnouncement from %d", j, + "ChannelAnnouncement1 from %d", j, ) require.Truef(t, gotChannelUpdate, "ChannelUpdate from %d", j) @@ -4548,7 +4548,7 @@ func testZeroConf(t *testing.T, chanType *lnwire.ChannelType) { // We'll assert that they both create new links. assertHandleChannelReady(t, alice, bob) - // We'll now assert that both sides send ChannelAnnouncement and + // We'll now assert that both sides send ChannelAnnouncement1 and // ChannelUpdate messages. assertChannelAnnouncements( t, alice, bob, fundingAmt, nil, nil, nil, nil, diff --git a/lnwire/channel_announcement.go b/lnwire/channel_announcement.go index 2b34c0f990..86d3335614 100644 --- a/lnwire/channel_announcement.go +++ b/lnwire/channel_announcement.go @@ -7,10 +7,10 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" ) -// ChannelAnnouncement message is used to announce the existence of a channel +// ChannelAnnouncement1 message is used to announce the existence of a channel // between two peers in the overlay, which is propagated by the discovery // service over broadcast handler. -type ChannelAnnouncement struct { +type ChannelAnnouncement1 struct { // This signatures are used by nodes in order to create cross // references between node's channel and node. Requiring both nodes // to sign indicates they are both willing to route other payments via @@ -58,15 +58,15 @@ type ChannelAnnouncement struct { ExtraOpaqueData ExtraOpaqueData } -// A compile time check to ensure ChannelAnnouncement implements the +// A compile time check to ensure ChannelAnnouncement1 implements the // lnwire.Message interface. -var _ Message = (*ChannelAnnouncement)(nil) +var _ Message = (*ChannelAnnouncement1)(nil) -// Decode deserializes a serialized ChannelAnnouncement stored in the passed +// Decode deserializes a serialized ChannelAnnouncement1 stored in the passed // io.Reader observing the specified protocol version. // // This is part of the lnwire.Message interface. -func (a *ChannelAnnouncement) Decode(r io.Reader, pver uint32) error { +func (a *ChannelAnnouncement1) Decode(r io.Reader, _ uint32) error { return ReadElements(r, &a.NodeSig1, &a.NodeSig2, @@ -83,11 +83,11 @@ func (a *ChannelAnnouncement) Decode(r io.Reader, pver uint32) error { ) } -// Encode serializes the target ChannelAnnouncement into the passed io.Writer +// Encode serializes the target ChannelAnnouncement1 into the passed io.Writer // observing the protocol version specified. // // This is part of the lnwire.Message interface. -func (a *ChannelAnnouncement) Encode(w *bytes.Buffer, pver uint32) error { +func (a *ChannelAnnouncement1) Encode(w *bytes.Buffer, _ uint32) error { if err := WriteSig(w, a.NodeSig1); err != nil { return err } @@ -139,13 +139,13 @@ func (a *ChannelAnnouncement) Encode(w *bytes.Buffer, pver uint32) error { // wire. // // This is part of the lnwire.Message interface. -func (a *ChannelAnnouncement) MsgType() MessageType { +func (a *ChannelAnnouncement1) MsgType() MessageType { return MsgChannelAnnouncement } // DataToSign is used to retrieve part of the announcement message which should // be signed. -func (a *ChannelAnnouncement) DataToSign() ([]byte, error) { +func (a *ChannelAnnouncement1) DataToSign() ([]byte, error) { // We should not include the signatures itself. b := make([]byte, 0, MaxMsgBody) buf := bytes.NewBuffer(b) diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 8c204d9dd2..3df833b0f0 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -775,7 +775,7 @@ func TestLightningWireProtocol(t *testing.T) { }, MsgChannelAnnouncement: func(v []reflect.Value, r *rand.Rand) { var err error - req := ChannelAnnouncement{ + req := ChannelAnnouncement1{ ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), Features: randRawFeatureVector(r), ExtraOpaqueData: make([]byte, 0), @@ -1204,7 +1204,7 @@ func TestLightningWireProtocol(t *testing.T) { }, { msgType: MsgChannelAnnouncement, - scenario: func(m ChannelAnnouncement) bool { + scenario: func(m ChannelAnnouncement1) bool { return mainScenario(&m) }, }, diff --git a/lnwire/message.go b/lnwire/message.go index 7eb6a2de26..fc5259d5cf 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -111,7 +111,7 @@ func (t MessageType) String() string { case MsgError: return "Error" case MsgChannelAnnouncement: - return "ChannelAnnouncement" + return "ChannelAnnouncement1" case MsgChannelUpdate: return "ChannelUpdate" case MsgNodeAnnouncement: @@ -215,7 +215,7 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { case MsgError: msg = &Error{} case MsgChannelAnnouncement: - msg = &ChannelAnnouncement{} + msg = &ChannelAnnouncement1{} case MsgChannelUpdate: msg = &ChannelUpdate{} case MsgNodeAnnouncement: diff --git a/lnwire/message_test.go b/lnwire/message_test.go index 1a3c61ac21..4c0ebdd45f 100644 --- a/lnwire/message_test.go +++ b/lnwire/message_test.go @@ -645,11 +645,11 @@ func newMsgChannelReestablish(t testing.TB, } func newMsgChannelAnnouncement(t testing.TB, - r *rand.Rand) *lnwire.ChannelAnnouncement { + r *rand.Rand) *lnwire.ChannelAnnouncement1 { t.Helper() - msg := &lnwire.ChannelAnnouncement{ + msg := &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(r.Int63())), Features: rawFeatureVector(), NodeID1: randRawKey(t), diff --git a/netann/channel_announcement.go b/netann/channel_announcement.go index 8fc040f6f3..64e8a0c52a 100644 --- a/netann/channel_announcement.go +++ b/netann/channel_announcement.go @@ -14,14 +14,14 @@ import ( // peer's initial routing table upon connect. func CreateChanAnnouncement(chanProof *models.ChannelAuthProof, chanInfo *models.ChannelEdgeInfo, - e1, e2 *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, + e1, e2 *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement1, *lnwire.ChannelUpdate, *lnwire.ChannelUpdate, error) { // First, using the parameters of the channel, along with the channel // authentication chanProof, we'll create re-create the original // authenticated channel announcement. chanID := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID) - chanAnn := &lnwire.ChannelAnnouncement{ + chanAnn := &lnwire.ChannelAnnouncement1{ ShortChannelID: chanID, NodeID1: chanInfo.NodeKey1Bytes, NodeID2: chanInfo.NodeKey2Bytes, diff --git a/netann/channel_announcement_test.go b/netann/channel_announcement_test.go index 92a6c74ce0..0a5b0f048b 100644 --- a/netann/channel_announcement_test.go +++ b/netann/channel_announcement_test.go @@ -24,7 +24,7 @@ func TestCreateChanAnnouncement(t *testing.T) { t.Fatalf("unable to encode features: %v", err) } - expChanAnn := &lnwire.ChannelAnnouncement{ + expChanAnn := &lnwire.ChannelAnnouncement1{ ChainHash: chainhash.Hash{0x1}, ShortChannelID: lnwire.ShortChannelID{BlockHeight: 1}, NodeID1: key, diff --git a/netann/sign.go b/netann/sign.go index 86634f6281..93bd8cdc9b 100644 --- a/netann/sign.go +++ b/netann/sign.go @@ -20,7 +20,7 @@ func SignAnnouncement(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator, ) switch m := msg.(type) { - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: data, err = m.DataToSign() case *lnwire.ChannelUpdate: data, err = m.DataToSign() diff --git a/peer/brontide.go b/peer/brontide.go index 6dc2f8634f..8d3f426366 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -1731,7 +1731,7 @@ out: } case *lnwire.ChannelUpdate, - *lnwire.ChannelAnnouncement, + *lnwire.ChannelAnnouncement1, *lnwire.NodeAnnouncement, *lnwire.AnnounceSignatures1, *lnwire.GossipTimestampRange, @@ -1984,7 +1984,7 @@ func messageSummary(msg lnwire.Message) string { return fmt.Sprintf("chan_id=%v, short_chan_id=%v", msg.ChannelID, msg.ShortChannelID.ToUint64()) - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: return fmt.Sprintf("chain_hash=%v, short_chan_id=%v", msg.ChainHash, msg.ShortChannelID.ToUint64()) diff --git a/routing/ann_validation.go b/routing/ann_validation.go index 35f0afd4d1..a60944bf8a 100644 --- a/routing/ann_validation.go +++ b/routing/ann_validation.go @@ -15,7 +15,7 @@ import ( // ValidateChannelAnn validates the channel announcement message and checks // that node signatures covers the announcement message, and that the bitcoin // signatures covers the node keys. -func ValidateChannelAnn(a *lnwire.ChannelAnnouncement) error { +func ValidateChannelAnn(a *lnwire.ChannelAnnouncement1) error { // First, we'll compute the digest (h) which is to be signed by each of // the keys included within the node announcement message. This hash // digest includes all the keys, so the (up to 4 signatures) will diff --git a/routing/router.go b/routing/router.go index fa255544cc..aed0bb1764 100644 --- a/routing/router.go +++ b/routing/router.go @@ -1568,7 +1568,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}, // graph. If the passed ShortChannelID is an alias, then we'll // skip validation as it will not map to a legitimate tx. This // is not a DoS vector as only we can add an alias - // ChannelAnnouncement from the gossiper. + // ChannelAnnouncement1 from the gossiper. scid := lnwire.NewShortChanIDFromInt(msg.ChannelID) if r.cfg.AssumeChannelValid || r.cfg.IsAlias(scid) { if err := r.cfg.Graph.AddChannelEdge(msg, op...); err != nil { diff --git a/routing/validation_barrier.go b/routing/validation_barrier.go index 52b7399da8..a860572538 100644 --- a/routing/validation_barrier.go +++ b/routing/validation_barrier.go @@ -36,13 +36,13 @@ type ValidationBarrier struct { validationSemaphore chan struct{} // chanAnnFinSignal is map that keep track of all the pending - // ChannelAnnouncement like validation job going on. Once the job has + // ChannelAnnouncement1 like validation job going on. Once the job has // been completed, the channel will be closed unblocking any // dependants. chanAnnFinSignal map[lnwire.ShortChannelID]*validationSignals // chanEdgeDependencies tracks any channel edge updates which should - // wait until the completion of the ChannelAnnouncement before + // wait until the completion of the ChannelAnnouncement1 before // proceeding. This is a dependency, as we can't validate the update // before we validate the announcement which creates the channel // itself. @@ -50,7 +50,7 @@ type ValidationBarrier struct { // nodeAnnDependencies tracks any pending NodeAnnouncement validation // jobs which should wait until the completion of the - // ChannelAnnouncement before proceeding. + // ChannelAnnouncement1 before proceeding. nodeAnnDependencies map[route.Vertex]*validationSignals quit chan struct{} @@ -102,12 +102,12 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) { // ChannelUpdates for the same channel, or NodeAnnouncements of nodes // that are involved in this channel. This goes for both the wire // type,s and also the types that we use within the database. - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: // We ensure that we only create a new announcement signal iff, // one doesn't already exist, as there may be duplicate // announcements. We'll close this signal once the - // ChannelAnnouncement has been validated. This will result in + // ChannelAnnouncement1 has been validated. This will result in // all the dependent jobs being unlocked so they can finish // execution themselves. if _, ok := v.chanAnnFinSignal[msg.ShortChannelID]; !ok { @@ -219,7 +219,7 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { case *lnwire.AnnounceSignatures1: // TODO(roasbeef): need to wait on chan ann? case *models.ChannelEdgeInfo: - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: } // Release the lock once the above read is finished. @@ -261,7 +261,7 @@ func (v *ValidationBarrier) SignalDependants(job interface{}, allow bool) { switch msg := job.(type) { - // If we've just finished executing a ChannelAnnouncement, then we'll + // If we've just finished executing a ChannelAnnouncement1, then we'll // close out the signal, and remove the signal from the map of active // ones. This will allow/deny any dependent jobs to continue execution. case *models.ChannelEdgeInfo: @@ -275,7 +275,7 @@ func (v *ValidationBarrier) SignalDependants(job interface{}, allow bool) { } delete(v.chanAnnFinSignal, shortID) } - case *lnwire.ChannelAnnouncement: + case *lnwire.ChannelAnnouncement1: finSignals, ok := v.chanAnnFinSignal[msg.ShortChannelID] if ok { if allow { diff --git a/routing/validation_barrier_test.go b/routing/validation_barrier_test.go index 2eda0120fc..e56c95a472 100644 --- a/routing/validation_barrier_test.go +++ b/routing/validation_barrier_test.go @@ -73,9 +73,9 @@ func TestValidationBarrierQuit(t *testing.T) { // Create a set of unique channel announcements that we will prep for // validation. - anns := make([]*lnwire.ChannelAnnouncement, 0, numTasks) + anns := make([]*lnwire.ChannelAnnouncement1, 0, numTasks) for i := 0; i < numTasks; i++ { - anns = append(anns, &lnwire.ChannelAnnouncement{ + anns = append(anns, &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(i)), NodeID1: nodeIDFromInt(uint64(2 * i)), NodeID2: nodeIDFromInt(uint64(2*i + 1)), From 5edb0c9af56de7417a0133ad08fb4e732373d152 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 12:07:47 +0200 Subject: [PATCH 03/20] multi: rename ChannelUpdate to ChannelUpdate1 In preparation for adding a new ChannelUpdate2 message and a ChannelUpdate interface, we rename the existing message to ChannelUpdate1. --- channeldb/models/channel.go | 2 +- discovery/chan_series.go | 11 +++-- discovery/gossiper.go | 70 +++++++++++++++------------ discovery/gossiper_test.go | 52 ++++++++++---------- discovery/message_store.go | 16 ++++-- discovery/message_store_test.go | 10 ++-- discovery/reliable_sender_test.go | 2 +- discovery/syncer.go | 8 +-- discovery/syncer_test.go | 18 +++---- funding/manager.go | 30 ++++++------ funding/manager_test.go | 14 +++--- htlcswitch/interfaces.go | 2 +- htlcswitch/link.go | 28 ++++++----- htlcswitch/link_test.go | 6 +-- htlcswitch/mock.go | 10 ++-- htlcswitch/switch.go | 21 ++++---- htlcswitch/switch_test.go | 10 ++-- htlcswitch/test_utils.go | 6 ++- itest/lnd_channel_policy_test.go | 4 +- itest/lnd_zero_conf_test.go | 2 +- lnrpc/routerrpc/router_backend.go | 2 +- lnwire/channel_update.go | 26 +++++----- lnwire/lnwire_test.go | 6 +-- lnwire/message.go | 4 +- lnwire/message_test.go | 6 +-- lnwire/onion_error.go | 52 +++++++++++--------- lnwire/onion_error_test.go | 6 +-- netann/chan_status_manager.go | 10 ++-- netann/chan_status_manager_test.go | 6 +-- netann/channel_announcement.go | 4 +- netann/channel_update.go | 24 ++++----- netann/channel_update_test.go | 4 +- netann/sign.go | 2 +- peer/brontide.go | 10 ++-- peer/test_utils.go | 2 +- routing/ann_validation.go | 6 +-- routing/missioncontrol_test.go | 6 +-- routing/mock_test.go | 4 +- routing/payment_session.go | 4 +- routing/payment_session_test.go | 2 +- routing/result_interpretation_test.go | 6 ++- routing/router.go | 8 +-- routing/router_test.go | 16 +++--- routing/validation_barrier.go | 8 +-- routing/validation_barrier_test.go | 4 +- server.go | 14 +++--- 46 files changed, 297 insertions(+), 267 deletions(-) diff --git a/channeldb/models/channel.go b/channeldb/models/channel.go index 4a65462e72..f3d8b8868c 100644 --- a/channeldb/models/channel.go +++ b/channeldb/models/channel.go @@ -96,7 +96,7 @@ func (k CircuitKey) String() string { // constraints will be consulted in order to ensure that adequate fees are // paid, and our time-lock parameters are respected. In the event that an // incoming HTLC violates any of these constraints, it is to be _rejected_ with -// the error possibly carrying along a ChannelUpdate message that includes the +// the error possibly carrying along a ChannelUpdate1 message that includes the // latest policy. type ForwardingPolicy struct { // MinHTLCOut is the smallest HTLC that is to be forwarded. diff --git a/discovery/chan_series.go b/discovery/chan_series.go index c811017abd..2166dda885 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -50,7 +50,7 @@ type ChannelGraphTimeSeries interface { // their updates that match the set of specified short channel ID's. // We'll use this to reply to a QueryShortChanIDs message sent by a // remote peer. The response will contain a unique set of - // ChannelAnnouncements, the latest ChannelUpdate for each of the + // ChannelAnnouncements, the latest ChannelUpdate1 for each of the // announcements, and a unique set of NodeAnnouncements. FetchChanAnns(chain chainhash.Hash, shortChanIDs []lnwire.ShortChannelID) ([]lnwire.Message, error) @@ -59,7 +59,8 @@ type ChannelGraphTimeSeries interface { // specified short channel ID. If no channel updates are known for the // channel, then an empty slice will be returned. FetchChanUpdates(chain chainhash.Hash, - shortChanID lnwire.ShortChannelID) ([]*lnwire.ChannelUpdate, error) + shortChanID lnwire.ShortChannelID) ([]*lnwire.ChannelUpdate1, + error) } // ChanSeries is an implementation of the ChannelGraphTimeSeries @@ -235,7 +236,7 @@ func (c *ChanSeries) FilterChannelRange(chain chainhash.Hash, // FetchChanAnns returns a full set of channel announcements as well as their // updates that match the set of specified short channel ID's. We'll use this // to reply to a QueryShortChanIDs message sent by a remote peer. The response -// will contain a unique set of ChannelAnnouncements, the latest ChannelUpdate +// will contain a unique set of ChannelAnnouncements, the latest ChannelUpdate1 // for each of the announcements, and a unique set of NodeAnnouncements. // // NOTE: This is part of the ChannelGraphTimeSeries interface. @@ -324,7 +325,7 @@ func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash, // // NOTE: This is part of the ChannelGraphTimeSeries interface. func (c *ChanSeries) FetchChanUpdates(chain chainhash.Hash, - shortChanID lnwire.ShortChannelID) ([]*lnwire.ChannelUpdate, error) { + shortChanID lnwire.ShortChannelID) ([]*lnwire.ChannelUpdate1, error) { chanInfo, e1, e2, err := c.graph.FetchChannelEdgesByID( shortChanID.ToUint64(), @@ -333,7 +334,7 @@ func (c *ChanSeries) FetchChanUpdates(chain chainhash.Hash, return nil, err } - chanUpdates := make([]*lnwire.ChannelUpdate, 0, 2) + chanUpdates := make([]*lnwire.ChannelUpdate1, 0, 2) if e1 != nil { chanUpdate, err := netann.ChannelUpdateFromEdge(chanInfo, e1) if err != nil { diff --git a/discovery/gossiper.go b/discovery/gossiper.go index eeb979606e..827ad74082 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -141,7 +141,7 @@ type networkMsg struct { } // chanPolicyUpdateRequest is a request that is sent to the server when a caller -// wishes to update a particular set of channels. New ChannelUpdate messages +// wishes to update a particular set of channels. New ChannelUpdate1 messages // will be crafted to be sent out during the next broadcast epoch and the fee // updates committed to the lower layer. type chanPolicyUpdateRequest struct { @@ -312,7 +312,7 @@ type Config struct { // SignAliasUpdate is used to re-sign a channel update using the // remote's alias if the option-scid-alias feature bit was negotiated. - SignAliasUpdate func(u *lnwire.ChannelUpdate) (*ecdsa.Signature, + SignAliasUpdate func(u *lnwire.ChannelUpdate1) (*ecdsa.Signature, error) // FindBaseByAlias finds the SCID stored in the graph by an alias SCID. @@ -885,7 +885,7 @@ func (d *AuthenticatedGossiper) ProcessLocalAnnouncement(msg lnwire.Message, return nMsg.err } -// channelUpdateID is a unique identifier for ChannelUpdate messages, as +// channelUpdateID is a unique identifier for ChannelUpdate1 messages, as // channel updates can be identified by the (ShortChannelID, ChannelFlags) // tuple. type channelUpdateID struct { @@ -1005,7 +1005,7 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) { // Channel updates are identified by the (short channel id, // channelflags) tuple. - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: sender := route.NewVertex(message.source) deDupKey := channelUpdateID{ msg.ShortChannelID, @@ -1017,7 +1017,15 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) { if ok { // If we already have seen this message, record its // timestamp. - oldTimestamp = mws.msg.(*lnwire.ChannelUpdate).Timestamp + update, ok := mws.msg.(*lnwire.ChannelUpdate1) + if !ok { + log.Errorf("Expected *lnwire.ChannelUpdate1, "+ + "got: %T", mws.msg) + + return + } + + oldTimestamp = update.Timestamp } // If we already had this message with a strictly newer @@ -1354,7 +1362,7 @@ func (d *AuthenticatedGossiper) networkHandler() { select { // A new policy update has arrived. We'll commit it to the // sub-systems below us, then craft, sign, and broadcast a new - // ChannelUpdate for the set of affected clients. + // ChannelUpdate1 for the set of affected clients. case policyUpdate := <-d.chanPolicyUpdates: log.Tracef("Received channel %d policy update requests", len(policyUpdate.edgesToUpdate)) @@ -1552,7 +1560,7 @@ func (d *AuthenticatedGossiper) isRecentlyRejectedMsg(msg lnwire.Message, var scid uint64 switch m := msg.(type) { - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: scid = m.ShortChannelID.ToUint64() case *lnwire.ChannelAnnouncement1: @@ -1604,7 +1612,7 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error { // announcement below. havePublicChannels = true - // If this edge has a ChannelUpdate that was created before the + // If this edge has a ChannelUpdate1 that was created before the // introduction of the MaxHTLC field, then we'll update this // edge to propagate this information in the network. if !edge.MessageFlags.HasMaxHtlc() { @@ -1642,7 +1650,7 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error { var signedUpdates []lnwire.Message for _, chanToUpdate := range edgesToUpdate { // Re-sign and update the channel on disk and retrieve our - // ChannelUpdate to broadcast. + // ChannelUpdate1 to broadcast. chanAnn, chanUpdate, err := d.updateChannel( chanToUpdate.info, chanToUpdate.edge, ) @@ -1718,7 +1726,7 @@ func (d *AuthenticatedGossiper) processChanPolicyUpdate( for _, edgeInfo := range edgesToUpdate { // Now that we've collected all the channels we need to update, // we'll re-sign and update the backing ChannelGraphSource, and - // retrieve our ChannelUpdate to broadcast. + // retrieve our ChannelUpdate1 to broadcast. _, chanUpdate, err := d.updateChannel( edgeInfo.Info, edgeInfo.Edge, ) @@ -2004,7 +2012,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement( // A new authenticated channel edge update has arrived. This indicates // that the directional information for an already known channel has // been updated. - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: return d.handleChanUpdate(nMsg, msg, schedulerOp) // A new signature announcement has been received. This indicates @@ -2023,7 +2031,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement( // processZombieUpdate determines whether the provided channel update should // resurrect a given zombie edge. func (d *AuthenticatedGossiper) processZombieUpdate( - chanInfo *models.ChannelEdgeInfo, msg *lnwire.ChannelUpdate) error { + chanInfo *models.ChannelEdgeInfo, msg *lnwire.ChannelUpdate1) error { // The least-significant bit in the flag on the channel update tells us // which edge is being updated. @@ -2108,7 +2116,7 @@ func (d *AuthenticatedGossiper) isMsgStale(msg lnwire.Message) bool { // can safely delete the local proof from the database. return chanInfo.AuthProof != nil - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: _, p1, p2, err := d.cfg.Router.GetChannelByID(msg.ShortChannelID) // If the channel cannot be found, it is most likely a leftover @@ -2153,7 +2161,7 @@ func (d *AuthenticatedGossiper) isMsgStale(msg lnwire.Message) bool { // the underlying graph with the new state. func (d *AuthenticatedGossiper) updateChannel(info *models.ChannelEdgeInfo, edge *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement1, - *lnwire.ChannelUpdate, error) { + *lnwire.ChannelUpdate1, error) { // Parse the unsigned edge into a channel update. chanUpdate := netann.UnsignedChannelUpdateFromEdge(info, edge) @@ -2239,7 +2247,7 @@ func (d *AuthenticatedGossiper) SyncManager() *SyncManager { // IsKeepAliveUpdate determines whether this channel update is considered a // keep-alive update based on the previous channel update processed for the same // direction. -func IsKeepAliveUpdate(update *lnwire.ChannelUpdate, +func IsKeepAliveUpdate(update *lnwire.ChannelUpdate1, prev *models.ChannelEdgePolicy) bool { // Both updates should be from the same direction. @@ -2573,7 +2581,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, channelUpdates = append(channelUpdates, chanMsgs.msgs...) } - // Launch a new goroutine to handle each ChannelUpdate, this is to + // Launch a new goroutine to handle each ChannelUpdate1, this is to // ensure we don't block here, as we can handle only one announcement // at a time. for _, cu := range channelUpdates { @@ -2582,9 +2590,9 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, continue } - // Mark the ChannelUpdate as processed. This ensures that a + // Mark the ChannelUpdate1 as processed. This ensures that a // subsequent announcement in the option-scid-alias case does - // not re-use an old ChannelUpdate. + // not re-use an old ChannelUpdate1. cu.processed = true d.wg.Add(1) @@ -2595,8 +2603,8 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, // Reprocess the message, making sure we return an // error to the original caller in case the gossiper // shuts down. - case *lnwire.ChannelUpdate: - log.Debugf("Reprocessing ChannelUpdate for "+ + case *lnwire.ChannelUpdate1: + log.Debugf("Reprocessing ChannelUpdate1 for "+ "shortChanID=%v", msg.ShortChannelID.ToUint64()) @@ -2607,7 +2615,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, } // We don't expect any other message type than - // ChannelUpdate to be in this cache. + // ChannelUpdate1 to be in this cache. default: log.Errorf("Unsupported message type found "+ "among ChannelUpdates: %T", msg) @@ -2639,16 +2647,16 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, // handleChanUpdate processes a new channel update. func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, - upd *lnwire.ChannelUpdate, + upd *lnwire.ChannelUpdate1, ops []batch.SchedulerOption) ([]networkMsg, bool) { - log.Debugf("Processing ChannelUpdate: peer=%v, short_chan_id=%v, ", + log.Debugf("Processing ChannelUpdate1: peer=%v, short_chan_id=%v, ", nMsg.peer, upd.ShortChannelID.ToUint64()) // We'll ignore any channel updates that target any chain other than // the set of chains we know of. if !bytes.Equal(upd.ChainHash[:], d.cfg.ChainHash[:]) { - err := fmt.Errorf("ignoring ChannelUpdate from chain=%v, "+ + err := fmt.Errorf("ignoring ChannelUpdate1 from chain=%v, "+ "gossiper on chain=%v", upd.ChainHash, d.cfg.ChainHash) log.Errorf(err.Error()) @@ -2748,7 +2756,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, case channeldb.ErrGraphNoEdgesFound: fallthrough case channeldb.ErrEdgeNotFound: - // If the edge corresponding to this ChannelUpdate was not + // If the edge corresponding to this ChannelUpdate1 was not // found in the graph, this might be a channel in the process // of being opened, and we haven't processed our own // ChannelAnnouncement1 yet, hence it is not found in the @@ -2788,13 +2796,13 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, }) } - log.Debugf("Got ChannelUpdate for edge not found in graph"+ + log.Debugf("Got ChannelUpdate1 for edge not found in graph"+ "(shortChanID=%v), saving for reprocessing later", shortChanID) // NOTE: We don't return anything on the error channel for this // message, as we expect that will be done when this - // ChannelUpdate is later reprocessed. + // ChannelUpdate1 is later reprocessed. return nil, false default: @@ -2829,7 +2837,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, edgeToUpdate = e2 } - log.Debugf("Validating ChannelUpdate: channel=%v, from node=%x, has "+ + log.Debugf("Validating ChannelUpdate1: channel=%v, from node=%x, has "+ "edge=%v", chanInfo.ChannelID, pubKey.SerializeCompressed(), edgeToUpdate != nil) @@ -2900,7 +2908,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, } // We'll use chanInfo.ChannelID rather than the peer-supplied - // ShortChannelID in the ChannelUpdate to avoid the router having to + // ShortChannelID in the ChannelUpdate1 to avoid the router having to // lookup the stored SCID. If we're sending the update, we'll always // use the SCID stored in the database rather than a potentially // different alias. This might mean that SigBytes is incorrect as it @@ -2946,7 +2954,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, return nil, false } - // If this is a local ChannelUpdate without an AuthProof, it means it + // If this is a local ChannelUpdate1 without an AuthProof, it means it // is an update to a channel that is not (yet) supposed to be announced // to the greater network. However, our channel counter party will need // to be given the update, so we'll try sending the update directly to @@ -3019,7 +3027,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, nMsg.err <- nil - log.Debugf("Processed ChannelUpdate: peer=%v, short_chan_id=%v, "+ + log.Debugf("Processed ChannelUpdate1: peer=%v, short_chan_id=%v, "+ "timestamp=%v", nMsg.peer, upd.ShortChannelID.ToUint64(), timestamp) return announcements, true diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index 09f2eaab38..b30da45d8a 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -462,8 +462,8 @@ type annBatch struct { chanAnn *lnwire.ChannelAnnouncement1 - chanUpdAnn1 *lnwire.ChannelUpdate - chanUpdAnn2 *lnwire.ChannelUpdate + chanUpdAnn1 *lnwire.ChannelUpdate1 + chanUpdAnn2 *lnwire.ChannelUpdate1 localProofAnn *lnwire.AnnounceSignatures1 remoteProofAnn *lnwire.AnnounceSignatures1 @@ -569,12 +569,12 @@ func createNodeAnnouncement(priv *btcec.PrivateKey, func createUpdateAnnouncement(blockHeight uint32, flags lnwire.ChanUpdateChanFlags, nodeKey *btcec.PrivateKey, timestamp uint32, - extraBytes ...[]byte) (*lnwire.ChannelUpdate, error) { + extraBytes ...[]byte) (*lnwire.ChannelUpdate1, error) { var err error htlcMinMsat := lnwire.MilliSatoshi(prand.Int63()) - a := &lnwire.ChannelUpdate{ + a := &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.ShortChannelID{ BlockHeight: blockHeight, }, @@ -602,7 +602,7 @@ func createUpdateAnnouncement(blockHeight uint32, return a, nil } -func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate) error { +func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate1) error { signer := mock.SingleSigner{Privkey: nodeKey} sig, err := netann.SignAnnouncement(&signer, testKeyLoc, a) if err != nil { @@ -731,7 +731,7 @@ func createTestCtx(t *testing.T, startHeight uint32) (*testCtx, error) { return false } - signAliasUpdate := func(*lnwire.ChannelUpdate) (*ecdsa.Signature, + signAliasUpdate := func(*lnwire.ChannelUpdate1) (*ecdsa.Signature, error) { return nil, nil @@ -1433,7 +1433,7 @@ func TestSignatureAnnouncementRetryAtStartup(t *testing.T) { return false } - signAliasUpdate := func(*lnwire.ChannelUpdate) (*ecdsa.Signature, + signAliasUpdate := func(*lnwire.ChannelUpdate1) (*ecdsa.Signature, error) { return nil, nil @@ -1509,7 +1509,7 @@ out: for { select { case msg := <-sentToPeer: - // Since the ChannelUpdate will also be resent as it is + // Since the ChannelUpdate1 will also be resent as it is // sent reliably, we'll need to filter it out. if _, ok := msg.(*lnwire.AnnounceSignatures1); !ok { continue @@ -1812,7 +1812,7 @@ func TestDeDuplicatedAnnouncements(t *testing.T) { } // Adding the very same announcement shouldn't cause an increase in the - // number of ChannelUpdate announcements stored. + // number of ChannelUpdate1 announcements stored. ua2, err := createUpdateAnnouncement(0, 0, remoteKeyPriv1, timestamp) require.NoError(t, err, "can't create update announcement") announcements.AddMsgs(networkMsg{ @@ -1837,7 +1837,7 @@ func TestDeDuplicatedAnnouncements(t *testing.T) { t.Fatal("channel update not replaced in batch") } - assertChannelUpdate := func(channelUpdate *lnwire.ChannelUpdate) { + assertChannelUpdate := func(channelUpdate *lnwire.ChannelUpdate1) { channelKey := channelUpdateID{ ua3.ShortChannelID, ua3.ChannelFlags, @@ -2356,7 +2356,7 @@ func TestProcessZombieEdgeNowLive(t *testing.T) { } } -// TestReceiveRemoteChannelUpdateFirst tests that if we receive a ChannelUpdate +// TestReceiveRemoteChannelUpdateFirst tests that if we receive a ChannelUpdate1 // from the remote before we have processed our own ChannelAnnouncement1, it will // be reprocessed later, after our ChannelAnnouncement1. func TestReceiveRemoteChannelUpdateFirst(t *testing.T) { @@ -2404,7 +2404,7 @@ func TestReceiveRemoteChannelUpdateFirst(t *testing.T) { case <-time.After(2 * trickleDelay): } - // Since the remote ChannelUpdate was added for an edge that + // Since the remote ChannelUpdate1 was added for an edge that // we did not already know about, it should have been added // to the map of premature ChannelUpdates. Check that nothing // was added to the graph. @@ -2464,7 +2464,7 @@ func TestReceiveRemoteChannelUpdateFirst(t *testing.T) { t.Fatal("gossiper did not send channel update to peer") } - // At this point the remote ChannelUpdate we received earlier should + // At this point the remote ChannelUpdate1 we received earlier should // be reprocessed, as we now have the necessary edge entry in the graph. select { case err := <-errRemoteAnn: @@ -2584,7 +2584,7 @@ func TestExtraDataChannelAnnouncementValidation(t *testing.T) { } // TestExtraDataChannelUpdateValidation tests that we're able to properly -// validate a ChannelUpdate that includes opaque bytes that we don't currently +// validate a ChannelUpdate1 that includes opaque bytes that we don't currently // know of. func TestExtraDataChannelUpdateValidation(t *testing.T) { t.Parallel() @@ -2775,7 +2775,7 @@ func TestRetransmit(t *testing.T) { switch msg.(type) { case *lnwire.ChannelAnnouncement1: chanAnn++ - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: chanUpd++ case *lnwire.NodeAnnouncement: nodeAnn++ @@ -2896,7 +2896,7 @@ func TestNodeAnnouncementNoChannels(t *testing.T) { } // TestOptionalFieldsChannelUpdateValidation tests that we're able to properly -// validate the msg flags and max HTLC field of a ChannelUpdate. +// validate the msg flags and max HTLC field of a ChannelUpdate1. func TestOptionalFieldsChannelUpdateValidation(t *testing.T) { t.Parallel() @@ -3206,7 +3206,7 @@ func TestSendChannelUpdateReliably(t *testing.T) { // already been announced. We'll keep track of the old message that is // now stale to use later on. staleChannelUpdate := batch.chanUpdAnn1 - newChannelUpdate := &lnwire.ChannelUpdate{} + newChannelUpdate := &lnwire.ChannelUpdate1{} *newChannelUpdate = *staleChannelUpdate newChannelUpdate.Timestamp++ if err := signUpdate(selfKeyPriv, newChannelUpdate); err != nil { @@ -3250,7 +3250,7 @@ func TestSendChannelUpdateReliably(t *testing.T) { peerChan <- remotePeer // At this point, we should have sent both the AnnounceSignatures1 and - // stale ChannelUpdate. + // stale ChannelUpdate1. for i := 0; i < 2; i++ { var msg lnwire.Message select { @@ -3260,7 +3260,7 @@ func TestSendChannelUpdateReliably(t *testing.T) { } switch msg := msg.(type) { - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: assertMessage(t, staleChannelUpdate, msg) case *lnwire.AnnounceSignatures1: assertMessage(t, batch.localProofAnn, msg) @@ -3370,7 +3370,7 @@ func TestPropagateChanPolicyUpdate(t *testing.T) { sentMsgs := make(chan lnwire.Message, 10) remotePeer := &mockPeer{remoteKey, sentMsgs, ctx.gossiper.quit} - // The forced code path for sending the private ChannelUpdate to the + // The forced code path for sending the private ChannelUpdate1 to the // remote peer will be hit, forcing it to request a notification that // the remote peer is active. We'll ensure that it targets the proper // pubkey, and hand it our mock peer above. @@ -3462,7 +3462,7 @@ out: // being the channel our first private channel. for i := 0; i < numChannels-1; i++ { assertBroadcastMsg(t, ctx, func(msg lnwire.Message) error { - upd, ok := msg.(*lnwire.ChannelUpdate) + upd, ok := msg.(*lnwire.ChannelUpdate1) if !ok { return fmt.Errorf("channel update not "+ "broadcast, instead %T was", msg) @@ -3482,11 +3482,11 @@ out: }) } - // Finally the ChannelUpdate should have been sent directly to the + // Finally the ChannelUpdate1 should have been sent directly to the // remote peer via the reliable sender. select { case msg := <-sentMsgs: - upd, ok := msg.(*lnwire.ChannelUpdate) + upd, ok := msg.(*lnwire.ChannelUpdate1) if !ok { t.Fatalf("channel update not "+ "broadcast, instead %T was", msg) @@ -3504,13 +3504,13 @@ out: t.Fatalf("message not sent directly to peer") } - // At this point, no other ChannelUpdate messages should be broadcast + // At this point, no other ChannelUpdate1 messages should be broadcast // as we sent the two public ones to the network, and the private one // was sent directly to the peer. for { select { case msg := <-ctx.broadcastedMessage: - if upd, ok := msg.msg.(*lnwire.ChannelUpdate); ok { + if upd, ok := msg.msg.(*lnwire.ChannelUpdate1); ok { if upd.ShortChannelID == firstChanID { t.Fatalf("chan update msg received: %v", spew.Sdump(msg)) @@ -3836,7 +3836,7 @@ func TestRateLimitChannelUpdates(t *testing.T) { // We'll define a helper to assert whether updates should be rate // limited or not depending on their contents. - assertRateLimit := func(update *lnwire.ChannelUpdate, peer lnpeer.Peer, + assertRateLimit := func(update *lnwire.ChannelUpdate1, peer lnpeer.Peer, shouldRateLimit bool) { t.Helper() diff --git a/discovery/message_store.go b/discovery/message_store.go index e89a65eefa..8db2db0e75 100644 --- a/discovery/message_store.go +++ b/discovery/message_store.go @@ -55,7 +55,7 @@ type GossipMessageStore interface { // MessageStore is an implementation of the GossipMessageStore interface backed // by a channeldb instance. By design, this store will only keep the latest -// version of a message (like in the case of multiple ChannelUpdate's) for a +// version of a message (like in the case of multiple ChannelUpdate1's) for a // channel with a peer. type MessageStore struct { db kvdb.Backend @@ -85,7 +85,7 @@ func msgShortChanID(msg lnwire.Message) (lnwire.ShortChannelID, error) { switch msg := msg.(type) { case *lnwire.AnnounceSignatures1: shortChanID = msg.ShortChannelID - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: shortChanID = msg.ShortChannelID default: return shortChanID, ErrUnsupportedMessage @@ -157,10 +157,10 @@ func (s *MessageStore) DeleteMessage(msg lnwire.Message, return ErrCorruptedMessageStore } - // In the event that we're attempting to delete a ChannelUpdate + // In the event that we're attempting to delete a ChannelUpdate1 // from the store, we'll make sure that we're actually deleting // the correct one as it can be overwritten. - if msg, ok := msg.(*lnwire.ChannelUpdate); ok { + if msg, ok := msg.(*lnwire.ChannelUpdate1); ok { // Deleting a value from a bucket that doesn't exist // acts as a NOP, so we'll return if a message doesn't // exist under this key. @@ -176,7 +176,13 @@ func (s *MessageStore) DeleteMessage(msg lnwire.Message, // If the timestamps don't match, then the update stored // should be the latest one, so we'll avoid deleting it. - if msg.Timestamp != dbMsg.(*lnwire.ChannelUpdate).Timestamp { + m, ok := dbMsg.(*lnwire.ChannelUpdate1) + if !ok { + return fmt.Errorf("expected "+ + "*lnwire.ChannelUpdate1, got: %T", + dbMsg) + } + if msg.Timestamp != m.Timestamp { return nil } } diff --git a/discovery/message_store_test.go b/discovery/message_store_test.go index 9027c68611..f706f31919 100644 --- a/discovery/message_store_test.go +++ b/discovery/message_store_test.go @@ -59,8 +59,8 @@ func randAnnounceSignatures() *lnwire.AnnounceSignatures1 { } } -func randChannelUpdate() *lnwire.ChannelUpdate { - return &lnwire.ChannelUpdate{ +func randChannelUpdate() *lnwire.ChannelUpdate1 { + return &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(rand.Uint64()), ExtraOpaqueData: make([]byte, 0), } @@ -118,7 +118,7 @@ func TestMessageStoreMessages(t *testing.T) { switch msg := msg.(type) { case *lnwire.AnnounceSignatures1: shortChanID = msg.ShortChannelID.ToUint64() - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: shortChanID = msg.ShortChannelID.ToUint64() default: t.Fatalf("found unexpected message type %T", msg) @@ -297,7 +297,7 @@ func TestMessageStoreDeleteMessage(t *testing.T) { // The store allows overwriting ChannelUpdates, since there can be // multiple versions, so we'll test things slightly different. // - // The ChannelUpdate message should exist within the store after adding + // The ChannelUpdate1 message should exist within the store after adding // it. chanUpdate := randChannelUpdate() if err := msgStore.AddMessage(chanUpdate, peer); err != nil { @@ -305,7 +305,7 @@ func TestMessageStoreDeleteMessage(t *testing.T) { } assertMsg(chanUpdate, peer, true) - // Now, we'll create a new version for the same ChannelUpdate message. + // Now, we'll create a new version for the same ChannelUpdate1 message. // Adding this one to the store will overwrite the previous one, so only // the new one should exist. newChanUpdate := randChannelUpdate() diff --git a/discovery/reliable_sender_test.go b/discovery/reliable_sender_test.go index 8835af42f4..ed455c6e23 100644 --- a/discovery/reliable_sender_test.go +++ b/discovery/reliable_sender_test.go @@ -282,7 +282,7 @@ func TestReliableSenderStaleMessages(t *testing.T) { } // Finally, notifying the peer is online should prompt the message to be - // sent. Only the ChannelUpdate will be sent in this case since the + // sent. Only the ChannelUpdate1 will be sent in this case since the // AnnounceSignatures1 message above was seen as stale. peerChan <- peer diff --git a/discovery/syncer.go b/discovery/syncer.go index 72174ea666..5110726d5a 100644 --- a/discovery/syncer.go +++ b/discovery/syncer.go @@ -1273,9 +1273,11 @@ func (g *GossipSyncer) FilterGossipMsgs(msgs ...msgWithSenders) { // set of channel announcements and channel updates. This will allow us // to quickly check if we should forward a chan ann, based on the known // channel updates for a channel. - chanUpdateIndex := make(map[lnwire.ShortChannelID][]*lnwire.ChannelUpdate) + chanUpdateIndex := make( + map[lnwire.ShortChannelID][]*lnwire.ChannelUpdate1, + ) for _, msg := range msgs { - chanUpdate, ok := msg.msg.(*lnwire.ChannelUpdate) + chanUpdate, ok := msg.msg.(*lnwire.ChannelUpdate1) if !ok { continue } @@ -1345,7 +1347,7 @@ func (g *GossipSyncer) FilterGossipMsgs(msgs ...msgWithSenders) { // For each channel update, we'll only send if it the timestamp // is between our time range. - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: if passesFilter(msg.Timestamp) { msgsToSend = append(msgsToSend, msg) } diff --git a/discovery/syncer_test.go b/discovery/syncer_test.go index 1fe94441b2..bd40489ac2 100644 --- a/discovery/syncer_test.go +++ b/discovery/syncer_test.go @@ -52,7 +52,7 @@ type mockChannelGraphTimeSeries struct { annResp chan []lnwire.Message updateReq chan lnwire.ShortChannelID - updateResp chan []*lnwire.ChannelUpdate + updateResp chan []*lnwire.ChannelUpdate1 } func newMockChannelGraphTimeSeries( @@ -74,7 +74,7 @@ func newMockChannelGraphTimeSeries( annResp: make(chan []lnwire.Message, 1), updateReq: make(chan lnwire.ShortChannelID, 1), - updateResp: make(chan []*lnwire.ChannelUpdate, 1), + updateResp: make(chan []*lnwire.ChannelUpdate1, 1), } } @@ -137,7 +137,7 @@ func (m *mockChannelGraphTimeSeries) FetchChanAnns(chain chainhash.Hash, return <-m.annResp, nil } func (m *mockChannelGraphTimeSeries) FetchChanUpdates(chain chainhash.Hash, - shortChanID lnwire.ShortChannelID) ([]*lnwire.ChannelUpdate, error) { + shortChanID lnwire.ShortChannelID) ([]*lnwire.ChannelUpdate1, error) { m.updateReq <- shortChanID @@ -288,7 +288,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { }, }, { - msg: &lnwire.ChannelUpdate{ + msg: &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(10), Timestamp: unixStamp(5), }, @@ -300,7 +300,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { }, }, { - msg: &lnwire.ChannelUpdate{ + msg: &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(15), Timestamp: unixStamp(25002), }, @@ -312,7 +312,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { }, }, { - msg: &lnwire.ChannelUpdate{ + msg: &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(20), Timestamp: unixStamp(999999), }, @@ -346,7 +346,7 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { } // If so, then we'll send back the missing update. - chanSeries.updateResp <- []*lnwire.ChannelUpdate{ + chanSeries.updateResp <- []*lnwire.ChannelUpdate1{ { ShortChannelID: lnwire.NewShortChanIDFromInt(25), Timestamp: unixStamp(5), @@ -528,7 +528,7 @@ func TestGossipSyncerApplyGossipFilter(t *testing.T) { // For this first response, we'll send back a proper // set of messages that should be echoed back. chanSeries.horizonResp <- []lnwire.Message{ - &lnwire.ChannelUpdate{ + &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(25), Timestamp: unixStamp(5), }, @@ -686,7 +686,7 @@ func TestGossipSyncerReplyShortChanIDs(t *testing.T) { &lnwire.ChannelAnnouncement1{ ShortChannelID: lnwire.NewShortChanIDFromInt(20), }, - &lnwire.ChannelUpdate{ + &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(20), Timestamp: unixStamp(999999), }, diff --git a/funding/manager.go b/funding/manager.go index 56f63545c4..e42a3db8d5 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -3296,12 +3296,12 @@ func (f *Manager) receivedChannelReady(node *btcec.PublicKey, // extractAnnounceParams extracts the various channel announcement and update // parameters that will be needed to construct a ChannelAnnouncement1 and a -// ChannelUpdate. +// ChannelUpdate1. func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) ( lnwire.MilliSatoshi, lnwire.MilliSatoshi) { // We'll obtain the min HTLC value we can forward in our direction, as - // we'll use this value within our ChannelUpdate. This constraint is + // we'll use this value within our ChannelUpdate1. This constraint is // originally set by the remote node, as it will be the one that will // need to determine the smallest HTLC it deems economically relevant. fwdMinHTLC := c.LocalChanCfg.MinHTLC @@ -3313,7 +3313,7 @@ func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) ( } // We'll obtain the max HTLC value we can forward in our direction, as - // we'll use this value within our ChannelUpdate. This value must be <= + // we'll use this value within our ChannelUpdate1. This value must be <= // channel capacity and <= the maximum in-flight msats set by the peer. fwdMaxHTLC := c.LocalChanCfg.MaxPendingAmount capacityMSat := lnwire.NewMSatFromSatoshis(c.Capacity) @@ -3324,13 +3324,13 @@ func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) ( return fwdMinHTLC, fwdMaxHTLC } -// addToRouterGraph sends a ChannelAnnouncement1 and a ChannelUpdate to the +// addToRouterGraph sends a ChannelAnnouncement1 and a ChannelUpdate1 to the // gossiper so that the channel is added to the Router's internal graph. // These announcement messages are NOT broadcasted to the greater network, // only to the channel counter party. The proofs required to announce the // channel to the greater network will be created and sent in annAfterSixConfs. // The peerAlias is used for zero-conf channels to give the counter-party a -// ChannelUpdate they understand. ourPolicy may be set for various +// ChannelUpdate1 they understand. ourPolicy may be set for various // option-scid-alias channels to re-use the same policy. func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel, shortChanID *lnwire.ShortChannelID, @@ -3353,7 +3353,7 @@ func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel, "announcement: %v", err) } - // Send ChannelAnnouncement1 and ChannelUpdate to the gossiper to add + // Send ChannelAnnouncement1 and ChannelUpdate1 to the gossiper to add // to the Router's topology. errChan := f.cfg.SendAnnouncement( ann.chanAnn, discovery.ChannelCapacity(completeChan.Capacity), @@ -3386,7 +3386,7 @@ func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel, routing.ErrIgnored) { log.Debugf("Router rejected "+ - "ChannelUpdate: %v", err) + "ChannelUpdate1: %v", err) } else { return fmt.Errorf("error sending channel "+ "update: %v", err) @@ -3514,7 +3514,7 @@ func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel, // We'll delete the edge and add it again via // addToRouterGraph. This is because the peer may have - // sent us a ChannelUpdate with an alias and we don't + // sent us a ChannelUpdate1 with an alias and we don't // want to relay this. ourPolicy, err := f.cfg.DeleteAliasEdge(baseScid) if err != nil { @@ -3762,7 +3762,7 @@ func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen // We'll need to store the received TLV alias if the option_scid_alias // feature was negotiated. This will be used to provide route hints // during invoice creation. In the zero-conf case, it is also used to - // provide a ChannelUpdate to the remote peer. This is done before the + // provide a ChannelUpdate1 to the remote peer. This is done before the // call to InsertNextRevocation in case the call to PutPeerAlias fails. // If it were to fail on the first call to handleChannelReady, we // wouldn't want the channel to be usable yet. @@ -3937,7 +3937,7 @@ func (f *Manager) handleChannelReadyReceived(channel *channeldb.OpenChannel, // We'll need to wait until channel_ready has been received and // the peer lets us know the alias they want to use for the // channel. With this information, we can then construct a - // ChannelUpdate for them. If an alias does not yet exist, + // ChannelUpdate1 for them. If an alias does not yet exist, // we'll just return, letting the next iteration of the loop // check again. var defaultAlias lnwire.ShortChannelID @@ -4051,7 +4051,7 @@ func (f *Manager) ensureInitialForwardingPolicy(chanID lnwire.ChannelID, // send out to the network after a new channel has been created locally. type chanAnnouncement struct { chanAnn *lnwire.ChannelAnnouncement1 - chanUpdateAnn *lnwire.ChannelUpdate + chanUpdateAnn *lnwire.ChannelUpdate1 chanProof *lnwire.AnnounceSignatures1 } @@ -4144,8 +4144,8 @@ func (f *Manager) newChanAnnouncement(localPubKey, msgFlags := lnwire.ChanUpdateRequiredMaxHtlc // We announce the channel with the default values. Some of - // these values can later be changed by crafting a new ChannelUpdate. - chanUpdateAnn := &lnwire.ChannelUpdate{ + // these values can later be changed by crafting a new ChannelUpdate1. + chanUpdateAnn := &lnwire.ChannelUpdate1{ ShortChannelID: shortChanID, ChainHash: chainHash, Timestamp: uint32(time.Now().Unix()), @@ -4171,7 +4171,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, switch { case ourPolicy != nil: // If ourPolicy is non-nil, modify the default parameters of the - // ChannelUpdate. + // ChannelUpdate1. chanUpdateAnn.MessageFlags = ourPolicy.MessageFlags chanUpdateAnn.ChannelFlags = ourPolicy.ChannelFlags chanUpdateAnn.TimeLockDelta = ourPolicy.TimeLockDelta @@ -4294,7 +4294,7 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey, // We only send the channel proof announcement and the node announcement // because addToRouterGraph previously sent the ChannelAnnouncement1 and - // the ChannelUpdate announcement messages. The channel proof and node + // the ChannelUpdate1 announcement messages. The channel proof and node // announcements are broadcast to the greater network. errChan := f.cfg.SendAnnouncement(ann.chanProof) select { diff --git a/funding/manager_test.go b/funding/manager_test.go index a51e40c15d..e29d3201df 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -1144,9 +1144,9 @@ func assertAddedToRouterGraph(t *testing.T, alice, bob *testNode, } // assertChannelAnnouncements checks that alice and bob both sends the expected -// announcements (ChannelAnnouncement1, ChannelUpdate) after the funding tx has +// announcements (ChannelAnnouncement1, ChannelUpdate1) after the funding tx has // confirmed. The last arguments can be set if we expect the nodes to advertise -// custom min_htlc values as part of their ChannelUpdate. We expect Alice to +// custom min_htlc values as part of their ChannelUpdate1. We expect Alice to // advertise the value required by Bob and vice versa. If they are not set the // advertised value will be checked against the other node's default min_htlc, // base fee and fee rate values. @@ -1176,8 +1176,8 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, // After the ChannelReady message is sent, Alice and Bob will each send // the following messages to their gossiper: // 1) ChannelAnnouncement1 - // 2) ChannelUpdate - // The ChannelAnnouncement1 is kept locally, while the ChannelUpdate is + // 2) ChannelUpdate1 + // The ChannelAnnouncement1 is kept locally, while the ChannelUpdate1 is // sent directly to the other peer, so the edge policies are known to // both peers. nodes := []*testNode{alice, bob} @@ -1197,7 +1197,7 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, switch m := msg.(type) { case *lnwire.ChannelAnnouncement1: gotChannelAnnouncement = true - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: // The channel update sent by the node should // advertise the MinHTLC value required by the @@ -1246,7 +1246,7 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode, t, gotChannelAnnouncement, "ChannelAnnouncement1 from %d", j, ) - require.Truef(t, gotChannelUpdate, "ChannelUpdate from %d", j) + require.Truef(t, gotChannelUpdate, "ChannelUpdate1 from %d", j) // Make sure no other message is sent. select { @@ -4549,7 +4549,7 @@ func testZeroConf(t *testing.T, chanType *lnwire.ChannelType) { assertHandleChannelReady(t, alice, bob) // We'll now assert that both sides send ChannelAnnouncement1 and - // ChannelUpdate messages. + // ChannelUpdate1 messages. assertChannelAnnouncements( t, alice, bob, fundingAmt, nil, nil, nil, nil, ) diff --git a/htlcswitch/interfaces.go b/htlcswitch/interfaces.go index 1ce4ffb2e5..9cadf41400 100644 --- a/htlcswitch/interfaces.go +++ b/htlcswitch/interfaces.go @@ -78,7 +78,7 @@ type scidAliasHandler interface { // HTLCs on option_scid_alias channels. attachFailAliasUpdate(failClosure func( sid lnwire.ShortChannelID, - incoming bool) *lnwire.ChannelUpdate) + incoming bool) *lnwire.ChannelUpdate1) // getAliases fetches the link's underlying aliases. This is used by // the Switch to determine whether to forward an HTLC and where to diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 2a1e49923d..e809176962 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -124,7 +124,8 @@ type ChannelLinkConfig struct { // specified when we receive an incoming HTLC. This will be used to // provide payment senders our latest policy when sending encrypted // error messages. - FetchLastChannelUpdate func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) + FetchLastChannelUpdate func(lnwire.ShortChannelID) ( + *lnwire.ChannelUpdate1, error) // Peer is a lightning network node with which we have the channel link // opened. @@ -266,7 +267,7 @@ type ChannelLinkConfig struct { // FailAliasUpdate is a function used to fail an HTLC for an // option_scid_alias channel. FailAliasUpdate func(sid lnwire.ShortChannelID, - incoming bool) *lnwire.ChannelUpdate + incoming bool) *lnwire.ChannelUpdate1 // GetAliases is used by the link and switch to fetch the set of // aliases for a given link. @@ -613,9 +614,9 @@ func shouldAdjustCommitFee(netFee, chanFee, } // failCb is used to cut down on the argument verbosity. -type failCb func(update *lnwire.ChannelUpdate) lnwire.FailureMessage +type failCb func(update *lnwire.ChannelUpdate1) lnwire.FailureMessage -// createFailureWithUpdate creates a ChannelUpdate when failing an incoming or +// createFailureWithUpdate creates a ChannelUpdate1 when failing an incoming or // outgoing HTLC. It may return a FailureMessage that references a channel's // alias. If the channel does not have an alias, then the regular channel // update from disk will be returned. @@ -623,7 +624,7 @@ func (l *channelLink) createFailureWithUpdate(incoming bool, outgoingScid lnwire.ShortChannelID, cb failCb) lnwire.FailureMessage { // Determine which SCID to use in case we need to use aliases in the - // ChannelUpdate. + // ChannelUpdate1. scid := outgoingScid if incoming { scid = l.ShortChanID() @@ -2491,7 +2492,7 @@ func (l *channelLink) getAliases() []lnwire.ShortChannelID { // // Part of the scidAliasHandler interface. func (l *channelLink) attachFailAliasUpdate(closure func( - sid lnwire.ShortChannelID, incoming bool) *lnwire.ChannelUpdate) { + sid lnwire.ShortChannelID, incoming bool) *lnwire.ChannelUpdate1) { l.Lock() l.cfg.FailAliasUpdate = closure @@ -2568,7 +2569,7 @@ func (l *channelLink) CheckHtlcForward(payHash [32]byte, // As part of the returned error, we'll send our latest routing // policy so the sending node obtains the most up to date data. - cb := func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage { + cb := func(upd *lnwire.ChannelUpdate1) lnwire.FailureMessage { return lnwire.NewFeeInsufficient(amtToForward, *upd) } failure := l.createFailureWithUpdate(false, originalScid, cb) @@ -2596,7 +2597,7 @@ func (l *channelLink) CheckHtlcForward(payHash [32]byte, // Grab the latest routing policy so the sending node is up to // date with our current policy. - cb := func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage { + cb := func(upd *lnwire.ChannelUpdate1) lnwire.FailureMessage { return lnwire.NewIncorrectCltvExpiry( incomingTimeout, *upd, ) @@ -2645,7 +2646,7 @@ func (l *channelLink) canSendHtlc(policy models.ForwardingPolicy, // As part of the returned error, we'll send our latest routing // policy so the sending node obtains the most up to date data. - cb := func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage { + cb := func(upd *lnwire.ChannelUpdate1) lnwire.FailureMessage { return lnwire.NewAmountBelowMinimum(amt, *upd) } failure := l.createFailureWithUpdate(false, originalScid, cb) @@ -2660,7 +2661,7 @@ func (l *channelLink) canSendHtlc(policy models.ForwardingPolicy, // As part of the returned error, we'll send our latest routing // policy so the sending node obtains the most up-to-date data. - cb := func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage { + cb := func(upd *lnwire.ChannelUpdate1) lnwire.FailureMessage { return lnwire.NewTemporaryChannelFailure(upd) } failure := l.createFailureWithUpdate(false, originalScid, cb) @@ -2675,7 +2676,7 @@ func (l *channelLink) canSendHtlc(policy models.ForwardingPolicy, "outgoing_expiry=%v, best_height=%v", payHash[:], timeout, heightNow) - cb := func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage { + cb := func(upd *lnwire.ChannelUpdate1) lnwire.FailureMessage { return lnwire.NewExpiryTooSoon(*upd) } failure := l.createFailureWithUpdate(false, originalScid, cb) @@ -2695,7 +2696,7 @@ func (l *channelLink) canSendHtlc(policy models.ForwardingPolicy, if amt > l.Bandwidth() { l.log.Warnf("insufficient bandwidth to route htlc: %v is "+ "larger than %v", amt, l.Bandwidth()) - cb := func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage { + cb := func(upd *lnwire.ChannelUpdate1) lnwire.FailureMessage { return lnwire.NewTemporaryChannelFailure(upd) } failure := l.createFailureWithUpdate(false, originalScid, cb) @@ -3152,7 +3153,8 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg, l.log.Errorf("unable to encode the "+ "remaining route %v", err) - cb := func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage { + //nolint:lll + cb := func(upd *lnwire.ChannelUpdate1) lnwire.FailureMessage { return lnwire.NewTemporaryChannelFailure(upd) } diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index 9c07cd53c1..187e48dd5b 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -5730,13 +5730,13 @@ func TestForwardingAsymmetricTimeLockPolicies(t *testing.T) { // forwarding policy. func TestCheckHtlcForward(t *testing.T) { fetchLastChannelUpdate := func(lnwire.ShortChannelID) ( - *lnwire.ChannelUpdate, error) { + *lnwire.ChannelUpdate1, error) { - return &lnwire.ChannelUpdate{}, nil + return &lnwire.ChannelUpdate1{}, nil } failAliasUpdate := func(sid lnwire.ShortChannelID, - incoming bool) *lnwire.ChannelUpdate { + incoming bool) *lnwire.ChannelUpdate1 { return nil } diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go index 9b0453dea9..9cdc583bb7 100644 --- a/htlcswitch/mock.go +++ b/htlcswitch/mock.go @@ -165,7 +165,7 @@ type mockServer struct { var _ lnpeer.Peer = (*mockServer)(nil) func initSwitchWithDB(startingHeight uint32, db *channeldb.DB) (*Switch, error) { - signAliasUpdate := func(u *lnwire.ChannelUpdate) (*ecdsa.Signature, + signAliasUpdate := func(u *lnwire.ChannelUpdate1) (*ecdsa.Signature, error) { return testSig, nil @@ -181,9 +181,9 @@ func initSwitchWithDB(startingHeight uint32, db *channeldb.DB) (*Switch, error) events: make(map[time.Time]channeldb.ForwardingEvent), }, FetchLastChannelUpdate: func(scid lnwire.ShortChannelID) ( - *lnwire.ChannelUpdate, error) { + *lnwire.ChannelUpdate1, error) { - return &lnwire.ChannelUpdate{ + return &lnwire.ChannelUpdate1{ ShortChannelID: scid, }, nil }, @@ -731,7 +731,7 @@ type mockChannelLink struct { checkHtlcForwardResult *LinkError failAliasUpdate func(sid lnwire.ShortChannelID, - incoming bool) *lnwire.ChannelUpdate + incoming bool) *lnwire.ChannelUpdate1 confirmedZC bool } @@ -860,7 +860,7 @@ func (f *mockChannelLink) AttachMailBox(mailBox MailBox) { } func (f *mockChannelLink) attachFailAliasUpdate(closure func( - sid lnwire.ShortChannelID, incoming bool) *lnwire.ChannelUpdate) { + sid lnwire.ShortChannelID, incoming bool) *lnwire.ChannelUpdate1) { f.failAliasUpdate = closure } diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go index 592d03a1ce..695e69fbb4 100644 --- a/htlcswitch/switch.go +++ b/htlcswitch/switch.go @@ -170,7 +170,8 @@ type Config struct { // specified when we receive an incoming HTLC. This will be used to // provide payment senders our latest policy when sending encrypted // error messages. - FetchLastChannelUpdate func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) + FetchLastChannelUpdate func(lnwire.ShortChannelID) ( + *lnwire.ChannelUpdate1, error) // Notifier is an instance of a chain notifier that we'll use to signal // the switch when a new block has arrived. @@ -216,8 +217,8 @@ type Config struct { // SignAliasUpdate is used when sending FailureMessages backwards for // option_scid_alias channels. This avoids a potential privacy leak by // replacing the public, confirmed SCID with the alias in the - // ChannelUpdate. - SignAliasUpdate func(u *lnwire.ChannelUpdate) (*ecdsa.Signature, + // ChannelUpdate1. + SignAliasUpdate func(u *lnwire.ChannelUpdate1) (*ecdsa.Signature, error) // IsAlias returns whether or not a given SCID is an alias. @@ -767,7 +768,7 @@ func (s *Switch) ForwardPackets(linkQuit chan struct{}, incomingID := failedPackets[0].incomingChanID // If the incoming channel is an option_scid_alias channel, - // then we'll need to replace the SCID in the ChannelUpdate. + // then we'll need to replace the SCID in the ChannelUpdate1. update := s.failAliasUpdate(incomingID, true) if update == nil { // Fallback to the original non-option behavior. @@ -2848,16 +2849,16 @@ func (s *Switch) failMailboxUpdate(outgoingScid, return lnwire.NewTemporaryChannelFailure(update) } -// failAliasUpdate prepares a ChannelUpdate for a failed incoming or outgoing +// failAliasUpdate prepares a ChannelUpdate1 for a failed incoming or outgoing // HTLC on a channel where the option-scid-alias feature bit was negotiated. If // the associated channel is not one of these, this function will return nil // and the caller is expected to handle this properly. In this case, a return // to the original non-alias behavior is expected. func (s *Switch) failAliasUpdate(scid lnwire.ShortChannelID, - incoming bool) *lnwire.ChannelUpdate { + incoming bool) *lnwire.ChannelUpdate1 { // This function does not defer the unlocking because of the database - // lookups for ChannelUpdate. + // lookups for ChannelUpdate1. s.indexMtx.RLock() if s.cfg.IsAlias(scid) { @@ -2932,7 +2933,7 @@ func (s *Switch) failAliasUpdate(scid lnwire.ShortChannelID, } // Fetch the link so we can get an alias to use in the ShortChannelID - // of the ChannelUpdate. + // of the ChannelUpdate1. link, ok := s.forwardingIndex[baseScid] s.indexMtx.RUnlock() if !ok { @@ -2947,14 +2948,14 @@ func (s *Switch) failAliasUpdate(scid lnwire.ShortChannelID, return nil } - // Fetch the ChannelUpdate via the real, confirmed SCID. + // Fetch the ChannelUpdate1 via the real, confirmed SCID. update, err := s.cfg.FetchLastChannelUpdate(scid) if err != nil { return nil } // The incoming case will replace the ShortChannelID in the retrieved - // ChannelUpdate with the alias to ensure no privacy leak occurs. This + // ChannelUpdate1 with the alias to ensure no privacy leak occurs. This // would happen if a private non-zero-conf option-scid-alias // feature-bit channel leaked its UTXO here rather than supplying an // alias. In the outgoing case, the confirmed SCID was actually used diff --git a/htlcswitch/switch_test.go b/htlcswitch/switch_test.go index 2d507f01b9..eb33c31f9e 100644 --- a/htlcswitch/switch_test.go +++ b/htlcswitch/switch_test.go @@ -3949,7 +3949,7 @@ func TestSwitchHoldForward(t *testing.T) { // Simulate an error during the composition of the failure message. currentCallback := c.s.cfg.FetchLastChannelUpdate c.s.cfg.FetchLastChannelUpdate = func( - lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) { + lnwire.ShortChannelID) (*lnwire.ChannelUpdate1, error) { return nil, errors.New("cannot fetch update") } @@ -4820,7 +4820,7 @@ func TestSwitchResolution(t *testing.T) { } // TestSwitchForwardFailAlias tests that if ForwardPackets returns a failure -// before actually forwarding, the ChannelUpdate uses the SCID from the +// before actually forwarding, the ChannelUpdate1 uses the SCID from the // incoming channel and does not leak private information like the UTXO. func TestSwitchForwardFailAlias(t *testing.T) { tests := []struct { @@ -5170,7 +5170,7 @@ func testSwitchAliasFailAdd(t *testing.T, zeroConf, private, useAlias bool) { select { case failPacket := <-bobLink.packets: // Assert that failPacket returns the expected SCID in the - // ChannelUpdate. + // ChannelUpdate1. msg := failPacket.linkFailure.msg failMsg, ok := msg.(*lnwire.FailTemporaryChannelFailure) require.True(t, ok) @@ -5369,7 +5369,7 @@ func testSwitchHandlePacketForward(t *testing.T, zeroConf, private, select { case failPacket := <-bobLink.packets: - // Assert that failPacket returns the expected ChannelUpdate. + // Assert that failPacket returns the expected ChannelUpdate1. msg := failPacket.linkFailure.msg failMsg, ok := msg.(*lnwire.FailAmountBelowMinimum) require.True(t, ok) @@ -5514,7 +5514,7 @@ func testSwitchAliasInterceptFail(t *testing.T, zeroConf bool) { select { case failPacket := <-aliceLink.packets: - // Assert that failPacket returns the expected ChannelUpdate. + // Assert that failPacket returns the expected ChannelUpdate1. failHtlc, ok := failPacket.htlc.(*lnwire.UpdateFailHTLC) require.True(t, ok) diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index da36e214cd..8577eceb94 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -91,8 +91,10 @@ func genIDs() (lnwire.ChannelID, lnwire.ChannelID, lnwire.ShortChannelID, // mockGetChanUpdateMessage helper function which returns topology update of // the channel -func mockGetChanUpdateMessage(cid lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) { - return &lnwire.ChannelUpdate{ +func mockGetChanUpdateMessage(_ lnwire.ShortChannelID) ( + *lnwire.ChannelUpdate1, error) { + + return &lnwire.ChannelUpdate1{ Signature: wireSig, }, nil } diff --git a/itest/lnd_channel_policy_test.go b/itest/lnd_channel_policy_test.go index 85527a0821..6f819308da 100644 --- a/itest/lnd_channel_policy_test.go +++ b/itest/lnd_channel_policy_test.go @@ -84,7 +84,7 @@ func testUpdateChannelPolicy(ht *lntest.HarnessTest) { // Open the channel Carol->Bob with a custom min_htlc value set. Since // Carol is opening the channel, she will require Bob to not forward // HTLCs smaller than this value, and hence he should advertise it as - // part of his ChannelUpdate. + // part of his ChannelUpdate1. const customMinHtlc = 5000 chanPoint2 := ht.OpenChannel( carol, bob, lntest.OpenChannelParams{ @@ -540,7 +540,7 @@ func testSendUpdateDisableChannel(ht *lntest.HarnessTest) { assertPolicyUpdate(eve, expectedPolicy, chanPointEveCarol, 2) // We restart Carol. Since the channel now becomes active again, Eve - // should send a ChannelUpdate setting the channel no longer disabled. + // should send a ChannelUpdate1 setting the channel no longer disabled. require.NoError(ht, restartCarol(), "unable to restart carol") expectedPolicy.Disabled = false diff --git a/itest/lnd_zero_conf_test.go b/itest/lnd_zero_conf_test.go index f2190bd2a9..fd15ec7aa3 100644 --- a/itest/lnd_zero_conf_test.go +++ b/itest/lnd_zero_conf_test.go @@ -488,7 +488,7 @@ func testPrivateUpdateAlias(ht *lntest.HarnessTest, ht.EnsureConnected(carol, dave) // We'll open a regular public channel between Eve and Carol here. Eve - // will be the one receiving the onion-encrypted ChannelUpdate. + // will be the one receiving the onion-encrypted ChannelUpdate1. ht.EnsureConnected(eve, carol) chanAmt := btcutil.Amount(1_000_000) diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index 549443f0fe..4d12ee58d4 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -1500,7 +1500,7 @@ func marshallWireError(msg lnwire.FailureMessage, // marshallChannelUpdate marshalls a channel update as received over the wire to // the router rpc format. -func marshallChannelUpdate(update *lnwire.ChannelUpdate) *lnrpc.ChannelUpdate { +func marshallChannelUpdate(update *lnwire.ChannelUpdate1) *lnrpc.ChannelUpdate { if update == nil { return nil } diff --git a/lnwire/channel_update.go b/lnwire/channel_update.go index 7f42a58b46..95f946da07 100644 --- a/lnwire/channel_update.go +++ b/lnwire/channel_update.go @@ -9,12 +9,12 @@ import ( ) // ChanUpdateMsgFlags is a bitfield that signals whether optional fields are -// present in the ChannelUpdate. +// present in the ChannelUpdate1. type ChanUpdateMsgFlags uint8 const ( // ChanUpdateRequiredMaxHtlc is a bit that indicates whether the - // required htlc_maximum_msat field is present in this ChannelUpdate. + // required htlc_maximum_msat field is present in this ChannelUpdate1. ChanUpdateRequiredMaxHtlc ChanUpdateMsgFlags = 1 << iota ) @@ -31,7 +31,7 @@ func (c ChanUpdateMsgFlags) HasMaxHtlc() bool { // ChanUpdateChanFlags is a bitfield that signals various options concerning a // particular channel edge. Each bit is to be examined in order to determine -// how the ChannelUpdate message is to be interpreted. +// how the ChannelUpdate1 message is to be interpreted. type ChanUpdateChanFlags uint8 const ( @@ -56,11 +56,11 @@ func (c ChanUpdateChanFlags) String() string { return fmt.Sprintf("%08b", c) } -// ChannelUpdate message is used after channel has been initially announced. +// ChannelUpdate1 message is used after channel has been initially announced. // Each side independently announces its fees and minimum expiry for HTLCs and // other parameters. Also this message is used to redeclare initially set // channel parameters. -type ChannelUpdate struct { +type ChannelUpdate1 struct { // Signature is used to validate the announced data and prove the // ownership of node id. Signature Sig @@ -120,15 +120,15 @@ type ChannelUpdate struct { ExtraOpaqueData ExtraOpaqueData } -// A compile time check to ensure ChannelUpdate implements the lnwire.Message +// A compile time check to ensure ChannelUpdate1 implements the lnwire.Message // interface. -var _ Message = (*ChannelUpdate)(nil) +var _ Message = (*ChannelUpdate1)(nil) -// Decode deserializes a serialized ChannelUpdate stored in the passed +// Decode deserializes a serialized ChannelUpdate1 stored in the passed // io.Reader observing the specified protocol version. // // This is part of the lnwire.Message interface. -func (a *ChannelUpdate) Decode(r io.Reader, pver uint32) error { +func (a *ChannelUpdate1) Decode(r io.Reader, _ uint32) error { err := ReadElements(r, &a.Signature, a.ChainHash[:], @@ -155,11 +155,11 @@ func (a *ChannelUpdate) Decode(r io.Reader, pver uint32) error { return a.ExtraOpaqueData.Decode(r) } -// Encode serializes the target ChannelUpdate into the passed io.Writer +// Encode serializes the target ChannelUpdate1 into the passed io.Writer // observing the protocol version specified. // // This is part of the lnwire.Message interface. -func (a *ChannelUpdate) Encode(w *bytes.Buffer, pver uint32) error { +func (a *ChannelUpdate1) Encode(w *bytes.Buffer, _ uint32) error { if err := WriteSig(w, a.Signature); err != nil { return err } @@ -217,13 +217,13 @@ func (a *ChannelUpdate) Encode(w *bytes.Buffer, pver uint32) error { // wire. // // This is part of the lnwire.Message interface. -func (a *ChannelUpdate) MsgType() MessageType { +func (a *ChannelUpdate1) MsgType() MessageType { return MsgChannelUpdate } // DataToSign is used to retrieve part of the announcement message which should // be signed. -func (a *ChannelUpdate) DataToSign() ([]byte, error) { +func (a *ChannelUpdate1) DataToSign() ([]byte, error) { // We should not include the signatures itself. b := make([]byte, 0, MaxMsgBody) buf := bytes.NewBuffer(b) diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 3df833b0f0..af94a9f836 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -889,14 +889,14 @@ func TestLightningWireProtocol(t *testing.T) { maxHtlc := MilliSatoshi(r.Int63()) // We make the max_htlc field zero if it is not flagged - // as being part of the ChannelUpdate, to pass + // as being part of the ChannelUpdate1, to pass // serialization tests, as it will be ignored if the bit // is not set. if msgFlags&ChanUpdateRequiredMaxHtlc == 0 { maxHtlc = 0 } - req := ChannelUpdate{ + req := ChannelUpdate1{ ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), Timestamp: uint32(r.Int31()), MessageFlags: msgFlags, @@ -1216,7 +1216,7 @@ func TestLightningWireProtocol(t *testing.T) { }, { msgType: MsgChannelUpdate, - scenario: func(m ChannelUpdate) bool { + scenario: func(m ChannelUpdate1) bool { return mainScenario(&m) }, }, diff --git a/lnwire/message.go b/lnwire/message.go index fc5259d5cf..46dd7de92c 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -113,7 +113,7 @@ func (t MessageType) String() string { case MsgChannelAnnouncement: return "ChannelAnnouncement1" case MsgChannelUpdate: - return "ChannelUpdate" + return "ChannelUpdate1" case MsgNodeAnnouncement: return "NodeAnnouncement" case MsgPing: @@ -217,7 +217,7 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { case MsgChannelAnnouncement: msg = &ChannelAnnouncement1{} case MsgChannelUpdate: - msg = &ChannelUpdate{} + msg = &ChannelUpdate1{} case MsgNodeAnnouncement: msg = &NodeAnnouncement{} case MsgPing: diff --git a/lnwire/message_test.go b/lnwire/message_test.go index 4c0ebdd45f..69c3901c12 100644 --- a/lnwire/message_test.go +++ b/lnwire/message_test.go @@ -692,21 +692,21 @@ func newMsgNodeAnnouncement(t testing.TB, return msg } -func newMsgChannelUpdate(t testing.TB, r *rand.Rand) *lnwire.ChannelUpdate { +func newMsgChannelUpdate(t testing.TB, r *rand.Rand) *lnwire.ChannelUpdate1 { t.Helper() msgFlags := lnwire.ChanUpdateMsgFlags(r.Int31()) maxHtlc := lnwire.MilliSatoshi(r.Int63()) // We make the max_htlc field zero if it is not flagged - // as being part of the ChannelUpdate, to pass + // as being part of the ChannelUpdate1, to pass // serialization tests, as it will be ignored if the bit // is not set. if msgFlags&lnwire.ChanUpdateRequiredMaxHtlc == 0 { maxHtlc = 0 } - msg := &lnwire.ChannelUpdate{ + msg := &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(r.Uint64()), Timestamp: uint32(r.Int31()), MessageFlags: msgFlags, diff --git a/lnwire/onion_error.go b/lnwire/onion_error.go index adf12781ac..7190e37016 100644 --- a/lnwire/onion_error.go +++ b/lnwire/onion_error.go @@ -597,7 +597,7 @@ func (f *FailInvalidOnionKey) Error() string { // unable to pull out a fully valid version, then we'll fall back to the // regular parsing mechanism which includes the length prefix an NO type byte. func parseChannelUpdateCompatibilityMode(reader io.Reader, length uint16, - chanUpdate *ChannelUpdate, pver uint32) error { + chanUpdate *ChannelUpdate1, pver uint32) error { // Instantiate a LimitReader because there may be additional data // present after the channel update. Without limiting the stream, the @@ -615,7 +615,7 @@ func parseChannelUpdateCompatibilityMode(reader io.Reader, length uint16, // Some nodes well prefix an additional set of bytes in front of their // channel updates. These bytes will _almost_ always be 258 or the type - // of the ChannelUpdate message. + // of the ChannelUpdate1 message. typeInt := binary.BigEndian.Uint16(maybeTypeBytes) if typeInt == MsgChannelUpdate { // At this point it's likely the case that this is a channel @@ -644,11 +644,14 @@ type FailTemporaryChannelFailure struct { // which caused the failure. // // NOTE: This field is optional. - Update *ChannelUpdate + Update *ChannelUpdate1 } -// NewTemporaryChannelFailure creates new instance of the FailTemporaryChannelFailure. -func NewTemporaryChannelFailure(update *ChannelUpdate) *FailTemporaryChannelFailure { +// NewTemporaryChannelFailure creates new instance of the +// FailTemporaryChannelFailure. +func NewTemporaryChannelFailure( + update *ChannelUpdate1) *FailTemporaryChannelFailure { + return &FailTemporaryChannelFailure{Update: update} } @@ -682,7 +685,7 @@ func (f *FailTemporaryChannelFailure) Decode(r io.Reader, pver uint32) error { } if length != 0 { - f.Update = &ChannelUpdate{} + f.Update = &ChannelUpdate1{} return parseChannelUpdateCompatibilityMode( r, length, f.Update, pver, @@ -717,12 +720,12 @@ type FailAmountBelowMinimum struct { // Update is used to update information about state of the channel // which caused the failure. - Update ChannelUpdate + Update ChannelUpdate1 } // NewAmountBelowMinimum creates new instance of the FailAmountBelowMinimum. func NewAmountBelowMinimum(htlcMsat MilliSatoshi, - update ChannelUpdate) *FailAmountBelowMinimum { + update ChannelUpdate1) *FailAmountBelowMinimum { return &FailAmountBelowMinimum{ HtlcMsat: htlcMsat, @@ -758,7 +761,7 @@ func (f *FailAmountBelowMinimum) Decode(r io.Reader, pver uint32) error { return err } - f.Update = ChannelUpdate{} + f.Update = ChannelUpdate1{} return parseChannelUpdateCompatibilityMode( r, length, &f.Update, pver, @@ -787,12 +790,13 @@ type FailFeeInsufficient struct { // Update is used to update information about state of the channel // which caused the failure. - Update ChannelUpdate + Update ChannelUpdate1 } // NewFeeInsufficient creates new instance of the FailFeeInsufficient. func NewFeeInsufficient(htlcMsat MilliSatoshi, - update ChannelUpdate) *FailFeeInsufficient { + update ChannelUpdate1) *FailFeeInsufficient { + return &FailFeeInsufficient{ HtlcMsat: htlcMsat, Update: update, @@ -827,7 +831,7 @@ func (f *FailFeeInsufficient) Decode(r io.Reader, pver uint32) error { return err } - f.Update = ChannelUpdate{} + f.Update = ChannelUpdate1{} return parseChannelUpdateCompatibilityMode( r, length, &f.Update, pver, @@ -858,12 +862,12 @@ type FailIncorrectCltvExpiry struct { // Update is used to update information about state of the channel // which caused the failure. - Update ChannelUpdate + Update ChannelUpdate1 } // NewIncorrectCltvExpiry creates new instance of the FailIncorrectCltvExpiry. func NewIncorrectCltvExpiry(cltvExpiry uint32, - update ChannelUpdate) *FailIncorrectCltvExpiry { + update ChannelUpdate1) *FailIncorrectCltvExpiry { return &FailIncorrectCltvExpiry{ CltvExpiry: cltvExpiry, @@ -896,7 +900,7 @@ func (f *FailIncorrectCltvExpiry) Decode(r io.Reader, pver uint32) error { return err } - f.Update = ChannelUpdate{} + f.Update = ChannelUpdate1{} return parseChannelUpdateCompatibilityMode( r, length, &f.Update, pver, @@ -921,11 +925,11 @@ func (f *FailIncorrectCltvExpiry) Encode(w *bytes.Buffer, pver uint32) error { type FailExpiryTooSoon struct { // Update is used to update information about state of the channel // which caused the failure. - Update ChannelUpdate + Update ChannelUpdate1 } // NewExpiryTooSoon creates new instance of the FailExpiryTooSoon. -func NewExpiryTooSoon(update ChannelUpdate) *FailExpiryTooSoon { +func NewExpiryTooSoon(update ChannelUpdate1) *FailExpiryTooSoon { return &FailExpiryTooSoon{ Update: update, } @@ -954,7 +958,7 @@ func (f *FailExpiryTooSoon) Decode(r io.Reader, pver uint32) error { return err } - f.Update = ChannelUpdate{} + f.Update = ChannelUpdate1{} return parseChannelUpdateCompatibilityMode( r, length, &f.Update, pver, @@ -980,11 +984,13 @@ type FailChannelDisabled struct { // Update is used to update information about state of the channel // which caused the failure. - Update ChannelUpdate + Update ChannelUpdate1 } // NewChannelDisabled creates new instance of the FailChannelDisabled. -func NewChannelDisabled(flags uint16, update ChannelUpdate) *FailChannelDisabled { +func NewChannelDisabled(flags uint16, + update ChannelUpdate1) *FailChannelDisabled { + return &FailChannelDisabled{ Flags: flags, Update: update, @@ -1019,7 +1025,7 @@ func (f *FailChannelDisabled) Decode(r io.Reader, pver uint32) error { return err } - f.Update = ChannelUpdate{} + f.Update = ChannelUpdate1{} return parseChannelUpdateCompatibilityMode( r, length, &f.Update, pver, @@ -1456,10 +1462,10 @@ func makeEmptyOnionError(code FailCode) (FailureMessage, error) { } } -// writeOnionErrorChanUpdate writes out a ChannelUpdate using the onion error +// writeOnionErrorChanUpdate writes out a ChannelUpdate1 using the onion error // format. The format is that we first write out the true serialized length of // the channel update, followed by the serialized channel update itself. -func writeOnionErrorChanUpdate(w *bytes.Buffer, chanUpdate *ChannelUpdate, +func writeOnionErrorChanUpdate(w *bytes.Buffer, chanUpdate *ChannelUpdate1, pver uint32) error { // First, we encode the channel update in a temporary buffer in order diff --git a/lnwire/onion_error_test.go b/lnwire/onion_error_test.go index 438306b666..4f230bd22f 100644 --- a/lnwire/onion_error_test.go +++ b/lnwire/onion_error_test.go @@ -20,7 +20,7 @@ var ( testType = uint64(3) testOffset = uint16(24) sig, _ = NewSigFromSignature(testSig) - testChannelUpdate = ChannelUpdate{ + testChannelUpdate = ChannelUpdate1{ Signature: sig, ShortChannelID: NewShortChanIDFromInt(1), Timestamp: 1, @@ -136,7 +136,7 @@ func TestChannelUpdateCompatibilityParsing(t *testing.T) { // Now that we have the set of bytes encoded, we'll ensure that we're // able to decode it using our compatibility method, as it's a regular // encoded channel update message. - var newChanUpdate ChannelUpdate + var newChanUpdate ChannelUpdate1 err := parseChannelUpdateCompatibilityMode( &b, uint16(b.Len()), &newChanUpdate, 0, ) @@ -163,7 +163,7 @@ func TestChannelUpdateCompatibilityParsing(t *testing.T) { // We should be able to properly parse the encoded channel update // message even with the extra two bytes. - var newChanUpdate2 ChannelUpdate + var newChanUpdate2 ChannelUpdate1 err = parseChannelUpdateCompatibilityMode( &b, uint16(b.Len()), &newChanUpdate2, 0, ) diff --git a/netann/chan_status_manager.go b/netann/chan_status_manager.go index 7ee543d2ac..9f1ec8cd2f 100644 --- a/netann/chan_status_manager.go +++ b/netann/chan_status_manager.go @@ -60,7 +60,7 @@ type ChanStatusConfig struct { // ApplyChannelUpdate processes new ChannelUpdates signed by our node by // updating our local routing table and broadcasting the update to our // peers. - ApplyChannelUpdate func(*lnwire.ChannelUpdate, *wire.OutPoint, + ApplyChannelUpdate func(*lnwire.ChannelUpdate1, *wire.OutPoint, bool) error // DB stores the set of channels that are to be monitored. @@ -90,7 +90,7 @@ type ChanStatusConfig struct { } // ChanStatusManager facilitates requests to enable or disable a channel via a -// network announcement that sets the disable bit on the ChannelUpdate +// network announcement that sets the disable bit on the ChannelUpdate1 // accordingly. The manager will periodically sample to detect cases where a // link has become inactive, and facilitate the process of disabling the channel // passively. The ChanStatusManager state machine is designed to reduce the @@ -202,7 +202,7 @@ func (m *ChanStatusManager) start() error { continue // If we are in the process of opening a channel, the funding - // manager might not have added the ChannelUpdate to the graph + // manager might not have added the ChannelUpdate1 to the graph // yet. We'll ignore the channel for now. case err == ErrUnableToExtractChanUpdate: log.Warnf("Unable to find channel policies for %v, "+ @@ -646,11 +646,11 @@ func (m *ChanStatusManager) signAndSendNextUpdate(outpoint wire.OutPoint, } // fetchLastChanUpdateByOutPoint fetches the latest policy for our direction of -// a channel, and crafts a new ChannelUpdate with this policy. Returns an error +// a channel, and crafts a new ChannelUpdate1 with this policy. Returns an error // in case our ChannelEdgePolicy is not found in the database. Also returns if // the channel is private by checking AuthProof for nil. func (m *ChanStatusManager) fetchLastChanUpdateByOutPoint(op wire.OutPoint) ( - *lnwire.ChannelUpdate, bool, error) { + *lnwire.ChannelUpdate1, bool, error) { // Get the edge info and policies for this channel from the graph. info, edge1, edge2, err := m.cfg.Graph.FetchChannelEdgesByOutpoint(&op) diff --git a/netann/chan_status_manager_test.go b/netann/chan_status_manager_test.go index cb871ba01f..4b114845bc 100644 --- a/netann/chan_status_manager_test.go +++ b/netann/chan_status_manager_test.go @@ -126,7 +126,7 @@ type mockGraph struct { chanPols2 map[wire.OutPoint]*models.ChannelEdgePolicy sidToCid map[lnwire.ShortChannelID]wire.OutPoint - updates chan *lnwire.ChannelUpdate + updates chan *lnwire.ChannelUpdate1 } func newMockGraph(t *testing.T, numChannels int, @@ -138,7 +138,7 @@ func newMockGraph(t *testing.T, numChannels int, chanPols1: make(map[wire.OutPoint]*models.ChannelEdgePolicy), chanPols2: make(map[wire.OutPoint]*models.ChannelEdgePolicy), sidToCid: make(map[lnwire.ShortChannelID]wire.OutPoint), - updates: make(chan *lnwire.ChannelUpdate, 2*numChannels), + updates: make(chan *lnwire.ChannelUpdate1, 2*numChannels), } for i := 0; i < numChannels; i++ { @@ -177,7 +177,7 @@ func (g *mockGraph) FetchChannelEdgesByOutpoint( return info, pol1, pol2, nil } -func (g *mockGraph) ApplyChannelUpdate(update *lnwire.ChannelUpdate, +func (g *mockGraph) ApplyChannelUpdate(update *lnwire.ChannelUpdate1, op *wire.OutPoint, private bool) error { g.mu.Lock() diff --git a/netann/channel_announcement.go b/netann/channel_announcement.go index 64e8a0c52a..4bc7669d2e 100644 --- a/netann/channel_announcement.go +++ b/netann/channel_announcement.go @@ -15,7 +15,7 @@ import ( func CreateChanAnnouncement(chanProof *models.ChannelAuthProof, chanInfo *models.ChannelEdgeInfo, e1, e2 *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement1, - *lnwire.ChannelUpdate, *lnwire.ChannelUpdate, error) { + *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 @@ -68,7 +68,7 @@ func CreateChanAnnouncement(chanProof *models.ChannelAuthProof, // Since it's up to a node's policy as to whether they advertise the // edge in a direction, we don't create an advertisement if the edge is // nil. - var edge1Ann, edge2Ann *lnwire.ChannelUpdate + var edge1Ann, edge2Ann *lnwire.ChannelUpdate1 if e1 != nil { edge1Ann, err = ChannelUpdateFromEdge(chanInfo, e1) if err != nil { diff --git a/netann/channel_update.go b/netann/channel_update.go index b93deb1d0c..743c41ed6f 100644 --- a/netann/channel_update.go +++ b/netann/channel_update.go @@ -17,13 +17,13 @@ import ( var ErrUnableToExtractChanUpdate = fmt.Errorf("unable to extract ChannelUpdate") // ChannelUpdateModifier is a closure that makes in-place modifications to an -// lnwire.ChannelUpdate. -type ChannelUpdateModifier func(*lnwire.ChannelUpdate) +// lnwire.ChannelUpdate1. +type ChannelUpdateModifier func(*lnwire.ChannelUpdate1) // ChanUpdSetDisable is a functional option that sets the disabled channel flag // if disabled is true, and clears the bit otherwise. func ChanUpdSetDisable(disabled bool) ChannelUpdateModifier { - return func(update *lnwire.ChannelUpdate) { + return func(update *lnwire.ChannelUpdate1) { if disabled { // Set the bit responsible for marking a channel as // disabled. @@ -39,7 +39,7 @@ func ChanUpdSetDisable(disabled bool) ChannelUpdateModifier { // ChanUpdSetTimestamp is a functional option that sets the timestamp of the // update to the current time, or increments it if the timestamp is already in // the future. -func ChanUpdSetTimestamp(update *lnwire.ChannelUpdate) { +func ChanUpdSetTimestamp(update *lnwire.ChannelUpdate1) { newTimestamp := uint32(time.Now().Unix()) if newTimestamp <= update.Timestamp { // Increment the prior value to ensure the timestamp @@ -51,13 +51,13 @@ func ChanUpdSetTimestamp(update *lnwire.ChannelUpdate) { } // SignChannelUpdate applies the given modifiers to the passed -// lnwire.ChannelUpdate, then signs the resulting update. The provided update +// lnwire.ChannelUpdate1, then signs the resulting update. The provided update // should be the most recent, valid update, otherwise the timestamp may not // monotonically increase from the prior. // // NOTE: This method modifies the given update. func SignChannelUpdate(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator, - update *lnwire.ChannelUpdate, mods ...ChannelUpdateModifier) error { + update *lnwire.ChannelUpdate1, mods ...ChannelUpdateModifier) error { // Apply the requested changes to the channel update. for _, modifier := range mods { @@ -79,14 +79,14 @@ func SignChannelUpdate(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator return nil } -// ExtractChannelUpdate attempts to retrieve a lnwire.ChannelUpdate message from -// an edge's info and a set of routing policies. +// ExtractChannelUpdate attempts to retrieve a lnwire.ChannelUpdate1 message +// from an edge's info and a set of routing policies. // // NOTE: The passed policies can be nil. func ExtractChannelUpdate(ownerPubKey []byte, info *models.ChannelEdgeInfo, policies ...*models.ChannelEdgePolicy) ( - *lnwire.ChannelUpdate, error) { + *lnwire.ChannelUpdate1, error) { // Helper function to extract the owner of the given policy. owner := func(edge *models.ChannelEdgePolicy) []byte { @@ -118,9 +118,9 @@ func ExtractChannelUpdate(ownerPubKey []byte, // UnsignedChannelUpdateFromEdge reconstructs an unsigned ChannelUpdate from the // given edge info and policy. func UnsignedChannelUpdateFromEdge(info *models.ChannelEdgeInfo, - policy *models.ChannelEdgePolicy) *lnwire.ChannelUpdate { + policy *models.ChannelEdgePolicy) *lnwire.ChannelUpdate1 { - return &lnwire.ChannelUpdate{ + return &lnwire.ChannelUpdate1{ ChainHash: info.ChainHash, ShortChannelID: lnwire.NewShortChanIDFromInt(policy.ChannelID), Timestamp: uint32(policy.LastUpdate.Unix()), @@ -138,7 +138,7 @@ func UnsignedChannelUpdateFromEdge(info *models.ChannelEdgeInfo, // ChannelUpdateFromEdge reconstructs a signed ChannelUpdate from the given edge // info and policy. func ChannelUpdateFromEdge(info *models.ChannelEdgeInfo, - policy *models.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) { + policy *models.ChannelEdgePolicy) (*lnwire.ChannelUpdate1, error) { update := UnsignedChannelUpdateFromEdge(info, policy) diff --git a/netann/channel_update_test.go b/netann/channel_update_test.go index e49e5c65e8..a32d96d88b 100644 --- a/netann/channel_update_test.go +++ b/netann/channel_update_test.go @@ -111,7 +111,7 @@ func TestUpdateDisableFlag(t *testing.T) { // Create the initial update, the only fields we are // concerned with in this test are the timestamp and the // channel flags. - ogUpdate := &lnwire.ChannelUpdate{ + ogUpdate := &lnwire.ChannelUpdate1{ Timestamp: uint32(tc.startTime.Unix()), } if !tc.startEnabled { @@ -122,7 +122,7 @@ func TestUpdateDisableFlag(t *testing.T) { // the original. UpdateDisableFlag will mutate the // passed channel update, so we keep the old one to test // against. - newUpdate := &lnwire.ChannelUpdate{ + newUpdate := &lnwire.ChannelUpdate1{ Timestamp: ogUpdate.Timestamp, ChannelFlags: ogUpdate.ChannelFlags, } diff --git a/netann/sign.go b/netann/sign.go index 93bd8cdc9b..66266310df 100644 --- a/netann/sign.go +++ b/netann/sign.go @@ -22,7 +22,7 @@ func SignAnnouncement(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator, switch m := msg.(type) { case *lnwire.ChannelAnnouncement1: data, err = m.DataToSign() - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: data, err = m.DataToSign() case *lnwire.NodeAnnouncement: data, err = m.DataToSign() diff --git a/peer/brontide.go b/peer/brontide.go index 8d3f426366..c0158ddef4 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -290,7 +290,7 @@ type Config struct { // FetchLastChanUpdate fetches our latest channel update for a target // channel. - FetchLastChanUpdate func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate, + FetchLastChanUpdate func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate1, error) // FundingManager is an implementation of the funding.Controller interface. @@ -1730,7 +1730,7 @@ out: nextMsg.MsgType()) } - case *lnwire.ChannelUpdate, + case *lnwire.ChannelUpdate1, *lnwire.ChannelAnnouncement1, *lnwire.NodeAnnouncement, *lnwire.AnnounceSignatures1, @@ -1988,7 +1988,7 @@ func messageSummary(msg lnwire.Message) string { return fmt.Sprintf("chain_hash=%v, short_chan_id=%v", msg.ChainHash, msg.ShortChannelID.ToUint64()) - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: return fmt.Sprintf("chain_hash=%v, short_chan_id=%v, "+ "mflags=%v, cflags=%v, update_time=%v", msg.ChainHash, msg.ShortChannelID.ToUint64(), msg.MessageFlags, @@ -2501,7 +2501,7 @@ out: // reenableActiveChannels searches the index of channels maintained with this // peer, and reenables each public, non-pending channel. This is done at the -// gossip level by broadcasting a new ChannelUpdate with the disabled bit unset. +// gossip level by broadcasting a new ChannelUpdate1 with the disabled bit unset. // No message will be sent if the channel is already enabled. func (p *Brontide) reenableActiveChannels() { // First, filter all known channels with this peer for ones that are @@ -2512,7 +2512,7 @@ func (p *Brontide) reenableActiveChannels() { retryChans := make(map[wire.OutPoint]struct{}, len(activePublicChans)) // For each of the public, non-pending channels, set the channel - // disabled bit to false and send out a new ChannelUpdate. If this + // disabled bit to false and send out a new ChannelUpdate1. If this // channel is already active, the update won't be sent. for _, chanPoint := range activePublicChans { err := p.cfg.ChanStatusMgr.RequestEnable(chanPoint, false) diff --git a/peer/test_utils.go b/peer/test_utils.go index add15cf19d..41d7546edd 100644 --- a/peer/test_utils.go +++ b/peer/test_utils.go @@ -337,7 +337,7 @@ func createTestPeer(t *testing.T, notifier chainntnfs.ChainNotifier, OurPubKey: aliceKeyPub, OurKeyLoc: testKeyLoc, IsChannelActive: func(lnwire.ChannelID) bool { return true }, - ApplyChannelUpdate: func(*lnwire.ChannelUpdate, + ApplyChannelUpdate: func(*lnwire.ChannelUpdate1, *wire.OutPoint, bool) error { return nil diff --git a/routing/ann_validation.go b/routing/ann_validation.go index a60944bf8a..46f263cb0e 100644 --- a/routing/ann_validation.go +++ b/routing/ann_validation.go @@ -127,7 +127,7 @@ func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error { // signed by the node's private key, and (2) that the announcement's message // flags and optional fields are sane. func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey, capacity btcutil.Amount, - a *lnwire.ChannelUpdate) error { + a *lnwire.ChannelUpdate1) error { if err := ValidateChannelUpdateFields(capacity, a); err != nil { return err @@ -138,7 +138,7 @@ func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey, capacity btcutil.Amount, // VerifyChannelUpdateSignature verifies that the channel update message was // signed by the party with the given node public key. -func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate, +func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate1, pubKey *btcec.PublicKey) error { data, err := msg.DataToSign() @@ -163,7 +163,7 @@ func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate, // ValidateChannelUpdateFields validates a channel update's message flags and // corresponding update fields. func ValidateChannelUpdateFields(capacity btcutil.Amount, - msg *lnwire.ChannelUpdate) error { + msg *lnwire.ChannelUpdate1) error { // The maxHTLC flag is mandatory. if !msg.MessageFlags.HasMaxHtlc() { diff --git a/routing/missioncontrol_test.go b/routing/missioncontrol_test.go index 27391d53e2..4a0f738715 100644 --- a/routing/missioncontrol_test.go +++ b/routing/missioncontrol_test.go @@ -197,7 +197,7 @@ func TestMissionControl(t *testing.T) { // A node level failure should bring probability of all known channels // back to zero. - ctx.reportFailure(0, lnwire.NewExpiryTooSoon(lnwire.ChannelUpdate{})) + ctx.reportFailure(0, lnwire.NewExpiryTooSoon(lnwire.ChannelUpdate1{})) ctx.expectP(1000, 0) // Check whether history snapshot looks sane. @@ -219,14 +219,14 @@ func TestMissionControlChannelUpdate(t *testing.T) { // Report a policy related failure. Because it is the first, we don't // expect a penalty. ctx.reportFailure( - 0, lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate{}), + 0, lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate1{}), ) ctx.expectP(100, testAprioriHopProbability) // Report another failure for the same channel. We expect it to be // pruned. ctx.reportFailure( - 0, lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate{}), + 0, lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate1{}), ) ctx.expectP(100, 0) } diff --git a/routing/mock_test.go b/routing/mock_test.go index 6ab8f7083d..bbb84a7ff2 100644 --- a/routing/mock_test.go +++ b/routing/mock_test.go @@ -174,7 +174,7 @@ func (m *mockPaymentSessionOld) RequestRoute(_, _ lnwire.MilliSatoshi, return r, nil } -func (m *mockPaymentSessionOld) UpdateAdditionalEdge(_ *lnwire.ChannelUpdate, +func (m *mockPaymentSessionOld) UpdateAdditionalEdge(_ *lnwire.ChannelUpdate1, _ *btcec.PublicKey, _ *models.CachedEdgePolicy) bool { return false @@ -676,7 +676,7 @@ func (m *mockPaymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi, return args.Get(0).(*route.Route), args.Error(1) } -func (m *mockPaymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate, +func (m *mockPaymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate1, pubKey *btcec.PublicKey, policy *models.CachedEdgePolicy) bool { args := m.Called(msg, pubKey, policy) diff --git a/routing/payment_session.go b/routing/payment_session.go index a04a4de550..956355949d 100644 --- a/routing/payment_session.go +++ b/routing/payment_session.go @@ -144,7 +144,7 @@ type PaymentSession interface { // (private channels) and applies the update from the message. Returns // a boolean to indicate whether the update has been applied without // error. - UpdateAdditionalEdge(msg *lnwire.ChannelUpdate, pubKey *btcec.PublicKey, + UpdateAdditionalEdge(msg *lnwire.ChannelUpdate1, pubKey *btcec.PublicKey, policy *models.CachedEdgePolicy) bool // GetAdditionalEdgePolicy uses the public key and channel ID to query @@ -405,7 +405,7 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi, // validates the message signature and checks it's up to date, then applies the // updates to the supplied policy. It returns a boolean to indicate whether // there's an error when applying the updates. -func (p *paymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate, +func (p *paymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate1, pubKey *btcec.PublicKey, policy *models.CachedEdgePolicy) bool { // Validate the message signature. diff --git a/routing/payment_session_test.go b/routing/payment_session_test.go index 1c199ff40c..a97325494e 100644 --- a/routing/payment_session_test.go +++ b/routing/payment_session_test.go @@ -149,7 +149,7 @@ func TestUpdateAdditionalEdge(t *testing.T) { ) // Create the channel update message and sign. - msg := &lnwire.ChannelUpdate{ + msg := &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(testChannelID), Timestamp: uint32(time.Now().Unix()), BaseFee: newFeeBaseMSat, diff --git a/routing/result_interpretation_test.go b/routing/result_interpretation_test.go index b9fcc68d14..b2b1126fad 100644 --- a/routing/result_interpretation_test.go +++ b/routing/result_interpretation_test.go @@ -94,7 +94,7 @@ var resultTestCases = []resultTestCase{ name: "fail expiry too soon", route: &routeFourHop, failureSrcIdx: 3, - failure: lnwire.NewExpiryTooSoon(lnwire.ChannelUpdate{}), + failure: lnwire.NewExpiryTooSoon(lnwire.ChannelUpdate1{}), expectedResult: &interpretedResult{ pairResults: map[DirectedNodePair]pairResult{ @@ -196,7 +196,9 @@ var resultTestCases = []resultTestCase{ name: "fail fee insufficient intermediate", route: &routeFourHop, failureSrcIdx: 2, - failure: lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate{}), + failure: lnwire.NewFeeInsufficient( + 0, lnwire.ChannelUpdate1{}, + ), expectedResult: &interpretedResult{ pairResults: map[DirectedNodePair]pairResult{ diff --git a/routing/router.go b/routing/router.go index aed0bb1764..b3248ffeac 100644 --- a/routing/router.go +++ b/routing/router.go @@ -288,7 +288,7 @@ type FeeSchema struct { // ChannelPolicy holds the parameters that determine the policy we enforce // when forwarding payments on a channel. These parameters are communicated -// to the rest of the network in ChannelUpdate messages. +// to the rest of the network in ChannelUpdate1 messages. type ChannelPolicy struct { // FeeSchema holds the fee configuration for a channel. FeeSchema @@ -2616,9 +2616,9 @@ func (r *ChannelRouter) sendPayment(feeLimit lnwire.MilliSatoshi, // extractChannelUpdate examines the error and extracts the channel update. func (r *ChannelRouter) extractChannelUpdate( - failure lnwire.FailureMessage) *lnwire.ChannelUpdate { + failure lnwire.FailureMessage) *lnwire.ChannelUpdate1 { - var update *lnwire.ChannelUpdate + var update *lnwire.ChannelUpdate1 switch onionErr := failure.(type) { case *lnwire.FailExpiryTooSoon: update = &onionErr.Update @@ -2639,7 +2639,7 @@ func (r *ChannelRouter) extractChannelUpdate( // applyChannelUpdate validates a channel update and if valid, applies it to the // database. It returns a bool indicating whether the updates were successful. -func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate) bool { +func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate1) bool { ch, _, _, err := r.GetChannelByID(msg.ShortChannelID) if err != nil { log.Errorf("Unable to retrieve channel by id: %v", err) diff --git a/routing/router_test.go b/routing/router_test.go index 14e2ae8397..eb3941e1cc 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -237,7 +237,7 @@ func createTestCtxFromFile(t *testing.T, // Add valid signature to channel update simulated as error received from the // network. func signErrChanUpdate(t *testing.T, key *btcec.PrivateKey, - errChanUpdate *lnwire.ChannelUpdate) { + errChanUpdate *lnwire.ChannelUpdate1) { chanUpdateMsg, err := errChanUpdate.DataToSign() require.NoError(t, err, "failed to retrieve data to sign") @@ -511,7 +511,7 @@ func TestChannelUpdateValidation(t *testing.T) { // Set up a channel update message with an invalid signature to be // returned to the sender. var invalidSignature lnwire.Sig - errChanUpdate := lnwire.ChannelUpdate{ + errChanUpdate := lnwire.ChannelUpdate1{ Signature: invalidSignature, FeeRate: 500, ShortChannelID: lnwire.NewShortChanIDFromInt(1), @@ -613,7 +613,7 @@ func TestSendPaymentErrorRepeatedFeeInsufficient(t *testing.T) { ) require.NoError(t, err, "unable to fetch chan id") - errChanUpdate := lnwire.ChannelUpdate{ + errChanUpdate := lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt( songokuSophonChanID, ), @@ -732,7 +732,7 @@ func TestSendPaymentErrorFeeInsufficientPrivateEdge(t *testing.T) { // Prepare an error update for the private channel, with twice the // original fee. updatedFeeBaseMSat := feeBaseMSat * 2 - errChanUpdate := lnwire.ChannelUpdate{ + errChanUpdate := lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(privateChannelID), Timestamp: uint32(testTime.Add(time.Minute).Unix()), BaseFee: updatedFeeBaseMSat, @@ -804,7 +804,7 @@ func TestSendPaymentErrorFeeInsufficientPrivateEdge(t *testing.T) { } // TestSendPaymentPrivateEdgeUpdateFeeExceedsLimit tests that upon receiving a -// ChannelUpdate in a fee related error from the private channel, we won't +// ChannelUpdate1 in a fee related error from the private channel, we won't // choose the route in our second attempt if the updated fee exceeds our fee // limit specified in the payment. // @@ -861,7 +861,7 @@ func TestSendPaymentPrivateEdgeUpdateFeeExceedsLimit(t *testing.T) { // Prepare an error update for the private channel. The updated fee // will exceeds the feeLimit. updatedFeeBaseMSat := feeBaseMSat + uint32(feeLimit) - errChanUpdate := lnwire.ChannelUpdate{ + errChanUpdate := lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(privateChannelID), Timestamp: uint32(testTime.Add(time.Minute).Unix()), BaseFee: updatedFeeBaseMSat, @@ -965,7 +965,7 @@ func TestSendPaymentErrorNonFinalTimeLockErrors(t *testing.T) { _, _, edgeUpdateToFail, err := ctx.graph.FetchChannelEdgesByID(chanID) require.NoError(t, err, "unable to fetch chan id") - errChanUpdate := lnwire.ChannelUpdate{ + errChanUpdate := lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(chanID), Timestamp: uint32(edgeUpdateToFail.LastUpdate.Unix()), MessageFlags: edgeUpdateToFail.MessageFlags, @@ -2916,7 +2916,7 @@ func TestSendToRouteStructuredError(t *testing.T) { testCases := map[int]lnwire.FailureMessage{ finalHopIndex: lnwire.NewFailIncorrectDetails(payAmt, 100), 1: &lnwire.FailFeeInsufficient{ - Update: lnwire.ChannelUpdate{}, + Update: lnwire.ChannelUpdate1{}, }, } diff --git a/routing/validation_barrier.go b/routing/validation_barrier.go index a860572538..d50e1a1e96 100644 --- a/routing/validation_barrier.go +++ b/routing/validation_barrier.go @@ -146,7 +146,7 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) { // initialization needs to be done beyond just occupying a job slot. case *models.ChannelEdgePolicy: return - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: return case *lnwire.NodeAnnouncement: // TODO(roasbeef): node ann needs to wait on existing channel updates @@ -202,10 +202,10 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { jobDesc = fmt.Sprintf("job=channeldb.LightningNode, pub=%s", vertex) - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: signals, ok = v.chanEdgeDependencies[msg.ShortChannelID] - jobDesc = fmt.Sprintf("job=lnwire.ChannelUpdate, scid=%v", + jobDesc = fmt.Sprintf("job=lnwire.ChannelUpdate1, scid=%v", msg.ShortChannelID.ToUint64()) case *lnwire.NodeAnnouncement: @@ -295,7 +295,7 @@ func (v *ValidationBarrier) SignalDependants(job interface{}, allow bool) { delete(v.nodeAnnDependencies, route.Vertex(msg.PubKeyBytes)) case *lnwire.NodeAnnouncement: delete(v.nodeAnnDependencies, route.Vertex(msg.NodeID)) - case *lnwire.ChannelUpdate: + case *lnwire.ChannelUpdate1: delete(v.chanEdgeDependencies, msg.ShortChannelID) case *models.ChannelEdgePolicy: shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID) diff --git a/routing/validation_barrier_test.go b/routing/validation_barrier_test.go index e56c95a472..a26ba4d9a0 100644 --- a/routing/validation_barrier_test.go +++ b/routing/validation_barrier_test.go @@ -85,9 +85,9 @@ func TestValidationBarrierQuit(t *testing.T) { // Create a set of channel updates, that must wait until their // associated channel announcement has been verified. - chanUpds := make([]*lnwire.ChannelUpdate, 0, numTasks) + chanUpds := make([]*lnwire.ChannelUpdate1, 0, numTasks) for i := 0; i < numTasks; i++ { - chanUpds = append(chanUpds, &lnwire.ChannelUpdate{ + chanUpds = append(chanUpds, &lnwire.ChannelUpdate1{ ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(i)), }) barrier.InitJobDependencies(chanUpds[i]) diff --git a/server.go b/server.go index fcc489435a..5076b3f347 100644 --- a/server.go +++ b/server.go @@ -1660,10 +1660,10 @@ func newServer(cfg *Config, listenAddrs []net.Addr, return s, nil } -// signAliasUpdate takes a ChannelUpdate and returns the signature. This is -// used for option_scid_alias channels where the ChannelUpdate to be sent back +// signAliasUpdate takes a ChannelUpdate1 and returns the signature. This is +// used for option_scid_alias channels where the ChannelUpdate1 to be sent back // may differ from what is on disk. -func (s *server) signAliasUpdate(u *lnwire.ChannelUpdate) (*ecdsa.Signature, +func (s *server) signAliasUpdate(u *lnwire.ChannelUpdate1) (*ecdsa.Signature, error) { data, err := u.DataToSign() @@ -4612,10 +4612,10 @@ func (s *server) fetchNodeAdvertisedAddrs(pub *btcec.PublicKey) ([]net.Addr, err // fetchLastChanUpdate returns a function which is able to retrieve our latest // channel update for a target channel. func (s *server) fetchLastChanUpdate() func(lnwire.ShortChannelID) ( - *lnwire.ChannelUpdate, error) { + *lnwire.ChannelUpdate1, error) { ourPubKey := s.identityECDH.PubKey().SerializeCompressed() - return func(cid lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) { + return func(cid lnwire.ShortChannelID) (*lnwire.ChannelUpdate1, error) { info, edge1, edge2, err := s.chanRouter.GetChannelByID(cid) if err != nil { return nil, err @@ -4630,7 +4630,7 @@ func (s *server) fetchLastChanUpdate() func(lnwire.ShortChannelID) ( // applyChannelUpdate applies the channel update to the different sub-systems of // the server. The useAlias boolean denotes whether or not to send an alias in // place of the real SCID. -func (s *server) applyChannelUpdate(update *lnwire.ChannelUpdate, +func (s *server) applyChannelUpdate(update *lnwire.ChannelUpdate1, op *wire.OutPoint, useAlias bool) error { var ( @@ -4641,7 +4641,7 @@ func (s *server) applyChannelUpdate(update *lnwire.ChannelUpdate, chanID := lnwire.NewChanIDFromOutPoint(op) // Fetch the peer's alias from the lnwire.ChannelID so it can be used - // in the ChannelUpdate if it hasn't been announced yet. + // in the ChannelUpdate1 if it hasn't been announced yet. if useAlias { foundAlias, _ := s.aliasMgr.GetPeerAlias(chanID) if foundAlias != defaultAlias { From b86dd40d7db6dd78c2af6ed9ae2ab1c778438eac Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 12:10:47 +0200 Subject: [PATCH 04/20] multi: rename NodeAnnouncement In preparation for adding a new NodeAnnouncement2 message along with a NodeAnnouncement interface, we rename the existing message to NodeAnnouncement1. --- channeldb/graph.go | 6 +++--- discovery/gossiper.go | 31 ++++++++++++++++++++----------- discovery/gossiper_test.go | 23 ++++++++++++----------- discovery/syncer.go | 2 +- discovery/syncer_test.go | 20 ++++++++++++++------ funding/manager.go | 8 ++++---- funding/manager_test.go | 26 +++++++++++++------------- lnrpc/peersrpc/config_active.go | 2 +- lnwire/fuzz_test.go | 8 ++++---- lnwire/lnwire_test.go | 4 ++-- lnwire/message.go | 4 ++-- lnwire/message_test.go | 4 ++-- lnwire/node_announcement.go | 23 +++++++++++------------ netann/host_ann.go | 10 +++++----- netann/node_announcement.go | 28 +++++++++++++++------------- netann/sign.go | 2 +- peer/brontide.go | 8 ++++---- routing/ann_validation.go | 4 ++-- routing/validation_barrier.go | 10 +++++----- server.go | 22 +++++++++++----------- subrpcserver_config.go | 2 +- 21 files changed, 133 insertions(+), 114 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index c0cbc32874..27781d95d3 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -2735,8 +2735,8 @@ func (l *LightningNode) AddPubKey(key *btcec.PublicKey) { } // NodeAnnouncement retrieves the latest node announcement of the node. -func (l *LightningNode) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement, - error) { +func (l *LightningNode) NodeAnnouncement(signed bool) ( + *lnwire.NodeAnnouncement1, error) { if !l.HaveNodeAnnouncement { return nil, fmt.Errorf("node does not have node announcement") @@ -2747,7 +2747,7 @@ func (l *LightningNode) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement, return nil, err } - nodeAnn := &lnwire.NodeAnnouncement{ + nodeAnn := &lnwire.NodeAnnouncement1{ Features: l.Features.RawFeatureVector, NodeID: l.PubKeyBytes, RGBColor: l.Color, diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 827ad74082..e958c62306 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -207,11 +207,11 @@ type Config struct { // FetchSelfAnnouncement retrieves our current node announcement, for // use when determining whether we should update our peers about our // presence in the network. - FetchSelfAnnouncement func() lnwire.NodeAnnouncement + FetchSelfAnnouncement func() lnwire.NodeAnnouncement1 // UpdateSelfAnnouncement produces a new announcement for our node with // an updated timestamp which can be broadcast to our peers. - UpdateSelfAnnouncement func() (lnwire.NodeAnnouncement, error) + UpdateSelfAnnouncement func() (lnwire.NodeAnnouncement1, error) // ProofMatureDelta the number of confirmations which is needed before // exchange the channel announcement proofs. @@ -1065,7 +1065,7 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) { // Node announcements are identified by the Vertex field. Use the // NodeID to create the corresponding Vertex. - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: sender := route.NewVertex(message.source) deDupKey := route.Vertex(msg.NodeID) @@ -1074,7 +1074,16 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) { oldTimestamp := uint32(0) mws, ok := d.nodeAnnouncements[deDupKey] if ok { - oldTimestamp = mws.msg.(*lnwire.NodeAnnouncement).Timestamp + ann, ok := mws.msg.(*lnwire.NodeAnnouncement1) + if !ok { + log.Errorf("Expected "+ + "*lnwire.NodeAnnouncement1, got: %T", + mws.msg) + + return + } + + oldTimestamp = ann.Timestamp } // Discard the message if it's old. @@ -1673,7 +1682,7 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error { return nil } - // We'll also check that our NodeAnnouncement is not too old. + // We'll also check that our NodeAnnouncement1 is not too old. currentNodeAnn := d.cfg.FetchSelfAnnouncement() timestamp := time.Unix(int64(currentNodeAnn.Timestamp), 0) timeElapsed := now.Sub(timestamp) @@ -1901,7 +1910,7 @@ func (d *AuthenticatedGossiper) processRejectedEdge( // addNode processes the given node announcement, and adds it to our channel // graph. -func (d *AuthenticatedGossiper) addNode(msg *lnwire.NodeAnnouncement, +func (d *AuthenticatedGossiper) addNode(msg *lnwire.NodeAnnouncement1, op ...batch.SchedulerOption) error { if err := routing.ValidateNodeAnn(msg); err != nil { @@ -1999,7 +2008,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement( // A new node announcement has arrived which either presents new // information about a node in one of the channels we know about, or a // updating previously advertised information. - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: return d.handleNodeAnnouncement(nMsg, msg, schedulerOp) // A new channel announcement has arrived, this indicates the @@ -2080,7 +2089,7 @@ func (d *AuthenticatedGossiper) processZombieUpdate( // fetchNodeAnn fetches the latest signed node announcement from our point of // view for the node with the given public key. func (d *AuthenticatedGossiper) fetchNodeAnn( - pubKey [33]byte) (*lnwire.NodeAnnouncement, error) { + pubKey [33]byte) (*lnwire.NodeAnnouncement1, error) { node, err := d.cfg.Router.FetchLightningNode(pubKey) if err != nil { @@ -2300,12 +2309,12 @@ func (d *AuthenticatedGossiper) latestHeight() uint32 { // handleNodeAnnouncement processes a new node announcement. func (d *AuthenticatedGossiper) handleNodeAnnouncement(nMsg *networkMsg, - nodeAnn *lnwire.NodeAnnouncement, + nodeAnn *lnwire.NodeAnnouncement1, ops []batch.SchedulerOption) ([]networkMsg, bool) { timestamp := time.Unix(int64(nodeAnn.Timestamp), 0) - log.Debugf("Processing NodeAnnouncement: peer=%v, timestamp=%v, "+ + log.Debugf("Processing NodeAnnouncement1: peer=%v, timestamp=%v, "+ "node=%x", nMsg.peer, timestamp, nodeAnn.NodeID) // We'll quickly ask the router if it already has a newer update for @@ -2364,7 +2373,7 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(nMsg *networkMsg, nMsg.err <- nil // TODO(roasbeef): get rid of the above - log.Debugf("Processed NodeAnnouncement: peer=%v, timestamp=%v, "+ + log.Debugf("Processed NodeAnnouncement1: peer=%v, timestamp=%v, "+ "node=%x", nMsg.peer, timestamp, nodeAnn.NodeID) return announcements, true diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index b30da45d8a..07e7268306 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -457,8 +457,8 @@ func (m *mockNotifier) Stop() error { } type annBatch struct { - nodeAnn1 *lnwire.NodeAnnouncement - nodeAnn2 *lnwire.NodeAnnouncement + nodeAnn1 *lnwire.NodeAnnouncement1 + nodeAnn2 *lnwire.NodeAnnouncement1 chanAnn *lnwire.ChannelAnnouncement1 @@ -532,7 +532,8 @@ func createAnnouncements(blockHeight uint32, key1, key2 *btcec.PrivateKey) (*ann } func createNodeAnnouncement(priv *btcec.PrivateKey, - timestamp uint32, extraBytes ...[]byte) (*lnwire.NodeAnnouncement, error) { + timestamp uint32, extraBytes ...[]byte) (*lnwire.NodeAnnouncement1, + error) { var err error k := hex.EncodeToString(priv.Serialize()) @@ -541,7 +542,7 @@ func createNodeAnnouncement(priv *btcec.PrivateKey, return nil, err } - a := &lnwire.NodeAnnouncement{ + a := &lnwire.NodeAnnouncement1{ Timestamp: timestamp, Addresses: testAddrs, Alias: alias, @@ -771,15 +772,15 @@ func createTestCtx(t *testing.T, startHeight uint32) (*testCtx, error) { c := make(chan struct{}) return c }, - FetchSelfAnnouncement: func() lnwire.NodeAnnouncement { - return lnwire.NodeAnnouncement{ + FetchSelfAnnouncement: func() lnwire.NodeAnnouncement1 { + return lnwire.NodeAnnouncement1{ Timestamp: testTimestamp, } }, - UpdateSelfAnnouncement: func() (lnwire.NodeAnnouncement, + UpdateSelfAnnouncement: func() (lnwire.NodeAnnouncement1, error) { - return lnwire.NodeAnnouncement{ + return lnwire.NodeAnnouncement1{ Timestamp: testTimestamp, }, nil }, @@ -2053,7 +2054,7 @@ func TestForwardPrivateNodeAnnouncement(t *testing.T) { case <-time.After(2 * trickleDelay): } - // Now, we'll attempt to forward the NodeAnnouncement for the same node + // Now, we'll attempt to forward the NodeAnnouncement1 for the same node // by opening a public channel on the network. We'll create a // ChannelAnnouncement1 and hand it off to the gossiper in order to // process it. @@ -2636,7 +2637,7 @@ func TestExtraDataChannelUpdateValidation(t *testing.T) { } // TestExtraDataNodeAnnouncementValidation tests that we're able to properly -// validate a NodeAnnouncement that includes opaque bytes that we don't +// validate a NodeAnnouncement1 that includes opaque bytes that we don't // currently know of. func TestExtraDataNodeAnnouncementValidation(t *testing.T) { t.Parallel() @@ -2777,7 +2778,7 @@ func TestRetransmit(t *testing.T) { chanAnn++ case *lnwire.ChannelUpdate1: chanUpd++ - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: nodeAnn++ } } diff --git a/discovery/syncer.go b/discovery/syncer.go index 5110726d5a..ceb29affb4 100644 --- a/discovery/syncer.go +++ b/discovery/syncer.go @@ -1354,7 +1354,7 @@ func (g *GossipSyncer) FilterGossipMsgs(msgs ...msgWithSenders) { // Similarly, we only send node announcements if the update // timestamp ifs between our set gossip filter time range. - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: if passesFilter(msg.Timestamp) { msgsToSend = append(msgsToSend, msg) } diff --git a/discovery/syncer_test.go b/discovery/syncer_test.go index bd40489ac2..e551df853a 100644 --- a/discovery/syncer_test.go +++ b/discovery/syncer_test.go @@ -213,10 +213,14 @@ func TestGossipSyncerFilterGossipMsgsNoHorizon(t *testing.T) { // through the gossiper to the target peer. msgs := []msgWithSenders{ { - msg: &lnwire.NodeAnnouncement{Timestamp: uint32(time.Now().Unix())}, + msg: &lnwire.NodeAnnouncement1{ + Timestamp: uint32(time.Now().Unix()), + }, }, { - msg: &lnwire.NodeAnnouncement{Timestamp: uint32(time.Now().Unix())}, + msg: &lnwire.NodeAnnouncement1{ + Timestamp: uint32(time.Now().Unix()), + }, }, } @@ -271,15 +275,19 @@ func TestGossipSyncerFilterGossipMsgsAllInMemory(t *testing.T) { msgs := []msgWithSenders{ { // Node ann above horizon. - msg: &lnwire.NodeAnnouncement{Timestamp: unixStamp(25001)}, + msg: &lnwire.NodeAnnouncement1{ + Timestamp: unixStamp(25001), + }, }, { // Node ann below horizon. - msg: &lnwire.NodeAnnouncement{Timestamp: unixStamp(5)}, + msg: &lnwire.NodeAnnouncement1{Timestamp: unixStamp(5)}, }, { // Node ann above horizon. - msg: &lnwire.NodeAnnouncement{Timestamp: unixStamp(999999)}, + msg: &lnwire.NodeAnnouncement1{ + Timestamp: unixStamp(999999), + }, }, { // Ann tuple below horizon. @@ -690,7 +698,7 @@ func TestGossipSyncerReplyShortChanIDs(t *testing.T) { ShortChannelID: lnwire.NewShortChanIDFromInt(20), Timestamp: unixStamp(999999), }, - &lnwire.NodeAnnouncement{Timestamp: unixStamp(25001)}, + &lnwire.NodeAnnouncement1{Timestamp: unixStamp(25001)}, } // We'll then craft a reply to the upcoming query for all the matching diff --git a/funding/manager.go b/funding/manager.go index e42a3db8d5..e0984e06dd 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -389,7 +389,7 @@ type Config struct { // CurrentNodeAnnouncement should return the latest, fully signed node // announcement from the backing Lightning Network node with a fresh // timestamp. - CurrentNodeAnnouncement func() (lnwire.NodeAnnouncement, error) + CurrentNodeAnnouncement func() (lnwire.NodeAnnouncement1, error) // SendAnnouncement is used by the FundingManager to send announcement // messages to the Gossiper to possibly broadcast to the greater @@ -3409,7 +3409,7 @@ func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel, shortChanID *lnwire.ShortChannelID) error { // If this channel is not meant to be announced to the greater network, - // we'll only send our NodeAnnouncement to our counterparty to ensure we + // we'll only send our NodeAnnouncement1 to our counterparty to ensure we // don't leak any of our information. announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0 if !announceChan { @@ -3431,7 +3431,7 @@ func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel, &completeChan.FundingOutpoint, ) pubKey := peer.PubKey() - log.Debugf("Sending our NodeAnnouncement for "+ + log.Debugf("Sending our NodeAnnouncement1 for "+ "ChannelID(%v) to %x", chanID, pubKey) // TODO(halseth): make reliable. If the peer is not online this @@ -4334,7 +4334,7 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey, routing.ErrIgnored) { log.Debugf("Router rejected "+ - "NodeAnnouncement: %v", err) + "NodeAnnouncement1: %v", err) } else { log.Errorf("Unable to send node "+ "announcement: %v", err) diff --git a/funding/manager_test.go b/funding/manager_test.go index e29d3201df..6102496ed6 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -468,10 +468,10 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, } return errChan }, - CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, + CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement1, error) { - return lnwire.NodeAnnouncement{}, nil + return lnwire.NodeAnnouncement1{}, nil }, TempChanIDSeed: chanIDSeed, FindChannel: func(node *btcec.PublicKey, @@ -631,10 +631,10 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) { } return errChan }, - CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, + CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement1, error) { - return lnwire.NodeAnnouncement{}, nil + return lnwire.NodeAnnouncement1{}, nil }, NotifyWhenOnline: func(peer [33]byte, connectedChan chan<- lnpeer.Peer) { @@ -1266,9 +1266,9 @@ func assertAnnouncementSignatures(t *testing.T, alice, bob *testNode) { // by having the nodes exchange announcement signatures. // Two distinct messages will be sent: // 1) AnnouncementSignatures - // 2) NodeAnnouncement + // 2) NodeAnnouncement1 // These may arrive in no particular order. - // Note that sending the NodeAnnouncement at this point is an + // Note that sending the NodeAnnouncement1 at this point is an // implementation detail, and not something required by the LN spec. for j, node := range []*testNode{alice, bob} { announcements := make([]lnwire.Message, 2) @@ -1286,7 +1286,7 @@ func assertAnnouncementSignatures(t *testing.T, alice, bob *testNode) { switch msg.(type) { case *lnwire.AnnounceSignatures1: gotAnnounceSignatures = true - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: gotNodeAnnouncement = true } } @@ -1296,7 +1296,7 @@ func assertAnnouncementSignatures(t *testing.T, alice, bob *testNode) { j) } if !gotNodeAnnouncement { - t.Fatalf("did not get NodeAnnouncement from node %d", j) + t.Fatalf("did not get NodeAnnouncement1 from node %d", j) } } } @@ -1316,7 +1316,7 @@ func assertNodeAnnSent(t *testing.T, alice, bob *testNode) { node.msgChan, time.Second*5, ) require.NoError(t, err) - assertType[*lnwire.NodeAnnouncement](t, *nodeAnn) + assertType[*lnwire.NodeAnnouncement1](t, *nodeAnn) } } @@ -2815,7 +2815,7 @@ func TestFundingManagerPrivateChannel(t *testing.T) { // We should however receive each side's node announcement. select { case msg := <-alice.msgChan: - if _, ok := msg.(*lnwire.NodeAnnouncement); !ok { + if _, ok := msg.(*lnwire.NodeAnnouncement1); !ok { t.Fatalf("expected to receive node announcement") } case <-time.After(time.Second): @@ -2824,7 +2824,7 @@ func TestFundingManagerPrivateChannel(t *testing.T) { select { case msg := <-bob.msgChan: - if _, ok := msg.(*lnwire.NodeAnnouncement); !ok { + if _, ok := msg.(*lnwire.NodeAnnouncement1); !ok { t.Fatalf("expected to receive node announcement") } case <-time.After(time.Second): @@ -2943,7 +2943,7 @@ func TestFundingManagerPrivateRestart(t *testing.T) { // We should however receive each side's node announcement. select { case msg := <-alice.msgChan: - if _, ok := msg.(*lnwire.NodeAnnouncement); !ok { + if _, ok := msg.(*lnwire.NodeAnnouncement1); !ok { t.Fatalf("expected to receive node announcement") } case <-time.After(time.Second): @@ -2952,7 +2952,7 @@ func TestFundingManagerPrivateRestart(t *testing.T) { select { case msg := <-bob.msgChan: - if _, ok := msg.(*lnwire.NodeAnnouncement); !ok { + if _, ok := msg.(*lnwire.NodeAnnouncement1); !ok { t.Fatalf("expected to receive node announcement") } case <-time.After(time.Second): diff --git a/lnrpc/peersrpc/config_active.go b/lnrpc/peersrpc/config_active.go index 4a2f028e45..708494fc03 100644 --- a/lnrpc/peersrpc/config_active.go +++ b/lnrpc/peersrpc/config_active.go @@ -18,7 +18,7 @@ import ( type Config struct { // GetNodeAnnouncement is used to send our retrieve the current // node announcement information. - GetNodeAnnouncement func() lnwire.NodeAnnouncement + GetNodeAnnouncement func() lnwire.NodeAnnouncement1 // ParseAddr parses an address from its string format to a net.Addr. ParseAddr func(addr string) (net.Addr, error) diff --git a/lnwire/fuzz_test.go b/lnwire/fuzz_test.go index f789e7ce72..974dc96852 100644 --- a/lnwire/fuzz_test.go +++ b/lnwire/fuzz_test.go @@ -281,10 +281,10 @@ func FuzzNodeAnnouncement(f *testing.F) { newMsg, err := ReadMessage(&b, 0) require.NoError(t, err) - require.IsType(t, &NodeAnnouncement{}, msg) - first, _ := msg.(*NodeAnnouncement) - require.IsType(t, &NodeAnnouncement{}, newMsg) - second, _ := newMsg.(*NodeAnnouncement) + require.IsType(t, &NodeAnnouncement1{}, msg) + first, _ := msg.(*NodeAnnouncement1) + require.IsType(t, &NodeAnnouncement1{}, newMsg) + second, _ := newMsg.(*NodeAnnouncement1) // We can't use require.Equal for Addresses, since the same IP // can be represented by different underlying bytes. Instead, we diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index af94a9f836..dec0c1e524 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -841,7 +841,7 @@ func TestLightningWireProtocol(t *testing.T) { }, MsgNodeAnnouncement: func(v []reflect.Value, r *rand.Rand) { var err error - req := NodeAnnouncement{ + req := NodeAnnouncement1{ Features: randRawFeatureVector(r), Timestamp: uint32(r.Int31()), Alias: randAlias(r), @@ -1210,7 +1210,7 @@ func TestLightningWireProtocol(t *testing.T) { }, { msgType: MsgNodeAnnouncement, - scenario: func(m NodeAnnouncement) bool { + scenario: func(m NodeAnnouncement1) bool { return mainScenario(&m) }, }, diff --git a/lnwire/message.go b/lnwire/message.go index 46dd7de92c..795a9e6ac8 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -115,7 +115,7 @@ func (t MessageType) String() string { case MsgChannelUpdate: return "ChannelUpdate1" case MsgNodeAnnouncement: - return "NodeAnnouncement" + return "NodeAnnouncement1" case MsgPing: return "Ping" case MsgAnnounceSignatures: @@ -219,7 +219,7 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { case MsgChannelUpdate: msg = &ChannelUpdate1{} case MsgNodeAnnouncement: - msg = &NodeAnnouncement{} + msg = &NodeAnnouncement1{} case MsgPing: msg = &Ping{} case MsgAnnounceSignatures: diff --git a/lnwire/message_test.go b/lnwire/message_test.go index 69c3901c12..58cff787ad 100644 --- a/lnwire/message_test.go +++ b/lnwire/message_test.go @@ -670,11 +670,11 @@ func newMsgChannelAnnouncement(t testing.TB, } func newMsgNodeAnnouncement(t testing.TB, - r *rand.Rand) *lnwire.NodeAnnouncement { + r *rand.Rand) *lnwire.NodeAnnouncement1 { t.Helper() - msg := &lnwire.NodeAnnouncement{ + msg := &lnwire.NodeAnnouncement1{ Features: rawFeatureVector(), Timestamp: uint32(r.Int31()), Alias: randAlias(r), diff --git a/lnwire/node_announcement.go b/lnwire/node_announcement.go index 4f16202812..f790bc0c48 100644 --- a/lnwire/node_announcement.go +++ b/lnwire/node_announcement.go @@ -62,11 +62,11 @@ func (n NodeAlias) String() string { return string(bytes.Trim(n[:], "\x00")) } -// NodeAnnouncement message is used to announce the presence of a Lightning +// NodeAnnouncement1 message is used to announce the presence of a Lightning // node and also to signal that the node is accepting incoming connections. -// Each NodeAnnouncement authenticating the advertised information within the +// Each NodeAnnouncement1 authenticating the advertised information within the // announcement via a signature using the advertised node pubkey. -type NodeAnnouncement struct { +type NodeAnnouncement1 struct { // Signature is used to prove the ownership of node id. Signature Sig @@ -100,15 +100,15 @@ type NodeAnnouncement struct { ExtraOpaqueData ExtraOpaqueData } -// A compile time check to ensure NodeAnnouncement implements the +// A compile time check to ensure NodeAnnouncement1 implements the // lnwire.Message interface. -var _ Message = (*NodeAnnouncement)(nil) +var _ Message = (*NodeAnnouncement1)(nil) -// Decode deserializes a serialized NodeAnnouncement stored in the passed +// Decode deserializes a serialized NodeAnnouncement1 stored in the passed // io.Reader observing the specified protocol version. // // This is part of the lnwire.Message interface. -func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error { +func (a *NodeAnnouncement1) Decode(r io.Reader, _ uint32) error { return ReadElements(r, &a.Signature, &a.Features, @@ -121,11 +121,11 @@ func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error { ) } -// Encode serializes the target NodeAnnouncement into the passed io.Writer +// Encode serializes the target NodeAnnouncement1 into the passed io.Writer // observing the protocol version specified. // // This is part of the lnwire.Message interface. -func (a *NodeAnnouncement) Encode(w *bytes.Buffer, pver uint32) error { +func (a *NodeAnnouncement1) Encode(w *bytes.Buffer, _ uint32) error { if err := WriteSig(w, a.Signature); err != nil { return err } @@ -161,13 +161,12 @@ func (a *NodeAnnouncement) Encode(w *bytes.Buffer, pver uint32) error { // wire. // // This is part of the lnwire.Message interface. -func (a *NodeAnnouncement) MsgType() MessageType { +func (a *NodeAnnouncement1) MsgType() MessageType { return MsgNodeAnnouncement } // DataToSign returns the part of the message that should be signed. -func (a *NodeAnnouncement) DataToSign() ([]byte, error) { - +func (a *NodeAnnouncement1) DataToSign() ([]byte, error) { // We should not include the signatures itself. buffer := make([]byte, 0, MaxMsgBody) buf := bytes.NewBuffer(buffer) diff --git a/netann/host_ann.go b/netann/host_ann.go index 95ba277b5a..9612f1ccb7 100644 --- a/netann/host_ann.go +++ b/netann/host_ann.go @@ -22,8 +22,8 @@ type HostAnnouncerConfig struct { LookupHost func(string) (net.Addr, error) // AdvertisedIPs is the set of IPs that we've already announced with - // our current NodeAnnouncement. This set will be constructed to avoid - // unnecessary node NodeAnnouncement updates. + // our current NodeAnnouncement1. This set will be constructed to avoid + // unnecessary node NodeAnnouncement1 updates. AdvertisedIPs map[string]struct{} // AnnounceNewIPs announces a new set of IP addresses for the backing @@ -36,7 +36,7 @@ type HostAnnouncerConfig struct { // HostAnnouncer is a sub-system that allows a user to specify a set of hosts // for lnd that will be continually resolved to notice any IP address changes. // If the target IP address for a host changes, then we'll generate a new -// NodeAnnouncement that includes these new IPs. +// NodeAnnouncement1 that includes these new IPs. type HostAnnouncer struct { cfg HostAnnouncerConfig @@ -171,7 +171,7 @@ func (h *HostAnnouncer) hostWatcher() { // announcement on disk. It returns the updated node announcement given a set // of updates to be applied to the current node announcement. type NodeAnnUpdater func(modifier ...NodeAnnModifier, -) (lnwire.NodeAnnouncement, error) +) (lnwire.NodeAnnouncement1, error) // IPAnnouncer is a factory function that generates a new function that uses // the passed annUpdater function to to announce new IP changes for a given @@ -181,7 +181,7 @@ func IPAnnouncer(annUpdater NodeAnnUpdater) func([]net.Addr, return func(newAddrs []net.Addr, oldAddrs map[string]struct{}) error { _, err := annUpdater(func( - currentNodeAnn *lnwire.NodeAnnouncement) { + currentNodeAnn *lnwire.NodeAnnouncement1) { // To ensure we don't duplicate any addresses, we'll // filter out the same of addresses we should no longer // advertise. diff --git a/netann/node_announcement.go b/netann/node_announcement.go index 5b6f7a430e..5e58b06a8f 100644 --- a/netann/node_announcement.go +++ b/netann/node_announcement.go @@ -11,37 +11,39 @@ import ( ) // NodeAnnModifier is a closure that makes in-place modifications to an -// lnwire.NodeAnnouncement. -type NodeAnnModifier func(*lnwire.NodeAnnouncement) +// lnwire.NodeAnnouncement1. +type NodeAnnModifier func(*lnwire.NodeAnnouncement1) // NodeAnnSetAlias is a functional option that sets the alias of the // given node announcement. -func NodeAnnSetAlias(alias lnwire.NodeAlias) func(*lnwire.NodeAnnouncement) { - return func(nodeAnn *lnwire.NodeAnnouncement) { +func NodeAnnSetAlias(alias lnwire.NodeAlias) func(*lnwire.NodeAnnouncement1) { + return func(nodeAnn *lnwire.NodeAnnouncement1) { nodeAnn.Alias = alias } } // NodeAnnSetAddrs is a functional option that allows updating the addresses of // the given node announcement. -func NodeAnnSetAddrs(addrs []net.Addr) func(*lnwire.NodeAnnouncement) { - return func(nodeAnn *lnwire.NodeAnnouncement) { +func NodeAnnSetAddrs(addrs []net.Addr) func(*lnwire.NodeAnnouncement1) { + return func(nodeAnn *lnwire.NodeAnnouncement1) { nodeAnn.Addresses = addrs } } // NodeAnnSetColor is a functional option that sets the color of the // given node announcement. -func NodeAnnSetColor(newColor color.RGBA) func(*lnwire.NodeAnnouncement) { - return func(nodeAnn *lnwire.NodeAnnouncement) { +func NodeAnnSetColor(newColor color.RGBA) func(*lnwire.NodeAnnouncement1) { + return func(nodeAnn *lnwire.NodeAnnouncement1) { nodeAnn.RGBColor = newColor } } // NodeAnnSetFeatures is a functional option that allows updating the features of // the given node announcement. -func NodeAnnSetFeatures(features *lnwire.RawFeatureVector) func(*lnwire.NodeAnnouncement) { - return func(nodeAnn *lnwire.NodeAnnouncement) { +func NodeAnnSetFeatures( + features *lnwire.RawFeatureVector) func(*lnwire.NodeAnnouncement1) { + + return func(nodeAnn *lnwire.NodeAnnouncement1) { nodeAnn.Features = features } } @@ -49,7 +51,7 @@ func NodeAnnSetFeatures(features *lnwire.RawFeatureVector) func(*lnwire.NodeAnno // NodeAnnSetTimestamp is a functional option that sets the timestamp of the // announcement to the current time, or increments it if the timestamp is // already in the future. -func NodeAnnSetTimestamp(nodeAnn *lnwire.NodeAnnouncement) { +func NodeAnnSetTimestamp(nodeAnn *lnwire.NodeAnnouncement1) { newTimestamp := uint32(time.Now().Unix()) if newTimestamp <= nodeAnn.Timestamp { // Increment the prior value to ensure the timestamp @@ -60,11 +62,11 @@ func NodeAnnSetTimestamp(nodeAnn *lnwire.NodeAnnouncement) { nodeAnn.Timestamp = newTimestamp } -// SignNodeAnnouncement signs the lnwire.NodeAnnouncement provided, which +// SignNodeAnnouncement signs the lnwire.NodeAnnouncement1 provided, which // should be the most recent, valid update, otherwise the timestamp may not // monotonically increase from the prior. func SignNodeAnnouncement(signer lnwallet.MessageSigner, - keyLoc keychain.KeyLocator, nodeAnn *lnwire.NodeAnnouncement) error { + keyLoc keychain.KeyLocator, nodeAnn *lnwire.NodeAnnouncement1) error { // Create the DER-encoded ECDSA signature over the message digest. sig, err := SignAnnouncement(signer, keyLoc, nodeAnn) diff --git a/netann/sign.go b/netann/sign.go index 66266310df..78821ad2ae 100644 --- a/netann/sign.go +++ b/netann/sign.go @@ -24,7 +24,7 @@ func SignAnnouncement(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator, data, err = m.DataToSign() case *lnwire.ChannelUpdate1: data, err = m.DataToSign() - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: data, err = m.DataToSign() default: return nil, fmt.Errorf("can't sign %T message", m) diff --git a/peer/brontide.go b/peer/brontide.go index c0158ddef4..27220f3d5f 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -282,7 +282,7 @@ type Config struct { // GenNodeAnnouncement is used to send our node announcement to the remote // on startup. GenNodeAnnouncement func(...netann.NodeAnnModifier) ( - lnwire.NodeAnnouncement, error) + lnwire.NodeAnnouncement1, error) // PrunePersistentPeerConnection is used to remove all internal state // related to this peer in the server. @@ -1627,7 +1627,7 @@ out: idleTimer.Reset(idleTimeout) continue - // If the NodeAnnouncement has an invalid alias, then + // If the NodeAnnouncement1 has an invalid alias, then // we'll log that error above and continue so we can // continue to read messages from the peer. We do not // store this error because it is of little debugging @@ -1732,7 +1732,7 @@ out: case *lnwire.ChannelUpdate1, *lnwire.ChannelAnnouncement1, - *lnwire.NodeAnnouncement, + *lnwire.NodeAnnouncement1, *lnwire.AnnounceSignatures1, *lnwire.GossipTimestampRange, *lnwire.QueryShortChanIDs, @@ -1994,7 +1994,7 @@ func messageSummary(msg lnwire.Message) string { msg.ShortChannelID.ToUint64(), msg.MessageFlags, msg.ChannelFlags, time.Unix(int64(msg.Timestamp), 0)) - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: return fmt.Sprintf("node=%x, update_time=%v", msg.NodeID, time.Unix(int64(msg.Timestamp), 0)) diff --git a/routing/ann_validation.go b/routing/ann_validation.go index 46f263cb0e..349332ca51 100644 --- a/routing/ann_validation.go +++ b/routing/ann_validation.go @@ -88,7 +88,7 @@ func ValidateChannelAnn(a *lnwire.ChannelAnnouncement1) error { // ValidateNodeAnn validates the node announcement by ensuring that the // attached signature is needed a signature of the node announcement under the // specified node public key. -func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error { +func ValidateNodeAnn(a *lnwire.NodeAnnouncement1) error { // Reconstruct the data of announcement which should be covered by the // signature so we can verify the signature shortly below data, err := a.DataToSign() @@ -114,7 +114,7 @@ func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error { return err } - return errors.Errorf("signature on NodeAnnouncement(%x) is "+ + return errors.Errorf("signature on NodeAnnouncement1(%x) is "+ "invalid: %x", nodeKey.SerializeCompressed(), msgBuf.Bytes()) } diff --git a/routing/validation_barrier.go b/routing/validation_barrier.go index d50e1a1e96..2a3bab9b8a 100644 --- a/routing/validation_barrier.go +++ b/routing/validation_barrier.go @@ -48,7 +48,7 @@ type ValidationBarrier struct { // itself. chanEdgeDependencies map[lnwire.ShortChannelID]*validationSignals - // nodeAnnDependencies tracks any pending NodeAnnouncement validation + // nodeAnnDependencies tracks any pending NodeAnnouncement1 validation // jobs which should wait until the completion of the // ChannelAnnouncement1 before proceeding. nodeAnnDependencies map[route.Vertex]*validationSignals @@ -148,7 +148,7 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) { return case *lnwire.ChannelUpdate1: return - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: // TODO(roasbeef): node ann needs to wait on existing channel updates return case *channeldb.LightningNode: @@ -208,10 +208,10 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { jobDesc = fmt.Sprintf("job=lnwire.ChannelUpdate1, scid=%v", msg.ShortChannelID.ToUint64()) - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: vertex := route.Vertex(msg.NodeID) signals, ok = v.nodeAnnDependencies[vertex] - jobDesc = fmt.Sprintf("job=lnwire.NodeAnnouncement, pub=%s", + jobDesc = fmt.Sprintf("job=lnwire.NodeAnnouncement1, pub=%s", vertex) // Other types of jobs can be executed immediately, so we'll just @@ -293,7 +293,7 @@ func (v *ValidationBarrier) SignalDependants(job interface{}, allow bool) { // finished executing and we can proceed. case *channeldb.LightningNode: delete(v.nodeAnnDependencies, route.Vertex(msg.PubKeyBytes)) - case *lnwire.NodeAnnouncement: + case *lnwire.NodeAnnouncement1: delete(v.nodeAnnDependencies, route.Vertex(msg.NodeID)) case *lnwire.ChannelUpdate1: delete(v.chanEdgeDependencies, msg.ShortChannelID) diff --git a/server.go b/server.go index 5076b3f347..59ab6a7c7c 100644 --- a/server.go +++ b/server.go @@ -303,7 +303,7 @@ type server struct { // currentNodeAnn is the node announcement that has been broadcast to // the network upon startup, if the attributes of the node (us) has // changed since last start. - currentNodeAnn *lnwire.NodeAnnouncement + currentNodeAnn *lnwire.NodeAnnouncement1 // chansToRestore is the set of channels that upon starting, the server // should attempt to restore/recover. @@ -1005,7 +1005,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, NotifyWhenOnline: s.NotifyWhenOnline, NotifyWhenOffline: s.NotifyWhenOffline, FetchSelfAnnouncement: s.getNodeAnnouncement, - UpdateSelfAnnouncement: func() (lnwire.NodeAnnouncement, + UpdateSelfAnnouncement: func() (lnwire.NodeAnnouncement1, error) { return s.genNodeAnnouncement(nil) @@ -1294,7 +1294,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, ChannelDB: s.chanStateDB, FeeEstimator: cc.FeeEstimator, SignMessage: cc.MsgSigner.SignMessage, - CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, + CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement1, error) { return s.genNodeAnnouncement(nil) @@ -1627,7 +1627,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, AdvertisedIPs: advertisedIPs, AnnounceNewIPs: netann.IPAnnouncer( func(modifier ...netann.NodeAnnModifier) ( - lnwire.NodeAnnouncement, error) { + lnwire.NodeAnnouncement1, error) { return s.genNodeAnnouncement( nil, modifier..., @@ -2899,7 +2899,7 @@ func (s *server) createNewHiddenService() error { // Now that the onion service has been created, we'll add the onion // address it can be reached at to our list of advertised addresses. newNodeAnn, err := s.genNodeAnnouncement( - nil, func(currentAnn *lnwire.NodeAnnouncement) { + nil, func(currentAnn *lnwire.NodeAnnouncement1) { currentAnn.Addresses = append(currentAnn.Addresses, addr) }, ) @@ -2950,7 +2950,7 @@ func (s *server) findChannel(node *btcec.PublicKey, chanID lnwire.ChannelID) ( } // getNodeAnnouncement fetches the current, fully signed node announcement. -func (s *server) getNodeAnnouncement() lnwire.NodeAnnouncement { +func (s *server) getNodeAnnouncement() lnwire.NodeAnnouncement1 { s.mu.Lock() defer s.mu.Unlock() @@ -2961,7 +2961,7 @@ func (s *server) getNodeAnnouncement() lnwire.NodeAnnouncement { // announcement. The time stamp of the announcement will be updated in order // to ensure it propagates through the network. func (s *server) genNodeAnnouncement(features *lnwire.RawFeatureVector, - modifiers ...netann.NodeAnnModifier) (lnwire.NodeAnnouncement, error) { + modifiers ...netann.NodeAnnModifier) (lnwire.NodeAnnouncement1, error) { s.mu.Lock() defer s.mu.Unlock() @@ -2974,7 +2974,7 @@ func (s *server) genNodeAnnouncement(features *lnwire.RawFeatureVector, } err := s.featureMgr.UpdateFeatureSets(proposedFeatures) if err != nil { - return lnwire.NodeAnnouncement{}, err + return lnwire.NodeAnnouncement1{}, err } // If we could successfully update our feature manager, add @@ -2999,7 +2999,7 @@ func (s *server) genNodeAnnouncement(features *lnwire.RawFeatureVector, s.nodeSigner, s.identityKeyLoc, s.currentNodeAnn, ) if err != nil { - return lnwire.NodeAnnouncement{}, err + return lnwire.NodeAnnouncement1{}, err } return *s.currentNodeAnn, nil @@ -3084,7 +3084,7 @@ func (s *server) establishPersistentConnections() error { // After checking our previous connections for addresses to connect to, // iterate through the nodes in our channel graph to find addresses - // that have been added via NodeAnnouncement messages. + // that have been added via NodeAnnouncement1 messages. sourceNode, err := s.graphDB.SourceNode() if err != nil { return err @@ -3849,7 +3849,7 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq, AnchorTowerClient: s.anchorTowerClient, DisconnectPeer: s.DisconnectPeer, GenNodeAnnouncement: func(...netann.NodeAnnModifier) ( - lnwire.NodeAnnouncement, error) { + lnwire.NodeAnnouncement1, error) { return s.genNodeAnnouncement(nil) }, diff --git a/subrpcserver_config.go b/subrpcserver_config.go index 7706dfd27d..0ed96e3e9e 100644 --- a/subrpcserver_config.go +++ b/subrpcserver_config.go @@ -118,7 +118,7 @@ func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config, tcpResolver lncfg.TCPResolver, genInvoiceFeatures func() *lnwire.FeatureVector, genAmpInvoiceFeatures func() *lnwire.FeatureVector, - getNodeAnnouncement func() lnwire.NodeAnnouncement, + getNodeAnnouncement func() lnwire.NodeAnnouncement1, updateNodeAnnouncement func(features *lnwire.RawFeatureVector, modifiers ...netann.NodeAnnModifier) error, parseAddr func(addr string) (net.Addr, error), From 3156421efb669f8051c1fc27548d05dd459ff18f Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 08:42:23 +0200 Subject: [PATCH 05/20] lnwire: make MuSig2Nonce TLV type re-usable Before this commit, any MuSig2Nonce TLV field used within a message is expected to use the same tlv type number. This is changed in this commit so that each message must specify which type number it wishes to use. This is necessary for if there is ever more than one MuSig2Nonce used within the same message or if it is ever used in a message with a conflicting type number. --- lnwire/accept_channel.go | 24 ++++++++++++++++++------ lnwire/channel_ready.go | 23 ++++++++++++++++++----- lnwire/channel_reestablish.go | 23 ++++++++++++++++------- lnwire/musig2.go | 25 ++++++++++++++++++------- lnwire/open_channel.go | 25 +++++++++++++++++++------ lnwire/revoke_and_ack.go | 21 ++++++++++++++++----- 6 files changed, 105 insertions(+), 36 deletions(-) diff --git a/lnwire/accept_channel.go b/lnwire/accept_channel.go index 66dda815c6..842ee6eb3b 100644 --- a/lnwire/accept_channel.go +++ b/lnwire/accept_channel.go @@ -9,6 +9,12 @@ import ( "github.com/lightningnetwork/lnd/tlv" ) +const ( + // AcceptChanLocalNonceType is the tlv number associated with the + // local nonce TLV record in the accept_channel message. + AcceptChanLocalNonceType = tlv.Type(4) +) + // AcceptChannel is the message Bob sends to Alice after she initiates the // single funder channel workflow via an AcceptChannel message. Once Alice // receives Bob's response, then she has all the items necessary to construct @@ -142,7 +148,12 @@ func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error { recordProducers = append(recordProducers, a.LeaseExpiry) } if a.LocalNonce != nil { - recordProducers = append(recordProducers, a.LocalNonce) + recordProducers = append(recordProducers, + &Musig2NonceRecordProducer{ + Musig2Nonce: *a.LocalNonce, + Type: AcceptChanLocalNonceType, + }, + ) } err := EncodeMessageExtraData(&a.ExtraData, recordProducers...) if err != nil { @@ -248,11 +259,12 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { var ( chanType ChannelType leaseExpiry LeaseExpiry - localNonce Musig2Nonce + localNonce = NewMusig2NonceRecordProducer( + AcceptChanLocalNonceType, + ) ) typeMap, err := tlvRecords.ExtractRecords( - &a.UpfrontShutdownScript, &chanType, &leaseExpiry, - &localNonce, + &a.UpfrontShutdownScript, &chanType, &leaseExpiry, localNonce, ) if err != nil { return err @@ -265,8 +277,8 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil { a.LeaseExpiry = &leaseExpiry } - if val, ok := typeMap[NonceRecordType]; ok && val == nil { - a.LocalNonce = &localNonce + if val, ok := typeMap[AcceptChanLocalNonceType]; ok && val == nil { + a.LocalNonce = &localNonce.Musig2Nonce } a.ExtraData = tlvRecords diff --git a/lnwire/channel_ready.go b/lnwire/channel_ready.go index 07872f8006..48a0cb0ed2 100644 --- a/lnwire/channel_ready.go +++ b/lnwire/channel_ready.go @@ -8,6 +8,12 @@ import ( "github.com/lightningnetwork/lnd/tlv" ) +const ( + // ChanReadyLocalNonceType is the tlv number associated with the local + // nonce TLV record in the channel_ready message. + ChanReadyLocalNonceType = tlv.Type(4) +) + // ChannelReady is the message that both parties to a new channel creation // send once they have observed the funding transaction being confirmed on the // blockchain. ChannelReady contains the signatures necessary for the channel @@ -77,10 +83,12 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { // the AliasScidRecordType. var ( aliasScid ShortChannelID - localNonce Musig2Nonce + localNonce = NewMusig2NonceRecordProducer( + ChanReadyLocalNonceType, + ) ) typeMap, err := tlvRecords.ExtractRecords( - &aliasScid, &localNonce, + &aliasScid, localNonce, ) if err != nil { return err @@ -91,8 +99,8 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { if val, ok := typeMap[AliasScidRecordType]; ok && val == nil { c.AliasScid = &aliasScid } - if val, ok := typeMap[NonceRecordType]; ok && val == nil { - c.NextLocalNonce = &localNonce + if val, ok := typeMap[ChanReadyLocalNonceType]; ok && val == nil { + c.NextLocalNonce = &localNonce.Musig2Nonce } if len(tlvRecords) != 0 { @@ -122,7 +130,12 @@ func (c *ChannelReady) Encode(w *bytes.Buffer, _ uint32) error { recordProducers = append(recordProducers, c.AliasScid) } if c.NextLocalNonce != nil { - recordProducers = append(recordProducers, c.NextLocalNonce) + recordProducers = append( + recordProducers, &Musig2NonceRecordProducer{ + Musig2Nonce: *c.NextLocalNonce, + Type: ChanReadyLocalNonceType, + }, + ) } err := EncodeMessageExtraData(&c.ExtraData, recordProducers...) if err != nil { diff --git a/lnwire/channel_reestablish.go b/lnwire/channel_reestablish.go index 1b6cfdffc3..efa8d946bc 100644 --- a/lnwire/channel_reestablish.go +++ b/lnwire/channel_reestablish.go @@ -8,6 +8,12 @@ import ( "github.com/lightningnetwork/lnd/tlv" ) +const ( + // ChanReestLocalNonceType is the tlv number associated with the local + // nonce TLV record in the channel_reestablish message. + ChanReestLocalNonceType = tlv.Type(4) +) + // ChannelReestablish is a message sent between peers that have an existing // open channel upon connection reestablishment. This message allows both sides // to report their local state, and their current knowledge of the state of the @@ -119,7 +125,12 @@ func (a *ChannelReestablish) Encode(w *bytes.Buffer, pver uint32) error { recordProducers := make([]tlv.RecordProducer, 0, 1) if a.LocalNonce != nil { - recordProducers = append(recordProducers, a.LocalNonce) + recordProducers = append(recordProducers, + &Musig2NonceRecordProducer{ + Musig2Nonce: *a.LocalNonce, + Type: ChanReestLocalNonceType, + }, + ) } err := EncodeMessageExtraData(&a.ExtraData, recordProducers...) if err != nil { @@ -179,16 +190,14 @@ func (a *ChannelReestablish) Decode(r io.Reader, pver uint32) error { return err } - var localNonce Musig2Nonce - typeMap, err := tlvRecords.ExtractRecords( - &localNonce, - ) + localNonce := NewMusig2NonceRecordProducer(ChanReestLocalNonceType) + typeMap, err := tlvRecords.ExtractRecords(localNonce) if err != nil { return err } - if val, ok := typeMap[NonceRecordType]; ok && val == nil { - a.LocalNonce = &localNonce + if val, ok := typeMap[ChanReestLocalNonceType]; ok && val == nil { + a.LocalNonce = &localNonce.Musig2Nonce } if len(tlvRecords) != 0 { diff --git a/lnwire/musig2.go b/lnwire/musig2.go index 6602ee6947..5d7c47195e 100644 --- a/lnwire/musig2.go +++ b/lnwire/musig2.go @@ -7,20 +7,31 @@ import ( "github.com/lightningnetwork/lnd/tlv" ) -const ( - // NonceRecordType is the TLV type used to encode a local musig2 nonce. - NonceRecordType tlv.Type = 4 -) - // Musig2Nonce represents a musig2 public nonce, which is the concatenation of // two EC points serialized in compressed format. type Musig2Nonce [musig2.PubNonceSize]byte +// Musig2NonceRecordProducer wraps a Musig2Nonce with the tlv type it should be +// encoded under. This can then be used to produce a TLV record. +type Musig2NonceRecordProducer struct { + Musig2Nonce + + Type tlv.Type +} + +// NewMusig2NonceRecordProducer constructs a new Musig2NonceRecordProducer with +// the given tlv type set. +func NewMusig2NonceRecordProducer(tlvType tlv.Type) *Musig2NonceRecordProducer { + return &Musig2NonceRecordProducer{ + Type: tlvType, + } +} + // Record returns a TLV record that can be used to encode/decode the musig2 // nonce from a given TLV stream. -func (m *Musig2Nonce) Record() tlv.Record { +func (m *Musig2NonceRecordProducer) Record() tlv.Record { return tlv.MakeStaticRecord( - NonceRecordType, m, musig2.PubNonceSize, nonceTypeEncoder, + m.Type, &m.Musig2Nonce, musig2.PubNonceSize, nonceTypeEncoder, nonceTypeDecoder, ) } diff --git a/lnwire/open_channel.go b/lnwire/open_channel.go index 9cb4bc41ad..c797801d00 100644 --- a/lnwire/open_channel.go +++ b/lnwire/open_channel.go @@ -21,6 +21,12 @@ const ( FFAnnounceChannel FundingFlag = 1 << iota ) +const ( + // OpenChanLocalNonceType is the tlv number associated with the local + // nonce TLV record in the open_channel message. + OpenChanLocalNonceType = tlv.Type(4) +) + // OpenChannel is the message Alice sends to Bob if we should like to create a // channel with Bob where she's the sole provider of funds to the channel. // Single funder channels simplify the initial funding workflow, are supported @@ -176,8 +182,14 @@ func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error { recordProducers = append(recordProducers, o.LeaseExpiry) } if o.LocalNonce != nil { - recordProducers = append(recordProducers, o.LocalNonce) + recordProducers = append(recordProducers, + &Musig2NonceRecordProducer{ + Musig2Nonce: *o.LocalNonce, + Type: OpenChanLocalNonceType, + }, + ) } + err := EncodeMessageExtraData(&o.ExtraData, recordProducers...) if err != nil { return err @@ -302,11 +314,12 @@ func (o *OpenChannel) Decode(r io.Reader, pver uint32) error { var ( chanType ChannelType leaseExpiry LeaseExpiry - localNonce Musig2Nonce + localNonce = NewMusig2NonceRecordProducer( + OpenChanLocalNonceType, + ) ) typeMap, err := tlvRecords.ExtractRecords( - &o.UpfrontShutdownScript, &chanType, &leaseExpiry, - &localNonce, + &o.UpfrontShutdownScript, &chanType, &leaseExpiry, localNonce, ) if err != nil { return err @@ -319,8 +332,8 @@ func (o *OpenChannel) Decode(r io.Reader, pver uint32) error { if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil { o.LeaseExpiry = &leaseExpiry } - if val, ok := typeMap[NonceRecordType]; ok && val == nil { - o.LocalNonce = &localNonce + if val, ok := typeMap[OpenChanLocalNonceType]; ok && val == nil { + o.LocalNonce = &localNonce.Musig2Nonce } o.ExtraData = tlvRecords diff --git a/lnwire/revoke_and_ack.go b/lnwire/revoke_and_ack.go index 6b6b801671..673f31a937 100644 --- a/lnwire/revoke_and_ack.go +++ b/lnwire/revoke_and_ack.go @@ -8,6 +8,12 @@ import ( "github.com/lightningnetwork/lnd/tlv" ) +const ( + // RevAndAckLocalNonceType is the tlv number associated with the local + // nonce TLV record in the revoke_and_ack message. + RevAndAckLocalNonceType = tlv.Type(4) +) + // RevokeAndAck is sent by either side once a CommitSig message has been // received, and validated. This message serves to revoke the prior commitment // transaction, which was the most up to date version until a CommitSig message @@ -74,15 +80,15 @@ func (c *RevokeAndAck) Decode(r io.Reader, pver uint32) error { return err } - var musigNonce Musig2Nonce - typeMap, err := tlvRecords.ExtractRecords(&musigNonce) + musigNonce := NewMusig2NonceRecordProducer(RevAndAckLocalNonceType) + typeMap, err := tlvRecords.ExtractRecords(musigNonce) if err != nil { return err } // Set the corresponding TLV types if they were included in the stream. - if val, ok := typeMap[NonceRecordType]; ok && val == nil { - c.LocalNonce = &musigNonce + if val, ok := typeMap[RevAndAckLocalNonceType]; ok && val == nil { + c.LocalNonce = &musigNonce.Musig2Nonce } if len(tlvRecords) != 0 { @@ -99,7 +105,12 @@ func (c *RevokeAndAck) Decode(r io.Reader, pver uint32) error { func (c *RevokeAndAck) Encode(w *bytes.Buffer, pver uint32) error { recordProducers := make([]tlv.RecordProducer, 0, 1) if c.LocalNonce != nil { - recordProducers = append(recordProducers, c.LocalNonce) + recordProducers = append(recordProducers, + &Musig2NonceRecordProducer{ + Musig2Nonce: *c.LocalNonce, + Type: RevAndAckLocalNonceType, + }, + ) } err := EncodeMessageExtraData(&c.ExtraData, recordProducers...) if err != nil { From 8b624433f53c8655af95e5ab93abb42d91068362 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 09:11:33 +0200 Subject: [PATCH 06/20] lnwire: add RawFeatureVectorRecordProducer This commits defines the RawFeatureVectorRecordProducer type which will allow RawFeatureVector type to be used for a TLV record. --- lnwire/features.go | 67 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/lnwire/features.go b/lnwire/features.go index 81472a7544..93d255c3d5 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" "io" + + "github.com/lightningnetwork/lnd/tlv" ) var ( @@ -372,7 +374,7 @@ func (fv RawFeatureVector) Equals(other *RawFeatureVector) bool { return true } -// Merges sets all feature bits in other on the receiver's feature vector. +// Merge sets all feature bits in other on the receiver's feature vector. func (fv *RawFeatureVector) Merge(other *RawFeatureVector) error { for bit := range other.features { err := fv.SafeSet(bit) @@ -721,3 +723,66 @@ func (fv *FeatureVector) Clone() *FeatureVector { features := fv.RawFeatureVector.Clone() return NewFeatureVector(features, fv.featureNames) } + +// featureBitLen returns the length in bytes of the encoded feature bits. +func (fv *RawFeatureVector) featureBitLen() uint64 { + return uint64(fv.SerializeSize()) +} + +// RawFeatureVectorRecordProducer wraps a RawFeatureVector with the TLV type +// that it should be encoded with. +type RawFeatureVectorRecordProducer struct { + RawFeatureVector + + Type tlv.Type +} + +// NewRawFeatureVectorRecord constructs a new RawFeatureVectorRecordProducer +// with the given TLV type. +func NewRawFeatureVectorRecord( + tlvType tlv.Type) *RawFeatureVectorRecordProducer { + + return &RawFeatureVectorRecordProducer{ + Type: tlvType, + } +} + +// Record returns a TLV record that can be used to encode/decode the channel +// type from a given TLV stream. +func (r *RawFeatureVectorRecordProducer) Record() tlv.Record { + return tlv.MakeDynamicRecord( + r.Type, &r.RawFeatureVector, r.featureBitLen, + rawFeatureVectorEncoder, rawFeatureVectorDecoder, + ) +} + +// rawFeatureVectorEncoder is a custom TLV encoder for a RawFeatureVector +// record. +func rawFeatureVectorEncoder(w io.Writer, val interface{}, _ *[8]byte) error { + if v, ok := val.(*RawFeatureVector); ok { + // Encode the feature bits as a byte slice without its length + // prepended, as that's already taken care of by the TLV record. + fv := *v + return fv.encode(w, fv.SerializeSize(), 8) + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.RawFeatureVector") +} + +// rawFeatureVectorDecoder is a custom TLV decoder for a RawFeatureVector +// record. +func rawFeatureVectorDecoder(r io.Reader, val interface{}, _ *[8]byte, + l uint64) error { + + if v, ok := val.(*RawFeatureVector); ok { + fv := NewRawFeatureVector() + if err := fv.decode(r, int(l), 8); err != nil { + return err + } + *v = *fv + + return nil + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.RawFeatureVector") +} From 1244c8d8939528d00236cd2fad669d6dfb807379 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 09:28:04 +0200 Subject: [PATCH 07/20] lnwire: add Encode and Pack methods for tlv.Records Sometimes we have a set of records instead of a set of record producers that we would want to extract from. So this commit renames the existing `ExtractRecords` method to `ExtractRecordsFromProducers` (since extracting from producers is what it is actually doing) and then adds a new `ExtractRecords` method which extracts from records. The `ExtractRecordsFromProducers` method calls `ExtractRecords` after first converting the given `tlv.RecordProducers` into `tlv.Records`. --- htlcswitch/failure_test.go | 2 +- lnwire/accept_channel.go | 2 +- lnwire/channel_ready.go | 2 +- lnwire/channel_reestablish.go | 2 +- lnwire/channel_type_test.go | 4 +-- lnwire/closing_signed.go | 2 +- lnwire/commit_sig.go | 2 +- lnwire/extra_bytes.go | 50 ++++++++++++++++++++---------- lnwire/extra_bytes_test.go | 7 ++--- lnwire/funding_created.go | 2 +- lnwire/funding_signed.go | 2 +- lnwire/open_channel.go | 2 +- lnwire/revoke_and_ack.go | 2 +- lnwire/short_channel_id_test.go | 4 +-- lnwire/shutdown.go | 2 +- lnwire/typed_delivery_addr_test.go | 4 +-- lnwire/typed_lease_expiry_test.go | 4 +-- 17 files changed, 56 insertions(+), 39 deletions(-) diff --git a/htlcswitch/failure_test.go b/htlcswitch/failure_test.go index 48ebc66821..b1bb5b402e 100644 --- a/htlcswitch/failure_test.go +++ b/htlcswitch/failure_test.go @@ -65,7 +65,7 @@ func TestLongFailureMessage(t *testing.T) { var value varBytesRecordProducer extraData := incorrectDetails.ExtraOpaqueData() - typeMap, err := extraData.ExtractRecords(&value) + typeMap, err := extraData.ExtractRecordsFromProducers(&value) require.NoError(t, err) require.Len(t, typeMap, 1) diff --git a/lnwire/accept_channel.go b/lnwire/accept_channel.go index 842ee6eb3b..3c99e00231 100644 --- a/lnwire/accept_channel.go +++ b/lnwire/accept_channel.go @@ -263,7 +263,7 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { AcceptChanLocalNonceType, ) ) - typeMap, err := tlvRecords.ExtractRecords( + typeMap, err := tlvRecords.ExtractRecordsFromProducers( &a.UpfrontShutdownScript, &chanType, &leaseExpiry, localNonce, ) if err != nil { diff --git a/lnwire/channel_ready.go b/lnwire/channel_ready.go index 48a0cb0ed2..bfd15e08a4 100644 --- a/lnwire/channel_ready.go +++ b/lnwire/channel_ready.go @@ -87,7 +87,7 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { ChanReadyLocalNonceType, ) ) - typeMap, err := tlvRecords.ExtractRecords( + typeMap, err := tlvRecords.ExtractRecordsFromProducers( &aliasScid, localNonce, ) if err != nil { diff --git a/lnwire/channel_reestablish.go b/lnwire/channel_reestablish.go index efa8d946bc..044702edaa 100644 --- a/lnwire/channel_reestablish.go +++ b/lnwire/channel_reestablish.go @@ -191,7 +191,7 @@ func (a *ChannelReestablish) Decode(r io.Reader, pver uint32) error { } localNonce := NewMusig2NonceRecordProducer(ChanReestLocalNonceType) - typeMap, err := tlvRecords.ExtractRecords(localNonce) + typeMap, err := tlvRecords.ExtractRecordsFromProducers(localNonce) if err != nil { return err } diff --git a/lnwire/channel_type_test.go b/lnwire/channel_type_test.go index dd8e02439a..1d477151c4 100644 --- a/lnwire/channel_type_test.go +++ b/lnwire/channel_type_test.go @@ -17,10 +17,10 @@ func TestChannelTypeEncodeDecode(t *testing.T) { )) var extraData ExtraOpaqueData - require.NoError(t, extraData.PackRecords(&chanType)) + require.NoError(t, extraData.PackRecordsFromProducers(&chanType)) var chanType2 ChannelType - tlvs, err := extraData.ExtractRecords(&chanType2) + tlvs, err := extraData.ExtractRecordsFromProducers(&chanType2) require.NoError(t, err) require.Contains(t, tlvs, ChannelTypeRecordType) diff --git a/lnwire/closing_signed.go b/lnwire/closing_signed.go index 3e3651964d..9b68ca11a1 100644 --- a/lnwire/closing_signed.go +++ b/lnwire/closing_signed.go @@ -79,7 +79,7 @@ func (c *ClosingSigned) Decode(r io.Reader, pver uint32) error { var ( partialSig PartialSig ) - typeMap, err := tlvRecords.ExtractRecords(&partialSig) + typeMap, err := tlvRecords.ExtractRecordsFromProducers(&partialSig) if err != nil { return err } diff --git a/lnwire/commit_sig.go b/lnwire/commit_sig.go index d25d36a8ad..21a39759d0 100644 --- a/lnwire/commit_sig.go +++ b/lnwire/commit_sig.go @@ -84,7 +84,7 @@ func (c *CommitSig) Decode(r io.Reader, pver uint32) error { var ( partialSig PartialSigWithNonce ) - typeMap, err := tlvRecords.ExtractRecords(&partialSig) + typeMap, err := tlvRecords.ExtractRecordsFromProducers(&partialSig) if err != nil { return err } diff --git a/lnwire/extra_bytes.go b/lnwire/extra_bytes.go index 200f313ca8..8f5668efa0 100644 --- a/lnwire/extra_bytes.go +++ b/lnwire/extra_bytes.go @@ -51,13 +51,7 @@ func (e *ExtraOpaqueData) Decode(r io.Reader) error { // PackRecords attempts to encode the set of tlv records into the target // ExtraOpaqueData instance. The records will be encoded as a raw TLV stream // and stored within the backing slice pointer. -func (e *ExtraOpaqueData) PackRecords(recordProducers ...tlv.RecordProducer) error { - // First, assemble all the records passed in in series. - records := make([]tlv.Record, 0, len(recordProducers)) - for _, producer := range recordProducers { - records = append(records, producer.Record()) - } - +func (e *ExtraOpaqueData) PackRecords(records ...tlv.Record) error { // Ensure that the set of records are sorted before we encode them into // the stream, to ensure they're canonical. tlv.SortRecords(records) @@ -72,24 +66,32 @@ func (e *ExtraOpaqueData) PackRecords(recordProducers ...tlv.RecordProducer) err return err } - *e = ExtraOpaqueData(extraBytesWriter.Bytes()) + *e = extraBytesWriter.Bytes() return nil } -// ExtractRecords attempts to decode any types in the internal raw bytes as if -// it were a tlv stream. The set of raw parsed types is returned, and any -// passed records (if found in the stream) will be parsed into the proper -// tlv.Record. -func (e *ExtraOpaqueData) ExtractRecords(recordProducers ...tlv.RecordProducer) ( - tlv.TypeMap, error) { +// PackRecordsFromProducers attempts to encode the set of tlv records into the +// target ExtraOpaqueData instance. The records will be encoded as a raw TLV +// stream and stored within the backing slice pointer. +func (e *ExtraOpaqueData) PackRecordsFromProducers( + recordProducers ...tlv.RecordProducer) error { - // First, assemble all the records passed in in series. + // First, assemble all the records passed in, in series. records := make([]tlv.Record, 0, len(recordProducers)) for _, producer := range recordProducers { records = append(records, producer.Record()) } + return e.PackRecords(records...) +} + +// ExtractRecords attempts to decode any types in the internal raw bytes as if +// it were a tlv stream. The set of raw parsed types is returned, and any passed +// records (if found in the stream) will be parsed into the proper tlv.Record. +func (e *ExtraOpaqueData) ExtractRecords(records ...tlv.Record) (tlv.TypeMap, + error) { + // Ensure that the set of records are sorted before we attempt to // decode from the stream, to ensure they're canonical. tlv.SortRecords(records) @@ -106,6 +108,22 @@ func (e *ExtraOpaqueData) ExtractRecords(recordProducers ...tlv.RecordProducer) return tlvStream.DecodeWithParsedTypesP2P(extraBytesReader) } +// ExtractRecordsFromProducers attempts to decode any types in the internal raw +// bytes as if it were a tlv stream. The set of raw parsed types is returned, +// and any records produced by the passed record producers (if found in the +// stream) will be parsed into the proper tlv.Record. +func (e *ExtraOpaqueData) ExtractRecordsFromProducers( + recordProducers ...tlv.RecordProducer) (tlv.TypeMap, error) { + + // First, assemble all the records passed in, in series. + records := make([]tlv.Record, 0, len(recordProducers)) + for _, producer := range recordProducers { + records = append(records, producer.Record()) + } + + return e.ExtractRecords(records...) +} + // EncodeMessageExtraData encodes the given recordProducers into the given // extraData. func EncodeMessageExtraData(extraData *ExtraOpaqueData, @@ -119,5 +137,5 @@ func EncodeMessageExtraData(extraData *ExtraOpaqueData, // Pack in the series of TLV records into this message. The order we // pass them in doesn't matter, as the method will ensure that things // are all properly sorted. - return extraData.PackRecords(recordProducers...) + return extraData.PackRecordsFromProducers(recordProducers...) } diff --git a/lnwire/extra_bytes_test.go b/lnwire/extra_bytes_test.go index fd9f28841d..46100d7cff 100644 --- a/lnwire/extra_bytes_test.go +++ b/lnwire/extra_bytes_test.go @@ -118,9 +118,8 @@ func TestExtraOpaqueDataPackUnpackRecords(t *testing.T) { // Now that we have our set of sample records and types, we'll encode // them into the passed ExtraOpaqueData instance. var extraBytes ExtraOpaqueData - if err := extraBytes.PackRecords(testRecordsProducers...); err != nil { - t.Fatalf("unable to pack records: %v", err) - } + err := extraBytes.PackRecordsFromProducers(testRecordsProducers...) + require.NoError(t, err) // We'll now simulate decoding these types _back_ into records on the // other side. @@ -128,7 +127,7 @@ func TestExtraOpaqueDataPackUnpackRecords(t *testing.T) { &recordProducer{tlv.MakePrimitiveRecord(type1, &channelType2)}, &recordProducer{tlv.MakePrimitiveRecord(type2, &hop2)}, } - typeMap, err := extraBytes.ExtractRecords(newRecords...) + typeMap, err := extraBytes.ExtractRecordsFromProducers(newRecords...) require.NoError(t, err, "unable to extract record") // We should find that the new backing values have been populated with diff --git a/lnwire/funding_created.go b/lnwire/funding_created.go index f8128ff761..06f15c9dfc 100644 --- a/lnwire/funding_created.go +++ b/lnwire/funding_created.go @@ -95,7 +95,7 @@ func (f *FundingCreated) Decode(r io.Reader, pver uint32) error { var ( partialSig PartialSigWithNonce ) - typeMap, err := tlvRecords.ExtractRecords(&partialSig) + typeMap, err := tlvRecords.ExtractRecordsFromProducers(&partialSig) if err != nil { return err } diff --git a/lnwire/funding_signed.go b/lnwire/funding_signed.go index c7fb03d155..1bf1fc234c 100644 --- a/lnwire/funding_signed.go +++ b/lnwire/funding_signed.go @@ -81,7 +81,7 @@ func (f *FundingSigned) Decode(r io.Reader, pver uint32) error { var ( partialSig PartialSigWithNonce ) - typeMap, err := tlvRecords.ExtractRecords(&partialSig) + typeMap, err := tlvRecords.ExtractRecordsFromProducers(&partialSig) if err != nil { return err } diff --git a/lnwire/open_channel.go b/lnwire/open_channel.go index c797801d00..90e5adbe76 100644 --- a/lnwire/open_channel.go +++ b/lnwire/open_channel.go @@ -318,7 +318,7 @@ func (o *OpenChannel) Decode(r io.Reader, pver uint32) error { OpenChanLocalNonceType, ) ) - typeMap, err := tlvRecords.ExtractRecords( + typeMap, err := tlvRecords.ExtractRecordsFromProducers( &o.UpfrontShutdownScript, &chanType, &leaseExpiry, localNonce, ) if err != nil { diff --git a/lnwire/revoke_and_ack.go b/lnwire/revoke_and_ack.go index 673f31a937..80dd847269 100644 --- a/lnwire/revoke_and_ack.go +++ b/lnwire/revoke_and_ack.go @@ -81,7 +81,7 @@ func (c *RevokeAndAck) Decode(r io.Reader, pver uint32) error { } musigNonce := NewMusig2NonceRecordProducer(RevAndAckLocalNonceType) - typeMap, err := tlvRecords.ExtractRecords(musigNonce) + typeMap, err := tlvRecords.ExtractRecordsFromProducers(musigNonce) if err != nil { return err } diff --git a/lnwire/short_channel_id_test.go b/lnwire/short_channel_id_test.go index 2916f20d17..c440a0e370 100644 --- a/lnwire/short_channel_id_test.go +++ b/lnwire/short_channel_id_test.go @@ -53,10 +53,10 @@ func TestScidTypeEncodeDecode(t *testing.T) { } var extraData ExtraOpaqueData - require.NoError(t, extraData.PackRecords(&aliasScid)) + require.NoError(t, extraData.PackRecordsFromProducers(&aliasScid)) var aliasScid2 ShortChannelID - tlvs, err := extraData.ExtractRecords(&aliasScid2) + tlvs, err := extraData.ExtractRecordsFromProducers(&aliasScid2) require.NoError(t, err) require.Contains(t, tlvs, AliasScidRecordType) diff --git a/lnwire/shutdown.go b/lnwire/shutdown.go index 5b59b47ab1..facfe79232 100644 --- a/lnwire/shutdown.go +++ b/lnwire/shutdown.go @@ -103,7 +103,7 @@ func (s *Shutdown) Decode(r io.Reader, pver uint32) error { } var musigNonce ShutdownNonce - typeMap, err := tlvRecords.ExtractRecords(&musigNonce) + typeMap, err := tlvRecords.ExtractRecordsFromProducers(&musigNonce) if err != nil { return err } diff --git a/lnwire/typed_delivery_addr_test.go b/lnwire/typed_delivery_addr_test.go index 9d00bc8bd8..0b8274750e 100644 --- a/lnwire/typed_delivery_addr_test.go +++ b/lnwire/typed_delivery_addr_test.go @@ -15,13 +15,13 @@ func TestDeliveryAddressEncodeDecode(t *testing.T) { ) var extraData ExtraOpaqueData - err := extraData.PackRecords(&addr) + err := extraData.PackRecordsFromProducers(&addr) if err != nil { t.Fatal(err) } var addr2 DeliveryAddress - tlvs, err := extraData.ExtractRecords(&addr2) + tlvs, err := extraData.ExtractRecordsFromProducers(&addr2) if err != nil { t.Fatal(err) } diff --git a/lnwire/typed_lease_expiry_test.go b/lnwire/typed_lease_expiry_test.go index d5f797b200..071a8ae91f 100644 --- a/lnwire/typed_lease_expiry_test.go +++ b/lnwire/typed_lease_expiry_test.go @@ -14,10 +14,10 @@ func TestLeaseExpiryEncodeDecode(t *testing.T) { leaseExpiry := LeaseExpiry(1337) var extraData ExtraOpaqueData - require.NoError(t, extraData.PackRecords(&leaseExpiry)) + require.NoError(t, extraData.PackRecordsFromProducers(&leaseExpiry)) var leaseExpiry2 LeaseExpiry - tlvs, err := extraData.ExtractRecords(&leaseExpiry2) + tlvs, err := extraData.ExtractRecordsFromProducers(&leaseExpiry2) require.NoError(t, err) require.Contains(t, tlvs, LeaseExpiryRecordType) From 96907a19a95638a2e880614ec554ee2a6475dc98 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 09:32:34 +0200 Subject: [PATCH 08/20] lnwire: use the RawFeatureVector record methods for ChannelType the `lnwire.ChannelType` type is just a `RawFeatureVector` underneath. Since we now have a more general `RawFeatureVectorRecordProducer`, we can use that for encoding the ChannelType. --- lnwire/accept_channel.go | 18 ++++++++++++---- lnwire/channel_type.go | 43 ------------------------------------- lnwire/channel_type_test.go | 19 +++++++++------- lnwire/features.go | 6 +++--- lnwire/open_channel.go | 20 ++++++++++++----- 5 files changed, 43 insertions(+), 63 deletions(-) diff --git a/lnwire/accept_channel.go b/lnwire/accept_channel.go index 3c99e00231..3c2f0b0fbc 100644 --- a/lnwire/accept_channel.go +++ b/lnwire/accept_channel.go @@ -142,7 +142,14 @@ var _ Message = (*AcceptChannel)(nil) func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error { recordProducers := []tlv.RecordProducer{&a.UpfrontShutdownScript} if a.ChannelType != nil { - recordProducers = append(recordProducers, a.ChannelType) + recordProducers = append(recordProducers, + &RawFeatureVectorRecordProducer{ + RawFeatureVector: RawFeatureVector( + *a.ChannelType, + ), + Type: ChannelTypeRecordType, + }, + ) } if a.LeaseExpiry != nil { recordProducers = append(recordProducers, a.LeaseExpiry) @@ -257,14 +264,16 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { // Next we'll parse out the set of known records, keeping the raw tlv // bytes untouched to ensure we don't drop any bytes erroneously. var ( - chanType ChannelType + chanType = NewRawFeatureVectorRecordProducer( + ChannelTypeRecordType, + ) leaseExpiry LeaseExpiry localNonce = NewMusig2NonceRecordProducer( AcceptChanLocalNonceType, ) ) typeMap, err := tlvRecords.ExtractRecordsFromProducers( - &a.UpfrontShutdownScript, &chanType, &leaseExpiry, localNonce, + &a.UpfrontShutdownScript, chanType, &leaseExpiry, localNonce, ) if err != nil { return err @@ -272,7 +281,8 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { // Set the corresponding TLV types if they were included in the stream. if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil { - a.ChannelType = &chanType + channelType := ChannelType(chanType.RawFeatureVector) + a.ChannelType = &channelType } if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil { a.LeaseExpiry = &leaseExpiry diff --git a/lnwire/channel_type.go b/lnwire/channel_type.go index a0696048be..3b8eaef781 100644 --- a/lnwire/channel_type.go +++ b/lnwire/channel_type.go @@ -1,8 +1,6 @@ package lnwire import ( - "io" - "github.com/lightningnetwork/lnd/tlv" ) @@ -15,44 +13,3 @@ const ( // ChannelType represents a specific channel type as a set of feature bits that // comprise it. type ChannelType RawFeatureVector - -// featureBitLen returns the length in bytes of the encoded feature bits. -func (c ChannelType) featureBitLen() uint64 { - fv := RawFeatureVector(c) - return uint64(fv.SerializeSize()) -} - -// Record returns a TLV record that can be used to encode/decode the channel -// type from a given TLV stream. -func (c *ChannelType) Record() tlv.Record { - return tlv.MakeDynamicRecord( - ChannelTypeRecordType, c, c.featureBitLen, channelTypeEncoder, - channelTypeDecoder, - ) -} - -// channelTypeEncoder is a custom TLV encoder for the ChannelType record. -func channelTypeEncoder(w io.Writer, val interface{}, buf *[8]byte) error { - if v, ok := val.(*ChannelType); ok { - // Encode the feature bits as a byte slice without its length - // prepended, as that's already taken care of by the TLV record. - fv := RawFeatureVector(*v) - return fv.encode(w, fv.SerializeSize(), 8) - } - - return tlv.NewTypeForEncodingErr(val, "lnwire.ChannelType") -} - -// channelTypeDecoder is a custom TLV decoder for the ChannelType record. -func channelTypeDecoder(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { - if v, ok := val.(*ChannelType); ok { - fv := NewRawFeatureVector() - if err := fv.decode(r, int(l), 8); err != nil { - return err - } - *v = ChannelType(*fv) - return nil - } - - return tlv.NewTypeForEncodingErr(val, "lnwire.ChannelType") -} diff --git a/lnwire/channel_type_test.go b/lnwire/channel_type_test.go index 1d477151c4..56f07cb432 100644 --- a/lnwire/channel_type_test.go +++ b/lnwire/channel_type_test.go @@ -11,18 +11,21 @@ import ( func TestChannelTypeEncodeDecode(t *testing.T) { t.Parallel() - chanType := ChannelType(*NewRawFeatureVector( - StaticRemoteKeyRequired, - AnchorsZeroFeeHtlcTxRequired, - )) + record1 := RawFeatureVectorRecordProducer{ + RawFeatureVector: *NewRawFeatureVector( + StaticRemoteKeyRequired, + AnchorsZeroFeeHtlcTxRequired, + ), + Type: ChannelTypeRecordType, + } var extraData ExtraOpaqueData - require.NoError(t, extraData.PackRecordsFromProducers(&chanType)) + require.NoError(t, extraData.PackRecordsFromProducers(&record1)) - var chanType2 ChannelType - tlvs, err := extraData.ExtractRecordsFromProducers(&chanType2) + record2 := NewRawFeatureVectorRecordProducer(ChannelTypeRecordType) + tlvs, err := extraData.ExtractRecordsFromProducers(record2) require.NoError(t, err) require.Contains(t, tlvs, ChannelTypeRecordType) - require.Equal(t, chanType, chanType2) + require.Equal(t, record1.RawFeatureVector, record2.RawFeatureVector) } diff --git a/lnwire/features.go b/lnwire/features.go index 93d255c3d5..0a2cae5677 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -737,9 +737,9 @@ type RawFeatureVectorRecordProducer struct { Type tlv.Type } -// NewRawFeatureVectorRecord constructs a new RawFeatureVectorRecordProducer -// with the given TLV type. -func NewRawFeatureVectorRecord( +// NewRawFeatureVectorRecordProducer constructs a new +// RawFeatureVectorRecordProducer with the given TLV type. +func NewRawFeatureVectorRecordProducer( tlvType tlv.Type) *RawFeatureVectorRecordProducer { return &RawFeatureVectorRecordProducer{ diff --git a/lnwire/open_channel.go b/lnwire/open_channel.go index 90e5adbe76..45a095c69f 100644 --- a/lnwire/open_channel.go +++ b/lnwire/open_channel.go @@ -173,10 +173,17 @@ var _ Message = (*OpenChannel)(nil) // Encode serializes the target OpenChannel into the passed io.Writer // implementation. Serialization will observe the rules defined by the passed // protocol version. -func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error { +func (o *OpenChannel) Encode(w *bytes.Buffer, _ uint32) error { recordProducers := []tlv.RecordProducer{&o.UpfrontShutdownScript} if o.ChannelType != nil { - recordProducers = append(recordProducers, o.ChannelType) + recordProducers = append(recordProducers, + &RawFeatureVectorRecordProducer{ + RawFeatureVector: RawFeatureVector( + *o.ChannelType, + ), + Type: ChannelTypeRecordType, + }, + ) } if o.LeaseExpiry != nil { recordProducers = append(recordProducers, o.LeaseExpiry) @@ -312,14 +319,16 @@ func (o *OpenChannel) Decode(r io.Reader, pver uint32) error { // Next we'll parse out the set of known records, keeping the raw tlv // bytes untouched to ensure we don't drop any bytes erroneously. var ( - chanType ChannelType + chanType = NewRawFeatureVectorRecordProducer( + ChannelTypeRecordType, + ) leaseExpiry LeaseExpiry localNonce = NewMusig2NonceRecordProducer( OpenChanLocalNonceType, ) ) typeMap, err := tlvRecords.ExtractRecordsFromProducers( - &o.UpfrontShutdownScript, &chanType, &leaseExpiry, localNonce, + &o.UpfrontShutdownScript, chanType, &leaseExpiry, localNonce, ) if err != nil { return err @@ -327,7 +336,8 @@ func (o *OpenChannel) Decode(r io.Reader, pver uint32) error { // Set the corresponding TLV types if they were included in the stream. if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil { - o.ChannelType = &chanType + channelType := ChannelType(chanType.RawFeatureVector) + o.ChannelType = &channelType } if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil { o.LeaseExpiry = &leaseExpiry From fc71936e0af51c3660a71275700584ed923ce192 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 09:41:11 +0200 Subject: [PATCH 09/20] lnwire: make ShortChannelID type re-usable The `ShortChannelID` type wont only be used for the `ChannelReady` message and so will sometimes have a type number other than 1. So in this commit, we make the type more re-usable by introducing a `ShortChannelIDRecordProducer` which wraps a `ShortChannelID` with a TLV type number. --- lnwire/channel_ready.go | 22 ++++++++++++++----- lnwire/short_channel_id.go | 39 ++++++++++++++++++++------------- lnwire/short_channel_id_test.go | 28 +++++++++++++++-------- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/lnwire/channel_ready.go b/lnwire/channel_ready.go index bfd15e08a4..12ecd746e4 100644 --- a/lnwire/channel_ready.go +++ b/lnwire/channel_ready.go @@ -9,6 +9,11 @@ import ( ) const ( + // ChanReadyAliasScidType is the TLV type of the experimental record of + // channel_ready to denote the alias being used in an option_scid_alias + // channel. + ChanReadyAliasScidType = tlv.Type(1) + // ChanReadyLocalNonceType is the tlv number associated with the local // nonce TLV record in the channel_ready message. ChanReadyLocalNonceType = tlv.Type(4) @@ -82,13 +87,15 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { // Next we'll parse out the set of known records. For now, this is just // the AliasScidRecordType. var ( - aliasScid ShortChannelID + aliasScid = NewShortChannelIDRecordProducer( + ChanReadyAliasScidType, + ) localNonce = NewMusig2NonceRecordProducer( ChanReadyLocalNonceType, ) ) typeMap, err := tlvRecords.ExtractRecordsFromProducers( - &aliasScid, localNonce, + aliasScid, localNonce, ) if err != nil { return err @@ -96,8 +103,8 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { // We'll only set AliasScid if the corresponding TLV type was included // in the stream. - if val, ok := typeMap[AliasScidRecordType]; ok && val == nil { - c.AliasScid = &aliasScid + if val, ok := typeMap[ChanReadyAliasScidType]; ok && val == nil { + c.AliasScid = &aliasScid.ShortChannelID } if val, ok := typeMap[ChanReadyLocalNonceType]; ok && val == nil { c.NextLocalNonce = &localNonce.Musig2Nonce @@ -127,7 +134,12 @@ func (c *ChannelReady) Encode(w *bytes.Buffer, _ uint32) error { // We'll only encode the AliasScid in a TLV segment if it exists. recordProducers := make([]tlv.RecordProducer, 0, 2) if c.AliasScid != nil { - recordProducers = append(recordProducers, c.AliasScid) + recordProducers = append(recordProducers, + &ShortChannelIDRecordProducer{ + ShortChannelID: *c.AliasScid, + Type: ChanReadyAliasScidType, + }, + ) } if c.NextLocalNonce != nil { recordProducers = append( diff --git a/lnwire/short_channel_id.go b/lnwire/short_channel_id.go index d4da518b76..d286a03221 100644 --- a/lnwire/short_channel_id.go +++ b/lnwire/short_channel_id.go @@ -7,11 +7,28 @@ import ( "github.com/lightningnetwork/lnd/tlv" ) -const ( - // AliasScidRecordType is the type of the experimental record to denote - // the alias being used in an option_scid_alias channel. - AliasScidRecordType tlv.Type = 1 -) +// ShortChannelIDRecordProducer wraps a ShortChannelID with the tlv type that it +// should be encoded with. +type ShortChannelIDRecordProducer struct { + ShortChannelID + Type tlv.Type +} + +// Record returns a TLV record that can be used to encode/decode a +// ShortChannelID to/from a TLV stream. +func (c *ShortChannelIDRecordProducer) Record() tlv.Record { + return tlv.MakeStaticRecord( + c.Type, &c.ShortChannelID, 8, EShortChannelID, DShortChannelID, + ) +} + +// NewShortChannelIDRecordProducer constructs a new ShortChannelIDRecordProducer +// with the given TLV type. +func NewShortChannelIDRecordProducer(t tlv.Type) *ShortChannelIDRecordProducer { + return &ShortChannelIDRecordProducer{ + Type: t, + } +} // ShortChannelID represents the set of data which is needed to retrieve all // necessary data to validate the channel existence. @@ -47,8 +64,8 @@ func NewShortChanIDFromInt(chanID uint64) ShortChannelID { // uint64 (8 bytes). func (c ShortChannelID) ToUint64() uint64 { // TODO(roasbeef): explicit error on overflow? - return ((uint64(c.BlockHeight) << 40) | (uint64(c.TxIndex) << 16) | - (uint64(c.TxPosition))) + return (uint64(c.BlockHeight) << 40) | (uint64(c.TxIndex) << 16) | + (uint64(c.TxPosition)) } // String generates a human-readable representation of the channel ID. @@ -56,14 +73,6 @@ func (c ShortChannelID) String() string { return fmt.Sprintf("%d:%d:%d", c.BlockHeight, c.TxIndex, c.TxPosition) } -// Record returns a TLV record that can be used to encode/decode a -// ShortChannelID to/from a TLV stream. -func (c *ShortChannelID) Record() tlv.Record { - return tlv.MakeStaticRecord( - AliasScidRecordType, c, 8, EShortChannelID, DShortChannelID, - ) -} - // IsDefault returns true if the ShortChannelID represents the zero value for // its type. func (c ShortChannelID) IsDefault() bool { diff --git a/lnwire/short_channel_id_test.go b/lnwire/short_channel_id_test.go index c440a0e370..37158b30c1 100644 --- a/lnwire/short_channel_id_test.go +++ b/lnwire/short_channel_id_test.go @@ -46,19 +46,29 @@ func TestShortChannelIDEncoding(t *testing.T) { func TestScidTypeEncodeDecode(t *testing.T) { t.Parallel() - aliasScid := ShortChannelID{ - BlockHeight: (1 << 24) - 1, - TxIndex: (1 << 24) - 1, - TxPosition: (1 << 16) - 1, + aliasScidRecordProducer := &ShortChannelIDRecordProducer{ + ShortChannelID: ShortChannelID{ + BlockHeight: (1 << 24) - 1, + TxIndex: (1 << 24) - 1, + TxPosition: (1 << 16) - 1, + }, + Type: ChanReadyAliasScidType, } var extraData ExtraOpaqueData - require.NoError(t, extraData.PackRecordsFromProducers(&aliasScid)) + require.NoError( + t, extraData.PackRecordsFromProducers(aliasScidRecordProducer), + ) + + aliasScid2RecordProducer := NewShortChannelIDRecordProducer( + ChanReadyAliasScidType, + ) - var aliasScid2 ShortChannelID - tlvs, err := extraData.ExtractRecordsFromProducers(&aliasScid2) + tlvs, err := extraData.ExtractRecordsFromProducers( + aliasScid2RecordProducer, + ) require.NoError(t, err) - require.Contains(t, tlvs, AliasScidRecordType) - require.Equal(t, aliasScid, aliasScid2) + require.Contains(t, tlvs, ChanReadyAliasScidType) + require.Equal(t, aliasScidRecordProducer, aliasScid2RecordProducer) } From 83da68821afc5464007554b590c8f6eb5a7b718d Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 09:51:27 +0200 Subject: [PATCH 10/20] lnwire: add btc and node announcement nonces to channel_ready In preparation for Gossip 1.75, we add new TLV's to the `ChannelReady` message. Namely: `AnnouncementBitcoinNonce` and `AnnouncementNodeNonce`. These will be used to exchange nones required for producing the partial signature to be send in the `AnnouncementSignatures2` message. The type numbers for these new fields are even because if they are set, then a peer is expecting it's peer to understand gossip 1.75 and the new fields. --- lnwire/channel_ready.go | 56 +++++++++++++++++++++++++++++++++++++---- lnwire/lnwire_test.go | 20 +++++++-------- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/lnwire/channel_ready.go b/lnwire/channel_ready.go index 12ecd746e4..028acc796d 100644 --- a/lnwire/channel_ready.go +++ b/lnwire/channel_ready.go @@ -9,11 +9,19 @@ import ( ) const ( + // ChanReadyAnnounceBtcNonce is the TLV type associated with the + // bitcoin nonce field in the channel_ready message. + ChanReadyAnnounceBtcNonce = tlv.Type(0) + // ChanReadyAliasScidType is the TLV type of the experimental record of // channel_ready to denote the alias being used in an option_scid_alias // channel. ChanReadyAliasScidType = tlv.Type(1) + // ChanReadyAnnounceNodeNonce is the TLV type associated with the node + // nonce field in the channel_ready message. + ChanReadyAnnounceNodeNonce = tlv.Type(2) + // ChanReadyLocalNonceType is the tlv number associated with the local // nonce TLV record in the channel_ready message. ChanReadyLocalNonceType = tlv.Type(4) @@ -38,6 +46,16 @@ type ChannelReady struct { // ShortChannelID for forwarding. AliasScid *ShortChannelID + // AnnouncementBitcoinNonce is an optional field that stores a public + // nonce that will be used along with the node's bitcoin key during + // signing of the ChannelAnnouncement2 message. + AnnouncementBitcoinNonce *Musig2Nonce + + // AnnouncementBitcoinNonce is an optional field that stores a public + // nonce that will be used along with the node's ID key during signing + // of the ChannelAnnouncement2 message. + AnnouncementNodeNonce *Musig2Nonce + // NextLocalNonce is an optional field that stores a local musig2 nonce. // This will only be populated if the simple taproot channels type was // negotiated. This is the local nonce that will be used by the sender @@ -84,8 +102,7 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { return err } - // Next we'll parse out the set of known records. For now, this is just - // the AliasScidRecordType. + // Next we'll parse out the set of known records. var ( aliasScid = NewShortChannelIDRecordProducer( ChanReadyAliasScidType, @@ -93,15 +110,21 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { localNonce = NewMusig2NonceRecordProducer( ChanReadyLocalNonceType, ) + btcNonce = NewMusig2NonceRecordProducer( + ChanReadyAnnounceBtcNonce, + ) + nodeNonce = NewMusig2NonceRecordProducer( + ChanReadyAnnounceNodeNonce, + ) ) typeMap, err := tlvRecords.ExtractRecordsFromProducers( - aliasScid, localNonce, + btcNonce, aliasScid, nodeNonce, localNonce, ) if err != nil { return err } - // We'll only set AliasScid if the corresponding TLV type was included + // We'll only set some fields if the corresponding TLV type was included // in the stream. if val, ok := typeMap[ChanReadyAliasScidType]; ok && val == nil { c.AliasScid = &aliasScid.ShortChannelID @@ -109,6 +132,12 @@ func (c *ChannelReady) Decode(r io.Reader, _ uint32) error { if val, ok := typeMap[ChanReadyLocalNonceType]; ok && val == nil { c.NextLocalNonce = &localNonce.Musig2Nonce } + if val, ok := typeMap[ChanReadyAnnounceBtcNonce]; ok && val == nil { + c.AnnouncementBitcoinNonce = &btcNonce.Musig2Nonce + } + if val, ok := typeMap[ChanReadyAnnounceNodeNonce]; ok && val == nil { + c.AnnouncementNodeNonce = &nodeNonce.Musig2Nonce + } if len(tlvRecords) != 0 { c.ExtraData = tlvRecords @@ -131,8 +160,17 @@ func (c *ChannelReady) Encode(w *bytes.Buffer, _ uint32) error { return err } - // We'll only encode the AliasScid in a TLV segment if it exists. + // We'll only encode the various optional fields in a TLV segment if + // they exists. recordProducers := make([]tlv.RecordProducer, 0, 2) + if c.AnnouncementBitcoinNonce != nil { + recordProducers = append( + recordProducers, &Musig2NonceRecordProducer{ + Type: ChanReadyAnnounceBtcNonce, + Musig2Nonce: *c.AnnouncementBitcoinNonce, + }, + ) + } if c.AliasScid != nil { recordProducers = append(recordProducers, &ShortChannelIDRecordProducer{ @@ -141,6 +179,14 @@ func (c *ChannelReady) Encode(w *bytes.Buffer, _ uint32) error { }, ) } + if c.AnnouncementNodeNonce != nil { + recordProducers = append( + recordProducers, &Musig2NonceRecordProducer{ + Type: ChanReadyAnnounceNodeNonce, + Musig2Nonce: *c.AnnouncementNodeNonce, + }, + ) + } if c.NextLocalNonce != nil { recordProducers = append( recordProducers, &Musig2NonceRecordProducer{ diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index dec0c1e524..27fcc7dd39 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -630,25 +630,23 @@ func TestLightningWireProtocol(t *testing.T) { }, MsgChannelReady: func(v []reflect.Value, r *rand.Rand) { var c [32]byte - if _, err := r.Read(c[:]); err != nil { - t.Fatalf("unable to generate chan id: %v", err) - return - } + _, err := r.Read(c[:]) + require.NoError(t, err) pubKey, err := randPubKey() - if err != nil { - t.Fatalf("unable to generate key: %v", err) - return - } + require.NoError(t, err) - req := NewChannelReady(ChannelID(c), pubKey) + req := NewChannelReady(c, pubKey) if r.Int31()%2 == 0 { - scid := NewShortChanIDFromInt(uint64(r.Int63())) - req.AliasScid = &scid req.NextLocalNonce = randLocalNonce(r) } + if r.Int31()%2 == 0 { + req.AnnouncementBitcoinNonce = randLocalNonce(r) + req.AnnouncementNodeNonce = randLocalNonce(r) + } + v[0] = reflect.ValueOf(*req) }, MsgShutdown: func(v []reflect.Value, r *rand.Rand) { From 0e50cf033680551d05b29c122b5b9d0526d23223 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 12:01:02 +0200 Subject: [PATCH 11/20] lnwire: add FirstBlock and BlockRange to GossipTimestampRange Add new FirstBlockHeight and BlockRange TLV fields to the GossipTimestampRange message. This will be used to query for Gossip 1.75 messages which are timestamped using block height instead of Unix timestamps. --- lnwire/extra_bytes.go | 16 ++++++ lnwire/gossip_timestamp_range.go | 97 ++++++++++++++++++++++++++++++-- lnwire/lnwire_test.go | 22 ++++++++ 3 files changed, 130 insertions(+), 5 deletions(-) diff --git a/lnwire/extra_bytes.go b/lnwire/extra_bytes.go index 8f5668efa0..b2a12a4602 100644 --- a/lnwire/extra_bytes.go +++ b/lnwire/extra_bytes.go @@ -139,3 +139,19 @@ func EncodeMessageExtraData(extraData *ExtraOpaqueData, // are all properly sorted. return extraData.PackRecordsFromProducers(recordProducers...) } + +// EncodeMessageExtraDataFromRecords encodes the given records into the given +// extraData. +func EncodeMessageExtraDataFromRecords(extraData *ExtraOpaqueData, + records ...tlv.Record) error { + + // Treat extraData as a mutable reference. + if extraData == nil { + return fmt.Errorf("extra data cannot be nil") + } + + // Pack in the series of TLV records into this message. The order we + // pass them in doesn't matter, as the method will ensure that things + // are all properly sorted. + return extraData.PackRecords(records...) +} diff --git a/lnwire/gossip_timestamp_range.go b/lnwire/gossip_timestamp_range.go index d2dbddecbc..6e60654b1a 100644 --- a/lnwire/gossip_timestamp_range.go +++ b/lnwire/gossip_timestamp_range.go @@ -5,6 +5,17 @@ import ( "io" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightningnetwork/lnd/tlv" +) + +const ( + // TimeStampRangeFirstBlockType is the TLV type number of the + // GossipTimestampRange FirstTimestamp field. + TimeStampRangeFirstBlockType tlv.Type = 2 + + // TimeStampRangeBlockRangeType is the TLV type number of the + // GossipTimestampRange BlockRange field. + TimeStampRangeBlockRangeType tlv.Type = 4 ) // GossipTimestampRange is a message that allows the sender to restrict the set @@ -17,15 +28,31 @@ type GossipTimestampRange struct { ChainHash chainhash.Hash // FirstTimestamp is the timestamp of the earliest announcement message - // that should be sent by the receiver. + // that should be sent by the receiver. This is only to be used for + // querying message of gossip 1.0 which are timestamped using Unix + // timestamps. FirstBlockHeight and BlockRange should be used to + // query for announcement messages timestamped using block heights. FirstTimestamp uint32 // TimestampRange is the horizon beyond the FirstTimestamp that any // announcement messages should be sent for. The receiving node MUST // NOT send any announcements that have a timestamp greater than - // FirstTimestamp + TimestampRange. + // FirstTimestamp + TimestampRange. This is used together with + // FirstTimestamp to query for gossip 1.0 messages timestamped with + // Unix timestamps. TimestampRange uint32 + // FirstBlockHeight is the height of earliest announcement message that + // should be sent by the receiver. This is used only for querying + // announcement messages that use block heights as a timestamp. + FirstBlockHeight *uint32 + + // BlockRange is the horizon beyond FirstBlockHeight that any + // announcement messages should be sent for. The receiving node MUST NOT + // send any announcements that have a timestamp greater than + // FirstBlockHeight + BlockRange. + BlockRange *uint32 + // ExtraData 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. @@ -45,13 +72,52 @@ var _ Message = (*GossipTimestampRange)(nil) // passed io.Reader observing the specified protocol version. // // This is part of the lnwire.Message interface. -func (g *GossipTimestampRange) Decode(r io.Reader, pver uint32) error { - return ReadElements(r, +func (g *GossipTimestampRange) Decode(r io.Reader, _ uint32) error { + err := ReadElements(r, g.ChainHash[:], &g.FirstTimestamp, &g.TimestampRange, - &g.ExtraData, ) + if err != nil { + return err + } + + var ( + firstBlock uint32 + blockRange uint32 + ) + records := []tlv.Record{ + tlv.MakePrimitiveRecord( + TimeStampRangeFirstBlockType, &firstBlock, + ), + tlv.MakePrimitiveRecord( + TimeStampRangeBlockRangeType, &blockRange, + ), + } + + var tlvRecords ExtraOpaqueData + if err := ReadElements(r, &tlvRecords); err != nil { + return err + } + + typeMap, err := tlvRecords.ExtractRecords(records...) + if err != nil { + return err + } + + if _, ok := typeMap[TimeStampRangeFirstBlockType]; ok { + g.FirstBlockHeight = &firstBlock + } + + if _, ok := typeMap[TimeStampRangeBlockRangeType]; ok { + g.BlockRange = &blockRange + } + + if len(tlvRecords) != 0 { + g.ExtraData = tlvRecords + } + + return nil } // Encode serializes the target GossipTimestampRange into the passed io.Writer @@ -71,6 +137,27 @@ func (g *GossipTimestampRange) Encode(w *bytes.Buffer, pver uint32) error { return err } + var records []tlv.Record + + if g.FirstBlockHeight != nil { + records = append(records, tlv.MakePrimitiveRecord( + TimeStampRangeFirstBlockType, + g.FirstBlockHeight, + )) + } + + if g.BlockRange != nil { + records = append(records, tlv.MakePrimitiveRecord( + TimeStampRangeBlockRangeType, + g.BlockRange, + )) + } + + err := EncodeMessageExtraDataFromRecords(&g.ExtraData, records...) + if err != nil { + return err + } + return WriteBytes(w, g.ExtraData) } diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 27fcc7dd39..d0abcb0e67 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -995,6 +995,28 @@ func TestLightningWireProtocol(t *testing.T) { v[0] = reflect.ValueOf(req) }, + MsgGossipTimestampRange: func(v []reflect.Value, r *rand.Rand) { + req := GossipTimestampRange{ + FirstTimestamp: rand.Uint32(), + TimestampRange: rand.Uint32(), + FirstBlockHeight: nil, + BlockRange: nil, + ExtraData: make([]byte, 0), + } + + _, err := rand.Read(req.ChainHash[:]) + require.NoError(t, err) + + // Sometimes add a block range. + if r.Int31()%2 == 0 { + firstBlock := rand.Uint32() + blockRange := rand.Uint32() + req.FirstBlockHeight = &firstBlock + req.BlockRange = &blockRange + } + + v[0] = reflect.ValueOf(req) + }, MsgQueryShortChanIDs: func(v []reflect.Value, r *rand.Rand) { req := QueryShortChanIDs{ ExtraData: make([]byte, 0), From 7bc9dcf4316b34baa9cc5744b425e6bfcf3e3e4f Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 12:17:12 +0200 Subject: [PATCH 12/20] lnwire: add AnnounceSignatures interface Add a AnnounceSignatures interface and ensure that AnnounceSignatures1 implements it. --- lnwire/announcement_signatures.go | 22 ++++++++++++++++++++-- lnwire/interfaces.go | 13 +++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 lnwire/interfaces.go diff --git a/lnwire/announcement_signatures.go b/lnwire/announcement_signatures.go index 3f0e72803d..a2bc21f39d 100644 --- a/lnwire/announcement_signatures.go +++ b/lnwire/announcement_signatures.go @@ -47,11 +47,15 @@ type AnnounceSignatures1 struct { // lnwire.Message interface. var _ Message = (*AnnounceSignatures1)(nil) +// A compile time check to ensure AnnounceSignatures1 implements the +// lnwire.AnnounceSignatures interface. +var _ AnnounceSignatures = (*AnnounceSignatures1)(nil) + // Decode deserializes a serialized AnnounceSignatures1 stored in the passed // io.Reader observing the specified protocol version. // // This is part of the lnwire.Message interface. -func (a *AnnounceSignatures1) Decode(r io.Reader, pver uint32) error { +func (a *AnnounceSignatures1) Decode(r io.Reader, _ uint32) error { return ReadElements(r, &a.ChannelID, &a.ShortChannelID, @@ -65,7 +69,7 @@ func (a *AnnounceSignatures1) Decode(r io.Reader, pver uint32) error { // observing the protocol version specified. // // This is part of the lnwire.Message interface. -func (a *AnnounceSignatures1) Encode(w *bytes.Buffer, pver uint32) error { +func (a *AnnounceSignatures1) Encode(w *bytes.Buffer, _ uint32) error { if err := WriteChannelID(w, a.ChannelID); err != nil { return err } @@ -92,3 +96,17 @@ func (a *AnnounceSignatures1) Encode(w *bytes.Buffer, pver uint32) error { func (a *AnnounceSignatures1) MsgType() MessageType { return MsgAnnounceSignatures } + +// SCID returns the ShortChannelID of the channel. +// +// This is part of the lnwire.AnnounceSignatures interface. +func (a *AnnounceSignatures1) SCID() ShortChannelID { + return a.ShortChannelID +} + +// ChanID returns the ChannelID identifying the channel. +// +// This is part of the lnwire.AnnounceSignatures interface. +func (a *AnnounceSignatures1) ChanID() ChannelID { + return a.ChannelID +} diff --git a/lnwire/interfaces.go b/lnwire/interfaces.go new file mode 100644 index 0000000000..f8e4373c38 --- /dev/null +++ b/lnwire/interfaces.go @@ -0,0 +1,13 @@ +package lnwire + +// AnnounceSignatures is an interface that represents a message used to +// exchange signatures of a ChannelAnnouncment message during the funding flow. +type AnnounceSignatures interface { + // SCID returns the ShortChannelID of the channel. + SCID() ShortChannelID + + // ChanID returns the ChannelID identifying the channel. + ChanID() ChannelID + + Message +} From 03347bff61a0c0d14fee2c820d71919370b0e424 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 12:19:23 +0200 Subject: [PATCH 13/20] lnwire: add a ChannelAnnouncement interface Add a new ChannelAnnouncement interface and ensure that ChannelAnnouncement1 implements it. --- lnwire/channel_announcement.go | 35 ++++++++++++++++++++++++++++++++++ lnwire/interfaces.go | 23 ++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/lnwire/channel_announcement.go b/lnwire/channel_announcement.go index 86d3335614..aca1e1119e 100644 --- a/lnwire/channel_announcement.go +++ b/lnwire/channel_announcement.go @@ -184,3 +184,38 @@ func (a *ChannelAnnouncement1) DataToSign() ([]byte, error) { return buf.Bytes(), nil } + +// Node1KeyBytes returns the bytes representing the public key of node 1 in the +// channel. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (a *ChannelAnnouncement1) Node1KeyBytes() [33]byte { + return a.NodeID1 +} + +// Node2KeyBytes returns the bytes representing the public key of node 2 in the +// channel. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (a *ChannelAnnouncement1) Node2KeyBytes() [33]byte { + return a.NodeID2 +} + +// GetChainHash returns the hash of the chain which this channel's funding +// transaction is confirmed in. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (a *ChannelAnnouncement1) GetChainHash() chainhash.Hash { + return a.ChainHash +} + +// SCID returns the short channel ID of the channel. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (a *ChannelAnnouncement1) SCID() ShortChannelID { + return a.ShortChannelID +} + +// A compile-time check to ensure that ChannelAnnouncement1 implements the +// ChannelAnnouncement interface. +var _ ChannelAnnouncement = (*ChannelAnnouncement1)(nil) diff --git a/lnwire/interfaces.go b/lnwire/interfaces.go index f8e4373c38..693c6ca719 100644 --- a/lnwire/interfaces.go +++ b/lnwire/interfaces.go @@ -1,5 +1,7 @@ package lnwire +import "github.com/btcsuite/btcd/chaincfg/chainhash" + // AnnounceSignatures is an interface that represents a message used to // exchange signatures of a ChannelAnnouncment message during the funding flow. type AnnounceSignatures interface { @@ -11,3 +13,24 @@ type AnnounceSignatures interface { Message } + +// ChannelAnnouncement is an interface that must be satisfied by any message +// used to announce and prove the existence of a channel. +type ChannelAnnouncement interface { + // SCID returns the short channel ID of the channel. + SCID() ShortChannelID + + // GetChainHash returns the hash of the chain which this channel's + // funding transaction is confirmed in. + GetChainHash() chainhash.Hash + + // Node1KeyBytes returns the bytes representing the public key of node + // 1 in the channel. + Node1KeyBytes() [33]byte + + // Node2KeyBytes returns the bytes representing the public key of node + // 2 in the channel. + Node2KeyBytes() [33]byte + + Message +} From 804f7f897caa7a80e39c455cf2ddf232c0632546 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 13:14:29 +0200 Subject: [PATCH 14/20] lnwire: add a ChannelUpdate interface In this commit, a new ChannelUpdate interface is added and ChannelUpdate1 is made to implement the new interface. --- lnwire/channel_update.go | 103 +++++++++++++++++++++++++++++++++++++++ lnwire/interfaces.go | 75 +++++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/lnwire/channel_update.go b/lnwire/channel_update.go index 95f946da07..b9cf206810 100644 --- a/lnwire/channel_update.go +++ b/lnwire/channel_update.go @@ -6,6 +6,7 @@ import ( "io" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightningnetwork/lnd/input" ) // ChanUpdateMsgFlags is a bitfield that signals whether optional fields are @@ -279,3 +280,105 @@ func (a *ChannelUpdate1) DataToSign() ([]byte, error) { return buf.Bytes(), nil } + +// SCID returns the ShortChannelID of the channel that the update applies to. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) SCID() ShortChannelID { + return a.ShortChannelID +} + +// IsNode1 is true if the update was produced by node 1 of the channel peers. +// Node 1 is the node with the lexicographically smaller public key. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) IsNode1() bool { + return a.ChannelFlags&ChanUpdateDirection == 0 +} + +// IsDisabled is true if the update is announcing that the channel should be +// considered disabled. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) IsDisabled() bool { + return a.ChannelFlags&ChanUpdateDisabled == ChanUpdateDisabled +} + +// GetChainHash returns the hash of the chain that the message is referring to. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) GetChainHash() chainhash.Hash { + return a.ChainHash +} + +// ForwardingPolicy returns the set of forwarding constraints of the update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) ForwardingPolicy() *ForwardingPolicy { + return &ForwardingPolicy{ + TimeLockDelta: a.TimeLockDelta, + BaseFee: MilliSatoshi(a.BaseFee), + FeeRate: MilliSatoshi(a.FeeRate), + MinHTLC: a.HtlcMinimumMsat, + HasMaxHTLC: a.MessageFlags.HasMaxHtlc(), + MaxHTLC: a.HtlcMaximumMsat, + } +} + +// CmpAge can be used to determine if the update is older or newer than the +// passed update. It returns 1 if this update is newer, -1 if it is older, and +// 0 if they are the same age. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) CmpAge(update ChannelUpdate) (int, error) { + other, ok := update.(*ChannelUpdate1) + if !ok { + return 0, fmt.Errorf("expected *ChannelUpdate1, got: %T", + update) + } + + switch { + case a.Timestamp > other.Timestamp: + return 1, nil + case a.Timestamp < other.Timestamp: + return -1, nil + default: + return 0, nil + } +} + +// SetDisabled can be used to adjust the disabled flag of an update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) SetDisabled(disabled bool) { + if disabled { + a.ChannelFlags |= ChanUpdateDisabled + } else { + a.ChannelFlags &= ^ChanUpdateDisabled + } +} + +// SetSig can be used to adjust the signature of the update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) SetSig(sig input.Signature) error { + s, err := NewSigFromSignature(sig) + if err != nil { + return err + } + + a.Signature = s + + return nil +} + +// SetSCID can be used to overwrite the SCID of the update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (a *ChannelUpdate1) SetSCID(scid ShortChannelID) { + a.ShortChannelID = scid +} + +// A compile time assertion to ensure ChannelUpdate1 implements the +// ChannelUpdate interface. +var _ ChannelUpdate = (*ChannelUpdate1)(nil) diff --git a/lnwire/interfaces.go b/lnwire/interfaces.go index 693c6ca719..02bb9a7ded 100644 --- a/lnwire/interfaces.go +++ b/lnwire/interfaces.go @@ -1,6 +1,9 @@ package lnwire -import "github.com/btcsuite/btcd/chaincfg/chainhash" +import ( + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightningnetwork/lnd/input" +) // AnnounceSignatures is an interface that represents a message used to // exchange signatures of a ChannelAnnouncment message during the funding flow. @@ -34,3 +37,73 @@ type ChannelAnnouncement interface { Message } + +// ChannelUpdate is an interface that describes a message used to update the +// forwarding rules of a channel. +type ChannelUpdate interface { + // SCID returns the ShortChannelID of the channel that the update + // applies to. + SCID() ShortChannelID + + // IsNode1 is true if the update was produced by node 1 of the channel + // peers. Node 1 is the node with the lexicographically smaller public + // key. + IsNode1() bool + + // IsDisabled is true if the update is announcing that the channel + // should be considered disabled. + IsDisabled() bool + + // GetChainHash returns the hash of the chain that the message is + // referring to. + GetChainHash() chainhash.Hash + + // ForwardingPolicy returns the set of forwarding constraints of the + // update. + ForwardingPolicy() *ForwardingPolicy + + // CmpAge can be used to determine if the update is older or newer than + // the passed update. It returns 1 if this update is newer, -1 if it is + // older and 0 if they are the same age. + CmpAge(update ChannelUpdate) (int, error) + + // SetDisabled can be used to adjust the disabled flag of an update. + SetDisabled(bool) + + // SetSig can be used to adjust the signature of the update. + SetSig(signature input.Signature) error + + // SetSCID can be used to overwrite the SCID of the update. + SetSCID(scid ShortChannelID) + + Message +} + +// ForwardingPolicy defines the set of forwarding constraints advertised in a +// ChannelUpdate message. +type ForwardingPolicy struct { + // TimeLockDelta is the minimum number of blocks that the node requires + // to be added to the expiry of HTLCs. This is a security parameter + // determined by the node operator. This value represents the required + // gap between the time locks of the incoming and outgoing HTLC's set + // to this node. + TimeLockDelta uint16 + + // BaseFee is the base fee that must be used for incoming HTLC's to + // this particular channel. This value will be tacked onto the required + // for a payment independent of the size of the payment. + BaseFee MilliSatoshi + + // FeeRate is the fee rate that will be charged per millionth of a + // satoshi. + FeeRate MilliSatoshi + + // HtlcMinimumMsat is the minimum HTLC value which will be accepted. + MinHTLC MilliSatoshi + + // HasMaxHTLC is true if the MaxHTLC field is provided in the update. + HasMaxHTLC bool + + // HtlcMaximumMsat is the maximum HTLC value which will be accepted. + MaxHTLC MilliSatoshi +} From c45525fc07db4366a0f23bf828097462f27e8c4c Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 26 Oct 2023 14:06:39 +0200 Subject: [PATCH 15/20] lnwire: add MsgHash helper This commit adds the MsgHash helper funcion which can be used to calculate the digest of a message to be signed using schnorr signatures. --- lnwire/msg_hash.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 lnwire/msg_hash.go diff --git a/lnwire/msg_hash.go b/lnwire/msg_hash.go new file mode 100644 index 0000000000..b9f8785753 --- /dev/null +++ b/lnwire/msg_hash.go @@ -0,0 +1,26 @@ +package lnwire + +import ( + "github.com/btcsuite/btcd/chaincfg/chainhash" +) + +// MsgHashTag is will prefix the message name and the field name in order to +// construct the message tag. +const MsgHashTag = "lightning" + +func MsgTag(msgName, fieldName string) []byte { + tag := []byte(MsgHashTag) + tag = append(tag, []byte(msgName)...) + + return append(tag, []byte(fieldName)...) +} + +// MsgHash computes the tagged hash of the given message as follows: +// +// tag = "lightning"||"msg_name"||"field_name" +// hash = sha256(sha246(tag) || sha256(tag) || msg) +func MsgHash(msgName, fieldName string, msg []byte) *chainhash.Hash { + tag := MsgTag(msgName, fieldName) + + return chainhash.TaggedHash(tag, msg) +} From 9d0c37213aaeda426ab47569ec2d4ab8cd23c6d4 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 10:22:25 +0200 Subject: [PATCH 16/20] lnwire: add AnnounceSignatures2 message And ensure that it implements the AnnounceSignatures interface. --- lnwire/announcement_signatures_2.go | 90 +++++++++++++++++++++++++++++ lnwire/lnwire.go | 19 ++++++ lnwire/lnwire_test.go | 35 +++++++++++ lnwire/message.go | 5 ++ lnwire/writer.go | 8 +++ 5 files changed, 157 insertions(+) create mode 100644 lnwire/announcement_signatures_2.go diff --git a/lnwire/announcement_signatures_2.go b/lnwire/announcement_signatures_2.go new file mode 100644 index 0000000000..14552764b2 --- /dev/null +++ b/lnwire/announcement_signatures_2.go @@ -0,0 +1,90 @@ +package lnwire + +import ( + "bytes" + "io" +) + +// AnnounceSignatures2 is a direct message between two endpoints of a +// channel and serves as an opt-in mechanism to allow the announcement of +// a taproot channel to the rest of the network. It contains the necessary +// signatures by the sender to construct the channel_announcement_ message. +type AnnounceSignatures2 struct { + // ChannelID is the unique description of the funding transaction. + // Channel id is better for users and debugging and short channel id is + // used for quick test on existence of the particular utxo inside the + // blockchain, because it contains information about block. + ChannelID ChannelID + + // ShortChannelID is the unique description of the funding transaction. + // It is constructed with the most significant 3 bytes as the block + // height, the next 3 bytes indicating the transaction index within the + // block, and the least significant two bytes indicating the output + // index which pays to the channel. + ShortChannelID ShortChannelID + + // PartialSignature is the combination of the partial Schnorr signature + // created for the node's bitcoin key with the partial signature created + // for the node's node ID key. + PartialSignature PartialSig + + // ExtraOpaqueData is the set of data that was appended to this + // message, some of which we may not actually know how to iterate or + // parse. By holding onto this data, we ensure that we're able to + // properly validate the set of signatures that cover these new fields, + // and ensure we're able to make upgrades to the network in a forwards + // compatible manner. + ExtraOpaqueData ExtraOpaqueData +} + +// A compile time check to ensure AnnounceSignatures2 implements the +// lnwire.Message interface. +var _ Message = (*AnnounceSignatures2)(nil) + +// Decode deserializes a serialized AnnounceSignatures2 stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures2) Decode(r io.Reader, _ uint32) error { + return ReadElements(r, + &a.ChannelID, + &a.ShortChannelID, + &a.PartialSignature, + &a.ExtraOpaqueData, + ) +} + +// Encode serializes the target AnnounceSignatures2 into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error { + return WriteElements(w, + a.ChannelID, + a.ShortChannelID, + a.PartialSignature, + a.ExtraOpaqueData, + ) +} + +// MsgType returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures2) MsgType() MessageType { + return MsgAnnounceSignatures2 +} + +// SCID returns the ShortChannelID of the channel. +// +// NOTE: this is part of the AnnounceSignatures interface. +func (a *AnnounceSignatures2) SCID() ShortChannelID { + return a.ShortChannelID +} + +// ChanID returns the ChannelID identifying the channel. +// +// NOTE: this is part of the AnnounceSignatures interface. +func (a *AnnounceSignatures2) ChanID() ChannelID { + return a.ChannelID +} diff --git a/lnwire/lnwire.go b/lnwire/lnwire.go index 46257cce51..79fec5d3b0 100644 --- a/lnwire/lnwire.go +++ b/lnwire/lnwire.go @@ -457,6 +457,12 @@ func WriteElement(w *bytes.Buffer, element interface{}) error { return err } + case PartialSig: + sigBytes := e.Sig.Bytes() + if _, err := w.Write(sigBytes[:]); err != nil { + return err + } + case ExtraOpaqueData: return e.Encode(w) @@ -928,6 +934,19 @@ func ReadElement(r io.Reader, element interface{}) error { } *e = addrBytes[:length] + case *PartialSig: + var sBytes [32]byte + if _, err := io.ReadFull(r, sBytes[:]); err != nil { + return err + } + + var s btcec.ModNScalar + s.SetBytes(&sBytes) + + *e = PartialSig{ + Sig: s, + } + case *ExtraOpaqueData: return e.Decode(r) diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index d0abcb0e67..79d3059aa0 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -1088,6 +1088,35 @@ func TestLightningWireProtocol(t *testing.T) { PaddingBytes: paddingBytes, } + v[0] = reflect.ValueOf(req) + }, + MsgAnnounceSignatures2: func(v []reflect.Value, + r *rand.Rand) { + + req := AnnounceSignatures2{ + ShortChannelID: NewShortChanIDFromInt( + uint64(r.Int63()), + ), + ExtraOpaqueData: make([]byte, 0), + } + + _, err := r.Read(req.ChannelID[:]) + require.NoError(t, err) + + partialSig, err := randPartialSig(r) + require.NoError(t, err) + + req.PartialSignature = *partialSig + + numExtraBytes := r.Int31n(1000) + if numExtraBytes > 0 { + req.ExtraOpaqueData = make( + []byte, numExtraBytes, + ) + _, err := r.Read(req.ExtraOpaqueData[:]) + require.NoError(t, err) + } + v[0] = reflect.ValueOf(req) }, } @@ -1276,6 +1305,12 @@ func TestLightningWireProtocol(t *testing.T) { return mainScenario(&m) }, }, + { + msgType: MsgAnnounceSignatures2, + scenario: func(m AnnounceSignatures2) bool { + return mainScenario(&m) + }, + }, } for _, test := range tests { var config *quick.Config diff --git a/lnwire/message.go b/lnwire/message.go index 795a9e6ac8..316fb30360 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -46,6 +46,7 @@ const ( MsgNodeAnnouncement = 257 MsgChannelUpdate = 258 MsgAnnounceSignatures = 259 + MsgAnnounceSignatures2 = 260 MsgQueryShortChanIDs = 261 MsgReplyShortChanIDsEnd = 262 MsgQueryChannelRange = 263 @@ -134,6 +135,8 @@ func (t MessageType) String() string { return "ReplyChannelRange" case MsgGossipTimestampRange: return "GossipTimestampRange" + case MsgAnnounceSignatures2: + return "MsgAnnounceSignatures2" default: return "" } @@ -236,6 +239,8 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { msg = &ReplyChannelRange{} case MsgGossipTimestampRange: msg = &GossipTimestampRange{} + case MsgAnnounceSignatures2: + msg = &AnnounceSignatures2{} default: // If the message is not within our custom range and has not // specifically been overridden, return an unknown message. diff --git a/lnwire/writer.go b/lnwire/writer.go index 671ebfdc00..c98bd9cbde 100644 --- a/lnwire/writer.go +++ b/lnwire/writer.go @@ -173,6 +173,14 @@ func WriteSigs(buf *bytes.Buffer, sigs []Sig) error { return nil } +// WritePartialSig appends the serialised partial signature to the provided +// buffer. +func WritePartialSig(buf *bytes.Buffer, sig PartialSig) error { + sigBytes := sig.Sig.Bytes() + + return WriteBytes(buf, sigBytes[:]) +} + // WriteFailCode appends the FailCode to the provided buffer. func WriteFailCode(buf *bytes.Buffer, e FailCode) error { return WriteUint16(buf, uint16(e)) From 0f129a469c0316d11c28ef2323ce7004bdae6ae7 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 10:33:24 +0200 Subject: [PATCH 17/20] lnwire: add ChannelAnnouncement2 message And ensure that it implements the ChannelAnnouncement interface. --- lnwire/channel_announcement_2.go | 331 +++++++++++++++++++++++++++++++ lnwire/lnwire_test.go | 136 +++++++++---- lnwire/message.go | 5 + 3 files changed, 428 insertions(+), 44 deletions(-) create mode 100644 lnwire/channel_announcement_2.go diff --git a/lnwire/channel_announcement_2.go b/lnwire/channel_announcement_2.go new file mode 100644 index 0000000000..c1e8ff9f58 --- /dev/null +++ b/lnwire/channel_announcement_2.go @@ -0,0 +1,331 @@ +package lnwire + +import ( + "bytes" + "io" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightningnetwork/lnd/tlv" +) + +const ( + // ChanAnn2ChainHashType is the tlv number associated with the chain + // hash TLV record in the channel_announcement_2 message. + ChanAnn2ChainHashType = tlv.Type(0) + + // ChanAnn2FeaturesType is the tlv number associated with the features + // TLV record in the channel_announcement_2 message. + ChanAnn2FeaturesType = tlv.Type(2) + + // ChanAnn2SCIDType is the tlv number associated with the SCID TLV + // record in the channel_announcement_2 message. + ChanAnn2SCIDType = tlv.Type(4) + + // ChanAnn2CapacityType is the tlv number associated with the capacity + // TLV record in the channel_announcement_2 message. + ChanAnn2CapacityType = tlv.Type(6) + + // ChanAnn2NodeID1Type is the tlv number associated with the node ID 1 + // TLV record in the channel_announcement_2 message. + ChanAnn2NodeID1Type = tlv.Type(8) + + // ChanAnn2NodeID2Type is the tlv number associated with the node ID 2 + // record in the channel_announcement_2 message. + ChanAnn2NodeID2Type = tlv.Type(10) + + // ChanAnn2BtcKey1Type is the tlv number associated with the bitcoin ID + // 1 record in the channel_announcement_2 message. + ChanAnn2BtcKey1Type = tlv.Type(12) + + // ChanAnn2BtcKey2Type is the tlv number associated with the bitcoin ID + // 2 record in the channel_announcement_2 message. + ChanAnn2BtcKey2Type = tlv.Type(14) + + // ChanAnn2MerkleRootHashType is the tlv number associated with the + // merkle root hash record in the channel_announcement_2 message. + ChanAnn2MerkleRootHashType = tlv.Type(16) +) + +// ChannelAnnouncement2 message is used to announce the existence of a taproot +// channel between two peers in the network. +type ChannelAnnouncement2 struct { + // Signature is a Schnorr signature over the TLV stream of the message. + Signature Sig + + // ChainHash denotes the target chain that this channel was opened + // within. This value should be the genesis hash of the target chain. + ChainHash chainhash.Hash + + // Features is the feature vector that encodes the features supported + // by the target node. This field can be used to signal the type of the + // channel, or modifications to the fields that would normally follow + // this vector. + Features RawFeatureVector + + // ShortChannelID is the unique description of the funding transaction, + // or where exactly it's located within the target blockchain. + ShortChannelID ShortChannelID + + // Capacity is the number of satoshis of the capacity of this channel. + // It must be less than or equal to the value of the on-chain funding + // output. + Capacity uint64 + + // NodeID1 is the numerically-lesser public key ID of one of the channel + // operators. + NodeID1 [33]byte + + // NodeID2 is the numerically-greater public key ID of one of the + // channel operators. + NodeID2 [33]byte + + // BitcoinKey1 is the public key of the key used by Node1 in the + // construction of the on-chain funding transaction. This is an optional + // field and only needs to be set if the 4-of-4 MuSig construction was + // used in the creation of the message signature. + BitcoinKey1 *[33]byte + + // BitcoinKey2 is the public key of the key used by Node2 in the + // construction of the on-chain funding transaction. This is an optional + // field and only needs to be set if the 4-of-4 MuSig construction was + // used in the creation of the message signature. + BitcoinKey2 *[33]byte + + // MerkleRootHash is the hash used to create the optional tweak in the + // funding output. If this is not set but the bitcoin keys are, then + // the funding output is a pure 2-of-2 MuSig aggregate public key. + MerkleRootHash *[32]byte + + // ExtraOpaqueData is the set of data that was appended to this + // message, some of which we may not actually know how to iterate or + // parse. By holding onto this data, we ensure that we're able to + // properly validate the set of signatures that cover these new fields, + // and ensure we're able to make upgrades to the network in a forwards + // compatible manner. + ExtraOpaqueData ExtraOpaqueData +} + +// Decode deserializes a serialized AnnounceSignatures1 stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. +func (c *ChannelAnnouncement2) Decode(r io.Reader, _ uint32) error { + err := ReadElement(r, &c.Signature) + if err != nil { + return err + } + c.Signature.ForceSchnorr() + + return c.DecodeTLVRecords(r) +} + +// DecodeTLVRecords decodes only the TLV section of the message. +func (c *ChannelAnnouncement2) DecodeTLVRecords(r io.Reader) error { + // First extract into extra opaque data. + var tlvRecords ExtraOpaqueData + if err := ReadElements(r, &tlvRecords); err != nil { + return err + } + + featuresRecordProducer := NewRawFeatureVectorRecordProducer( + ChanAnn2FeaturesType, + ) + + scidRecordProducer := NewShortChannelIDRecordProducer( + ChanAnn2SCIDType, + ) + + var ( + chainHash, merkleRootHash [32]byte + btcKey1, btcKey2 [33]byte + ) + + records := []tlv.Record{ + tlv.MakePrimitiveRecord(ChanAnn2ChainHashType, &chainHash), + featuresRecordProducer.Record(), + scidRecordProducer.Record(), + tlv.MakePrimitiveRecord(ChanAnn2CapacityType, &c.Capacity), + tlv.MakePrimitiveRecord(ChanAnn2NodeID1Type, &c.NodeID1), + tlv.MakePrimitiveRecord(ChanAnn2NodeID2Type, &c.NodeID2), + tlv.MakePrimitiveRecord(ChanAnn2BtcKey1Type, &btcKey1), + tlv.MakePrimitiveRecord(ChanAnn2BtcKey2Type, &btcKey2), + tlv.MakePrimitiveRecord( + ChanAnn2MerkleRootHashType, &merkleRootHash, + ), + } + + typeMap, err := tlvRecords.ExtractRecords(records...) + if err != nil { + return err + } + + // By default, the chain-hash is the bitcoin mainnet genesis block hash. + c.ChainHash = *chaincfg.MainNetParams.GenesisHash + if _, ok := typeMap[ChanAnn2ChainHashType]; ok { + c.ChainHash = chainHash + } + + if _, ok := typeMap[ChanAnn2FeaturesType]; ok { + c.Features = featuresRecordProducer.RawFeatureVector + } + + if _, ok := typeMap[ChanAnn2SCIDType]; ok { + c.ShortChannelID = scidRecordProducer.ShortChannelID + } + + if _, ok := typeMap[ChanAnn2BtcKey1Type]; ok { + c.BitcoinKey1 = &btcKey1 + } + + if _, ok := typeMap[ChanAnn2BtcKey2Type]; ok { + c.BitcoinKey2 = &btcKey2 + } + + if _, ok := typeMap[ChanAnn2MerkleRootHashType]; ok { + c.MerkleRootHash = &merkleRootHash + } + + if len(tlvRecords) != 0 { + c.ExtraOpaqueData = tlvRecords + } + + return nil +} + +// Encode serializes the target AnnounceSignatures1 into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. +func (c *ChannelAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error { + _, err := w.Write(c.Signature.RawBytes()) + if err != nil { + return err + } + _, err = c.DataToSign() + if err != nil { + return err + } + + return WriteBytes(w, c.ExtraOpaqueData) +} + +// DigestToSign computes the digest of the message to be signed. +func (c *ChannelAnnouncement2) DigestToSign() (*chainhash.Hash, error) { + data, err := c.DataToSign() + if err != nil { + return nil, err + } + + hash := MsgHash( + "channel_announcement_2", "announcement_signature", data, + ) + + return hash, nil +} + +// DataToSign encodes the data to be signed into the ExtraOpaqueData member and +// returns it. +func (c *ChannelAnnouncement2) DataToSign() ([]byte, error) { + // The chain-hash record is only included if it is _not_ equal to the + // bitcoin mainnet genisis block hash. + var records []tlv.Record + if !c.ChainHash.IsEqual(chaincfg.MainNetParams.GenesisHash) { + chainHash := [32]byte(c.ChainHash) + records = append(records, tlv.MakePrimitiveRecord( + ChanAnn2ChainHashType, &chainHash, + )) + } + + featuresRecordProducer := &RawFeatureVectorRecordProducer{ + RawFeatureVector: c.Features, + Type: ChanAnn2FeaturesType, + } + + scidRecordProducer := &ShortChannelIDRecordProducer{ + ShortChannelID: c.ShortChannelID, + Type: ChanAnn2SCIDType, + } + + records = append(records, + featuresRecordProducer.Record(), + scidRecordProducer.Record(), + tlv.MakePrimitiveRecord(ChanAnn2CapacityType, &c.Capacity), + tlv.MakePrimitiveRecord(ChanAnn2NodeID1Type, &c.NodeID1), + tlv.MakePrimitiveRecord(ChanAnn2NodeID2Type, &c.NodeID2), + ) + + if c.BitcoinKey1 != nil && c.BitcoinKey2 != nil { + records = append(records, + tlv.MakePrimitiveRecord( + ChanAnn2BtcKey1Type, c.BitcoinKey1, + ), + tlv.MakePrimitiveRecord( + ChanAnn2BtcKey2Type, c.BitcoinKey2, + ), + ) + + if c.MerkleRootHash != nil { + records = append(records, + tlv.MakePrimitiveRecord( + ChanAnn2MerkleRootHashType, + c.MerkleRootHash, + ), + ) + } + } + + err := EncodeMessageExtraDataFromRecords(&c.ExtraOpaqueData, records...) + if err != nil { + return nil, err + } + + return c.ExtraOpaqueData, nil +} + +// MsgType returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. +func (c *ChannelAnnouncement2) MsgType() MessageType { + return MsgChannelAnnouncement2 +} + +// A compile time check to ensure ChannelAnnouncement2 implements the +// lnwire.Message interface. +var _ Message = (*ChannelAnnouncement2)(nil) + +// Node1KeyBytes returns the bytes representing the public key of node 1 in the +// channel. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (c *ChannelAnnouncement2) Node1KeyBytes() [33]byte { + return c.NodeID1 +} + +// Node2KeyBytes returns the bytes representing the public key of node 2 in the +// channel. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (c *ChannelAnnouncement2) Node2KeyBytes() [33]byte { + return c.NodeID2 +} + +// GetChainHash returns the hash of the chain which this channel's funding +// transaction is confirmed in. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (c *ChannelAnnouncement2) GetChainHash() chainhash.Hash { + return c.ChainHash +} + +// SCID returns the short channel ID of the channel. +// +// NOTE: This is part of the ChannelAnnouncement interface. +func (c *ChannelAnnouncement2) SCID() ShortChannelID { + return c.ShortChannelID +} + +// A compile-time check to ensure that ChannelAnnouncement2 implements the +// ChannelAnnouncement interface. +var _ ChannelAnnouncement = (*ChannelAnnouncement2)(nil) diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 79d3059aa0..689c1f45f5 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -18,6 +18,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/ecdsa" "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/tor" @@ -26,17 +27,25 @@ import ( ) var ( - shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - shaHash1, _ = chainhash.NewHash(shaHash1Bytes) - outpoint1 = wire.NewOutPoint(shaHash1, 0) - - testRBytes, _ = hex.DecodeString("8ce2bc69281ce27da07e6683571319d18e949ddfa2965fb6caa1bf0314f882d7") - testSBytes, _ = hex.DecodeString("299105481d63e0f4bc2a88121167221b6700d72a0ead154c03be696a292d24ae") - testRScalar = new(btcec.ModNScalar) - testSScalar = new(btcec.ModNScalar) - _ = testRScalar.SetByteSlice(testRBytes) - _ = testSScalar.SetByteSlice(testSBytes) - testSig = ecdsa.NewSignature(testRScalar, testSScalar) + shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb" + + "92427ae41e4649b934ca495991b7852b855") + + shaHash1, _ = chainhash.NewHash(shaHash1Bytes) + outpoint1 = wire.NewOutPoint(shaHash1, 0) + + testRBytes, _ = hex.DecodeString("8ce2bc69281ce27da07e6683571" + + "319d18e949ddfa2965fb6caa1bf0314f882d7") + testSBytes, _ = hex.DecodeString("299105481d63e0f4bc2a" + + "88121167221b6700d72a0ead154c03be696a292d24ae") + testRScalar = new(btcec.ModNScalar) + testSScalar = new(btcec.ModNScalar) + _ = testRScalar.SetByteSlice(testRBytes) + _ = testSScalar.SetByteSlice(testSBytes) + testSig = ecdsa.NewSignature(testRScalar, testSScalar) + testSchnorrSigStr, _ = hex.DecodeString("04E7F9037658A92AFEB4F2" + + "5BAE5339E3DDCA81A353493827D26F16D92308E49E2A25E9220867" + + "8A2DF86970DA91B03A8AF8815A8A60498B358DAF560B347AA557") + testSchnorrSig, _ = NewSigFromSchnorrRawSignature(testSchnorrSigStr) ) const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -95,17 +104,15 @@ func randPubKey() (*btcec.PublicKey, error) { return priv.PubKey(), nil } -func randRawKey() ([33]byte, error) { +func randRawKey(t *testing.T) [33]byte { var n [33]byte priv, err := btcec.NewPrivateKey() - if err != nil { - return n, err - } + require.NoError(t, err) copy(n[:], priv.PubKey().SerializeCompressed()) - return n, nil + return n } func randDeliveryAddress(r *rand.Rand) (DeliveryAddress, error) { @@ -774,7 +781,13 @@ func TestLightningWireProtocol(t *testing.T) { MsgChannelAnnouncement: func(v []reflect.Value, r *rand.Rand) { var err error req := ChannelAnnouncement1{ - ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), + ShortChannelID: NewShortChanIDFromInt( + uint64(r.Int63()), + ), + NodeID1: randRawKey(t), + NodeID2: randRawKey(t), + BitcoinKey1: randRawKey(t), + BitcoinKey2: randRawKey(t), Features: randRawFeatureVector(r), ExtraOpaqueData: make([]byte, 0), } @@ -799,26 +812,6 @@ func TestLightningWireProtocol(t *testing.T) { return } - req.NodeID1, err = randRawKey() - if err != nil { - t.Fatalf("unable to generate key: %v", err) - return - } - req.NodeID2, err = randRawKey() - if err != nil { - t.Fatalf("unable to generate key: %v", err) - return - } - req.BitcoinKey1, err = randRawKey() - if err != nil { - t.Fatalf("unable to generate key: %v", err) - return - } - req.BitcoinKey2, err = randRawKey() - if err != nil { - t.Fatalf("unable to generate key: %v", err) - return - } if _, err := r.Read(req.ChainHash[:]); err != nil { t.Fatalf("unable to generate chain hash: %v", err) return @@ -840,6 +833,7 @@ func TestLightningWireProtocol(t *testing.T) { MsgNodeAnnouncement: func(v []reflect.Value, r *rand.Rand) { var err error req := NodeAnnouncement1{ + NodeID: randRawKey(t), Features: randRawFeatureVector(r), Timestamp: uint32(r.Int31()), Alias: randAlias(r), @@ -856,12 +850,6 @@ func TestLightningWireProtocol(t *testing.T) { return } - req.NodeID, err = randRawKey() - if err != nil { - t.Fatalf("unable to generate key: %v", err) - return - } - req.Addresses, err = randAddrs(r) if err != nil { t.Fatalf("unable to generate addresses: %v", err) @@ -895,7 +883,9 @@ func TestLightningWireProtocol(t *testing.T) { } req := ChannelUpdate1{ - ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), + ShortChannelID: NewShortChanIDFromInt( + uint64(r.Int63()), + ), Timestamp: uint32(r.Int31()), MessageFlags: msgFlags, ChannelFlags: ChanUpdateChanFlags(r.Int31()), @@ -1117,6 +1107,58 @@ func TestLightningWireProtocol(t *testing.T) { require.NoError(t, err) } + v[0] = reflect.ValueOf(req) + }, + MsgChannelAnnouncement2: func(v []reflect.Value, r *rand.Rand) { + req := ChannelAnnouncement2{ + Signature: testSchnorrSig, + ShortChannelID: NewShortChanIDFromInt( + uint64(r.Int63()), + ), + Capacity: rand.Uint64(), + NodeID1: randRawKey(t), + NodeID2: randRawKey(t), + ExtraOpaqueData: make([]byte, 0), + } + + features := randRawFeatureVector(r) + req.Features = *features + + // Sometimes set chain hash to bitcoin mainnet genesis + // hash. + req.ChainHash = *chaincfg.MainNetParams.GenesisHash + if r.Int31()%2 == 0 { + _, err := r.Read(req.ChainHash[:]) + require.NoError(t, err) + } + + // Sometimes set the bitcoin keys. + if r.Int31()%2 == 0 { + btcKey1 := randRawKey(t) + req.BitcoinKey1 = &btcKey1 + + btcKey2 := randRawKey(t) + req.BitcoinKey2 = &btcKey2 + + // Occasionally also set the merkle root hash. + if r.Int31()%2 == 0 { + var merkleRootHash [32]byte + _, err := r.Read(merkleRootHash[:]) + require.NoError(t, err) + + req.MerkleRootHash = &merkleRootHash + } + } + + numExtraBytes := r.Int31n(1000) + if numExtraBytes > 0 { + req.ExtraOpaqueData = make( + []byte, numExtraBytes, + ) + _, err := r.Read(req.ExtraOpaqueData[:]) + require.NoError(t, err) + } + v[0] = reflect.ValueOf(req) }, } @@ -1311,6 +1353,12 @@ func TestLightningWireProtocol(t *testing.T) { return mainScenario(&m) }, }, + { + msgType: MsgChannelAnnouncement2, + scenario: func(m ChannelAnnouncement2) bool { + return mainScenario(&m) + }, + }, } for _, test := range tests { var config *quick.Config diff --git a/lnwire/message.go b/lnwire/message.go index 316fb30360..b31baf35da 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -52,6 +52,7 @@ const ( MsgQueryChannelRange = 263 MsgReplyChannelRange = 264 MsgGossipTimestampRange = 265 + MsgChannelAnnouncement2 = 267 ) // ErrorEncodeMessage is used when failed to encode the message payload. @@ -137,6 +138,8 @@ func (t MessageType) String() string { return "GossipTimestampRange" case MsgAnnounceSignatures2: return "MsgAnnounceSignatures2" + case MsgChannelAnnouncement2: + return "ChannelAnnouncement2" default: return "" } @@ -241,6 +244,8 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { msg = &GossipTimestampRange{} case MsgAnnounceSignatures2: msg = &AnnounceSignatures2{} + case MsgChannelAnnouncement2: + msg = &ChannelAnnouncement2{} default: // If the message is not within our custom range and has not // specifically been overridden, return an unknown message. From 695c431c437967683cacfb9ef2ed2a119a542eed Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 11:13:53 +0200 Subject: [PATCH 18/20] lnwire: introduce the BooleanRecordProducer --- lnwire/boolean.go | 53 ++++++++++++++++++++++++++++++++++++++++++ lnwire/boolean_test.go | 40 +++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 lnwire/boolean.go create mode 100644 lnwire/boolean_test.go diff --git a/lnwire/boolean.go b/lnwire/boolean.go new file mode 100644 index 0000000000..00a474f357 --- /dev/null +++ b/lnwire/boolean.go @@ -0,0 +1,53 @@ +package lnwire + +import ( + "fmt" + "io" + + "github.com/lightningnetwork/lnd/tlv" +) + +// BooleanRecordProducer wraps a boolean with the tlv type it should be encoded +// with. A boolean is by default false, if the TLV is present then the boolean +// is true. +type BooleanRecordProducer struct { + Bool bool + Type tlv.Type +} + +// Record returns the tlv record for the boolean entry. +func (b *BooleanRecordProducer) Record() tlv.Record { + return tlv.MakeStaticRecord( + b.Type, &b.Bool, 0, booleanEncoder, booleanDecoder, + ) +} + +// NewBooleanRecordProducer constructs a new BooleanRecordProducer. +func NewBooleanRecordProducer(t tlv.Type) *BooleanRecordProducer { + return &BooleanRecordProducer{ + Type: t, + } +} + +func booleanEncoder(_ io.Writer, val interface{}, _ *[8]byte) error { + if v, ok := val.(*bool); ok { + if !*v { + return fmt.Errorf("a boolean record should only be " + + "encoded if the value of the boolean is true") + } + + return nil + } + + return tlv.NewTypeForEncodingErr(val, "bool") +} + +func booleanDecoder(_ io.Reader, val interface{}, _ *[8]byte, _ uint64) error { + if v, ok := val.(*bool); ok { + *v = true + + return nil + } + + return tlv.NewTypeForEncodingErr(val, "bool") +} diff --git a/lnwire/boolean_test.go b/lnwire/boolean_test.go new file mode 100644 index 0000000000..6aa0565de4 --- /dev/null +++ b/lnwire/boolean_test.go @@ -0,0 +1,40 @@ +package lnwire + +import ( + "testing" + + "github.com/lightningnetwork/lnd/tlv" + "github.com/stretchr/testify/require" +) + +// TestBooleanRecord tests the encoding and decoding of a boolean tlv record. +func TestBooleanRecord(t *testing.T) { + t.Parallel() + + const recordType = tlv.Type(0) + + b1 := BooleanRecordProducer{ + Bool: false, + Type: recordType, + } + + var extraData ExtraOpaqueData + + // A false boolean should not be encoded. + require.ErrorContains(t, extraData.PackRecordsFromProducers(&b1), + "a boolean record should only be encoded if the value of "+ + "the boolean is true") + + b2 := BooleanRecordProducer{ + Bool: true, + Type: recordType, + } + require.NoError(t, extraData.PackRecordsFromProducers(&b2)) + + b3 := NewBooleanRecordProducer(recordType) + tlvs, err := extraData.ExtractRecordsFromProducers(b3) + require.NoError(t, err) + + require.Contains(t, tlvs, recordType) + require.Equal(t, b2.Bool, b3.Bool) +} From 8c08665203dd3c6310a2e3b626b86599fce9d9ed Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 11:37:39 +0200 Subject: [PATCH 19/20] lnwire: add ChannelUpdate2 Add the new ChannelUpdate2 message and ensure that it implements the ChannelUpdate interface. --- lnwire/channel_update_2.go | 510 +++++++++++++++++++++++++++++++++++++ lnwire/lnwire_test.go | 68 +++++ lnwire/message.go | 5 + 3 files changed, 583 insertions(+) create mode 100644 lnwire/channel_update_2.go diff --git a/lnwire/channel_update_2.go b/lnwire/channel_update_2.go new file mode 100644 index 0000000000..1e6392116d --- /dev/null +++ b/lnwire/channel_update_2.go @@ -0,0 +1,510 @@ +package lnwire + +import ( + "bytes" + "fmt" + "io" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/tlv" +) + +const ( + // ChanUpdate2ChainHashType is the tlv number associated with the chain + // hash TLV record in the channel_update_2 message. + ChanUpdate2ChainHashType = tlv.Type(0) + + // ChanUpdate2SCIDType is the tlv number associated with the SCID TLV + // record in the channel_update_2 message. + ChanUpdate2SCIDType = tlv.Type(2) + + // ChanUpdate2BlockHeightType is the tlv number associated with the + // block height record in the channel_update_2 message. + ChanUpdate2BlockHeightType = tlv.Type(4) + + // ChanUpdate2DisableFlagsType is the tlv number associated with the + // disable flags record in the channel_update_2 message. + ChanUpdate2DisableFlagsType = tlv.Type(6) + + // ChanUpdate2DirectionType is the tlv number associated with the + // disable boolean TLV record in the channel_update_2 message. + ChanUpdate2DirectionType = tlv.Type(8) + + // ChanUpdate2CLTVExpiryDeltaType is the tlv number associated with the + // CLTV expiry delta TLV record in the channel_update_2 message. + ChanUpdate2CLTVExpiryDeltaType = tlv.Type(10) + + // ChanUpdate2HTLCMinMsatType is the tlv number associated with the htlc + // minimum msat record in the channel_update_2 message. + ChanUpdate2HTLCMinMsatType = tlv.Type(12) + + // ChanUpdate2HTLCMaxMsatType is the tlv number associated with the htlc + // maximum msat record in the channel_update_2 message. + ChanUpdate2HTLCMaxMsatType = tlv.Type(14) + + // ChanUpdate2FeeBaseMsatType is the tlv number associated with the fee + // base msat record in the channel_update_2 message. + ChanUpdate2FeeBaseMsatType = tlv.Type(16) + + // ChanUpdate2FeeProportionalMillionthsType is the tlv number associated + // with the fee proportional millionths record in the channel_update_2 + // message. + ChanUpdate2FeeProportionalMillionthsType = tlv.Type(18) + + defaultCltvExpiryDelta = uint16(80) + defaultHtlcMinMsat = MilliSatoshi(1) + defaultFeeBaseMsat = uint32(1000) + defaultFeeProportionalMillionths = uint32(1) +) + +// ChannelUpdate2 message is used after taproot channel has been initially +// announced. Each side independently announces its fees and minimum expiry for +// HTLCs and other parameters. Also this message is used to redeclare initially +// set channel parameters. +type ChannelUpdate2 struct { + // Signature is used to validate the announced data and prove the + // ownership of node id. + Signature Sig + + // ChainHash denotes the target chain that this channel was opened + // within. This value should be the genesis hash of the target chain. + // Along with the short channel ID, this uniquely identifies the + // channel globally in a blockchain. + ChainHash chainhash.Hash + + // ShortChannelID is the unique description of the funding transaction. + ShortChannelID ShortChannelID + + // BlockHeight allows ordering in the case of multiple announcements. We + // should ignore the message if block height is not greater than the + // last-received. The block height must always be greater or equal to + // the block height that the channel funding transaction was confirmed + // in. + BlockHeight uint32 + + // DisabledFlags is an optional bitfield that describes various reasons + // that the node is communicating that the channel should be considered + // disabled. + DisabledFlags ChanUpdateDisableFlags + + // Direction is false if this update was produced by node 1 of the + // channel announcement and true if it is from node 2. + Direction bool + + // CLTVExpiryDelta is the minimum number of blocks this node requires to + // be added to the expiry of HTLCs. This is a security parameter + // determined by the node operator. This value represents the required + // gap between the time locks of the incoming and outgoing HTLC's set + // to this node. + CLTVExpiryDelta uint16 + + // HTLCMinimumMsat is the minimum HTLC value which will be accepted. + HTLCMinimumMsat MilliSatoshi + + // HtlcMaximumMsat is the maximum HTLC value which will be accepted. + HTLCMaximumMsat MilliSatoshi + + // FeeBaseMsat is the base fee that must be used for incoming HTLC's to + // this particular channel. This value will be tacked onto the required + // for a payment independent of the size of the payment. + FeeBaseMsat uint32 + + // FeeProportionalMillionths is the fee rate that will be charged per + // millionth of a satoshi. + FeeProportionalMillionths uint32 + + // 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 ExtraOpaqueData +} + +// Decode deserializes a serialized ChannelUpdate2 stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. +func (c *ChannelUpdate2) Decode(r io.Reader, _ uint32) error { + err := ReadElement(r, &c.Signature) + if err != nil { + return err + } + c.Signature.ForceSchnorr() + + // First extract into extra opaque data. + var tlvRecords ExtraOpaqueData + if err := ReadElements(r, &tlvRecords); err != nil { + return err + } + + scidRecordProducer := NewShortChannelIDRecordProducer( + ChanUpdate2SCIDType, + ) + + directionRecordProducer := NewBooleanRecordProducer( + ChanUpdate2DirectionType, + ) + + var ( + chainHash [32]byte + htlcMin, htlcMax uint64 + disableFlags uint8 + ) + + records := []tlv.Record{ + tlv.MakePrimitiveRecord(ChanUpdate2ChainHashType, &chainHash), + scidRecordProducer.Record(), + tlv.MakePrimitiveRecord( + ChanUpdate2BlockHeightType, &c.BlockHeight, + ), + tlv.MakePrimitiveRecord( + ChanUpdate2DisableFlagsType, &disableFlags, + ), + directionRecordProducer.Record(), + tlv.MakePrimitiveRecord( + ChanUpdate2CLTVExpiryDeltaType, &c.CLTVExpiryDelta, + ), + tlv.MakePrimitiveRecord( + ChanUpdate2HTLCMinMsatType, &htlcMin, + ), + tlv.MakePrimitiveRecord( + ChanUpdate2HTLCMaxMsatType, &htlcMax, + ), + tlv.MakePrimitiveRecord( + ChanUpdate2FeeBaseMsatType, &c.FeeBaseMsat, + ), + tlv.MakePrimitiveRecord( + ChanUpdate2FeeProportionalMillionthsType, + &c.FeeProportionalMillionths, + ), + } + + typeMap, err := tlvRecords.ExtractRecords(records...) + if err != nil { + return err + } + + // By default, the chain-hash is the bitcoin mainnet genesis block hash. + c.ChainHash = *chaincfg.MainNetParams.GenesisHash + if _, ok := typeMap[ChanUpdate2ChainHashType]; ok { + c.ChainHash = chainHash + } + + if _, ok := typeMap[ChanUpdate2DisableFlagsType]; ok { + c.DisabledFlags = ChanUpdateDisableFlags(disableFlags) + } + + if _, ok := typeMap[ChanUpdate2SCIDType]; ok { + c.ShortChannelID = scidRecordProducer.ShortChannelID + } + + if _, ok := typeMap[ChanUpdate2DirectionType]; ok { + c.Direction = directionRecordProducer.Bool + } + + // If the CLTV expiry delta was not encoded, then set it to the default + // value. + if _, ok := typeMap[ChanUpdate2CLTVExpiryDeltaType]; !ok { + c.CLTVExpiryDelta = defaultCltvExpiryDelta + } + + c.HTLCMinimumMsat = defaultHtlcMinMsat + if _, ok := typeMap[ChanUpdate2HTLCMinMsatType]; ok { + c.HTLCMinimumMsat = MilliSatoshi(htlcMin) + } + + if _, ok := typeMap[ChanUpdate2HTLCMaxMsatType]; ok { + c.HTLCMaximumMsat = MilliSatoshi(htlcMax) + } + + // If the base fee was not encoded, then set it to the default value. + if _, ok := typeMap[ChanUpdate2FeeBaseMsatType]; !ok { + c.FeeBaseMsat = defaultFeeBaseMsat + } + + // If the proportional fee was not encoded, then set it to the default + // value. + if _, ok := typeMap[ChanUpdate2FeeProportionalMillionthsType]; !ok { + c.FeeProportionalMillionths = defaultFeeProportionalMillionths + } + + if len(tlvRecords) != 0 { + c.ExtraOpaqueData = tlvRecords + } + + return nil +} + +// Encode serializes the target ChannelUpdate2 into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. +func (c *ChannelUpdate2) Encode(w *bytes.Buffer, _ uint32) error { + _, err := w.Write(c.Signature.RawBytes()) + if err != nil { + return err + } + + _, err = c.DataToSign() + if err != nil { + return err + } + + return WriteBytes(w, c.ExtraOpaqueData) +} + +// DigestTag returns the tag to be used when signing the digest. +func (c *ChannelUpdate2) DigestTag() []byte { + return MsgTag("channel_announcement_2", "announcement_signature") +} + +// DigestToSign computes the digest of the message to be signed. +func (c *ChannelUpdate2) DigestToSign() ([]byte, error) { + data, err := c.DataToSign() + if err != nil { + return nil, err + } + + hash := MsgHash( + "channel_announcement_2", "announcement_signature", data, + ) + + return hash[:], nil +} + +// DataToSign is used to retrieve part of the announcement message which should +// be signed. For the ChannelUpdate2 message, this includes the serialised TLV +// records. +func (c *ChannelUpdate2) DataToSign() ([]byte, error) { + // The chain-hash record is only included if it is _not_ equal to the + // bitcoin mainnet genisis block hash. + var records []tlv.Record + if !c.ChainHash.IsEqual(chaincfg.MainNetParams.GenesisHash) { + chainHash := [32]byte(c.ChainHash) + records = append(records, tlv.MakePrimitiveRecord( + ChanUpdate2ChainHashType, &chainHash, + )) + } + + scidRecordProducer := &ShortChannelIDRecordProducer{ + ShortChannelID: c.ShortChannelID, + Type: ChanUpdate2SCIDType, + } + + records = append(records, + scidRecordProducer.Record(), + tlv.MakePrimitiveRecord( + ChanUpdate2BlockHeightType, &c.BlockHeight, + ), + ) + + // Only include the disable flags if any bit is set. + if !c.DisabledFlags.IsEnabled() { + disableFlags := uint8(c.DisabledFlags) + records = append(records, tlv.MakePrimitiveRecord( + ChanUpdate2DisableFlagsType, &disableFlags, + )) + } + + // We only need to encode the direction if the direction is set to 1. + if c.Direction { + directionRecordProducer := &BooleanRecordProducer{ + Bool: true, + Type: ChanUpdate2DirectionType, + } + records = append(records, directionRecordProducer.Record()) + } + + // We only encode the cltv expiry delta if it is not equal to the + // default. + if c.CLTVExpiryDelta != defaultCltvExpiryDelta { + records = append(records, tlv.MakePrimitiveRecord( + ChanUpdate2CLTVExpiryDeltaType, &c.CLTVExpiryDelta, + )) + } + + if c.HTLCMinimumMsat != defaultHtlcMinMsat { + var htlcMin = uint64(c.HTLCMinimumMsat) + records = append(records, tlv.MakePrimitiveRecord( + ChanUpdate2HTLCMinMsatType, &htlcMin, + )) + } + + var htlcMax = uint64(c.HTLCMaximumMsat) + records = append(records, tlv.MakePrimitiveRecord( + ChanUpdate2HTLCMaxMsatType, &htlcMax, + )) + + if c.FeeBaseMsat != defaultFeeBaseMsat { + records = append(records, tlv.MakePrimitiveRecord( + ChanUpdate2FeeBaseMsatType, &c.FeeBaseMsat, + )) + } + + if c.FeeProportionalMillionths != defaultFeeProportionalMillionths { + records = append(records, tlv.MakePrimitiveRecord( + ChanUpdate2FeeProportionalMillionthsType, + &c.FeeProportionalMillionths, + )) + } + + err := EncodeMessageExtraDataFromRecords(&c.ExtraOpaqueData, records...) + if err != nil { + return nil, err + } + + return c.ExtraOpaqueData, nil +} + +// MsgType returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. +func (c *ChannelUpdate2) MsgType() MessageType { + return MsgChannelUpdate2 +} + +// A compile time check to ensure ChannelUpdate2 implements the +// lnwire.Message interface. +var _ Message = (*ChannelUpdate2)(nil) + +// SCID returns the ShortChannelID of the channel that the update applies to. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) SCID() ShortChannelID { + return c.ShortChannelID +} + +// IsNode1 is true if the update was produced by node 1 of the channel peers. +// Node 1 is the node with the lexicographically smaller public key. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) IsNode1() bool { + return !c.Direction +} + +// IsDisabled is true if the update is announcing that the channel should be +// considered disabled. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) IsDisabled() bool { + return !c.DisabledFlags.IsEnabled() +} + +// GetChainHash returns the hash of the chain that the message is referring to. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) GetChainHash() chainhash.Hash { + return c.ChainHash +} + +// ForwardingPolicy returns the set of forwarding constraints of the update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) ForwardingPolicy() *ForwardingPolicy { + return &ForwardingPolicy{ + TimeLockDelta: c.CLTVExpiryDelta, + BaseFee: MilliSatoshi(c.FeeBaseMsat), + FeeRate: MilliSatoshi(c.FeeProportionalMillionths), + MinHTLC: c.HTLCMinimumMsat, + HasMaxHTLC: true, + MaxHTLC: c.HTLCMaximumMsat, + } +} + +// CmpAge can be used to determine if the update is older or newer than the +// passed update. It returns 1 if this update is newer, -1 if it is older, and +// 0 if they are the same age. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) CmpAge(update ChannelUpdate) (int, error) { + other, ok := update.(*ChannelUpdate2) + if !ok { + return 0, fmt.Errorf("expected *ChannelUpdate2, got: %T", + update) + } + + switch { + case c.BlockHeight > other.BlockHeight: + return 1, nil + case c.BlockHeight < other.BlockHeight: + return -1, nil + default: + return 0, nil + } +} + +// SetDisabled can be used to adjust the disabled flag of an update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) SetDisabled(disabled bool) { + if disabled { + c.DisabledFlags |= ChanUpdateDisableIncoming + c.DisabledFlags |= ChanUpdateDisableOutgoing + } else { + c.DisabledFlags &^= ChanUpdateDisableIncoming + c.DisabledFlags &^= ChanUpdateDisableOutgoing + } +} + +// SetSig can be used to adjust the signature of the update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) SetSig(signature input.Signature) error { + sig, err := NewSigFromSignature(signature) + if err != nil { + return err + } + + c.Signature = sig + + return nil +} + +// SetSCID can be used to overwrite the SCID of the update. +// +// NOTE: this is part of the ChannelUpdate interface. +func (c *ChannelUpdate2) SetSCID(scid ShortChannelID) { + c.ShortChannelID = scid +} + +// A compile time check to ensure ChannelUpdate2 implements the +// lnwire.ChannelUpdate interface. +var _ ChannelUpdate = (*ChannelUpdate2)(nil) + +// ChanUpdateDisableFlags is a bit vector that can be used to indicate various +// reasons for the channel being marked as disabled. +type ChanUpdateDisableFlags uint8 + +const ( + // ChanUpdateDisableIncoming is a bit indicates that a channel is + // disabled in the inbound direction meaning that the node broadcasting + // the update is communicating that they cannot receive funds. + ChanUpdateDisableIncoming ChanUpdateDisableFlags = 1 << iota + + // ChanUpdateDisableOutgoing is a bit indicates that a channel is + // disabled in the outbound direction meaning that the node broadcasting + // the update is communicating that they cannot send or route funds. + ChanUpdateDisableOutgoing = 2 +) + +// IncomingDisabled returns true if the ChanUpdateDisableIncoming bit is set. +func (c ChanUpdateDisableFlags) IncomingDisabled() bool { + return c&ChanUpdateDisableIncoming == ChanUpdateDisableIncoming +} + +// OutgoingDisabled returns true if the ChanUpdateDisableOutgoing bit is set. +func (c ChanUpdateDisableFlags) OutgoingDisabled() bool { + return c&ChanUpdateDisableOutgoing == ChanUpdateDisableOutgoing +} + +// IsEnabled returns true if none of the disable bits are set. +func (c ChanUpdateDisableFlags) IsEnabled() bool { + return c == 0 +} + +// String returns the bitfield flags as a string. +func (c ChanUpdateDisableFlags) String() string { + return fmt.Sprintf("%08b", c) +} diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 689c1f45f5..688a3ae455 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -1161,6 +1161,74 @@ func TestLightningWireProtocol(t *testing.T) { v[0] = reflect.ValueOf(req) }, + MsgChannelUpdate2: func(v []reflect.Value, r *rand.Rand) { + req := ChannelUpdate2{ + Signature: testSchnorrSig, + ShortChannelID: NewShortChanIDFromInt( + uint64(r.Int63()), + ), + BlockHeight: r.Uint32(), + HTLCMaximumMsat: MilliSatoshi(r.Uint64()), + ExtraOpaqueData: make([]byte, 0), + } + + // Sometimes set chain hash to bitcoin mainnet genesis + // hash. + req.ChainHash = *chaincfg.MainNetParams.GenesisHash + if r.Int31()%2 == 0 { + _, err := r.Read(req.ChainHash[:]) + require.NoError(t, err) + } + + // Sometimes use default htlc min msat. + req.HTLCMinimumMsat = defaultHtlcMinMsat + if r.Int31()%2 == 0 { + req.HTLCMinimumMsat = MilliSatoshi(r.Uint64()) + } + + // Sometimes set the cltv expiry delta to the default. + req.CLTVExpiryDelta = defaultCltvExpiryDelta + if r.Int31()%2 == 0 { + req.CLTVExpiryDelta = uint16(r.Int31()) + } + + // Sometimes use default fee base. + req.FeeBaseMsat = defaultFeeBaseMsat + if r.Int31()%2 == 0 { + req.FeeBaseMsat = r.Uint32() + } + + // Sometimes use default proportional fee. + req.FeeProportionalMillionths = + defaultFeeProportionalMillionths + if r.Int31()%2 == 0 { + req.FeeProportionalMillionths = r.Uint32() + } + + // Alternate between the two direction possibilities. + if r.Int31()%2 == 0 { + req.Direction = true + } + + // Sometimes set the incoming disabled flag. + if r.Int31()%2 == 0 { + req.DisabledFlags |= ChanUpdateDisableIncoming + } + + // Sometimes set the outgoing disabled flag. + if r.Int31()%2 == 0 { + req.DisabledFlags |= ChanUpdateDisableOutgoing + } + + numExtraBytes := r.Int31n(1000) + if numExtraBytes > 0 { + req.ExtraOpaqueData = make( + []byte, numExtraBytes, + ) + _, err := r.Read(req.ExtraOpaqueData[:]) + require.NoError(t, err) + } + }, } // With the above types defined, we'll now generate a slice of diff --git a/lnwire/message.go b/lnwire/message.go index b31baf35da..6961b5911b 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -53,6 +53,7 @@ const ( MsgReplyChannelRange = 264 MsgGossipTimestampRange = 265 MsgChannelAnnouncement2 = 267 + MsgChannelUpdate2 = 271 ) // ErrorEncodeMessage is used when failed to encode the message payload. @@ -140,6 +141,8 @@ func (t MessageType) String() string { return "MsgAnnounceSignatures2" case MsgChannelAnnouncement2: return "ChannelAnnouncement2" + case MsgChannelUpdate2: + return "ChannelUpdate2" default: return "" } @@ -246,6 +249,8 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { msg = &AnnounceSignatures2{} case MsgChannelAnnouncement2: msg = &ChannelAnnouncement2{} + case MsgChannelUpdate2: + msg = &ChannelUpdate2{} default: // If the message is not within our custom range and has not // specifically been overridden, return an unknown message. From e2c260bc3037f9ff5e54b414dfd2f73421ddcb84 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 29 Sep 2023 11:56:58 +0200 Subject: [PATCH 20/20] lnwire: add NodeAnnouncement2 --- lnwire/lnwire_test.go | 73 +++++ lnwire/message.go | 5 + lnwire/node_announcement_2.go | 554 ++++++++++++++++++++++++++++++++++ 3 files changed, 632 insertions(+) create mode 100644 lnwire/node_announcement_2.go diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 688a3ae455..f475eab015 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -2,6 +2,7 @@ package lnwire import ( "bytes" + "encoding/base64" "encoding/binary" "encoding/hex" "fmt" @@ -1229,6 +1230,72 @@ func TestLightningWireProtocol(t *testing.T) { require.NoError(t, err) } }, + MsgNodeAnnouncement2: func(v []reflect.Value, r *rand.Rand) { + req := NodeAnnouncement2{ + Signature: testSchnorrSig, + BlockHeight: r.Uint32(), + NodeID: randRawKey(t), + ExtraOpaqueData: make([]byte, 0), + } + + features := randRawFeatureVector(r) + req.Features = *features + + // Sometimes set the colour field. + if r.Int31()%2 == 0 { + req.RGBColor = &color.RGBA{ + R: uint8(r.Int31()), + G: uint8(r.Int31()), + B: uint8(r.Int31()), + } + } + + n := r.Intn(33) + b := make([]byte, n) + _, err := rand.Read(b) + require.NoError(t, err) + + if n > 0 { + req.Alias = []byte( + base64.StdEncoding.EncodeToString(b), + ) + if len(req.Alias) > 32 { + req.Alias = req.Alias[:32] + } + } + + // Sometimes add some ipv4 addrs. + if r.Int31()%2 == 0 { + ipv4Addr, err := randTCP4Addr(r) + require.NoError(t, err) + req.Addresses = append(req.Addresses, ipv4Addr) + } + + // Sometimes add some ipv6 addrs. + if r.Int31()%2 == 0 { + ipv6Addr, err := randTCP6Addr(r) + require.NoError(t, err) + req.Addresses = append(req.Addresses, ipv6Addr) + } + + // Sometimes add some torv3 addrs. + if r.Int31()%2 == 0 { + ipv6Addr, err := randV3OnionAddr(r) + require.NoError(t, err) + req.Addresses = append(req.Addresses, ipv6Addr) + } + + numExtraBytes := r.Int31n(1000) + if numExtraBytes > 0 { + req.ExtraOpaqueData = make( + []byte, numExtraBytes, + ) + _, err := r.Read(req.ExtraOpaqueData[:]) + require.NoError(t, err) + } + + v[0] = reflect.ValueOf(req) + }, } // With the above types defined, we'll now generate a slice of @@ -1427,6 +1494,12 @@ func TestLightningWireProtocol(t *testing.T) { return mainScenario(&m) }, }, + { + msgType: MsgNodeAnnouncement2, + scenario: func(m NodeAnnouncement2) bool { + return mainScenario(&m) + }, + }, } for _, test := range tests { var config *quick.Config diff --git a/lnwire/message.go b/lnwire/message.go index 6961b5911b..1530eb8ca0 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -53,6 +53,7 @@ const ( MsgReplyChannelRange = 264 MsgGossipTimestampRange = 265 MsgChannelAnnouncement2 = 267 + MsgNodeAnnouncement2 = 269 MsgChannelUpdate2 = 271 ) @@ -143,6 +144,8 @@ func (t MessageType) String() string { return "ChannelAnnouncement2" case MsgChannelUpdate2: return "ChannelUpdate2" + case MsgNodeAnnouncement2: + return "NodeAnnouncement2" default: return "" } @@ -251,6 +254,8 @@ func makeEmptyMessage(msgType MessageType) (Message, error) { msg = &ChannelAnnouncement2{} case MsgChannelUpdate2: msg = &ChannelUpdate2{} + case MsgNodeAnnouncement2: + msg = &NodeAnnouncement2{} default: // If the message is not within our custom range and has not // specifically been overridden, return an unknown message. diff --git a/lnwire/node_announcement_2.go b/lnwire/node_announcement_2.go new file mode 100644 index 0000000000..252f787aca --- /dev/null +++ b/lnwire/node_announcement_2.go @@ -0,0 +1,554 @@ +package lnwire + +import ( + "bytes" + "encoding/binary" + "fmt" + "image/color" + "io" + "net" + "unicode/utf8" + + "github.com/lightningnetwork/lnd/tlv" + "github.com/lightningnetwork/lnd/tor" +) + +const ( + // NodeAnn2FeaturesType is the tlv number associated with the features + // vector TLV record in the node_announcement_2 message. + NodeAnn2FeaturesType = tlv.Type(0) + + // NodeAnn2RGBColorType is the tlv number associated with the color TLV + // record in the node_announcement_2 message. + NodeAnn2RGBColorType = tlv.Type(1) + + // NodeAnn2BlockHeightType is the tlv number associated with the block + // height TLV record in the node_announcement_2 message. + NodeAnn2BlockHeightType = tlv.Type(2) + + // NodeAnn2AliasType is the tlv number associated with the alias vector + // TLV record in the node_announcement_2 message. + NodeAnn2AliasType = tlv.Type(3) + + // NodeAnn2NodeIDType is the tlv number associated with the node ID TLV + // record in the node_announcement_2 message. + NodeAnn2NodeIDType = tlv.Type(4) + + // NodeAnn2IPV4AddrsType is the tlv number associated with the ipv4 + // addresses TLV record in the node_announcement_2 message. + NodeAnn2IPV4AddrsType = tlv.Type(5) + + // NodeAnn2IPV6AddrsType is the tlv number associated with the ipv6 + // addresses TLV record in the node_announcement_2 message. + NodeAnn2IPV6AddrsType = tlv.Type(7) + + // NodeAnn2TorV3AddrsType is the tlv number associated with the tor V3 + // addresses TLV record in the node_announcement_2 message. + NodeAnn2TorV3AddrsType = tlv.Type(9) +) + +// NodeAnnouncement2 message is used to announce the presence of a Lightning +// node and also to signal that the node is accepting incoming connections. +// Each NodeAnnouncement authenticating the advertised information within the +// announcement via a signature using the advertised node pubkey. +type NodeAnnouncement2 struct { + // Signature is used to prove the ownership of node id. + Signature Sig + + // Features is the list of protocol features this node supports. + Features RawFeatureVector + + // RGBColor is an optional field used to customize a node's appearance + // in maps and graphs. + RGBColor *color.RGBA + + // BlockHeight allows ordering in the case of multiple announcements. + BlockHeight uint32 + + // Alias is used to customize their node's appearance in maps and + // graphs. + Alias []byte + + // NodeID is a public key which is used as node identification. + NodeID [33]byte + + // Address are addresses on which the node is accepting incoming + // connections. + Addresses []net.Addr + + // ExtraOpaqueData is the set of data that was appended to this + // message, some of which we may not actually know how to iterate or + // parse. By holding onto this data, we ensure that we're able to + // properly validate the set of signatures that cover these new fields, + // and ensure we're able to make upgrades to the network in a forwards + // compatible manner. + ExtraOpaqueData ExtraOpaqueData +} + +// A compile time check to ensure NodeAnnouncement2 implements the +// lnwire.Message interface. +var _ Message = (*NodeAnnouncement2)(nil) + +// Decode deserializes a serialized NodeAnnouncement2 stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. +func (n *NodeAnnouncement2) Decode(r io.Reader, _ uint32) error { + err := ReadElement(r, &n.Signature) + if err != nil { + return err + } + n.Signature.ForceSchnorr() + + // First extract into extra opaque data. + var tlvRecords ExtraOpaqueData + if err := ReadElements(r, &tlvRecords); err != nil { + return err + } + + featuresRecordProducer := NewRawFeatureVectorRecordProducer( + NodeAnn2FeaturesType, + ) + + var ( + rbgColour color.RGBA + alias []byte + ipv4 IPV4Addrs + ipv6 IPV6Addrs + torV3 TorV3Addrs + ) + records := []tlv.Record{ + featuresRecordProducer.Record(), + tlv.MakeStaticRecord( + NodeAnn2RGBColorType, &rbgColour, 3, rgbEncoder, + rgbDecoder, + ), + tlv.MakePrimitiveRecord( + NodeAnn2BlockHeightType, &n.BlockHeight, + ), + tlv.MakePrimitiveRecord(NodeAnn2AliasType, &alias), + tlv.MakePrimitiveRecord(NodeAnn2NodeIDType, &n.NodeID), + tlv.MakeDynamicRecord( + NodeAnn2IPV4AddrsType, &ipv4, ipv4.EncodedSize, + ipv4AddrsEncoder, ipv4AddrsDecoder, + ), + tlv.MakeDynamicRecord( + NodeAnn2IPV6AddrsType, &ipv6, ipv6.EncodedSize, + ipv6AddrsEncoder, ipv6AddrsDecoder, + ), + tlv.MakeDynamicRecord( + NodeAnn2TorV3AddrsType, &torV3, torV3.EncodedSize, + torV3AddrsEncoder, torV3AddrsDecoder, + ), + } + + typeMap, err := tlvRecords.ExtractRecords(records...) + if err != nil { + return err + } + + if _, ok := typeMap[NodeAnn2FeaturesType]; ok { + n.Features = featuresRecordProducer.RawFeatureVector + } + + if _, ok := typeMap[NodeAnn2RGBColorType]; ok { + n.RGBColor = &rbgColour + } + + if _, ok := typeMap[NodeAnn2AliasType]; ok { + // TODO(elle): do this before we allocate the bytes for it + // somehow? + if len(alias) > 32 { + return fmt.Errorf("alias too large: max is %v, got %v", + 32, len(alias)) + } + + // Validate the alias. + if !utf8.ValidString(string(alias)) { + return fmt.Errorf("node alias has non-utf8 characters") + } + + n.Alias = alias + } + + if _, ok := typeMap[NodeAnn2IPV4AddrsType]; ok { + for _, addr := range ipv4 { + n.Addresses = append(n.Addresses, net.Addr(addr)) + } + } + + if _, ok := typeMap[NodeAnn2IPV6AddrsType]; ok { + for _, addr := range ipv6 { + n.Addresses = append(n.Addresses, net.Addr(addr)) + } + } + + if _, ok := typeMap[NodeAnn2TorV3AddrsType]; ok { + for _, addr := range torV3 { + n.Addresses = append(n.Addresses, net.Addr(addr)) + } + } + + if len(tlvRecords) != 0 { + n.ExtraOpaqueData = tlvRecords + } + + return nil +} + +// Encode serializes the target NodeAnnouncement2 into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. +func (n *NodeAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error { + _, err := w.Write(n.Signature.RawBytes()) + if err != nil { + return err + } + + featuresRecordProducer := &RawFeatureVectorRecordProducer{ + RawFeatureVector: n.Features, + Type: NodeAnn2FeaturesType, + } + + records := []tlv.Record{ + featuresRecordProducer.Record(), + } + + // Only encode the colour if it is specified. + if n.RGBColor != nil { + records = append(records, tlv.MakeStaticRecord( + NodeAnn2RGBColorType, n.RGBColor, 3, rgbEncoder, + rgbDecoder, + )) + } + + records = append(records, tlv.MakePrimitiveRecord( + NodeAnn2BlockHeightType, &n.BlockHeight, + )) + + if len(n.Alias) != 0 { + records = append(records, + tlv.MakePrimitiveRecord(NodeAnn2AliasType, &n.Alias), + ) + } + + records = append( + records, tlv.MakePrimitiveRecord(NodeAnn2NodeIDType, &n.NodeID), + ) + + // Iterate over the addresses and collect the various types. + var ( + ipv4 IPV4Addrs + ipv6 IPV6Addrs + torv3 TorV3Addrs + ) + for _, addr := range n.Addresses { + switch a := addr.(type) { + case *net.TCPAddr: + if a.IP.To4() != nil { + ipv4 = append(ipv4, a) + } else { + ipv6 = append(ipv6, a) + } + + case *tor.OnionAddr: + torv3 = append(torv3, a) + } + } + + if len(ipv4) > 0 { + records = append(records, tlv.MakeDynamicRecord( + NodeAnn2IPV4AddrsType, &ipv4, ipv4.EncodedSize, + ipv4AddrsEncoder, ipv4AddrsDecoder, + )) + } + + if len(ipv6) > 0 { + records = append(records, tlv.MakeDynamicRecord( + NodeAnn2IPV6AddrsType, &ipv6, ipv6.EncodedSize, + ipv6AddrsEncoder, ipv6AddrsDecoder, + )) + } + + if len(torv3) > 0 { + records = append(records, tlv.MakeDynamicRecord( + NodeAnn2TorV3AddrsType, &torv3, torv3.EncodedSize, + torV3AddrsEncoder, torV3AddrsDecoder, + )) + } + + err = EncodeMessageExtraDataFromRecords(&n.ExtraOpaqueData, records...) + if err != nil { + return err + } + + return WriteBytes(w, n.ExtraOpaqueData) +} + +// MsgType returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. +func (n *NodeAnnouncement2) MsgType() MessageType { + return MsgNodeAnnouncement2 +} + +func rgbEncoder(w io.Writer, val interface{}, _ *[8]byte) error { + if v, ok := val.(*color.RGBA); ok { + buf := bytes.NewBuffer(nil) + err := WriteColorRGBA(buf, *v) + if err != nil { + return err + } + + _, err = w.Write(buf.Bytes()) + + return err + } + + return tlv.NewTypeForEncodingErr(val, "color.RGBA") +} + +func rgbDecoder(r io.Reader, val interface{}, _ *[8]byte, l uint64) error { + if v, ok := val.(*color.RGBA); ok { + return ReadElements(r, &v.R, &v.G, &v.B) + } + + return tlv.NewTypeForDecodingErr(val, "color.RGBA", l, 3) +} + +// IPV4Addrs is a list of ipv4 addresses that can be encoded as a TLV record. +type IPV4Addrs []*net.TCPAddr + +// ipv4AddrEncodedSize is the number of bytes required to encode a single ipv4 +// address. Four bytes are used to encode the IP address and two bytes for the +// port number. +const ipv4AddrEncodedSize = 4 + 2 + +// EncodedSize returns the number of bytes required to encode an IPV4Addrs +// variable. +func (i *IPV4Addrs) EncodedSize() uint64 { + return uint64(len(*i) * ipv4AddrEncodedSize) +} + +func ipv4AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error { + if v, ok := val.(*IPV4Addrs); ok { + for _, ip := range *v { + _, err := w.Write(ip.IP.To4()) + if err != nil { + return err + } + + var port [2]byte + binary.BigEndian.PutUint16(port[:], uint16(ip.Port)) + + _, err = w.Write(port[:]) + + return err + } + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs") +} + +func ipv4AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte, + l uint64) error { + + if v, ok := val.(*IPV4Addrs); ok { + if l%(ipv4AddrEncodedSize) != 0 { + return fmt.Errorf("invalid ipv4 list encoding") + } + + var ( + numAddrs = int(l / ipv4AddrEncodedSize) + addrs = make([]*net.TCPAddr, 0, numAddrs) + ip [4]byte + port [2]byte + ) + for len(addrs) < numAddrs { + _, err := r.Read(ip[:]) + if err != nil { + return err + } + + _, err = r.Read(port[:]) + if err != nil { + return err + } + + addrs = append(addrs, &net.TCPAddr{ + IP: ip[:], + Port: int(binary.BigEndian.Uint16(port[:])), + }) + } + + *v = addrs + + return nil + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs") +} + +// IPV6Addrs is a list of ipv6 addresses that can be encoded as a TLV record. +type IPV6Addrs []*net.TCPAddr + +// ipv6AddrEncodedSize is the number of bytes required to encode a single ipv6 +// address. Sixteen bytes are used to encode the IP address and two bytes for +// the port number. +const ipv6AddrEncodedSize = 16 + 2 + +// EncodedSize returns the number of bytes required to encode an IPV6Addrs +// variable. +func (i *IPV6Addrs) EncodedSize() uint64 { + return uint64(len(*i) * ipv6AddrEncodedSize) +} + +func ipv6AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error { + if v, ok := val.(*IPV6Addrs); ok { + for _, ip := range *v { + _, err := w.Write(ip.IP.To16()) + if err != nil { + return err + } + + var port [2]byte + binary.BigEndian.PutUint16(port[:], uint16(ip.Port)) + + _, err = w.Write(port[:]) + + return err + } + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs") +} + +func ipv6AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte, + l uint64) error { + + if v, ok := val.(*IPV6Addrs); ok { + if l%(ipv6AddrEncodedSize) != 0 { + return fmt.Errorf("invalid ipv6 list encoding") + } + + var ( + numAddrs = int(l / ipv6AddrEncodedSize) + addrs = make([]*net.TCPAddr, 0, numAddrs) + ip [16]byte + port [2]byte + ) + for len(addrs) < numAddrs { + _, err := r.Read(ip[:]) + if err != nil { + return err + } + + _, err = r.Read(port[:]) + if err != nil { + return err + } + + addrs = append(addrs, &net.TCPAddr{ + IP: ip[:], + Port: int(binary.BigEndian.Uint16(port[:])), + }) + } + + *v = addrs + + return nil + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs") +} + +// TorV3Addrs is a list of tor v3 addresses that can be encoded as a TLV record. +type TorV3Addrs []*tor.OnionAddr + +// torV3AddrEncodedSize is the number of bytes required to encode a single tor +// v3 address. +const torV3AddrEncodedSize = tor.V3DecodedLen + 2 + +// EncodedSize returns the number of bytes required to encode an TorV3Addrs +// variable. +func (i *TorV3Addrs) EncodedSize() uint64 { + return uint64(len(*i) * torV3AddrEncodedSize) +} + +func torV3AddrsEncoder(w io.Writer, val interface{}, _ *[8]byte) error { + if v, ok := val.(*TorV3Addrs); ok { + for _, addr := range *v { + encodedHostLen := tor.V3Len - tor.OnionSuffixLen + host, err := tor.Base32Encoding.DecodeString( + addr.OnionService[:encodedHostLen], + ) + if err != nil { + return err + } + + if len(host) != tor.V3DecodedLen { + return fmt.Errorf("expected a tor v3 host "+ + "length of %d, got: %d", + tor.V2DecodedLen, len(host)) + } + + if _, err = w.Write(host); err != nil { + return err + } + + var port [2]byte + binary.BigEndian.PutUint16(port[:], uint16(addr.Port)) + + _, err = w.Write(port[:]) + + return err + } + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs") +} + +func torV3AddrsDecoder(r io.Reader, val interface{}, _ *[8]byte, + l uint64) error { + + if v, ok := val.(*TorV3Addrs); ok { + if l%torV3AddrEncodedSize != 0 { + return fmt.Errorf("invalid tor v3 list encoding") + } + + var ( + numAddrs = int(l / torV3AddrEncodedSize) + addrs = make([]*tor.OnionAddr, 0, numAddrs) + ip [tor.V3DecodedLen]byte + p [2]byte + ) + for len(addrs) < numAddrs { + _, err := r.Read(ip[:]) + if err != nil { + return err + } + + _, err = r.Read(p[:]) + if err != nil { + return err + } + + onionService := tor.Base32Encoding.EncodeToString(ip[:]) + onionService += tor.OnionSuffix + port := int(binary.BigEndian.Uint16(p[:])) + + addrs = append(addrs, &tor.OnionAddr{ + OnionService: onionService, + Port: port, + }) + } + + *v = addrs + + return nil + } + + return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs") +}