Skip to content

Commit 055fb43

Browse files
authored
Merge pull request #9175 from ellemouton/g175UpdateMessageStructure
lnwire+netann: update structure of g175 messages to be pure TLV
2 parents b34fc96 + d68d1fb commit 055fb43

18 files changed

+1448
-256
lines changed

discovery/gossiper.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import (
1313
"github.com/btcsuite/btcd/btcec/v2"
1414
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
1515
"github.com/btcsuite/btcd/btcutil"
16+
"github.com/btcsuite/btcd/chaincfg"
1617
"github.com/btcsuite/btcd/chaincfg/chainhash"
18+
"github.com/btcsuite/btcd/txscript"
1719
"github.com/btcsuite/btcd/wire"
1820
"github.com/lightninglabs/neutrino/cache"
1921
"github.com/lightninglabs/neutrino/cache/lru"
@@ -192,14 +194,9 @@ type PinnedSyncers map[route.Vertex]struct{}
192194
// Config defines the configuration for the service. ALL elements within the
193195
// configuration MUST be non-nil for the service to carry out its duties.
194196
type Config struct {
195-
// ChainHash is a hash that indicates which resident chain of the
196-
// AuthenticatedGossiper. Any announcements that don't match this
197-
// chain hash will be ignored.
198-
//
199-
// TODO(roasbeef): eventually make into map so can de-multiplex
200-
// incoming announcements
201-
// * also need to do same for Notifier
202-
ChainHash chainhash.Hash
197+
// ChainParams holds the chain parameters for the active network this
198+
// node is participating on.
199+
ChainParams *chaincfg.Params
203200

204201
// Graph is the subsystem which is responsible for managing the
205202
// topology of lightning network. After incoming channel, node, channel
@@ -599,7 +596,7 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper
599596
gossiper.vb = NewValidationBarrier(1000, gossiper.quit)
600597

601598
gossiper.syncMgr = newSyncManager(&SyncManagerCfg{
602-
ChainHash: cfg.ChainHash,
599+
ChainHash: *cfg.ChainParams.GenesisHash,
603600
ChanSeries: cfg.ChanSeries,
604601
RotateTicker: cfg.RotateTicker,
605602
HistoricalSyncTicker: cfg.HistoricalSyncTicker,
@@ -2037,10 +2034,29 @@ func (d *AuthenticatedGossiper) processRejectedEdge(_ context.Context,
20372034
}
20382035

20392036
// fetchPKScript fetches the output script for the given SCID.
2040-
func (d *AuthenticatedGossiper) fetchPKScript(chanID *lnwire.ShortChannelID) (
2041-
[]byte, error) {
2037+
func (d *AuthenticatedGossiper) fetchPKScript(chanID lnwire.ShortChannelID) (
2038+
txscript.ScriptClass, btcutil.Address, error) {
20422039

2043-
return lnwallet.FetchPKScriptWithQuit(d.cfg.ChainIO, chanID, d.quit)
2040+
pkScript, err := lnwallet.FetchPKScriptWithQuit(
2041+
d.cfg.ChainIO, chanID, d.quit,
2042+
)
2043+
if err != nil {
2044+
return txscript.WitnessUnknownTy, nil, err
2045+
}
2046+
2047+
scriptClass, addrs, _, err := txscript.ExtractPkScriptAddrs(
2048+
pkScript, d.cfg.ChainParams,
2049+
)
2050+
if err != nil {
2051+
return txscript.WitnessUnknownTy, nil, err
2052+
}
2053+
2054+
if len(addrs) != 1 {
2055+
return txscript.WitnessUnknownTy, nil, fmt.Errorf("expected "+
2056+
"1 address, got: %d", len(addrs))
2057+
}
2058+
2059+
return scriptClass, addrs[0], nil
20442060
}
20452061

20462062
// addNode processes the given node announcement, and adds it to our channel
@@ -2541,16 +2557,16 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(ctx context.Context,
25412557
ops ...batch.SchedulerOption) ([]networkMsg, bool) {
25422558

25432559
scid := ann.ShortChannelID
2560+
chainHash := d.cfg.ChainParams.GenesisHash
25442561

25452562
log.Debugf("Processing ChannelAnnouncement1: peer=%v, short_chan_id=%v",
25462563
nMsg.peer, scid.ToUint64())
25472564

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

25562572
key := newRejectCacheKey(
@@ -2971,11 +2987,13 @@ func (d *AuthenticatedGossiper) handleChanUpdate(ctx context.Context,
29712987
log.Debugf("Processing ChannelUpdate: peer=%v, short_chan_id=%v, ",
29722988
nMsg.peer, upd.ShortChannelID.ToUint64())
29732989

2990+
chainHash := d.cfg.ChainParams.GenesisHash
2991+
29742992
// We'll ignore any channel updates that target any chain other than
29752993
// the set of chains we know of.
2976-
if !bytes.Equal(upd.ChainHash[:], d.cfg.ChainHash[:]) {
2994+
if !bytes.Equal(upd.ChainHash[:], chainHash[:]) {
29772995
err := fmt.Errorf("ignoring ChannelUpdate from chain=%v, "+
2978-
"gossiper on chain=%v", upd.ChainHash, d.cfg.ChainHash)
2996+
"gossiper on chain=%v", upd.ChainHash, chainHash)
29792997
log.Errorf(err.Error())
29802998

29812999
key := newRejectCacheKey(
@@ -3748,7 +3766,7 @@ func (d *AuthenticatedGossiper) validateFundingTransaction(_ context.Context,
37483766
// Before we can add the channel to the channel graph, we need to obtain
37493767
// the full funding outpoint that's encoded within the channel ID.
37503768
fundingTx, err := lnwallet.FetchFundingTxWrapper(
3751-
d.cfg.ChainIO, &scid, d.quit,
3769+
d.cfg.ChainIO, scid, d.quit,
37523770
)
37533771
if err != nil {
37543772
//nolint:ll

discovery/gossiper_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/btcsuite/btcd/btcec/v2"
1919
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
2020
"github.com/btcsuite/btcd/btcutil"
21+
"github.com/btcsuite/btcd/chaincfg"
2122
"github.com/btcsuite/btcd/chaincfg/chainhash"
2223
"github.com/btcsuite/btcd/wire"
2324
"github.com/davecgh/go-spew/spew"
@@ -620,6 +621,7 @@ func createUpdateAnnouncement(blockHeight uint32,
620621

621622
htlcMinMsat := lnwire.MilliSatoshi(100)
622623
a := &lnwire.ChannelUpdate1{
624+
ChainHash: *chaincfg.MainNetParams.GenesisHash,
623625
ShortChannelID: lnwire.ShortChannelID{
624626
BlockHeight: blockHeight,
625627
},
@@ -772,6 +774,7 @@ func (ctx *testCtx) createAnnouncementWithoutProof(blockHeight uint32,
772774
}
773775

774776
a := &lnwire.ChannelAnnouncement1{
777+
ChainHash: *chaincfg.MainNetParams.GenesisHash,
775778
ShortChannelID: lnwire.ShortChannelID{
776779
BlockHeight: blockHeight,
777780
TxIndex: 0,
@@ -938,8 +941,9 @@ func createTestCtx(t *testing.T, startHeight uint32, isChanPeer bool) (
938941
}
939942

940943
gossiper := New(Config{
941-
ChainIO: chain,
942-
Notifier: notifier,
944+
ChainIO: chain,
945+
ChainParams: &chaincfg.MainNetParams,
946+
Notifier: notifier,
943947
Broadcast: func(senders map[route.Vertex]struct{},
944948
msgs ...lnwire.Message) error {
945949

@@ -1669,6 +1673,7 @@ func TestSignatureAnnouncementRetryAtStartup(t *testing.T) {
16691673

16701674
//nolint:ll
16711675
gossiper := New(Config{
1676+
ChainParams: &chaincfg.MainNetParams,
16721677
Notifier: tCtx.gossiper.cfg.Notifier,
16731678
Broadcast: tCtx.gossiper.cfg.Broadcast,
16741679
NotifyWhenOnline: tCtx.gossiper.reliableSender.cfg.NotifyWhenOnline,

lnwallet/interface.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ func SupportedWallets() []string {
760760

761761
// FetchFundingTxWrapper is a wrapper around FetchFundingTx, except that it will
762762
// exit when the supplied quit channel is closed.
763-
func FetchFundingTxWrapper(chain BlockChainIO, chanID *lnwire.ShortChannelID,
763+
func FetchFundingTxWrapper(chain BlockChainIO, chanID lnwire.ShortChannelID,
764764
quit chan struct{}) (*wire.MsgTx, error) {
765765

766766
txChan := make(chan *wire.MsgTx, 1)
@@ -795,7 +795,7 @@ func FetchFundingTxWrapper(chain BlockChainIO, chanID *lnwire.ShortChannelID,
795795
// TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to
796796
// later use getblocktxn).
797797
func FetchFundingTx(chain BlockChainIO,
798-
chanID *lnwire.ShortChannelID) (*wire.MsgTx, error) {
798+
chanID lnwire.ShortChannelID) (*wire.MsgTx, error) {
799799

800800
// First fetch the block hash by the block number encoded, then use
801801
// that hash to fetch the block itself.
@@ -826,7 +826,7 @@ func FetchFundingTx(chain BlockChainIO,
826826
// FetchPKScriptWithQuit fetches the output script for the given SCID and exits
827827
// early with an error if the provided quit channel is closed before
828828
// completion.
829-
func FetchPKScriptWithQuit(chain BlockChainIO, chanID *lnwire.ShortChannelID,
829+
func FetchPKScriptWithQuit(chain BlockChainIO, chanID lnwire.ShortChannelID,
830830
quit chan struct{}) ([]byte, error) {
831831

832832
tx, err := FetchFundingTxWrapper(chain, chanID, quit)
@@ -835,7 +835,7 @@ func FetchPKScriptWithQuit(chain BlockChainIO, chanID *lnwire.ShortChannelID,
835835
}
836836

837837
outputLocator := chanvalidate.ShortChanIDChanLocator{
838-
ID: *chanID,
838+
ID: chanID,
839839
}
840840

841841
output, _, err := outputLocator.Locate(tx)

lnwire/announcement_signatures_2.go

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package lnwire
33
import (
44
"bytes"
55
"io"
6+
7+
"github.com/lightningnetwork/lnd/tlv"
68
)
79

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

1921
// ShortChannelID is the unique description of the funding transaction.
2022
// It is constructed with the most significant 3 bytes as the block
2123
// height, the next 3 bytes indicating the transaction index within the
2224
// block, and the least significant two bytes indicating the output
2325
// index which pays to the channel.
24-
ShortChannelID ShortChannelID
26+
ShortChannelID tlv.RecordT[tlv.TlvType2, ShortChannelID]
2527

2628
// PartialSignature is the combination of the partial Schnorr signature
2729
// created for the node's bitcoin key with the partial signature created
2830
// for the node's node ID key.
29-
PartialSignature PartialSig
30-
31-
// ExtraOpaqueData is the set of data that was appended to this
32-
// message, some of which we may not actually know how to iterate or
33-
// parse. By holding onto this data, we ensure that we're able to
34-
// properly validate the set of signatures that cover these new fields,
35-
// and ensure we're able to make upgrades to the network in a forwards
36-
// compatible manner.
37-
ExtraOpaqueData ExtraOpaqueData
31+
PartialSignature tlv.RecordT[tlv.TlvType4, PartialSig]
32+
33+
// Any extra fields in the signed range that we do not yet know about,
34+
// but we need to keep them for signature validation and to produce a
35+
// valid message.
36+
ExtraSignedFields
37+
}
38+
39+
// NewAnnSigs2 is a constructor for AnnounceSignatures2.
40+
func NewAnnSigs2(chanID ChannelID, scid ShortChannelID,
41+
partialSig PartialSig) *AnnounceSignatures2 {
42+
43+
return &AnnounceSignatures2{
44+
ChannelID: tlv.NewRecordT[tlv.TlvType0, ChannelID](chanID),
45+
ShortChannelID: tlv.NewRecordT[tlv.TlvType2, ShortChannelID](
46+
scid,
47+
),
48+
PartialSignature: tlv.NewRecordT[tlv.TlvType4, PartialSig](
49+
partialSig,
50+
),
51+
ExtraSignedFields: make(ExtraSignedFields),
52+
}
3853
}
3954

4055
// A compile time check to ensure AnnounceSignatures2 implements the
@@ -45,37 +60,38 @@ var _ Message = (*AnnounceSignatures2)(nil)
4560
// lnwire.SizeableMessage interface.
4661
var _ SizeableMessage = (*AnnounceSignatures2)(nil)
4762

63+
// A compile time check to ensure ChannelAnnouncement2 implements the
64+
// lnwire.PureTLVMessage interface.
65+
var _ PureTLVMessage = (*AnnounceSignatures2)(nil)
66+
4867
// Decode deserializes a serialized AnnounceSignatures2 stored in the passed
4968
// io.Reader observing the specified protocol version.
5069
//
5170
// This is part of the lnwire.Message interface.
5271
func (a *AnnounceSignatures2) Decode(r io.Reader, _ uint32) error {
53-
return ReadElements(r,
54-
&a.ChannelID,
55-
&a.ShortChannelID,
56-
&a.PartialSignature,
57-
&a.ExtraOpaqueData,
58-
)
59-
}
60-
61-
// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
62-
// observing the protocol version specified.
63-
//
64-
// This is part of the lnwire.Message interface.
65-
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
66-
if err := WriteChannelID(w, a.ChannelID); err != nil {
72+
stream, err := tlv.NewStream(ProduceRecordsSorted(
73+
&a.ChannelID, &a.ShortChannelID, &a.PartialSignature,
74+
)...)
75+
if err != nil {
6776
return err
6877
}
6978

70-
if err := WriteShortChannelID(w, a.ShortChannelID); err != nil {
79+
typeMap, err := stream.DecodeWithParsedTypesP2P(r)
80+
if err != nil {
7181
return err
7282
}
7383

74-
if err := WriteElement(w, a.PartialSignature); err != nil {
75-
return err
76-
}
84+
a.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
85+
86+
return nil
87+
}
7788

78-
return WriteBytes(w, a.ExtraOpaqueData)
89+
// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
90+
// observing the protocol version specified.
91+
//
92+
// This is part of the lnwire.Message interface.
93+
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
94+
return EncodePureTLVMessage(a, w)
7995
}
8096

8197
// MsgType returns the integer uniquely identifying this message type on the
@@ -93,16 +109,34 @@ func (a *AnnounceSignatures2) SerializedSize() (uint32, error) {
93109
return MessageSerializedSize(a)
94110
}
95111

112+
// AllRecords returns all the TLV records for the message. This will include all
113+
// the records we know about along with any that we don't know about but that
114+
// fall in the signed TLV range.
115+
//
116+
// NOTE: this is part of the PureTLVMessage interface.
117+
func (a *AnnounceSignatures2) AllRecords() []tlv.Record {
118+
recordProducers := []tlv.RecordProducer{
119+
&a.ChannelID, &a.ShortChannelID,
120+
&a.PartialSignature,
121+
}
122+
123+
recordProducers = append(recordProducers, RecordsAsProducers(
124+
tlv.MapToRecords(a.ExtraSignedFields),
125+
)...)
126+
127+
return ProduceRecordsSorted(recordProducers...)
128+
}
129+
96130
// SCID returns the ShortChannelID of the channel.
97131
//
98132
// NOTE: this is part of the AnnounceSignatures interface.
99133
func (a *AnnounceSignatures2) SCID() ShortChannelID {
100-
return a.ShortChannelID
134+
return a.ShortChannelID.Val
101135
}
102136

103137
// ChanID returns the ChannelID identifying the channel.
104138
//
105139
// NOTE: this is part of the AnnounceSignatures interface.
106140
func (a *AnnounceSignatures2) ChanID() ChannelID {
107-
return a.ChannelID
141+
return a.ChannelID.Val
108142
}

0 commit comments

Comments
 (0)