-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
base: master
Are you sure you want to change the base?
Changes from all commits
20db079
de6061e
321083c
df034bc
7483ed7
22293d5
6f0ce3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
|
@@ -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 | ||
|
||
// Graph is the subsystem which is responsible for managing the | ||
// topology of lightning network. After incoming channel, node, channel | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need it here if we have |
||
} | ||
|
||
// processedNetworkMsg is a wrapper around networkMsg and a boolean. It is | ||
|
@@ -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, | ||
|
@@ -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, | ||
|
@@ -1946,9 +1951,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( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the merkle proof case? |
||
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 | ||
|
@@ -2448,10 +2472,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( | ||
|
@@ -2837,9 +2861,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( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -210,3 +210,5 @@ replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-d | |
go 1.22.6 | ||
|
||
retract v0.0.2 | ||
|
||
replace github.com/lightningnetwork/lnd/tlv => github.com/ellemouton/lnd/tlv v0.0.0-20241012094556-298ff9eaed58 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can remove this now? |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ package lnwire | |
import ( | ||
"bytes" | ||
"io" | ||
|
||
"github.com/lightningnetwork/lnd/tlv" | ||
) | ||
|
||
// AnnounceSignatures2 is a direct message between two endpoints of a | ||
|
@@ -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. | ||
ExtraFieldsInSignedRange map[uint64][]byte | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also why can't we just continue to store it in the serialized form? |
||
} | ||
|
||
// 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, | ||
), | ||
ExtraFieldsInSignedRange: make(map[uint64][]byte, 0), | ||
} | ||
} | ||
|
||
// A compile time check to ensure AnnounceSignatures2 implements the | ||
|
@@ -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.ExtraFieldsInSignedRange = 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 | ||
|
@@ -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.ExtraFieldsInSignedRange), | ||
)...) | ||
|
||
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 | ||
} |
There was a problem hiding this comment.
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.