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

lightningnetwork / lnd / 17917482292

22 Sep 2025 01:50PM UTC coverage: 56.562% (-10.1%) from 66.668%
17917482292

Pull #10182

github

web-flow
Merge 9efe3bd8c into 055fb436e
Pull Request #10182: Aux feature bits

32 of 68 new or added lines in 5 files covered. (47.06%)

29734 existing lines in 467 files now uncovered.

98449 of 174056 relevant lines covered (56.56%)

1.18 hits per line

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

0.0
/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.
UNCOV
73
func (c *ChannelAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
×
UNCOV
74
        return EncodePureTLVMessage(c, w)
×
UNCOV
75
}
×
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.
UNCOV
82
func (c *ChannelAnnouncement2) AllRecords() []tlv.Record {
×
UNCOV
83
        recordProducers := append(
×
UNCOV
84
                c.allNonSignatureRecordProducers(), &c.Signature,
×
UNCOV
85
        )
×
UNCOV
86

×
UNCOV
87
        return ProduceRecordsSorted(recordProducers...)
×
UNCOV
88
}
×
89

90
// allNonSignatureRecordProducers returns all the TLV record producers for the
91
// message except the signature record producer.
92
//
93
//nolint:ll
UNCOV
94
func (c *ChannelAnnouncement2) allNonSignatureRecordProducers() []tlv.RecordProducer {
×
UNCOV
95
        // The chain-hash record is only included if it is _not_ equal to the
×
UNCOV
96
        // bitcoin mainnet genisis block hash.
×
UNCOV
97
        var recordProducers []tlv.RecordProducer
×
UNCOV
98
        if !c.ChainHash.Val.IsEqual(chaincfg.MainNetParams.GenesisHash) {
×
UNCOV
99
                hash := tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
×
UNCOV
100
                hash.Val = c.ChainHash.Val
×
UNCOV
101

×
UNCOV
102
                recordProducers = append(recordProducers, &hash)
×
UNCOV
103
        }
×
104

UNCOV
105
        recordProducers = append(recordProducers,
×
UNCOV
106
                &c.Features, &c.ShortChannelID, &c.Capacity, &c.NodeID1,
×
UNCOV
107
                &c.NodeID2,
×
UNCOV
108
        )
×
UNCOV
109

×
UNCOV
110
        c.BitcoinKey1.WhenSome(func(key tlv.RecordT[tlv.TlvType12, [33]byte]) {
×
UNCOV
111
                recordProducers = append(recordProducers, &key)
×
UNCOV
112
        })
×
113

UNCOV
114
        c.BitcoinKey2.WhenSome(func(key tlv.RecordT[tlv.TlvType14, [33]byte]) {
×
UNCOV
115
                recordProducers = append(recordProducers, &key)
×
UNCOV
116
        })
×
117

UNCOV
118
        c.MerkleRootHash.WhenSome(
×
UNCOV
119
                func(hash tlv.RecordT[tlv.TlvType16, [32]byte]) {
×
UNCOV
120
                        recordProducers = append(recordProducers, &hash)
×
UNCOV
121
                },
×
122
        )
123

UNCOV
124
        recordProducers = append(recordProducers, RecordsAsProducers(
×
UNCOV
125
                tlv.MapToRecords(c.ExtraSignedFields),
×
UNCOV
126
        )...)
×
UNCOV
127

×
UNCOV
128
        return recordProducers
×
129
}
130

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

×
UNCOV
159
        typeMap, err := stream.DecodeWithParsedTypesP2P(r)
×
UNCOV
160
        if err != nil {
×
UNCOV
161
                return err
×
UNCOV
162
        }
×
163

164
        // By default, the chain-hash is the bitcoin mainnet genesis block hash.
UNCOV
165
        c.ChainHash.Val = *chaincfg.MainNetParams.GenesisHash
×
UNCOV
166
        if _, ok := typeMap[c.ChainHash.TlvType()]; ok {
×
UNCOV
167
                c.ChainHash.Val = chainHash.Val
×
UNCOV
168
        }
×
169

UNCOV
170
        if _, ok := typeMap[c.BitcoinKey1.TlvType()]; ok {
×
UNCOV
171
                c.BitcoinKey1 = tlv.SomeRecordT(btcKey1)
×
UNCOV
172
        }
