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

lightningnetwork / lnd / 16983297902

15 Aug 2025 04:58AM UTC coverage: 66.777% (+0.02%) from 66.758%
16983297902

Pull #10140

github

web-flow
Merge 33b9b55dc into 3841d5554
Pull Request #10140: [2/3] lnwire: fix encoding customized TLV records

178 of 191 new or added lines in 8 files covered. (93.19%)

79 existing lines in 13 files now uncovered.

136014 of 203685 relevant lines covered (66.78%)

21511.77 hits per line

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

84.52
/lnwire/channel_ready.go
1
package lnwire
2

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

7
        "github.com/btcsuite/btcd/btcec/v2"
8
        "github.com/lightningnetwork/lnd/tlv"
9
)
10

11
// ChannelReady is the message that both parties to a new channel creation
12
// send once they have observed the funding transaction being confirmed on the
13
// blockchain. ChannelReady contains the signatures necessary for the channel
14
// participants to advertise the existence of the channel to the rest of the
15
// network.
16
type ChannelReady struct {
17
        // ChanID is the outpoint of the channel's funding transaction. This
18
        // can be used to query for the channel in the database.
19
        ChanID ChannelID
20

21
        // NextPerCommitmentPoint is the secret that can be used to revoke the
22
        // next commitment transaction for the channel.
23
        NextPerCommitmentPoint *btcec.PublicKey
24

25
        // NOTE: The following fields are TLV records.
26
        //
27
        // AliasScid is an alias ShortChannelID used to refer to the underlying
28
        // channel. It can be used instead of the confirmed on-chain
29
        // ShortChannelID for forwarding.
30
        AliasScid *ShortChannelID
31

32
        // NextLocalNonce is an optional field that stores a local musig2 nonce.
33
        // This will only be populated if the simple taproot channels type was
34
        // negotiated. This is the local nonce that will be used by the sender
35
        // to accept a new commitment state transition.
36
        NextLocalNonce OptMusig2NonceTLV
37

38
        // AnnouncementNodeNonce is an optional field that stores a public
39
        // nonce that will be used along with the node's ID key during signing
40
        // of the ChannelAnnouncement2 message.
41
        AnnouncementNodeNonce tlv.OptionalRecordT[tlv.TlvType0, Musig2Nonce]
42

43
        // AnnouncementBitcoinNonce is an optional field that stores a public
44
        // nonce that will be used along with the node's bitcoin key during
45
        // signing of the ChannelAnnouncement2 message.
46
        AnnouncementBitcoinNonce tlv.OptionalRecordT[tlv.TlvType2, Musig2Nonce]
47

48
        // ExtraData is the set of data that was appended to this message to
49
        // fill out the full maximum transport message size. These fields can
50
        // be used to specify optional data such as custom TLV fields.
51
        ExtraData ExtraOpaqueData
52
}
53

54
// NewChannelReady creates a new ChannelReady message, populating it with the
55
// necessary IDs and revocation secret.
56
func NewChannelReady(cid ChannelID, npcp *btcec.PublicKey) *ChannelReady {
202✔
57
        return &ChannelReady{
202✔
58
                ChanID:                 cid,
202✔
59
                NextPerCommitmentPoint: npcp,
202✔
60
                ExtraData:              nil,
202✔
61
        }
202✔
62
}
202✔
63

64
// A compile time check to ensure ChannelReady implements the lnwire.Message
65
// interface.
66
var _ Message = (*ChannelReady)(nil)
67

68
// A compile time check to ensure ChannelReady implements the
69
// lnwire.SizeableMessage interface.
70
var _ SizeableMessage = (*ChannelReady)(nil)
71

