Merge pull request #10232 from ellemouton/g175MessageFollowup
lnwire: add missing Gossip 1.75 fields and message
This commit is contained in:
32 files changed
+1435
-136
No files matched your search
+12
-11
@@ -244,11 +244,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.
|
||||
@@ -1186,7 +1186,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)
|
||||
|
||||
@@ -1195,7 +1195,8 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) {
|
||||
oldTimestamp := uint32(0)
|
||||
mws, ok := d.nodeAnnouncements[deDupKey]
|
||||
if ok {
|
||||
oldTimestamp = mws.msg.(*lnwire.NodeAnnouncement).Timestamp
|
||||
ann, _ := mws.msg.(*lnwire.NodeAnnouncement1)
|
||||
oldTimestamp = ann.Timestamp
|
||||
}
|
||||
|
||||
// Discard the message if it's old.
|
||||
@@ -1806,7 +1807,7 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(ctx context.Context,
|
||||
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)
|
||||
@@ -2062,7 +2063,7 @@ func (d *AuthenticatedGossiper) fetchPKScript(chanID lnwire.ShortChannelID) (
|
||||
// addNode processes the given node announcement, and adds it to our channel
|
||||
// graph.
|
||||
func (d *AuthenticatedGossiper) addNode(ctx context.Context,
|
||||
msg *lnwire.NodeAnnouncement, op ...batch.SchedulerOption) error {
|
||||
msg *lnwire.NodeAnnouncement1, op ...batch.SchedulerOption) error {
|
||||
|
||||
if err := netann.ValidateNodeAnn(msg); err != nil {
|
||||
return fmt.Errorf("unable to validate node announcement: %w",
|
||||
@@ -2153,7 +2154,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(ctx context.Context,
|
||||
// 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(ctx, nMsg, msg, schedulerOp)
|
||||
|
||||
// A new channel announcement has arrived, this indicates the
|
||||
@@ -2248,7 +2249,7 @@ func (d *AuthenticatedGossiper) processZombieUpdate(_ context.Context,
|
||||
// announcement fields and returns an error if they are invalid to prevent
|
||||
// forwarding invalid node announcements to our peers.
|
||||
func (d *AuthenticatedGossiper) fetchNodeAnn(ctx context.Context,
|
||||
pubKey [33]byte) (*lnwire.NodeAnnouncement, error) {
|
||||
pubKey [33]byte) (*lnwire.NodeAnnouncement1, error) {
|
||||
|
||||
node, err := d.cfg.Graph.FetchNode(ctx, pubKey)
|
||||
if err != nil {
|
||||
@@ -2478,12 +2479,12 @@ func (d *AuthenticatedGossiper) latestHeight() uint32 {
|
||||
|
||||
// handleNodeAnnouncement processes a new node announcement.
|
||||
func (d *AuthenticatedGossiper) handleNodeAnnouncement(ctx context.Context,
|
||||
nMsg *networkMsg, nodeAnn *lnwire.NodeAnnouncement,
|
||||
nMsg *networkMsg, 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, source=%x", nMsg.peer, timestamp, nodeAnn.NodeID,
|
||||
nMsg.source.SerializeCompressed())
|
||||
|
||||
@@ -2542,7 +2543,7 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(ctx context.Context,
|
||||
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, source=%x", nMsg.peer, timestamp, nodeAnn.NodeID,
|
||||
nMsg.source.SerializeCompressed())
|
||||
|
||||
|
||||
+15
-14
@@ -493,8 +493,8 @@ func (m *mockNotifier) Stop() error {
|
||||
}
|
||||
|
||||
type annBatch struct {
|
||||
nodeAnn1 *lnwire.NodeAnnouncement
|
||||
nodeAnn2 *lnwire.NodeAnnouncement
|
||||
nodeAnn1 *lnwire.NodeAnnouncement1
|
||||
nodeAnn2 *lnwire.NodeAnnouncement1
|
||||
|
||||
chanAnn *lnwire.ChannelAnnouncement1
|
||||
|
||||
@@ -577,8 +577,8 @@ func (ctx *testCtx) createAnnouncements(blockHeight uint32, key1,
|
||||
|
||||
}
|
||||
|
||||
func createNodeAnnouncement(priv *btcec.PrivateKey,
|
||||
timestamp uint32, extraBytes ...[]byte) (*lnwire.NodeAnnouncement, error) {
|
||||
func createNodeAnnouncement(priv *btcec.PrivateKey, timestamp uint32,
|
||||
extraBytes ...[]byte) (*lnwire.NodeAnnouncement1, error) {
|
||||
|
||||
var err error
|
||||
k := hex.EncodeToString(priv.Serialize())
|
||||
@@ -587,7 +587,7 @@ func createNodeAnnouncement(priv *btcec.PrivateKey,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
a := &lnwire.NodeAnnouncement{
|
||||
a := &lnwire.NodeAnnouncement1{
|
||||
Timestamp: timestamp,
|
||||
Addresses: testAddrs,
|
||||
Alias: alias,
|
||||
@@ -966,15 +966,15 @@ func createTestCtx(t *testing.T, startHeight uint32, isChanPeer bool) (
|
||||
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
|
||||
},
|
||||
@@ -2285,7 +2285,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
|
||||
// ChannelAnnouncement and hand it off to the gossiper in order to
|
||||
// process it.
|
||||
@@ -2312,8 +2312,9 @@ func TestForwardPrivateNodeAnnouncement(t *testing.T) {
|
||||
t.Fatal("gossiper should have broadcast the channel announcement")
|
||||
}
|
||||
|
||||
// We'll recreate the NodeAnnouncement with an updated timestamp to
|
||||
// prevent a stale update. The NodeAnnouncement should now be forwarded.
|
||||
// We'll recreate the NodeAnnouncement1 with an updated timestamp to
|
||||
// prevent a stale update. The NodeAnnouncement1 should now be
|
||||
// forwarded.
|
||||
nodeAnn, err = createNodeAnnouncement(remoteKeyPriv1, timestamp+1)
|
||||
require.NoError(t, err, "unable to create node announcement")
|
||||
|
||||
@@ -2897,7 +2898,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()
|
||||
@@ -3044,7 +3045,7 @@ func TestRetransmit(t *testing.T) {
|
||||
chanAnn++
|
||||
case *lnwire.ChannelUpdate1:
|
||||
chanUpd++
|
||||
case *lnwire.NodeAnnouncement:
|
||||
case *lnwire.NodeAnnouncement1:
|
||||
nodeAnn++
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1653,7 +1653,7 @@ func (g *GossipSyncer) FilterGossipMsgs(ctx context.Context,
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
@@ -249,10 +249,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()),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -308,15 +312,21 @@ 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.
|
||||
@@ -737,7 +747,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
|
||||
|
||||
@@ -188,7 +188,7 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) (JobID,
|
||||
populateDependencies(msg.ShortChannelID.String(), childJobID)
|
||||
|
||||
return childJobID, nil
|
||||
case *lnwire.NodeAnnouncement:
|
||||
case *lnwire.NodeAnnouncement1:
|
||||
childJobID := JobID(v.idCtr.Add(1))
|
||||
populateDependencies(
|
||||
route.Vertex(msg.NodeID).String(), childJobID,
|
||||
@@ -242,7 +242,7 @@ func (v *ValidationBarrier) WaitForParents(childJobID JobID,
|
||||
v.Lock()
|
||||
|
||||
switch msg := job.(type) {
|
||||
// Any ChannelUpdate or NodeAnnouncement jobs will need to wait on the
|
||||
// Any ChannelUpdate or NodeAnnouncement1 jobs will need to wait on the
|
||||
// completion of any active ChannelAnnouncement jobs related to them.
|
||||
case *lnwire.ChannelUpdate1:
|
||||
annID = msg.ShortChannelID.String()
|
||||
@@ -258,7 +258,7 @@ func (v *ValidationBarrier) WaitForParents(childJobID JobID,
|
||||
jobDesc = fmt.Sprintf("job=lnwire.ChannelUpdate, scid=%v",
|
||||
msg.ShortChannelID.ToUint64())
|
||||
|
||||
case *lnwire.NodeAnnouncement:
|
||||
case *lnwire.NodeAnnouncement1:
|
||||
annID = route.Vertex(msg.NodeID).String()
|
||||
|
||||
parentJobIDs, ok = v.jobDependencies[childJobID]
|
||||
@@ -269,7 +269,7 @@ func (v *ValidationBarrier) WaitForParents(childJobID JobID,
|
||||
return nil
|
||||
}
|
||||
|
||||
jobDesc = fmt.Sprintf("job=lnwire.NodeAnnouncement, pub=%s",
|
||||
jobDesc = fmt.Sprintf("job=lnwire.NodeAnnouncement1, pub=%s",
|
||||
route.Vertex(msg.NodeID))
|
||||
|
||||
// Other types of jobs can be executed immediately, so we'll just
|
||||
@@ -446,7 +446,7 @@ func (v *ValidationBarrier) SignalDependents(job interface{}, id JobID) error {
|
||||
|
||||
return nil
|
||||
|
||||
case *lnwire.NodeAnnouncement:
|
||||
case *lnwire.NodeAnnouncement1:
|
||||
// Remove child job info.
|
||||
return removeJob(route.Vertex(msg.NodeID).String(), id, true)
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ func TestValidationBarrierQuit(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestValidationBarrierParentJobsClear tests that creating two parent jobs for
|
||||
// ChannelUpdate / NodeAnnouncement will pause child jobs until the set of
|
||||
// ChannelUpdate / NodeAnnouncement1 will pause child jobs until the set of
|
||||
// parent jobs has cleared.
|
||||
func TestValidationBarrierParentJobsClear(t *testing.T) {
|
||||
t.Parallel()
|
||||
@@ -230,14 +230,14 @@ func TestValidationBarrierParentJobsClear(t *testing.T) {
|
||||
parentID3, err := barrier.InitJobDependencies(ann3)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create the ChannelUpdate & NodeAnnouncement messages.
|
||||
// Create the ChannelUpdate & NodeAnnouncement1 messages.
|
||||
upd1 := &lnwire.ChannelUpdate1{
|
||||
ShortChannelID: sharedScid,
|
||||
}
|
||||
childID1, err := barrier.InitJobDependencies(upd1)
|
||||
require.NoError(t, err)
|
||||
|
||||
node1 := &lnwire.NodeAnnouncement{
|
||||
node1 := &lnwire.NodeAnnouncement1{
|
||||
NodeID: sharedNodeID,
|
||||
}
|
||||
childID2, err := barrier.InitJobDependencies(node1)
|
||||
|
||||
+5
-5
@@ -398,7 +398,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
|
||||
@@ -3757,8 +3757,8 @@ 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
|
||||
// don't leak any of our information.
|
||||
// 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 {
|
||||
log.Debugf("Will not announce private channel %v.",
|
||||
@@ -3779,7 +3779,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
|
||||
@@ -4724,7 +4724,7 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
|
||||
graph.ErrIgnored) {
|
||||
|
||||
log.Debugf("Graph rejected "+
|
||||
"NodeAnnouncement: %v", err)
|
||||
"NodeAnnouncement1: %v", err)
|
||||
} else {
|
||||
log.Errorf("Unable to send node "+
|
||||
"announcement: %v", err)
|
||||
|
||||
+14
-13
@@ -485,10 +485,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,
|
||||
@@ -660,10 +660,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) {
|
||||
@@ -1328,9 +1328,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)
|
||||
@@ -1348,7 +1348,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
|
||||
}
|
||||
}
|
||||
@@ -1358,7 +1358,8 @@ 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1378,7 +1379,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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2959,7 +2960,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):
|
||||
@@ -2968,7 +2969,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):
|
||||
@@ -3085,7 +3086,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):
|
||||
@@ -3094,7 +3095,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):
|
||||
|
||||
@@ -4754,10 +4754,10 @@ func TestLightningNodePersistence(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Use the raw serialized node announcement message create an
|
||||
// lnwire.NodeAnnouncement instance.
|
||||
// lnwire.NodeAnnouncement1 instance.
|
||||
msg, err := lnwire.ReadMessage(bytes.NewBuffer(nodeAnnBytes), 0)
|
||||
require.NoError(t, err)
|
||||
na, ok := msg.(*lnwire.NodeAnnouncement)
|
||||
na, ok := msg.(*lnwire.NodeAnnouncement1)
|
||||
require.True(t, ok)
|
||||
|
||||
// Convert the wire message to our internal node representation.
|
||||
|
||||
@@ -96,7 +96,7 @@ func (l *Node) AddPubKey(key *btcec.PublicKey) {
|
||||
}
|
||||
|
||||
// NodeAnnouncement retrieves the latest node announcement of the node.
|
||||
func (l *Node) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement,
|
||||
func (l *Node) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement1,
|
||||
error) {
|
||||
|
||||
if !l.HaveNodeAnnouncement {
|
||||
@@ -108,7 +108,7 @@ func (l *Node) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeAnn := &lnwire.NodeAnnouncement{
|
||||
nodeAnn := &lnwire.NodeAnnouncement1{
|
||||
Features: l.Features.RawFeatureVector,
|
||||
NodeID: l.PubKeyBytes,
|
||||
RGBColor: l.Color,
|
||||
@@ -133,8 +133,8 @@ func (l *Node) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement,
|
||||
}
|
||||
|
||||
// NodeFromWireAnnouncement creates a Node instance from an
|
||||
// lnwire.NodeAnnouncement message.
|
||||
func NodeFromWireAnnouncement(msg *lnwire.NodeAnnouncement) *Node {
|
||||
// lnwire.NodeAnnouncement1 message.
|
||||
func NodeFromWireAnnouncement(msg *lnwire.NodeAnnouncement1) *Node {
|
||||
timestamp := time.Unix(int64(msg.Timestamp), 0)
|
||||
features := lnwire.NewFeatureVector(msg.Features, lnwire.Features)
|
||||
|
||||
|
||||
@@ -19,7 +19,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)
|
||||
|
||||
@@ -56,6 +56,9 @@ type ChannelAnnouncement2 struct {
|
||||
// the funding output is a pure 2-of-2 MuSig aggregate public key.
|
||||
MerkleRootHash tlv.OptionalRecordT[tlv.TlvType16, [32]byte]
|
||||
|
||||
// Outpoint is the outpoint of the funding transaction.
|
||||
Outpoint tlv.RecordT[tlv.TlvType18, OutPoint]
|
||||
|
||||
// Signature is a Schnorr signature over serialised signed-range TLV
|
||||
// stream of the message.
|
||||
Signature tlv.RecordT[tlv.TlvType160, Sig]
|
||||
@@ -81,17 +84,17 @@ func (c *ChannelAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
|
||||
// NOTE: this is part of the PureTLVMessage interface.
|
||||
func (c *ChannelAnnouncement2) AllRecords() []tlv.Record {
|
||||
recordProducers := append(
|
||||
c.allNonSignatureRecordProducers(), &c.Signature,
|
||||
c.nonSignatureRecordProducers(), &c.Signature,
|
||||
)
|
||||
|
||||
return ProduceRecordsSorted(recordProducers...)
|
||||
}
|
||||
|
||||
// allNonSignatureRecordProducers returns all the TLV record producers for the
|
||||
// nonSignatureRecordProducers returns all the TLV record producers for the
|
||||
// message except the signature record producer.
|
||||
//
|
||||
//nolint:ll
|
||||
func (c *ChannelAnnouncement2) allNonSignatureRecordProducers() []tlv.RecordProducer {
|
||||
func (c *ChannelAnnouncement2) nonSignatureRecordProducers() []tlv.RecordProducer {
|
||||
// The chain-hash record is only included if it is _not_ equal to the
|
||||
// bitcoin mainnet genisis block hash.
|
||||
var recordProducers []tlv.RecordProducer
|
||||
@@ -121,6 +124,7 @@ func (c *ChannelAnnouncement2) allNonSignatureRecordProducers() []tlv.RecordProd
|
||||
},
|
||||
)
|
||||
|
||||
recordProducers = append(recordProducers, &c.Outpoint)
|
||||
recordProducers = append(recordProducers, RecordsAsProducers(
|
||||
tlv.MapToRecords(c.ExtraSignedFields),
|
||||
)...)
|
||||
@@ -149,6 +153,7 @@ func (c *ChannelAnnouncement2) Decode(r io.Reader, _ uint32) error {
|
||||
&btcKey1,
|
||||
&btcKey2,
|
||||
&merkleRootHash,
|
||||
&c.Outpoint,
|
||||
&c.Signature,
|
||||
)...)
|
||||
if err != nil {
|
||||
@@ -202,6 +207,7 @@ func (c *ChannelAnnouncement2) DecodeNonSigTLVRecords(r io.Reader) error {
|
||||
&btcKey1,
|
||||
&btcKey2,
|
||||
&merkleRootHash,
|
||||
&c.Outpoint,
|
||||
)...)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -239,7 +245,7 @@ func (c *ChannelAnnouncement2) DecodeNonSigTLVRecords(r io.Reader) error {
|
||||
// excludes the signature field.
|
||||
func (c *ChannelAnnouncement2) EncodeAllNonSigFields(w io.Writer) error {
|
||||
return EncodeRecordsTo(
|
||||
w, ProduceRecordsSorted(c.allNonSignatureRecordProducers()...),
|
||||
w, ProduceRecordsSorted(c.nonSignatureRecordProducers()...),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,17 @@ func TestChanAnn2EncodeDecode(t *testing.T) {
|
||||
0xb3, 0xee, 0x17, 0x2f, 0x7f, 0x16, 0x1, 0xe6, 0x7d, 0x1d, 0xa6,
|
||||
0xca, 0xd4, 0xb, 0x54, 0xc4, 0x46, 0x8d, 0x48, 0x23, 0x6c, 0x39,
|
||||
|
||||
// Outpoint record.
|
||||
0x12, // type (18).
|
||||
0x22, // length (34 bytes).
|
||||
// Hash (32 bytes).
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
// Index (2 bytes).
|
||||
0x30, 0x39, // value: 12345.
|
||||
|
||||
// Unknown TLV record.
|
||||
0x6f, // type.
|
||||
0x2, // length.
|
||||
|
||||
@@ -70,6 +70,11 @@ type ChannelUpdate2 struct {
|
||||
// millionth of a satoshi.
|
||||
FeeProportionalMillionths tlv.RecordT[tlv.TlvType18, uint32]
|
||||
|
||||
// InboundFee is an optional TLV record that contains the fee
|
||||
// information for incoming HTLCs.
|
||||
// TODO(elle): assign normal tlv type?
|
||||
InboundFee tlv.OptionalRecordT[tlv.TlvType55555, Fee]
|
||||
|
||||
// Signature is used to validate the announced data and prove the
|
||||
// ownership of node id.
|
||||
Signature tlv.RecordT[tlv.TlvType160, Sig]
|
||||
@@ -102,12 +107,13 @@ func (c *ChannelUpdate2) Decode(r io.Reader, _ uint32) error {
|
||||
var (
|
||||
chainHash = tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
|
||||
secondPeer = tlv.ZeroRecordT[tlv.TlvType8, TrueBoolean]()
|
||||
inboundFee = tlv.ZeroRecordT[tlv.TlvType55555, Fee]()
|
||||
)
|
||||
typeMap, err := tlvRecords.ExtractRecords(
|
||||
&chainHash, &c.ShortChannelID, &c.BlockHeight, &c.DisabledFlags,
|
||||
&secondPeer, &c.CLTVExpiryDelta, &c.HTLCMinimumMsat,
|
||||
&c.HTLCMaximumMsat, &c.FeeBaseMsat,
|
||||
&c.FeeProportionalMillionths,
|
||||
&c.FeeProportionalMillionths, &inboundFee,
|
||||
&c.Signature,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -149,6 +155,11 @@ func (c *ChannelUpdate2) Decode(r io.Reader, _ uint32) error {
|
||||
c.FeeProportionalMillionths.Val = defaultFeeProportionalMillionths //nolint:ll
|
||||
}
|
||||
|
||||
// If the inbound fee was encoded, set it.
|
||||
if _, ok := typeMap[c.InboundFee.TlvType()]; ok {
|
||||
c.InboundFee = tlv.SomeRecordT(inboundFee)
|
||||
}
|
||||
|
||||
c.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
|
||||
|
||||
return nil
|
||||
@@ -207,6 +218,10 @@ func (c *ChannelUpdate2) AllRecords() []tlv.Record {
|
||||
)
|
||||
}
|
||||
|
||||
c.InboundFee.WhenSome(func(r tlv.RecordT[tlv.TlvType55555, Fee]) {
|
||||
recordProducers = append(recordProducers, &r)
|
||||
})
|
||||
|
||||
recordProducers = append(recordProducers, RecordsAsProducers(
|
||||
tlv.MapToRecords(c.ExtraSignedFields),
|
||||
)...)
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -86,3 +90,70 @@ func ValidateDNSAddr(hostname string, port uint16) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Record returns a TLV record that can be used to encode/decode the DNSAddress.
|
||||
//
|
||||
// NOTE: this is part of the tlv.RecordProducer interface.
|
||||
func (d *DNSAddress) Record() tlv.Record {
|
||||
sizeFunc := func() uint64 {
|
||||
// Hostname length + 2 bytes for port.
|
||||
return uint64(len(d.Hostname) + 2)
|
||||
}
|
||||
|
||||
return tlv.MakeDynamicRecord(
|
||||
0, d, sizeFunc, dnsAddressEncoder, dnsAddressDecoder,
|
||||
)
|
||||
}
|
||||
|
||||
// dnsAddressEncoder is a TLV encoder for DNSAddress.
|
||||
func dnsAddressEncoder(w io.Writer, val any, _ *[8]byte) error {
|
||||
if v, ok := val.(*DNSAddress); ok {
|
||||
var buf bytes.Buffer
|
||||
|
||||
// Write the hostname as raw bytes (no length prefix for TLV).
|
||||
if _, err := buf.WriteString(v.Hostname); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write the port as 2 bytes.
|
||||
err := WriteUint16(&buf, v.Port)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(buf.Bytes())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return tlv.NewTypeForEncodingErr(val, "DNSAddress")
|
||||
}
|
||||
|
||||
// dnsAddressDecoder is a TLV decoder for DNSAddress.
|
||||
func dnsAddressDecoder(r io.Reader, val any, _ *[8]byte,
|
||||
l uint64) error {
|
||||
|
||||
if v, ok := val.(*DNSAddress); ok {
|
||||
if l < 2 {
|
||||
return fmt.Errorf("DNS address must be at least 2 " +
|
||||
"bytes")
|
||||
}
|
||||
|
||||
// Read hostname (all bytes except last 2).
|
||||
hostnameLen := l - 2
|
||||
hostnameBytes := make([]byte, hostnameLen)
|
||||
if _, err := io.ReadFull(r, hostnameBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
v.Hostname = string(hostnameBytes)
|
||||
|
||||
// Read port (last 2 bytes).
|
||||
if err := ReadElement(r, &v.Port); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ValidateDNSAddr(v.Hostname, v.Port)
|
||||
}
|
||||
|
||||
return tlv.NewTypeForDecodingErr(val, "DNSAddress", l, 0)
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
"github.com/stretchr/testify/require"
|
||||
"pgregory.net/rapid"
|
||||
)
|
||||
|
||||
// TestValidateDNSAddr tests hostname and port validation per BOLT #7.
|
||||
@@ -85,3 +88,112 @@ func TestValidateDNSAddr(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestDNSAddressTLVEncoding tests the TLV encoding and decoding of DNSAddress
|
||||
// structs using the ExtraOpaqueData interface.
|
||||
func TestDNSAddressTLVEncoding(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testDNSAddr := DNSAddress{
|
||||
Hostname: "lightning.example.com",
|
||||
Port: 9000,
|
||||
}
|
||||
|
||||
var extraData ExtraOpaqueData
|
||||
require.NoError(t, extraData.PackRecords(&testDNSAddr))
|
||||
|
||||
var decodedDNSAddr DNSAddress
|
||||
tlvs, err := extraData.ExtractRecords(&decodedDNSAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Contains(t, tlvs, tlv.Type(0))
|
||||
require.Equal(t, testDNSAddr, decodedDNSAddr)
|
||||
}
|
||||
|
||||
// TestDNSAddressRecord tests the TLV Record interface of DNSAddress
|
||||
// by directly encoding and decoding using the Record method.
|
||||
func TestDNSAddressRecord(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testDNSAddr := DNSAddress{
|
||||
Hostname: "lightning.example.com",
|
||||
Port: 9000,
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
record := testDNSAddr.Record()
|
||||
require.NoError(t, record.Encode(&buf))
|
||||
|
||||
var decodedDNSAddr DNSAddress
|
||||
decodedRecord := decodedDNSAddr.Record()
|
||||
require.NoError(t, decodedRecord.Decode(&buf, uint64(buf.Len())))
|
||||
|
||||
require.Equal(t, testDNSAddr, decodedDNSAddr)
|
||||
}
|
||||
|
||||
// TestDNSAddressInvalidDecoding tests error cases during TLV decoding.
|
||||
func TestDNSAddressInvalidDecoding(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
name: "too short (only 1 byte)",
|
||||
data: []byte{0x61},
|
||||
errMsg: "DNS address must be at least 2 bytes",
|
||||
},
|
||||
{
|
||||
name: "empty data",
|
||||
data: []byte{},
|
||||
errMsg: "DNS address must be at least 2 bytes",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var dnsAddr DNSAddress
|
||||
record := dnsAddr.Record()
|
||||
|
||||
buf := bytes.NewReader(tc.data)
|
||||
err := record.Decode(buf, uint64(len(tc.data)))
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, tc.errMsg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestDNSAddressProperty uses property-based testing to verify that DNSAddress
|
||||
// TLV encoding and decoding is correct for random DNSAddress values.
|
||||
func TestDNSAddressProperty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
scenario := func(t *rapid.T) {
|
||||
// Generate a random valid hostname.
|
||||
hostname := genValidHostname(t)
|
||||
|
||||
// Generate a random port (excluding 0 which is invalid).
|
||||
port := rapid.Uint16Range(1, 65535).Draw(t, "port")
|
||||
|
||||
dnsAddr := DNSAddress{
|
||||
Hostname: hostname,
|
||||
Port: port,
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
record := dnsAddr.Record()
|
||||
err := record.Encode(&buf)
|
||||
require.NoError(t, err)
|
||||
|
||||
var decodedDNSAddr DNSAddress
|
||||
decodedRecord := decodedDNSAddr.Record()
|
||||
err = decodedRecord.Decode(&buf, uint64(buf.Len()))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, dnsAddr, decodedDNSAddr)
|
||||
}
|
||||
|
||||
rapid.Check(t, scenario)
|
||||
}
|
||||
+28
-4
@@ -220,10 +220,10 @@ func FuzzNodeAnnouncement(f *testing.F) {
|
||||
// can be represented by different underlying bytes. Instead, we
|
||||
// compare the normalized string representation of each address.
|
||||
assertEq := func(t *testing.T, x, y any) {
|
||||
require.IsType(t, &NodeAnnouncement{}, x)
|
||||
first, _ := x.(*NodeAnnouncement)
|
||||
require.IsType(t, &NodeAnnouncement{}, y)
|
||||
second, _ := y.(*NodeAnnouncement)
|
||||
require.IsType(t, &NodeAnnouncement1{}, x)
|
||||
first, _ := x.(*NodeAnnouncement1)
|
||||
require.IsType(t, &NodeAnnouncement1{}, y)
|
||||
second, _ := y.(*NodeAnnouncement1)
|
||||
|
||||
require.Equal(
|
||||
t, len(first.Addresses), len(second.Addresses),
|
||||
@@ -244,6 +244,30 @@ func FuzzNodeAnnouncement(f *testing.F) {
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzNodeAnnouncement2(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// We can't use require.Equal for Features, since we consider
|
||||
// the empty map and nil to be equivalent.
|
||||
assertEq := func(t *testing.T, x, y any) {
|
||||
require.IsType(t, &NodeAnnouncement2{}, x)
|
||||
first, _ := x.(*NodeAnnouncement2)
|
||||
require.IsType(t, &NodeAnnouncement2{}, y)
|
||||
second, _ := y.(*NodeAnnouncement2)
|
||||
|
||||
require.True(
|
||||
t,
|
||||
first.Features.Val.Equals(&second.Features.Val),
|
||||
)
|
||||
first.Features.Val = *NewRawFeatureVector()
|
||||
second.Features.Val = *NewRawFeatureVector()
|
||||
|
||||
require.Equal(t, first, second)
|
||||
}
|
||||
|
||||
wireMsgHarnessCustom(t, data, MsgNodeAnnouncement2, assertEq)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzOpenChannel(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// We can't use require.Equal for UpfrontShutdownScript, since
|
||||
|
||||
+7
-2
@@ -64,6 +64,7 @@ const (
|
||||
MsgReplyChannelRange = 264
|
||||
MsgGossipTimestampRange = 265
|
||||
MsgChannelAnnouncement2 = 267
|
||||
MsgNodeAnnouncement2 = 269
|
||||
MsgChannelUpdate2 = 271
|
||||
MsgKickoffSig = 777
|
||||
|
||||
@@ -166,7 +167,7 @@ func (t MessageType) String() string {
|
||||
case MsgChannelUpdate:
|
||||
return "ChannelUpdate"
|
||||
case MsgNodeAnnouncement:
|
||||
return "NodeAnnouncement"
|
||||
return "NodeAnnouncement1"
|
||||
case MsgPing:
|
||||
return "Ping"
|
||||
case MsgAnnounceSignatures:
|
||||
@@ -193,6 +194,8 @@ func (t MessageType) String() string {
|
||||
return "MsgAnnounceSignatures2"
|
||||
case MsgChannelAnnouncement2:
|
||||
return "ChannelAnnouncement2"
|
||||
case MsgNodeAnnouncement2:
|
||||
return "NodeAnnouncement2"
|
||||
case MsgChannelUpdate2:
|
||||
return "ChannelUpdate2"
|
||||
default:
|
||||
@@ -330,7 +333,7 @@ func makeEmptyMessage(msgType MessageType) (Message, error) {
|
||||
case MsgChannelUpdate:
|
||||
msg = &ChannelUpdate1{}
|
||||
case MsgNodeAnnouncement:
|
||||
msg = &NodeAnnouncement{}
|
||||
msg = &NodeAnnouncement1{}
|
||||
case MsgPing:
|
||||
msg = &Ping{}
|
||||
case MsgAnnounceSignatures:
|
||||
@@ -355,6 +358,8 @@ func makeEmptyMessage(msgType MessageType) (Message, error) {
|
||||
msg = &AnnounceSignatures2{}
|
||||
case MsgChannelAnnouncement2:
|
||||
msg = &ChannelAnnouncement2{}
|
||||
case MsgNodeAnnouncement2:
|
||||
msg = &NodeAnnouncement2{}
|
||||
case MsgChannelUpdate2:
|
||||
msg = &ChannelUpdate2{}
|
||||
default:
|
||||
|
||||
@@ -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),
|
||||
|
||||
+14
-15
@@ -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,19 +100,19 @@ 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)
|
||||
|
||||
// A compile time check to ensure NodeAnnouncement implements the
|
||||
// A compile time check to ensure NodeAnnouncement1 implements the
|
||||
// lnwire.SizeableMessage interface.
|
||||
var _ SizeableMessage = (*NodeAnnouncement)(nil)
|
||||
var _ SizeableMessage = (*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, _ uint32) error {
|
||||
func (a *NodeAnnouncement1) Decode(r io.Reader, _ uint32) error {
|
||||
err := ReadElements(r,
|
||||
&a.Signature,
|
||||
&a.Features,
|
||||
@@ -130,11 +130,11 @@ func (a *NodeAnnouncement) Decode(r io.Reader, _ uint32) error {
|
||||
return a.ExtraOpaqueData.ValidateTLV()
|
||||
}
|
||||
|
||||
// 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, pver uint32) error {
|
||||
if err := WriteSig(w, a.Signature); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -170,13 +170,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)
|
||||
@@ -215,6 +214,6 @@ func (a *NodeAnnouncement) DataToSign() ([]byte, error) {
|
||||
// SerializedSize returns the serialized size of the message in bytes.
|
||||
//
|
||||
// This is part of the lnwire.SizeableMessage interface.
|
||||
func (a *NodeAnnouncement) SerializedSize() (uint32, error) {
|
||||
func (a *NodeAnnouncement1) SerializedSize() (uint32, error) {
|
||||
return MessageSerializedSize(a)
|
||||
}
|
||||
@@ -0,0 +1,581 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io"
|
||||
"net"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
"github.com/lightningnetwork/lnd/tor"
|
||||
)
|
||||
|
||||
// NodeAnnouncement2 message is used to announce the presence of a Lightning
|
||||
// node and also to signal that the node is accepting incoming connections.
|
||||
// Each NodeAnnouncement2 authenticating the advertised information within the
|
||||
// announcement via a signature using the advertised node pubkey.
|
||||
type NodeAnnouncement2 struct {
|
||||
// Features is the feature vector that encodes the features supported
|
||||
// by the target node.
|
||||
Features tlv.RecordT[tlv.TlvType0, RawFeatureVector]
|
||||
|
||||
// Color is an optional field used to customize a node's appearance in
|
||||
// maps and graphs.
|
||||
Color tlv.OptionalRecordT[tlv.TlvType1, Color]
|
||||
|
||||
// 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 tlv.RecordT[tlv.TlvType2, uint32]
|
||||
|
||||
// Alias is used to customize their node's appearance in maps and
|
||||
// graphs.
|
||||
Alias tlv.OptionalRecordT[tlv.TlvType3, NodeAlias2]
|
||||
|
||||
// NodeID is the public key of the node creating the announcement.
|
||||
NodeID tlv.RecordT[tlv.TlvType4, [33]byte]
|
||||
|
||||
// IPV4Addrs is an optional list of ipv4 addresses that the node is
|
||||
// reachable at.
|
||||
IPV4Addrs tlv.OptionalRecordT[tlv.TlvType5, IPV4Addrs]
|
||||
|
||||
// IPV6Addrs is an optional list of ipv6 addresses that the node is
|
||||
// reachable at.
|
||||
IPV6Addrs tlv.OptionalRecordT[tlv.TlvType7, IPV6Addrs]
|
||||
|
||||
// TorV3Addrs is an optional list of tor v3 addresses that the node is
|
||||
// reachable at.
|
||||
TorV3Addrs tlv.OptionalRecordT[tlv.TlvType9, TorV3Addrs]
|
||||
|
||||
// DNSHostName is an optional DNS hostname that the node is reachable
|
||||
// at.
|
||||
DNSHostName tlv.OptionalRecordT[tlv.TlvType11, DNSAddress]
|
||||
|
||||
// Signature is used to validate the announced data and prove the
|
||||
// ownership of node id.
|
||||
Signature tlv.RecordT[tlv.TlvType160, Sig]
|
||||
|
||||
// Any extra fields in the signed range that we do not yet know about,
|
||||
// but we need to keep them for signature validation and to produce a
|
||||
// valid message.
|
||||
ExtraSignedFields
|
||||
}
|
||||
|
||||
// SerializedSize returns the serialized size of the message in bytes.
|
||||
//
|
||||
// This is part of the lnwire.SizeableMessage interface.
|
||||
func (n *NodeAnnouncement2) SerializedSize() (uint32, error) {
|
||||
return MessageSerializedSize(n)
|
||||
}
|
||||
|
||||
// AllRecords returns all the TLV records for the message. This will include all
|
||||
// the records we know about along with any that we don't know about but that
|
||||
// fall in the signed TLV range.
|
||||
//
|
||||
// NOTE: this is part of the PureTLVMessage interface.
|
||||
func (n *NodeAnnouncement2) AllRecords() []tlv.Record {
|
||||
recordProducers := []tlv.RecordProducer{
|
||||
&n.Features,
|
||||
&n.BlockHeight,
|
||||
&n.NodeID,
|
||||
&n.Signature,
|
||||
}
|
||||
|
||||
n.Color.WhenSome(func(r tlv.RecordT[tlv.TlvType1, Color]) {
|
||||
recordProducers = append(recordProducers, &r)
|
||||
})
|
||||
|
||||
n.Alias.WhenSome(func(a tlv.RecordT[tlv.TlvType3, NodeAlias2]) {
|
||||
recordProducers = append(recordProducers, &a)
|
||||
})
|
||||
|
||||
n.IPV4Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType5, IPV4Addrs]) {
|
||||
recordProducers = append(recordProducers, &r)
|
||||
})
|
||||
|
||||
n.IPV6Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType7, IPV6Addrs]) {
|
||||
recordProducers = append(recordProducers, &r)
|
||||
})
|
||||
|
||||
n.TorV3Addrs.WhenSome(func(r tlv.RecordT[tlv.TlvType9, TorV3Addrs]) {
|
||||
recordProducers = append(recordProducers, &r)
|
||||
})
|
||||
|
||||
n.DNSHostName.WhenSome(func(r tlv.RecordT[tlv.TlvType11, DNSAddress]) {
|
||||
recordProducers = append(recordProducers, &r)
|
||||
})
|
||||
|
||||
recordProducers = append(recordProducers, RecordsAsProducers(
|
||||
tlv.MapToRecords(n.ExtraSignedFields),
|
||||
)...)
|
||||
|
||||
return ProduceRecordsSorted(recordProducers...)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
var (
|
||||
color = tlv.ZeroRecordT[tlv.TlvType1, Color]()
|
||||
alias = tlv.ZeroRecordT[tlv.TlvType3, NodeAlias2]()
|
||||
ipv4 = tlv.ZeroRecordT[tlv.TlvType5, IPV4Addrs]()
|
||||
ipv6 = tlv.ZeroRecordT[tlv.TlvType7, IPV6Addrs]()
|
||||
torV3 = tlv.ZeroRecordT[tlv.TlvType9, TorV3Addrs]()
|
||||
dns = tlv.ZeroRecordT[tlv.TlvType11, DNSAddress]()
|
||||
)
|
||||
|
||||
stream, err := tlv.NewStream(ProduceRecordsSorted(
|
||||
&n.Features,
|
||||
&n.BlockHeight,
|
||||
&n.NodeID,
|
||||
&n.Signature,
|
||||
&alias,
|
||||
&color,
|
||||
&ipv4,
|
||||
&ipv6,
|
||||
&torV3,
|
||||
&dns,
|
||||
)...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.Signature.Val.ForceSchnorr()
|
||||
|
||||
typeMap, err := stream.DecodeWithParsedTypesP2P(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := typeMap[n.Alias.TlvType()]; ok {
|
||||
n.Alias = tlv.SomeRecordT(alias)
|
||||
}
|
||||
|
||||
if _, ok := typeMap[n.Color.TlvType()]; ok {
|
||||
n.Color = tlv.SomeRecordT(color)
|
||||
}
|
||||
|
||||
if _, ok := typeMap[n.IPV4Addrs.TlvType()]; ok {
|
||||
n.IPV4Addrs = tlv.SomeRecordT(ipv4)
|
||||
}
|
||||
|
||||
if _, ok := typeMap[n.IPV6Addrs.TlvType()]; ok {
|
||||
n.IPV6Addrs = tlv.SomeRecordT(ipv6)
|
||||
}
|
||||
|
||||
if _, ok := typeMap[n.TorV3Addrs.TlvType()]; ok {
|
||||
n.TorV3Addrs = tlv.SomeRecordT(torV3)
|
||||
}
|
||||
|
||||
if _, ok := typeMap[n.DNSHostName.TlvType()]; ok {
|
||||
n.DNSHostName = tlv.SomeRecordT(dns)
|
||||
}
|
||||
|
||||
n.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
|
||||
|
||||
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 {
|
||||
return EncodePureTLVMessage(n, w)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// A compile-time check to ensure NodeAnnouncement2 implements the Message
|
||||
// interface.
|
||||
var _ Message = (*NodeAnnouncement2)(nil)
|
||||
|
||||
// A compile-time check to ensure NodeAnnouncement2 implements the
|
||||
// PureTLVMessage interface.
|
||||
var _ PureTLVMessage = (*NodeAnnouncement2)(nil)
|
||||
|
||||
// A compile time check to ensure ChannelAnnouncement2 implements the
|
||||
// lnwire.SizeableMessage interface.
|
||||
var _ SizeableMessage = (*NodeAnnouncement2)(nil)
|
||||
|
||||
// NodeAlias2 represents a UTF-8 encoded node alias with a maximum length of 32
|
||||
// bytes.
|
||||
type NodeAlias2 []byte
|
||||
|
||||
// Record returns a TLV record for encoding/decoding NodeAlias2.
|
||||
func (n *NodeAlias2) Record() tlv.Record {
|
||||
sizeFunc := func() uint64 {
|
||||
return uint64(len(*n))
|
||||
}
|
||||
|
||||
return tlv.MakeDynamicRecord(
|
||||
0, n, sizeFunc, nodeAlias2Encoder, nodeAlias2Decoder,
|
||||
)
|
||||
}
|
||||
|
||||
// ValidateNodeAlias2 validates that the node alias is valid UTF-8 and within
|
||||
// the 32-byte limit.
|
||||
func ValidateNodeAlias2(alias []byte) error {
|
||||
if len(alias) == 0 {
|
||||
return errors.New("node alias cannot be empty")
|
||||
}
|
||||
|
||||
if len(alias) > 32 {
|
||||
return fmt.Errorf("node alias exceeds 32 bytes: length %d",
|
||||
len(alias))
|
||||
}
|
||||
|
||||
if !utf8.Valid(alias) {
|
||||
return errors.New("node alias contains invalid UTF-8")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// nodeAlias2Encoder encodes a NodeAlias2 as raw UTF-8 bytes.
|
||||
func nodeAlias2Encoder(w io.Writer, val any, _ *[8]byte) error {
|
||||
if v, ok := val.(*NodeAlias2); ok {
|
||||
if err := ValidateNodeAlias2(*v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := w.Write(*v)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return tlv.NewTypeForEncodingErr(val, "NodeAlias2")
|
||||
}
|
||||
|
||||
// nodeAlias2Decoder decodes raw bytes into a NodeAlias2.
|
||||
func nodeAlias2Decoder(r io.Reader, val any, _ *[8]byte, l uint64) error {
|
||||
if v, ok := val.(*NodeAlias2); ok {
|
||||
if l > 32 {
|
||||
return fmt.Errorf("node alias exceeds 32 bytes: %d", l)
|
||||
}
|
||||
|
||||
aliasBytes := make([]byte, l)
|
||||
if _, err := io.ReadFull(r, aliasBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ValidateNodeAlias2(aliasBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = aliasBytes
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return tlv.NewTypeForDecodingErr(val, "NodeAlias2", l, 0)
|
||||
}
|
||||
|
||||
// Color is a custom type to represent a color.RGBA that can be encoded/decoded
|
||||
// as a TLV record.
|
||||
type Color color.RGBA
|
||||
|
||||
// Record returns a TLV record for encoding/decoding Color.
|
||||
func (c *Color) Record() tlv.Record {
|
||||
return tlv.MakeStaticRecord(0, c, 3, rgbEncoder, rgbDecoder)
|
||||
}
|
||||
|
||||
// rgbEncoder encodes a Color as RGB bytes.
|
||||
func rgbEncoder(w io.Writer, val any, _ *[8]byte) error {
|
||||
if v, ok := val.(*Color); ok {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
err := WriteColorRGBA(buf, color.RGBA(*v))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(buf.Bytes())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return tlv.NewTypeForEncodingErr(val, "Color")
|
||||
}
|
||||
|
||||
// rgbDecoder decodes RGB bytes into a Color.
|
||||
func rgbDecoder(r io.Reader, val any, _ *[8]byte, l uint64) error {
|
||||
if v, ok := val.(*Color); ok {
|
||||
return ReadElements(r, &v.R, &v.G, &v.B)
|
||||
}
|
||||
|
||||
return tlv.NewTypeForDecodingErr(val, "Color", l, 3)
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// IPV4Addrs is a list of ipv4 addresses that can be encoded as a TLV record.
|
||||
type IPV4Addrs []*net.TCPAddr
|
||||
|
||||
// Record returns a Record that can be used to encode/decode a IPV4Addrs
|
||||
// to/from a TLV stream.
|
||||
func (a *IPV4Addrs) Record() tlv.Record {
|
||||
return tlv.MakeDynamicRecord(
|
||||
0, a, a.encodedSize, ipv4AddrsEncoder, ipv4AddrsDecoder,
|
||||
)
|
||||
}
|
||||
|
||||
// encodedSize returns the number of bytes required to encode an IPV4Addrs
|
||||
// variable.
|
||||
func (a *IPV4Addrs) encodedSize() uint64 {
|
||||
return uint64(len(*a) * ipv4AddrEncodedSize)
|
||||
}
|
||||
|
||||
// ipv4AddrsEncoder encodes IPv4 addresses as TLV bytes.
|
||||
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[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return tlv.NewTypeForEncodingErr(val, "lnwire.IPV4Addrs")
|
||||
}
|
||||
|
||||
// ipv4AddrsDecoder decodes TLV bytes into IPv4 addresses.
|
||||
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
|
||||
|
||||
// Record returns a Record that can be used to encode/decode a IPV4Addrs
|
||||
// to/from a TLV stream.
|
||||
func (a *IPV6Addrs) Record() tlv.Record {
|
||||
return tlv.MakeDynamicRecord(
|
||||
0, a, a.encodedSize, ipv6AddrsEncoder, ipv6AddrsDecoder,
|
||||
)
|
||||
}
|
||||
|
||||
// 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 (a *IPV6Addrs) encodedSize() uint64 {
|
||||
return uint64(len(*a) * ipv6AddrEncodedSize)
|
||||
}
|
||||
|
||||
// ipv6AddrsEncoder encodes IPv6 addresses as TLV bytes.
|
||||
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[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return tlv.NewTypeForEncodingErr(val, "lnwire.IPV6Addrs")
|
||||
}
|
||||
|
||||
// ipv6AddrsDecoder decodes TLV bytes into IPv6 addresses.
|
||||
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 (a *TorV3Addrs) encodedSize() uint64 {
|
||||
return uint64(len(*a) * torV3AddrEncodedSize)
|
||||
}
|
||||
|
||||
// Record returns a Record that can be used to encode/decode a IPV4Addrs
|
||||
// to/from a TLV stream.
|
||||
func (a *TorV3Addrs) Record() tlv.Record {
|
||||
return tlv.MakeDynamicRecord(
|
||||
0, a, a.encodedSize, torV3AddrsEncoder, torV3AddrsDecoder,
|
||||
)
|
||||
}
|
||||
|
||||
// torV3AddrsEncoder encodes Tor v3 addresses as TLV bytes.
|
||||
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.V3DecodedLen, len(host))
|
||||
}
|
||||
|
||||
if _, err = w.Write(host); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var port [2]byte
|
||||
binary.BigEndian.PutUint16(port[:], uint16(addr.Port))
|
||||
if _, err = w.Write(port[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return tlv.NewTypeForEncodingErr(val, "lnwire.TorV3Addrs")
|
||||
}
|
||||
|
||||
// torV3AddrsDecoder decodes TLV bytes into Tor v3 addresses.
|
||||
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
|
||||
|
||||
if len(onionService) != tor.V3Len {
|
||||
return fmt.Errorf("expected a tor v3 onion "+
|
||||
"service length of %d, got: %d",
|
||||
tor.V3Len, len(onionService))
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestNodeAnn2EncodeDecode tests the encoding and decoding of the
|
||||
// NodeAnnouncement2 message using hardcoded byte slices.
|
||||
func TestNodeAnn2EncodeDecode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// We'll create a raw byte stream that represents a valid
|
||||
// NodeAnnouncement2 message with various known and unknown fields in
|
||||
// the signed TLV ranges along with the signature in the unsigned range.
|
||||
rawBytes := []byte{
|
||||
// Features record.
|
||||
0x00, // type.
|
||||
0x02, // length.
|
||||
0x1, 0x2, // value.
|
||||
|
||||
// Color record (optional).
|
||||
0x01, // type.
|
||||
0x03, // length.
|
||||
0xff, 0x00, 0x80, // value: RGB(255, 0, 128).
|
||||
|
||||
// BlockHeight record.
|
||||
0x02, // type.
|
||||
0x04, // length.
|
||||
0x00, 0x01, 0x86, 0xa0, // value: 100000.
|
||||
|
||||
// Alias record (optional).
|
||||
0x03, // type.
|
||||
0x20, // length (32).
|
||||
0x4c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e,
|
||||
0x67, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x54,
|
||||
0x65, 0x73, 0x74, 0x20, 0x41, 0x6c, 0x69, 0x61,
|
||||
0x73, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x21, 0x00, // value.
|
||||
|
||||
// NodeID record.
|
||||
0x04, // type.
|
||||
0x21, // length.
|
||||
0x02, 0x28, 0xf2, 0xaf, 0xa, 0xbe, 0x32, 0x24, 0x3, 0x48, 0xf,
|
||||
0xb3, 0xee, 0x17, 0x2f, 0x7f, 0x16, 0x1, 0xe6, 0x7d, 0x1d, 0xa6,
|
||||
0xca, 0xd4, 0xb, 0x54, 0xc4, 0x46, 0x8d, 0x48, 0x23, 0x6c, 0x39,
|
||||
|
||||
// IPV4Addrs record (optional).
|
||||
0x05, // type.
|
||||
0x0c, // length (12 bytes).
|
||||
0x0a, 0x00, 0x00, 0x01, 0x23, 0x28, // 10.0.0.1:9000
|
||||
0x0a, 0x00, 0x00, 0x01, 0x1f, 0x90, // 10.0.0.1:8080
|
||||
|
||||
// IPV6Addrs record (optional).
|
||||
0x07, // type.
|
||||
0x12, // length.
|
||||
0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, // IPv6 address
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // 2001:db8::1
|
||||
0x1f, 0x40, // port 8000
|
||||
|
||||
// TorV3Addrs record (optional).
|
||||
0x09, // type.
|
||||
0x25, // length (37 bytes = 1 address).
|
||||
// value: 35-byte tor v3 address + 2-byte port.
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
0x21, 0x22, 0x23,
|
||||
0x23, 0x28, // port 9000.
|
||||
|
||||
// DNSHostName record (optional).
|
||||
0x0b, // type (11).
|
||||
0x17, // length (23).
|
||||
0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e,
|
||||
0x67, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, // value.
|
||||
0x65, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x23, 0x28, // port 9000.
|
||||
|
||||
// Signature.
|
||||
0xa0, // type.
|
||||
0x40, // length.
|
||||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
|
||||
0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
||||
0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
||||
0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
||||
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
|
||||
0x3f, // value.
|
||||
}
|
||||
secondSignedRangeType := new(bytes.Buffer)
|
||||
var buf [8]byte
|
||||
err := tlv.WriteVarInt(
|
||||
secondSignedRangeType, pureTLVSignedSecondRangeStart+1, &buf,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
rawBytes = append(rawBytes, secondSignedRangeType.Bytes()...) // type.
|
||||
rawBytes = append(rawBytes, []byte{
|
||||
0x02, // length.
|
||||
0x79, 0x79, // value.
|
||||
}...)
|
||||
|
||||
// Now, create a new empty message and decode the raw bytes into it.
|
||||
msg := &NodeAnnouncement2{}
|
||||
r := bytes.NewReader(rawBytes)
|
||||
err = msg.Decode(r, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Next, encode the message back into a new byte buffer.
|
||||
var b bytes.Buffer
|
||||
err = msg.Encode(&b, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
// The re-encoded bytes should be exactly the same as the original raw
|
||||
// bytes.
|
||||
require.Equal(t, rawBytes, b.Bytes())
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
)
|
||||
|
||||
// OutPoint describes an outpoint of a transaction via its transaction hash
|
||||
// and the outpoint index. This is a thin wrapper around the wire.OutPoint to
|
||||
// provide TLV encoding/decoding.
|
||||
type OutPoint wire.OutPoint
|
||||
|
||||
// Record returns a TLV record that can be used to encode/decode the OutPoint.
|
||||
//
|
||||
// NOTE: this is part of the tlv.RecordProducer interface.
|
||||
func (o *OutPoint) Record() tlv.Record {
|
||||
return tlv.MakeStaticRecord(0, o, 34, outpointEncoder, outpointDecoder)
|
||||
}
|
||||
|
||||
// outpointEncoder is a TLV encoder for OutPoint.
|
||||
func outpointEncoder(w io.Writer, val any, _ *[8]byte) error {
|
||||
if v, ok := val.(*OutPoint); ok {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
err := WriteOutPoint(buf, wire.OutPoint(*v))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(buf.Bytes())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return tlv.NewTypeForEncodingErr(val, "OutPoint")
|
||||
}
|
||||
|
||||
// outpointDecoder is a TLV decoder for OutPoint.
|
||||
func outpointDecoder(r io.Reader, val any, _ *[8]byte, l uint64) error {
|
||||
if v, ok := val.(*OutPoint); ok {
|
||||
var o wire.OutPoint
|
||||
if err := ReadElement(r, &o); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = OutPoint(o)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return tlv.NewTypeForDecodingErr(val, "OutPoint", l, 34)
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
"github.com/stretchr/testify/require"
|
||||
"pgregory.net/rapid"
|
||||
)
|
||||
|
||||
// TestOutPointTLVEncoding tests the TLV encoding and decoding of OutPoint
|
||||
// structs using the Record interface.
|
||||
func TestOutPointTLVEncoding(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testOutPoint := OutPoint(wire.OutPoint{
|
||||
Hash: chainhash.Hash{
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
},
|
||||
Index: 12345,
|
||||
})
|
||||
|
||||
var extraData ExtraOpaqueData
|
||||
require.NoError(t, extraData.PackRecords(&testOutPoint))
|
||||
|
||||
var decodedOutPoint OutPoint
|
||||
tlvs, err := extraData.ExtractRecords(&decodedOutPoint)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Contains(t, tlvs, tlv.Type(0))
|
||||
require.Equal(t, testOutPoint, decodedOutPoint)
|
||||
}
|
||||
|
||||
// TestOutPointRecord tests the TLV Record interface of OutPoint
|
||||
// by directly encoding and decoding using the Record method.
|
||||
func TestOutPointRecord(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testOutPoint := OutPoint(wire.OutPoint{
|
||||
Hash: chainhash.Hash{
|
||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
|
||||
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
|
||||
0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
|
||||
0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
|
||||
},
|
||||
Index: 65535,
|
||||
})
|
||||
|
||||
var buf bytes.Buffer
|
||||
record := testOutPoint.Record()
|
||||
require.NoError(t, record.Encode(&buf))
|
||||
|
||||
var decodedOutPoint OutPoint
|
||||
decodedRecord := decodedOutPoint.Record()
|
||||
require.NoError(t, decodedRecord.Decode(&buf, uint64(buf.Len())))
|
||||
|
||||
require.Equal(t, testOutPoint, decodedOutPoint)
|
||||
}
|
||||
|
||||
// TestOutPointProperty uses property-based testing to verify that OutPoint
|
||||
// TLV encoding and decoding is correct for random OutPoint values.
|
||||
func TestOutPointProperty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
scenario := func(t *rapid.T) {
|
||||
wireOutPoint := RandOutPoint(t)
|
||||
lnOutPoint := OutPoint(wireOutPoint)
|
||||
|
||||
var buf bytes.Buffer
|
||||
record := lnOutPoint.Record()
|
||||
err := record.Encode(&buf)
|
||||
require.NoError(t, err)
|
||||
|
||||
var decodedOutPoint OutPoint
|
||||
decodedRecord := decodedOutPoint.Record()
|
||||
err = decodedRecord.Decode(&buf, uint64(buf.Len()))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, lnOutPoint, decodedOutPoint)
|
||||
require.Equal(t, wireOutPoint, wire.OutPoint(decodedOutPoint))
|
||||
}
|
||||
|
||||
rapid.Check(t, scenario)
|
||||
}
|
||||
|
||||
// TestOutPointZeroValues tests that OutPoint handles zero values correctly.
|
||||
func TestOutPointZeroValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
zeroOutPoint := OutPoint(wire.OutPoint{})
|
||||
|
||||
var buf bytes.Buffer
|
||||
record := zeroOutPoint.Record()
|
||||
require.NoError(t, record.Encode(&buf))
|
||||
|
||||
var decodedOutPoint OutPoint
|
||||
decodedRecord := decodedOutPoint.Record()
|
||||
require.NoError(t, decodedRecord.Decode(&buf, uint64(buf.Len())))
|
||||
|
||||
require.Equal(t, zeroOutPoint, decodedOutPoint)
|
||||
}
|
||||
+172
-4
@@ -5,12 +5,14 @@ import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"math"
|
||||
"net"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/lightningnetwork/lnd/fn/v2"
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
"github.com/lightningnetwork/lnd/tor"
|
||||
"github.com/stretchr/testify/require"
|
||||
"pgregory.net/rapid"
|
||||
)
|
||||
@@ -291,6 +293,10 @@ func (c *ChannelAnnouncement2) RandTestMessage(t *rapid.T) Message {
|
||||
)
|
||||
}
|
||||
|
||||
msg.Outpoint = tlv.NewRecordT[tlv.TlvType18, OutPoint](
|
||||
OutPoint(RandOutPoint(t)),
|
||||
)
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
@@ -565,6 +571,18 @@ func (c *ChannelUpdate2) RandTestMessage(t *rapid.T) Message {
|
||||
ExtraSignedFields: make(map[uint64][]byte),
|
||||
}
|
||||
|
||||
if rapid.Bool().Draw(t, "includeInboundFee") {
|
||||
base := rapid.IntRange(-1000, 1000).Draw(t, "inFeeBase")
|
||||
rate := rapid.IntRange(-1000, 1000).Draw(t, "inFeeProp")
|
||||
fee := Fee{
|
||||
BaseFee: int32(base),
|
||||
FeeRate: int32(rate),
|
||||
}
|
||||
msg.InboundFee = tlv.SomeRecordT(
|
||||
tlv.NewRecordT[tlv.TlvType55555](fee),
|
||||
)
|
||||
}
|
||||
|
||||
msg.Signature.Val = RandSignature(t)
|
||||
msg.Signature.Val.ForceSchnorr()
|
||||
|
||||
@@ -1211,15 +1229,19 @@ func (ks *KickoffSig) RandTestMessage(t *rapid.T) Message {
|
||||
}
|
||||
}
|
||||
|
||||
// A compile time check to ensure NodeAnnouncement implements the
|
||||
// A compile time check to ensure NodeAnnouncement1 implements the
|
||||
// lnwire.TestMessage interface.
|
||||
var _ TestMessage = (*NodeAnnouncement)(nil)
|
||||
var _ TestMessage = (*NodeAnnouncement1)(nil)
|
||||
|
||||
// A compile time check to ensure NodeAnnouncement2 implements the
|
||||
// lnwire.TestMessage interface.
|
||||
var _ TestMessage = (*NodeAnnouncement2)(nil)
|
||||
|
||||
// RandTestMessage populates the message with random data suitable for testing.
|
||||
// It uses the rapid testing framework to generate random values.
|
||||
//
|
||||
// This is part of the TestMessage interface.
|
||||
func (a *NodeAnnouncement) RandTestMessage(t *rapid.T) Message {
|
||||
func (a *NodeAnnouncement1) RandTestMessage(t *rapid.T) Message {
|
||||
// Generate random compressed public key for node ID
|
||||
pubKey := RandPubKey(t)
|
||||
var nodeID [33]byte
|
||||
@@ -1232,7 +1254,7 @@ func (a *NodeAnnouncement) RandTestMessage(t *rapid.T) Message {
|
||||
B: uint8(rapid.IntRange(0, 255).Draw(t, "rgbB")),
|
||||
}
|
||||
|
||||
return &NodeAnnouncement{
|
||||
return &NodeAnnouncement1{
|
||||
Signature: RandSignature(t),
|
||||
Features: RandFeatureVector(t),
|
||||
Timestamp: uint32(rapid.IntRange(0, 0x7FFFFFFF).Draw(
|
||||
@@ -1246,6 +1268,131 @@ func (a *NodeAnnouncement) RandTestMessage(t *rapid.T) Message {
|
||||
}
|
||||
}
|
||||
|
||||
// RandTestMessage populates the message with random data suitable for testing.
|
||||
// It uses the rapid testing framework to generate random values.
|
||||
//
|
||||
// This is part of the TestMessage interface.
|
||||
func (n *NodeAnnouncement2) RandTestMessage(t *rapid.T) Message {
|
||||
features := RandFeatureVector(t)
|
||||
blockHeight := uint32(rapid.IntRange(0, 1000000).Draw(t, "blockHeight"))
|
||||
|
||||
// Generate random compressed public key for node ID
|
||||
pubKey := RandPubKey(t)
|
||||
var nodeID [33]byte
|
||||
copy(nodeID[:], pubKey.SerializeCompressed())
|
||||
|
||||
msg := &NodeAnnouncement2{
|
||||
Features: tlv.NewRecordT[tlv.TlvType0](*features),
|
||||
BlockHeight: tlv.NewPrimitiveRecord[tlv.TlvType2](
|
||||
blockHeight,
|
||||
),
|
||||
NodeID: tlv.NewPrimitiveRecord[tlv.TlvType4](nodeID),
|
||||
ExtraSignedFields: make(map[uint64][]byte),
|
||||
}
|
||||
|
||||
msg.Signature.Val = RandSignature(t)
|
||||
msg.Signature.Val.ForceSchnorr()
|
||||
|
||||
// Test optional fields one by one
|
||||
if rapid.Bool().Draw(t, "includeColor") {
|
||||
rgbColor := Color{
|
||||
R: uint8(rapid.IntRange(0, 255).Draw(t, "rgbR")),
|
||||
G: uint8(rapid.IntRange(0, 255).Draw(t, "rgbG")),
|
||||
B: uint8(rapid.IntRange(0, 255).Draw(t, "rgbB")),
|
||||
}
|
||||
colorRecord := tlv.ZeroRecordT[tlv.TlvType1, Color]()
|
||||
colorRecord.Val = rgbColor
|
||||
msg.Color = tlv.SomeRecordT(colorRecord)
|
||||
}
|
||||
|
||||
if rapid.Bool().Draw(t, "includeAlias") {
|
||||
aliasBytes := RandNodeAlias2(t)
|
||||
aliasRecord := tlv.ZeroRecordT[tlv.TlvType3, NodeAlias2]()
|
||||
aliasRecord.Val = aliasBytes
|
||||
msg.Alias = tlv.SomeRecordT(aliasRecord)
|
||||
}
|
||||
|
||||
if rapid.Bool().Draw(t, "includeIPV4Addrs") {
|
||||
ipv4Addrs := make(IPV4Addrs, 1)
|
||||
ip := make(net.IP, 4)
|
||||
ip[0] = uint8(rapid.IntRange(1, 223).Draw(t, "ip4_0"))
|
||||
ip[1] = uint8(rapid.IntRange(0, 255).Draw(t, "ip4_1"))
|
||||
ip[2] = uint8(rapid.IntRange(0, 255).Draw(t, "ip4_2"))
|
||||
ip[3] = uint8(rapid.IntRange(1, 254).Draw(t, "ip4_3"))
|
||||
|
||||
ipv4Addrs[0] = &net.TCPAddr{
|
||||
IP: ip,
|
||||
Port: rapid.IntRange(1, 65535).Draw(t, "port4"),
|
||||
}
|
||||
|
||||
ipv4Record := tlv.ZeroRecordT[tlv.TlvType5, IPV4Addrs]()
|
||||
ipv4Record.Val = ipv4Addrs
|
||||
msg.IPV4Addrs = tlv.SomeRecordT(ipv4Record)
|
||||
}
|
||||
|
||||
if rapid.Bool().Draw(t, "includeIPV6Addrs") {
|
||||
ipv6Addrs := make(IPV6Addrs, 1)
|
||||
ip := make(net.IP, 16)
|
||||
// Generate random IPv6 address.
|
||||
for j := 0; j < 16; j++ {
|
||||
ip[j] = uint8(rapid.IntRange(0, 255).Draw(
|
||||
t, fmt.Sprintf("ip6_%d", j)),
|
||||
)
|
||||
}
|
||||
|
||||
ipv6Addrs[0] = &net.TCPAddr{
|
||||
IP: ip,
|
||||
Port: rapid.IntRange(1, 65535).Draw(t, "port6"),
|
||||
}
|
||||
|
||||
ipv6Record := tlv.ZeroRecordT[tlv.TlvType7, IPV6Addrs]()
|
||||
ipv6Record.Val = ipv6Addrs
|
||||
msg.IPV6Addrs = tlv.SomeRecordT(ipv6Record)
|
||||
}
|
||||
|
||||
if rapid.Bool().Draw(t, "includeTorV3Addrs") {
|
||||
torV3Addrs := make(TorV3Addrs, 1)
|
||||
onionBytes := rapid.SliceOfN(rapid.Byte(), 35, 35).Draw(
|
||||
t, "onion",
|
||||
)
|
||||
onionService := tor.Base32Encoding.EncodeToString(onionBytes) +
|
||||
tor.OnionSuffix
|
||||
|
||||
torV3Addrs[0] = &tor.OnionAddr{
|
||||
OnionService: onionService,
|
||||
Port: rapid.IntRange(1, 65535).Draw(
|
||||
t, "torPort",
|
||||
),
|
||||
}
|
||||
|
||||
torV3Record := tlv.ZeroRecordT[tlv.TlvType9, TorV3Addrs]()
|
||||
torV3Record.Val = torV3Addrs
|
||||
msg.TorV3Addrs = tlv.SomeRecordT(torV3Record)
|
||||
}
|
||||
|
||||
if rapid.Bool().Draw(t, "includeDNSHostName") {
|
||||
// Generate a valid DNS hostname.
|
||||
hostname := genValidHostname(t)
|
||||
port := rapid.Uint16Range(1, 65535).Draw(t, "dnsPort")
|
||||
|
||||
dnsAddr := DNSAddress{
|
||||
Hostname: hostname,
|
||||
Port: port,
|
||||
}
|
||||
|
||||
dnsRecord := tlv.ZeroRecordT[tlv.TlvType11, DNSAddress]()
|
||||
dnsRecord.Val = dnsAddr
|
||||
msg.DNSHostName = tlv.SomeRecordT(dnsRecord)
|
||||
}
|
||||
|
||||
randRecs, _ := RandSignedRangeRecords(t)
|
||||
if len(randRecs) > 0 {
|
||||
msg.ExtraSignedFields = ExtraSignedFields(randRecs)
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
// A compile time check to ensure OpenChannel implements the TestMessage
|
||||
// interface.
|
||||
var _ TestMessage = (*OpenChannel)(nil)
|
||||
@@ -1851,3 +1998,24 @@ func (c *Error) RandTestMessage(t *rapid.T) Message {
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
// genValidHostname generates a random valid hostname according to BOLT #7
|
||||
// rules.
|
||||
func genValidHostname(t *rapid.T) string {
|
||||
// Valid characters: a-z, A-Z, 0-9, -, .
|
||||
validChars := "abcdefghijklmnopqrstuvwxyzABCDE" +
|
||||
"FGHIJKLMNOPQRSTUVWXYZ0123456789-."
|
||||
|
||||
// Generate hostname length between 1 and 255 characters.
|
||||
length := rapid.IntRange(1, 255).Draw(t, "hostname_length")
|
||||
|
||||
hostname := make([]byte, length)
|
||||
for i := 0; i < length; i++ {
|
||||
charIndex := rapid.IntRange(0, len(validChars)-1).Draw(
|
||||
t, fmt.Sprintf("char_%d", i),
|
||||
)
|
||||
hostname[i] = validChars[charIndex]
|
||||
}
|
||||
|
||||
return string(hostname)
|
||||
}
|
||||
@@ -152,6 +152,19 @@ func RandNodeAlias(t *rapid.T) NodeAlias {
|
||||
return alias
|
||||
}
|
||||
|
||||
// RandNodeAlias2 generates a random node alias that is compatible with
|
||||
// NodeAlias2 validation (non-empty, max 32 bytes, valid UTF-8).
|
||||
func RandNodeAlias2(t *rapid.T) NodeAlias2 {
|
||||
// Ensure length is at least 1 to satisfy NodeAlias2 validation
|
||||
aliasLength := rapid.IntRange(1, 32).Draw(t, "aliasLength")
|
||||
|
||||
aliasBytes := rapid.SliceOfN(
|
||||
rapid.SampledFrom([]rune(charset)), aliasLength, aliasLength,
|
||||
).Draw(t, "alias")
|
||||
|
||||
return []byte(string(aliasBytes))
|
||||
}
|
||||
|
||||
// RandNetAddrs generates random network addresses.
|
||||
func RandNetAddrs(t *rapid.T) []net.Addr {
|
||||
numAddresses := rapid.IntRange(0, 5).Draw(t, "numAddresses")
|
||||
|
||||
+5
-5
@@ -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.
|
||||
|
||||
+19
-17
@@ -16,37 +16,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
|
||||
}
|
||||
}
|
||||
@@ -54,7 +56,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
|
||||
@@ -65,11 +67,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)
|
||||
@@ -83,7 +85,7 @@ func SignNodeAnnouncement(signer lnwallet.MessageSigner,
|
||||
}
|
||||
|
||||
// ValidateNodeAnn validates the fields and signature of a node announcement.
|
||||
func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error {
|
||||
func ValidateNodeAnn(a *lnwire.NodeAnnouncement1) error {
|
||||
err := ValidateNodeAnnFields(a)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid node announcement fields: %w", err)
|
||||
@@ -93,7 +95,7 @@ func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error {
|
||||
}
|
||||
|
||||
// ValidateNodeAnnFields validates the fields of a node announcement.
|
||||
func ValidateNodeAnnFields(a *lnwire.NodeAnnouncement) error {
|
||||
func ValidateNodeAnnFields(a *lnwire.NodeAnnouncement1) error {
|
||||
// Check that it only has at most one DNS address.
|
||||
hasDNSAddr := false
|
||||
for _, addr := range a.Addresses {
|
||||
@@ -120,7 +122,7 @@ func ValidateNodeAnnFields(a *lnwire.NodeAnnouncement) error {
|
||||
// ValidateNodeAnnSignature 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 ValidateNodeAnnSignature(a *lnwire.NodeAnnouncement) error {
|
||||
func ValidateNodeAnnSignature(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()
|
||||
@@ -146,7 +148,7 @@ func ValidateNodeAnnSignature(a *lnwire.NodeAnnouncement) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("signature on NodeAnnouncement(%x) is "+
|
||||
return fmt.Errorf("signature on NodeAnnouncement1(%x) is "+
|
||||
"invalid: %x", nodeKey.SerializeCompressed(),
|
||||
msgBuf.Bytes())
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+4
-4
@@ -329,7 +329,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.
|
||||
@@ -2092,7 +2092,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
|
||||
@@ -2213,7 +2213,7 @@ out:
|
||||
|
||||
case *lnwire.ChannelUpdate1,
|
||||
*lnwire.ChannelAnnouncement1,
|
||||
*lnwire.NodeAnnouncement,
|
||||
*lnwire.NodeAnnouncement1,
|
||||
*lnwire.AnnounceSignatures1,
|
||||
*lnwire.GossipTimestampRange,
|
||||
*lnwire.QueryShortChanIDs,
|
||||
@@ -2494,7 +2494,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))
|
||||
|
||||
|
||||
@@ -400,7 +400,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.
|
||||
@@ -1069,7 +1069,7 @@ func newServer(ctx context.Context, 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)
|
||||
@@ -1466,7 +1466,7 @@ func newServer(ctx context.Context, 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)
|
||||
@@ -1796,7 +1796,7 @@ func newServer(ctx context.Context, 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...,
|
||||
@@ -3306,7 +3306,7 @@ func (s *server) createNewHiddenService(ctx context.Context) 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)
|
||||
},
|
||||
)
|
||||
@@ -3357,7 +3357,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()
|
||||
|
||||
@@ -3368,7 +3368,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()
|
||||
@@ -3386,7 +3386,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
|
||||
@@ -3411,7 +3411,7 @@ func (s *server) genNodeAnnouncement(features *lnwire.RawFeatureVector,
|
||||
s.nodeSigner, s.identityKeyLoc, &newNodeAnn,
|
||||
)
|
||||
if err != nil {
|
||||
return lnwire.NodeAnnouncement{}, err
|
||||
return lnwire.NodeAnnouncement1{}, err
|
||||
}
|
||||
|
||||
// If signing succeeds, update the current announcement.
|
||||
@@ -3501,7 +3501,7 @@ func (s *server) establishPersistentConnections(ctx context.Context) 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.
|
||||
// TODO(roasbeef): instead iterate over link nodes and query graph for
|
||||
// each of the nodes.
|
||||
graphAddrs := make(map[string]*nodeAddresses)
|
||||
@@ -4394,7 +4394,7 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq,
|
||||
TowerClient: towerClient,
|
||||
DisconnectPeer: s.DisconnectPeer,
|
||||
GenNodeAnnouncement: func(...netann.NodeAnnModifier) (
|
||||
lnwire.NodeAnnouncement, error) {
|
||||
lnwire.NodeAnnouncement1, error) {
|
||||
|
||||
return s.genNodeAnnouncement(nil)
|
||||
},
|
||||
|
||||
@@ -122,7 +122,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(ctx context.Context,
|
||||
features *lnwire.RawFeatureVector,
|
||||
modifiers ...netann.NodeAnnModifier) error,
|
||||
|
||||
Reference in new issue
Block a user