×
173

UNCOV
174
        if _, ok := typeMap[c.BitcoinKey2.TlvType()]; ok {
×
UNCOV
175
                c.BitcoinKey2 = tlv.SomeRecordT(btcKey2)
×
UNCOV
176
        }
×
177

UNCOV
178
        if _, ok := typeMap[c.MerkleRootHash.TlvType()]; ok {
×
UNCOV
179
                c.MerkleRootHash = tlv.SomeRecordT(merkleRootHash)
×
UNCOV
180
        }
×
181

UNCOV
182
        c.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
×
UNCOV
183

×
UNCOV
184
        return nil
×
185
}
186

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

210
        typeMap, err := stream.DecodeWithParsedTypesP2P(r)
×
211
        if err != nil {
×
212
                return err
×
213
        }
×
214

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

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

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

229
        if _, ok := typeMap[c.MerkleRootHash.TlvType()]; ok {
×
230
                c.MerkleRootHash = tlv.SomeRecordT(merkleRootHash)
×
231
        }
×
232

233
        c.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
×
234

×
235
        return nil
×
236
}
237

238
// EncodeAllNonSigFields encodes the entire message to the given writer but
239
// excludes the signature field.
240
func (c *ChannelAnnouncement2) EncodeAllNonSigFields(w io.Writer) error {
×
241
        return EncodeRecordsTo(
×
242
                w, ProduceRecordsSorted(c.allNonSignatureRecordProducers()...),
×
243
        )
×
244
}
×
245

246
// MsgType returns the integer uniquely identifying this message type on the
247
// wire.
248
//
249
// This is part of the lnwire.Message interface.
UNCOV
250
func (c *ChannelAnnouncement2) MsgType() MessageType {
×
UNCOV
251
        return MsgChannelAnnouncement2
×
UNCOV
252
}
×
253

254
// SerializedSize returns the serialized size of the message in bytes.
255
//
256
// This is part of the lnwire.SizeableMessage interface.
257
func (c *ChannelAnnouncement2) SerializedSize() (uint32, error) {
×
258
        return MessageSerializedSize(c)
×
259
}
×
260

261
// A compile time check to ensure ChannelAnnouncement2 implements the
262
// lnwire.Message interface.
263
var _ Message = (*ChannelAnnouncement2)(nil)
264

265
// A compile time check to ensure ChannelAnnouncement2 implements the
266
// lnwire.SizeableMessage interface.
267
var _ SizeableMessage = (*ChannelAnnouncement2)(nil)
268

269
// A compile time check to ensure ChannelAnnouncement2 implements the
270
// lnwire.PureTLVMessage interface.
271
var _ PureTLVMessage = (*ChannelAnnouncement2)(nil)
272

273
// Node1KeyBytes returns the bytes representing the public key of node 1 in the
274
// channel.
275
//
276
// NOTE: This is part of the ChannelAnnouncement interface.
277
func (c *ChannelAnnouncement2) Node1KeyBytes() [33]byte {
×
278
        return c.NodeID1.Val
×
279
}
×
280

281
// Node2KeyBytes returns the bytes representing the public key of node 2 in the
282
// channel.
283
//
284
// NOTE: This is part of the ChannelAnnouncement interface.
285
func (c *ChannelAnnouncement2) Node2KeyBytes() [33]byte {
×
286
        return c.NodeID2.Val
×
287
}
×
288

289
// GetChainHash returns the hash of the chain which this channel's funding
290
// transaction is confirmed in.
291
//
292
// NOTE: This is part of the ChannelAnnouncement interface.
293
func (c *ChannelAnnouncement2) GetChainHash() chainhash.Hash {
×
294
        return c.ChainHash.Val
×
295
}
×
296

297
// SCID returns the short channel ID of the channel.
298
//
299
// NOTE: This is part of the ChannelAnnouncement interface.
300
func (c *ChannelAnnouncement2) SCID() ShortChannelID {
×
301
        return c.ShortChannelID.Val
×
302
}
×
303

304
// A compile-time check to ensure that ChannelAnnouncement2 implements the
305
// ChannelAnnouncement interface.
306
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