72
// Decode deserializes the serialized ChannelReady message stored in the
73
// passed io.Reader into the target ChannelReady using the deserialization
74
// rules defined by the passed protocol version.
75
//
76
// This is part of the lnwire.Message interface.
77
func (c *ChannelReady) Decode(r io.Reader, _ uint32) error {
197✔
78
        // Read all the mandatory fields in the message.
197✔
79
        err := ReadElements(r,
197✔
80
                &c.ChanID,
197✔
81
                &c.NextPerCommitmentPoint,
197✔
82
        )
197✔
83
        if err != nil {
205✔
84
                return err
8✔
85
        }
8✔
86

87
        var tlvRecords ExtraOpaqueData
189✔
88
        if err := ReadElements(r, &tlvRecords); err != nil {
189✔
89
                return err
×
90
        }
×
91

92
        // Next we'll parse out the set of known records. For now, this is just
93
        // the AliasScidRecordType.
94
        var (
189✔
95
                aliasScid  ShortChannelID
189✔
96
                localNonce = c.NextLocalNonce.Zero()
189✔
97
                nodeNonce  = tlv.ZeroRecordT[tlv.TlvType0, Musig2Nonce]()
189✔
98
                btcNonce   = tlv.ZeroRecordT[tlv.TlvType2, Musig2Nonce]()
189✔
99
        )
189✔
100
        knownRecords, extraData, err := ParseAndExtractExtraData(
189✔
101
                tlvRecords, &btcNonce, &aliasScid, &nodeNonce, &localNonce,
189✔
102
        )
189✔
103
        if err != nil {
234✔
104
                return err
45✔
105
        }
45✔
106

107
        // We'll only set AliasScid if the corresponding TLV type was included
108
        // in the stream.
109
        if _, ok := knownRecords[AliasScidRecordType]; ok {
213✔
110
                c.AliasScid = &aliasScid
69✔
111
        }
69✔
112
        if _, ok := knownRecords[c.NextLocalNonce.TlvType()]; ok {
208✔
113
                c.NextLocalNonce = tlv.SomeRecordT(localNonce)
64✔
114
        }
64✔
115
        if _, ok := knownRecords[c.AnnouncementBitcoinNonce.TlvType()]; ok {
194✔
116
                c.AnnouncementBitcoinNonce = tlv.SomeRecordT(btcNonce)
50✔
117
        }
50✔
118
        if _, ok := knownRecords[c.AnnouncementNodeNonce.TlvType()]; ok {
208✔
119
                c.AnnouncementNodeNonce = tlv.SomeRecordT(nodeNonce)
64✔
120
        }
64✔
121

122
        c.ExtraData = extraData
144✔
123

144✔
124
        return nil
144✔
125
}
126

127
// Encode serializes the target ChannelReady message into the passed io.Writer
128
// implementation. Serialization will observe the rules defined by the passed
129
// protocol version.
130
//
131
// This is part of the lnwire.Message interface.
132
func (c *ChannelReady) Encode(w *bytes.Buffer, _ uint32) error {
124✔
133
        if err := WriteChannelID(w, c.ChanID); err != nil {
124✔
134
                return err
×
135
        }
×
136

137
        if err := WritePublicKey(w, c.NextPerCommitmentPoint); err != nil {
124✔
138
                return err
×
139
        }
×
140

141
        // Get producers from extra data.
142
        producers, err := c.ExtraData.RecordProducers()
124✔
143
        if err != nil {
124✔
NEW
144
                return err
×
NEW
145
        }
×
146

147
        // We'll only encode the AliasScid in a TLV segment if it exists.
148
        if c.AliasScid != nil {
187✔
149
                producers = append(producers, c.AliasScid)
63✔
150
        }
63✔
151
        c.NextLocalNonce.WhenSome(func(localNonce Musig2NonceTLV) {
184✔
152
                producers = append(producers, &localNonce)
60✔
153
        })
60✔
154
        c.AnnouncementBitcoinNonce.WhenSome(
124✔
155
                func(nonce tlv.RecordT[tlv.TlvType2, Musig2Nonce]) {
173✔
156
                        producers = append(producers, &nonce)
49✔
157
                },
49✔
158
        )
159
        c.AnnouncementNodeNonce.WhenSome(
124✔
160
                func(nonce tlv.RecordT[tlv.TlvType0, Musig2Nonce]) {
184✔
161
                        producers = append(producers, &nonce)
60✔
162
                },
60✔
163
        )
164

165
        // Pack all records into a new TLV stream.
166
        var tlvData ExtraOpaqueData
124✔
167
        err = tlvData.PackRecords(producers...)
124✔
168
        if err != nil {
124✔
169
                return err
×
170
        }
×
171

172
        return WriteBytes(w, tlvData)
124✔
173
}
174

175
// MsgType returns the uint32 code which uniquely identifies this message as a
176
// ChannelReady message on the wire.
177
//
178
// This is part of the lnwire.Message interface.
179
func (c *ChannelReady) MsgType() MessageType {
149✔
180
        return MsgChannelReady
149✔
181
}
149✔
182

183
// SerializedSize returns the serialized size of the message in bytes.
184
//
185
// This is part of the lnwire.SizeableMessage interface.
186
func (c *ChannelReady) SerializedSize() (uint32, error) {
×
187
        return MessageSerializedSize(c)
×
188
}
×
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