• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 12118348650

02 Dec 2024 11:25AM UTC coverage: 58.552% (-0.4%) from 58.977%
12118348650

Pull #9175

github

ellemouton
lnwire: add NodeAnnouncement2
Pull Request #9175: lnwire+netann: update structure of g175 messages to be pure TLV

405 of 571 new or added lines in 11 files covered. (70.93%)

1754 existing lines in 33 files now uncovered.

133774 of 228469 relevant lines covered (58.55%)

19422.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.24
/lnwire/channel_announcement_2.go
1
package lnwire
2

3
import (
4
        "bytes"
5
        "io"
6

7
        "github.com/btcsuite/btcd/chaincfg"
8
        "github.com/btcsuite/btcd/chaincfg/chainhash"
9
        "github.com/lightningnetwork/lnd/tlv"
10
)
11

12
// ChannelAnnouncement2 message is used to announce the existence of a taproot
13
// channel between two peers in the network.
14
type ChannelAnnouncement2 struct {
15
        // ChainHash denotes the target chain that this channel was opened
16
        // within. This value should be the genesis hash of the target chain.
17
        ChainHash tlv.RecordT[tlv.TlvType0, chainhash.Hash]
18

19
        // Features is the feature vector that encodes the features supported
20
        // by the target node. This field can be used to signal the type of the
21
        // channel, or modifications to the fields that would normally follow
22
        // this vector.
23
        Features tlv.RecordT[tlv.TlvType2, RawFeatureVector]
24

25
        // ShortChannelID is the unique description of the funding transaction,
26
        // or where exactly it's located within the target blockchain.
27
        ShortChannelID tlv.RecordT[tlv.TlvType4, ShortChannelID]
28

29
        // Capacity is the number of satoshis of the capacity of this channel.
30
        // It must be less than or equal to the value of the on-chain funding
31
        // output.
32
        Capacity tlv.RecordT[tlv.TlvType6, uint64]
33

34
        // NodeID1 is the numerically-lesser public key ID of one of the channel
35
        // operators.
36
        NodeID1 tlv.RecordT[tlv.TlvType8, [33]byte]
37

38
        // NodeID2 is the numerically-greater public key ID of one of the
39
        // channel operators.
40
        NodeID2 tlv.RecordT[tlv.TlvType10, [33]byte]
41

42
        // BitcoinKey1 is the public key of the key used by Node1 in the
43
        // construction of the on-chain funding transaction. This is an optional
44
        // field and only needs to be set if the 4-of-4 MuSig construction was
45
        // used in the creation of the message signature.
46
        BitcoinKey1 tlv.OptionalRecordT[tlv.TlvType12, [33]byte]
47

48
        // BitcoinKey2 is the public key of the key used by Node2 in the
49
        // construction of the on-chain funding transaction. This is an optional
50
        // field and only needs to be set if the 4-of-4 MuSig construction was
51
        // used in the creation of the message signature.
52
        BitcoinKey2 tlv.OptionalRecordT[tlv.TlvType14, [33]byte]
53

54
        // MerkleRootHash is the hash used to create the optional tweak in the
55
        // funding output. If this is not set but the bitcoin keys are, then
56
        // the funding output is a pure 2-of-2 MuSig aggregate public key.
57
        MerkleRootHash tlv.OptionalRecordT[tlv.TlvType16, [32]byte]
58

59
        // Signature is a Schnorr signature over serialised signed-range TLV
60
        // stream of the message.
61
        Signature tlv.RecordT[tlv.TlvType160, Sig]
62

63
        // Any extra fields in the signed range that we do not yet know about,
64
        // but we need to keep them for signature validation and to produce a
65
        // valid message.
66
        ExtraSignedFields
67
}
68

69
// Encode serializes the target AnnounceSignatures1 into the passed io.Writer
70
// observing the protocol version specified.
71
//
72
// This is part of the lnwire.Message interface.
73
func (c *ChannelAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
100✔
74
        return EncodePureTLVMessage(c, w)
100✔
75
}
100✔
76

77
// AllRecords returns all the TLV records for the message. This will include all
78
// the records we know about along with any that we don't know about but that
79
// fall in the signed TLV range.
80
//
81
// NOTE: this is part of the PureTLVMessage interface.
82
func (c *ChannelAnnouncement2) AllRecords() []tlv.Record {
106✔
83
        recordProducers := append(
106✔
84
                c.allNonSignatureRecordProducers(), &c.Signature,
106✔
85
        )
106✔
86

106✔
87
        return ProduceRecordsSorted(recordProducers...)
106✔
88
}
106✔
89

