Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lnwire+netann: update structure of g175 messages to be pure TLV #9175

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 39 additions & 15 deletions discovery/gossiper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
"github.com/lightninglabs/neutrino/cache"
Expand Down Expand Up @@ -166,14 +168,9 @@ type PinnedSyncers map[route.Vertex]struct{}
// Config defines the configuration for the service. ALL elements within the
// configuration MUST be non-nil for the service to carry out its duties.
type Config struct {
// ChainHash is a hash that indicates which resident chain of the
// AuthenticatedGossiper. Any announcements that don't match this
// chain hash will be ignored.
//
// TODO(roasbeef): eventually make into map so can de-multiplex
// incoming announcements
// * also need to do same for Notifier
ChainHash chainhash.Hash
// ChainParams holds the chain parameters for the active network this
// node is participating on.
ChainParams *chaincfg.Params
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be a normal value rather than a pointer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wont it copy over struct values then though?


// Graph is the subsystem which is responsible for managing the
// topology of lightning network. After incoming channel, node, channel
Expand Down Expand Up @@ -359,6 +356,12 @@ type Config struct {
// updates for a channel and returns true if the channel should be
// considered a zombie based on these timestamps.
IsStillZombieChannel func(time.Time, time.Time) bool

// chainHash is a hash that indicates which resident chain of the
// AuthenticatedGossiper. Any announcements that don't match this
// chain hash will be ignored. This is an internal config value obtained
// from ChainParams.
chainHash *chainhash.Hash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need it here if we have ChainParams?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just had it there as a helper so that we dont need to do cfg.ChainParams.GenesisHash everytime.... but happy to remove

}

// processedNetworkMsg is a wrapper around networkMsg and a boolean. It is
Expand Down Expand Up @@ -518,6 +521,8 @@ type AuthenticatedGossiper struct {
// New creates a new AuthenticatedGossiper instance, initialized with the
// passed configuration parameters.
func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper {
cfg.chainHash = cfg.ChainParams.GenesisHash

gossiper := &AuthenticatedGossiper{
selfKey: selfKeyDesc.PubKey,
selfKeyLoc: selfKeyDesc.KeyLocator,
Expand All @@ -538,7 +543,7 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper
}

gossiper.syncMgr = newSyncManager(&SyncManagerCfg{
ChainHash: cfg.ChainHash,
ChainHash: *cfg.chainHash,
ChanSeries: cfg.ChanSeries,
RotateTicker: cfg.RotateTicker,
HistoricalSyncTicker: cfg.HistoricalSyncTicker,
Expand Down Expand Up @@ -1945,9 +1950,28 @@ func (d *AuthenticatedGossiper) processRejectedEdge(

// fetchPKScript fetches the output script for the given SCID.
func (d *AuthenticatedGossiper) fetchPKScript(chanID *lnwire.ShortChannelID) (
[]byte, error) {
txscript.ScriptClass, btcutil.Address, error) {

pkScript, err := lnwallet.FetchPKScriptWithQuit(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the merkle proof case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that wont be supported from the get go. That will be a separate feature bit

d.cfg.ChainIO, chanID, d.quit,
)
if err != nil {
return txscript.WitnessUnknownTy, nil, err
}

scriptClass, addrs, _, err := txscript.ExtractPkScriptAddrs(
pkScript, d.cfg.ChainParams,
)
if err != nil {
return txscript.WitnessUnknownTy, nil, err
}

if len(addrs) != 1 {
return txscript.WitnessUnknownTy, nil, fmt.Errorf("expected "+
"1 address, got: %d", len(addrs))
}

return lnwallet.FetchPKScriptWithQuit(d.cfg.ChainIO, chanID, d.quit)
return scriptClass, addrs[0], nil
}

// addNode processes the given node announcement, and adds it to our channel
Expand Down Expand Up @@ -2447,10 +2471,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,

// We'll ignore any channel announcements that target any chain other
// than the set of chains we know of.
if !bytes.Equal(ann.ChainHash[:], d.cfg.ChainHash[:]) {
if !bytes.Equal(ann.ChainHash[:], d.cfg.chainHash[:]) {
err := fmt.Errorf("ignoring ChannelAnnouncement1 from chain=%v"+
", gossiper on chain=%v", ann.ChainHash,
d.cfg.ChainHash)
d.cfg.chainHash)
log.Errorf(err.Error())

key := newRejectCacheKey(
Expand Down Expand Up @@ -2836,9 +2860,9 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,

// We'll ignore any channel updates that target any chain other than
// the set of chains we know of.
if !bytes.Equal(upd.ChainHash[:], d.cfg.ChainHash[:]) {
if !bytes.Equal(upd.ChainHash[:], d.cfg.chainHash[:]) {
err := fmt.Errorf("ignoring ChannelUpdate from chain=%v, "+
"gossiper on chain=%v", upd.ChainHash, d.cfg.ChainHash)
"gossiper on chain=%v", upd.ChainHash, d.cfg.chainHash)
log.Errorf(err.Error())

key := newRejectCacheKey(
Expand Down
7 changes: 6 additions & 1 deletion discovery/gossiper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
Expand Down Expand Up @@ -577,6 +578,7 @@ func createUpdateAnnouncement(blockHeight uint32,

htlcMinMsat := lnwire.MilliSatoshi(prand.Int63())
a := &lnwire.ChannelUpdate1{
ChainHash: *chaincfg.MainNetParams.GenesisHash,
ShortChannelID: lnwire.ShortChannelID{
BlockHeight: blockHeight,
},
Expand Down Expand Up @@ -624,6 +626,7 @@ func createAnnouncementWithoutProof(blockHeight uint32,
extraBytes ...[]byte) *lnwire.ChannelAnnouncement1 {

a := &lnwire.ChannelAnnouncement1{
ChainHash: *chaincfg.MainNetParams.GenesisHash,
ShortChannelID: lnwire.ShortChannelID{
BlockHeight: blockHeight,
TxIndex: 0,
Expand Down Expand Up @@ -749,7 +752,8 @@ func createTestCtx(t *testing.T, startHeight uint32, isChanPeer bool) (
}

gossiper := New(Config{
Notifier: notifier,
ChainParams: &chaincfg.MainNetParams,
Notifier: notifier,
Broadcast: func(senders map[route.Vertex]struct{},
msgs ...lnwire.Message) error {

Expand Down Expand Up @@ -1463,6 +1467,7 @@ func TestSignatureAnnouncementRetryAtStartup(t *testing.T) {

//nolint:ll
gossiper := New(Config{
ChainParams: &chaincfg.MainNetParams,
Notifier: ctx.gossiper.cfg.Notifier,
Broadcast: ctx.gossiper.cfg.Broadcast,
NotifyWhenOnline: ctx.gossiper.reliableSender.cfg.NotifyWhenOnline,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ require (
github.com/lightningnetwork/lnd/queue v1.1.1
github.com/lightningnetwork/lnd/sqldb v1.0.5
github.com/lightningnetwork/lnd/ticker v1.1.1
github.com/lightningnetwork/lnd/tlv v1.2.6
github.com/lightningnetwork/lnd/tlv v1.2.7
github.com/lightningnetwork/lnd/tor v1.1.4
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796
github.com/miekg/dns v1.1.43
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ github.com/lightningnetwork/lnd/sqldb v1.0.5 h1:ax5vBPf44tN/uD6C5+hBPBjOJ7cRMrUL
github.com/lightningnetwork/lnd/sqldb v1.0.5/go.mod h1:OG09zL/PHPaBJefp4HsPz2YLUJ+zIQHbpgCtLnOx8I4=
github.com/lightningnetwork/lnd/ticker v1.1.1 h1:J/b6N2hibFtC7JLV77ULQp++QLtCwT6ijJlbdiZFbSM=
github.com/lightningnetwork/lnd/ticker v1.1.1/go.mod h1:waPTRAAcwtu7Ji3+3k+u/xH5GHovTsCoSVpho0KDvdA=
github.com/lightningnetwork/lnd/tlv v1.2.6 h1:icvQG2yDr6k3ZuZzfRdG3EJp6pHurcuh3R6dg0gv/Mw=
github.com/lightningnetwork/lnd/tlv v1.2.6/go.mod h1:/CmY4VbItpOldksocmGT4lxiJqRP9oLxwSZOda2kzNQ=
github.com/lightningnetwork/lnd/tlv v1.2.7 h1:Lko3qFw7i1laTbx0byO64AuehkscXbXPRrdfQ1UzRX8=
github.com/lightningnetwork/lnd/tlv v1.2.7/go.mod h1:/CmY4VbItpOldksocmGT4lxiJqRP9oLxwSZOda2kzNQ=
github.com/lightningnetwork/lnd/tor v1.1.4 h1:TUW27EXqoZCcCAQPlD4aaDfh8jMbBS9CghNz50qqwtA=
github.com/lightningnetwork/lnd/tor v1.1.4/go.mod h1:qSRB8llhAK+a6kaTPWOLLXSZc6Hg8ZC0mq1sUQ/8JfI=
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 h1:sjOGyegMIhvgfq5oaue6Td+hxZuf3tDC8lAPrFldqFw=
Expand Down
94 changes: 62 additions & 32 deletions lnwire/announcement_signatures_2.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package lnwire
import (
"bytes"
"io"

"github.com/lightningnetwork/lnd/tlv"
)

// AnnounceSignatures2 is a direct message between two endpoints of a
Expand All @@ -14,27 +16,40 @@ type AnnounceSignatures2 struct {
// Channel id is better for users and debugging and short channel id is
// used for quick test on existence of the particular utxo inside the
// blockchain, because it contains information about block.
ChannelID ChannelID
ChannelID tlv.RecordT[tlv.TlvType0, ChannelID]

// ShortChannelID is the unique description of the funding transaction.
// It is constructed with the most significant 3 bytes as the block
// height, the next 3 bytes indicating the transaction index within the
// block, and the least significant two bytes indicating the output
// index which pays to the channel.
ShortChannelID ShortChannelID
ShortChannelID tlv.RecordT[tlv.TlvType2, ShortChannelID]

// PartialSignature is the combination of the partial Schnorr signature
// created for the node's bitcoin key with the partial signature created
// for the node's node ID key.
PartialSignature PartialSig

// ExtraOpaqueData is the set of data that was appended to this
// message, some of which we may not actually know how to iterate or
// parse. By holding onto this data, we ensure that we're able to
// properly validate the set of signatures that cover these new fields,
// and ensure we're able to make upgrades to the network in a forwards
// compatible manner.
ExtraOpaqueData ExtraOpaqueData
PartialSignature tlv.RecordT[tlv.TlvType4, PartialSig]

// 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
}

// NewAnnSigs2 is a constructor for AnnounceSignatures2.
func NewAnnSigs2(chanID ChannelID, scid ShortChannelID,
partialSig PartialSig) *AnnounceSignatures2 {

return &AnnounceSignatures2{
ChannelID: tlv.NewRecordT[tlv.TlvType0, ChannelID](chanID),
ShortChannelID: tlv.NewRecordT[tlv.TlvType2, ShortChannelID](
scid,
),
PartialSignature: tlv.NewRecordT[tlv.TlvType4, PartialSig](
partialSig,
),
ExtraSignedFields: make(ExtraSignedFields),
}
}

// A compile time check to ensure AnnounceSignatures2 implements the
Expand All @@ -46,32 +61,29 @@ var _ Message = (*AnnounceSignatures2)(nil)
//
// This is part of the lnwire.Message interface.
func (a *AnnounceSignatures2) Decode(r io.Reader, _ uint32) error {
return ReadElements(r,
&a.ChannelID,
&a.ShortChannelID,
&a.PartialSignature,
&a.ExtraOpaqueData,
)
}

// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
// observing the protocol version specified.
//
// This is part of the lnwire.Message interface.
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
if err := WriteChannelID(w, a.ChannelID); err != nil {
stream, err := tlv.NewStream(ProduceRecordsSorted(
&a.ChannelID, &a.ShortChannelID, &a.PartialSignature,
)...)
if err != nil {
return err
}

if err := WriteShortChannelID(w, a.ShortChannelID); err != nil {
typeMap, err := stream.DecodeWithParsedTypesP2P(r)
if err != nil {
return err
}

if err := WriteElement(w, a.PartialSignature); err != nil {
return err
}
a.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)

return nil
}

return WriteBytes(w, a.ExtraOpaqueData)
// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
// observing the protocol version specified.
//
// This is part of the lnwire.Message interface.
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
return EncodePureTLVMessage(a, w)
}

// MsgType returns the integer uniquely identifying this message type on the
Expand All @@ -82,16 +94,34 @@ func (a *AnnounceSignatures2) MsgType() MessageType {
return MsgAnnounceSignatures2
}

// 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 (a *AnnounceSignatures2) AllRecords() []tlv.Record {
recordProducers := []tlv.RecordProducer{
&a.ChannelID, &a.ShortChannelID,
&a.PartialSignature,
}

recordProducers = append(recordProducers, RecordsAsProducers(
tlv.MapToRecords(a.ExtraSignedFields),
)...)

return ProduceRecordsSorted(recordProducers...)
}

// SCID returns the ShortChannelID of the channel.
//
// NOTE: this is part of the AnnounceSignatures interface.
func (a *AnnounceSignatures2) SCID() ShortChannelID {
return a.ShortChannelID
return a.ShortChannelID.Val
}

// ChanID returns the ChannelID identifying the channel.
//
// NOTE: this is part of the AnnounceSignatures interface.
func (a *AnnounceSignatures2) ChanID() ChannelID {
return a.ChannelID
return a.ChannelID.Val
}
Loading
Loading