90
func (c *ChannelAnnouncement2) allNonSignatureRecordProducers() []tlv.RecordProducer {
106✔
91
        // The chain-hash record is only included if it is _not_ equal to the
106✔
92
        // bitcoin mainnet genisis block hash.
106✔
93
        var recordProducers []tlv.RecordProducer
106✔
94
        if !c.ChainHash.Val.IsEqual(chaincfg.MainNetParams.GenesisHash) {
158✔
95
                hash := tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
52✔
96
                hash.Val = c.ChainHash.Val
52✔
97

52✔
98
                recordProducers = append(recordProducers, &hash)
52✔
99
        }
52✔
100

101
        recordProducers = append(recordProducers,
106✔
102
                &c.Features, &c.ShortChannelID, &c.Capacity, &c.NodeID1,
106✔
103
                &c.NodeID2,
106✔
104
        )
106✔
105

106✔
106
        c.BitcoinKey1.WhenSome(func(key tlv.RecordT[tlv.TlvType12, [33]byte]) {
154✔
107
                recordProducers = append(recordProducers, &key)
48✔
108
        })
48✔
109

110
        c.BitcoinKey2.WhenSome(func(key tlv.RecordT[tlv.TlvType14, [33]byte]) {
154✔
111
                recordProducers = append(recordProducers, &key)
48✔
112
        })
48✔
113

114
        c.MerkleRootHash.WhenSome(
106✔
115
                func(hash tlv.RecordT[tlv.TlvType16, [32]byte]) {
127✔
116
                        recordProducers = append(recordProducers, &hash)
21✔
117
                },
21✔
118
        )
119

120
        recordProducers = append(recordProducers, RecordsAsProducers(
106✔
121
                tlv.MapToRecords(c.ExtraSignedFields),
106✔
122
        )...)
106✔
123

106✔
124
        return recordProducers
106✔
125
}
126

127
// Decode deserializes a serialized AnnounceSignatures1 stored in the passed
128
// io.Reader observing the specified protocol version.
129
//
130
// This is part of the lnwire.Message interface.
131
func (c *ChannelAnnouncement2) Decode(r io.Reader, _ uint32) error {
100✔
132
        var (
100✔
133
                chainHash      = tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
100✔
134
                btcKey1        = tlv.ZeroRecordT[tlv.TlvType12, [33]byte]()
100✔
135
                btcKey2        = tlv.ZeroRecordT[tlv.TlvType14, [33]byte]()
100✔
136
                merkleRootHash = tlv.ZeroRecordT[tlv.TlvType16, [32]byte]()
100✔
137
        )
100✔
138
        stream, err := tlv.NewStream(ProduceRecordsSorted(
100✔
139
                &chainHash,
100✔
140
                &c.Features,
100✔
141
                &c.ShortChannelID,
100✔
142
                &c.Capacity,
100✔
143
                &c.NodeID1,
100✔
144
                &c.NodeID2,
100✔
145
                &btcKey1,
100✔
146
                &btcKey2,
100✔
147
                &merkleRootHash,
100✔
148
                &c.Signature,
100✔
149
        )...)
100✔
150
        if err != nil {
100✔
NEW
151
                return err
×
NEW
152
        }
×
153
        c.Signature.Val.ForceSchnorr()
100✔
154

100✔
155
        typeMap, err := stream.DecodeWithParsedTypesP2P(r)
100✔
156
        if err != nil {
100✔
157
                return err
×
158
        }
×
159

160
        // By default, the chain-hash is the bitcoin mainnet genesis block hash.
161
        c.ChainHash.Val = *chaincfg.MainNetParams.GenesisHash
100✔
162
        if _, ok := typeMap[c.ChainHash.TlvType()]; ok {
152✔
163
                c.ChainHash.Val = chainHash.Val
52✔
164
        }
52✔
165

166
        if _, ok := typeMap[c.BitcoinKey1.TlvType()]; ok {
144✔
167
                c.BitcoinKey1 = tlv.SomeRecordT(btcKey1)
44✔
168
        }
44✔
169

170
        if _, ok := typeMap[c.BitcoinKey2.TlvType()]; ok {
144✔
171
                c.BitcoinKey2 = tlv.SomeRecordT(btcKey2)
44✔
172
        }
44✔
173

174
        if _, ok := typeMap[c.MerkleRootHash.TlvType()]; ok {
121✔
175
                c.MerkleRootHash = tlv.SomeRecordT(merkleRootHash)
21✔
176
        }
21✔
177

178
        c.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
100✔
179

100✔
180
        return nil
100✔
181
}
182

183
// DecodeNonSigTLVRecords decodes only the TLV section of the message.
NEW
184
func (c *ChannelAnnouncement2) DecodeNonSigTLVRecords(r io.Reader) error {
×
NEW
185
        var (
×
NEW
186
                chainHash      = tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
×
NEW
187
                btcKey1        = tlv.ZeroRecordT[tlv.TlvType12, [33]byte]()
×
NEW
188
                btcKey2        = tlv.ZeroRecordT[tlv.TlvType14, [33]byte]()
×
NEW
189
                merkleRootHash = tlv.ZeroRecordT[tlv.TlvType16, [32]byte]()
×
NEW
190
        )
×
NEW
191
        stream, err := tlv.NewStream(ProduceRecordsSorted(
×
NEW
192
                &chainHash,
×
NEW
193
                &c.Features,
×
NEW
194
                &c.ShortChannelID,
×
NEW
195
                &c.Capacity,
×
NEW
196
                &c.NodeID1,
×
NEW
197
                &c.NodeID2,
×
NEW
198
                &btcKey1,
×
NEW
199
                &btcKey2,
×
NEW
200
                &merkleRootHash,
×
NEW
201
        )...)
×
202
        if err != nil {
×
203
                return err
×
204
        }
×
205

NEW
206
        typeMap, err := stream.DecodeWithParsedTypesP2P(r)
×
207
        if err != nil {
×
208
                return err
×
209
        }
×
210

211
        // By default, the chain-hash is the bitcoin mainnet genesis block hash.
NEW
212
        c.ChainHash.Val = *chaincfg.MainNetParams.GenesisHash
×
NEW
213
        if _, ok := typeMap[c.ChainHash.TlvType()]; ok {
×
NEW
214
                c.ChainHash.Val = chainHash.Val
×
NEW
215
        }
×
216

NEW
217
        if _, ok := typeMap[c.BitcoinKey1.TlvType()]; ok {
×
NEW
218
                c.BitcoinKey1 = tlv.SomeRecordT(btcKey1)
×
NEW
219
        }
×
220

NEW
221
        if _, ok := typeMap[c.BitcoinKey2.TlvType()]; ok {
×
NEW
222
                c.BitcoinKey2 = tlv.SomeRecordT(btcKey2)
×
UNCOV
223
        }
×
224

NEW
225
        if _, ok := typeMap[c.MerkleRootHash.TlvType()]; ok {
×
NEW
226
                c.MerkleRootHash = tlv.SomeRecordT(merkleRootHash)
×
NEW
227
        }
×
228

NEW
229
        c.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
×
UNCOV
230

×
NEW
231
        return nil
×
232
}
233

234
// EncodeAllNonSigFields encodes the entire message to the given writer but
235
// excludes the signature field.
NEW
236
func (c *ChannelAnnouncement2) EncodeAllNonSigFields(w io.Writer) error {
×
NEW
237
        return EncodeRecordsTo(
×
NEW
238
                w, ProduceRecordsSorted(c.allNonSignatureRecordProducers()...),
×
UNCOV
239
        )
×
UNCOV
240
}
×
241

242
// MsgType returns the integer uniquely identifying this message type on the
243
// wire.
244
//
245
// This is part of the lnwire.Message interface.
246
func (c *ChannelAnnouncement2) MsgType() MessageType {
100✔
247
        return MsgChannelAnnouncement2
100✔
248
}
100✔
249

250
// A compile time check to ensure ChannelAnnouncement2 implements the
251
// lnwire.Message interface.
252
var _ Message = (*ChannelAnnouncement2)(nil)
253

254
// A compile time check to ensure ChannelAnnouncement2 implements the
255
// lnwire.PureTLVMessage interface.
256
var _ PureTLVMessage = (*ChannelAnnouncement2)(nil)
257

258
// Node1KeyBytes returns the bytes representing the public key of node 1 in the
259
// channel.
260
//
261
// NOTE: This is part of the ChannelAnnouncement interface.
262
func (c *ChannelAnnouncement2) Node1KeyBytes() [33]byte {
×
263
        return c.NodeID1.Val
×
264
}
×
265

266
// Node2KeyBytes returns the bytes representing the public key of node 2 in the
267
// channel.
268
//
269
// NOTE: This is part of the ChannelAnnouncement interface.
270
func (c *ChannelAnnouncement2) Node2KeyBytes() [33]byte {
×
271
        return c.NodeID2.Val
×
272
}
×
273

274
// GetChainHash returns the hash of the chain which this channel's funding
275
// transaction is confirmed in.
276
//
277
// NOTE: This is part of the ChannelAnnouncement interface.
278
func (c *ChannelAnnouncement2) GetChainHash() chainhash.Hash {
×
279
        return c.ChainHash.Val
×
280
}
×
281

282
// SCID returns the short channel ID of the channel.
283
//
284
// NOTE: This is part of the ChannelAnnouncement interface.
285
func (c *ChannelAnnouncement2) SCID() ShortChannelID {
×
286
        return c.ShortChannelID.Val
×
287
}
×
288

289
// A compile-time check to ensure that ChannelAnnouncement2 implements the
290
// ChannelAnnouncement interface.
291
var _ ChannelAnnouncement = (*ChannelAnnouncement2)(nil)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc