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

lightningnetwork / lnd / 13980275562

20 Mar 2025 10:06PM UTC coverage: 58.6% (-10.2%) from 68.789%
13980275562

Pull #9623

github

web-flow
Merge b9b960345 into 09b674508
Pull Request #9623: Size msg test msg

0 of 1518 new or added lines in 42 files covered. (0.0%)

26603 existing lines in 443 files now uncovered.

96807 of 165200 relevant lines covered (58.6%)

1.82 hits per line

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

42.05
/lnwire/accept_channel.go
1
package lnwire
2

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

7
        "github.com/btcsuite/btcd/btcec/v2"
8
        "github.com/btcsuite/btcd/btcutil"
9
        "github.com/lightningnetwork/lnd/tlv"
10
        "pgregory.net/rapid"
11
)
12

13
// AcceptChannel is the message Bob sends to Alice after she initiates the
14
// single funder channel workflow via an AcceptChannel message. Once Alice
15
// receives Bob's response, then she has all the items necessary to construct
16
// the funding transaction, and both commitment transactions.
17
type AcceptChannel struct {
18
        // PendingChannelID serves to uniquely identify the future channel
19
        // created by the initiated single funder workflow.
20
        PendingChannelID [32]byte
21

22
        // DustLimit is the specific dust limit the sender of this message
23
        // would like enforced on their version of the commitment transaction.
24
        // Any output below this value will be "trimmed" from the commitment
25
        // transaction, with the amount of the HTLC going to dust.
26
        DustLimit btcutil.Amount
27

28
        // MaxValueInFlight represents the maximum amount of coins that can be
29
        // pending within the channel at any given time. If the amount of funds
30
        // in limbo exceeds this amount, then the channel will be failed.
31
        MaxValueInFlight MilliSatoshi
32

33
        // ChannelReserve is the amount of BTC that the receiving party MUST
34
        // maintain a balance above at all times. This is a safety mechanism to
35
        // ensure that both sides always have skin in the game during the
36
        // channel's lifetime.
37
        ChannelReserve btcutil.Amount
38

39
        // HtlcMinimum is the smallest HTLC that the sender of this message
40
        // will accept.
41
        HtlcMinimum MilliSatoshi
42

43
        // MinAcceptDepth is the minimum depth that the initiator of the
44
        // channel should wait before considering the channel open.
45
        MinAcceptDepth uint32
46

47
        // CsvDelay is the number of blocks to use for the relative time lock
48
        // in the pay-to-self output of both commitment transactions.
49
        CsvDelay uint16
50

51
        // MaxAcceptedHTLCs is the total number of incoming HTLC's that the
52
        // sender of this channel will accept.
53
        //
54
        // TODO(roasbeef): acks the initiator's, same with max in flight?
55
        MaxAcceptedHTLCs uint16
56

57
        // FundingKey is the key that should be used on behalf of the sender
58
        // within the 2-of-2 multi-sig output that it contained within the
59
        // funding transaction.
60
        FundingKey *btcec.PublicKey
61

62
        // RevocationPoint is the base revocation point for the sending party.
63
        // Any commitment transaction belonging to the receiver of this message
64
        // should use this key and their per-commitment point to derive the
65
        // revocation key for the commitment transaction.
66
        RevocationPoint *btcec.PublicKey
67

68
        // PaymentPoint is the base payment point for the sending party. This
69
        // key should be combined with the per commitment point for a
70
        // particular commitment state in order to create the key that should
71
        // be used in any output that pays directly to the sending party, and
72
        // also within the HTLC covenant transactions.
73
        PaymentPoint *btcec.PublicKey
74

75
        // DelayedPaymentPoint is the delay point for the sending party. This
76
        // key should be combined with the per commitment point to derive the
77
        // keys that are used in outputs of the sender's commitment transaction
78
        // where they claim funds.
79
        DelayedPaymentPoint *btcec.PublicKey
80

81
        // HtlcPoint is the base point used to derive the set of keys for this
82
        // party that will be used within the HTLC public key scripts.  This
83
        // value is combined with the receiver's revocation base point in order
84
        // to derive the keys that are used within HTLC scripts.
85
        HtlcPoint *btcec.PublicKey
86

87
        // FirstCommitmentPoint is the first commitment point for the sending
88
        // party. This value should be combined with the receiver's revocation
89
        // base point in order to derive the revocation keys that are placed
90
        // within the commitment transaction of the sender.
91
        FirstCommitmentPoint *btcec.PublicKey
92

93
        // UpfrontShutdownScript is the script to which the channel funds should
94
        // be paid when mutually closing the channel. This field is optional, and
95
        // and has a length prefix, so a zero will be written if it is not set
96
        // and its length followed by the script will be written if it is set.
97
        UpfrontShutdownScript DeliveryAddress
98

99
        // ChannelType is the explicit channel type the initiator wishes to
100
        // open.
101
        ChannelType *ChannelType
102

103
        // LeaseExpiry represents the absolute expiration height of a channel
104
        // lease. This is a custom TLV record that will only apply when a leased
105
        // channel is being opened using the script enforced lease commitment
106
        // type.
107
        LeaseExpiry *LeaseExpiry
108

109
        // LocalNonce is an optional field that transmits the
110
        // local/verification nonce for a party. This nonce will be used to
111
        // verify the very first commitment transaction signature.
112
        // This will only be populated if the simple taproot channels type was
113
        // negotiated.
114
        LocalNonce OptMusig2NonceTLV
115

116
        // ExtraData is the set of data that was appended to this message to
117
        // fill out the full maximum transport message size. These fields can
118
        // be used to specify optional data such as custom TLV fields.
119
        //
120
        // NOTE: Since the upfront shutdown script MUST be present (though can
121
        // be zero-length) if any TLV data is available, the script will be
122
        // extracted and removed from this blob when decoding. ExtraData will
123
        // contain all TLV records _except_ the DeliveryAddress record in that
124
        // case.
125
        ExtraData ExtraOpaqueData
126
}
127

128
// A compile time check to ensure AcceptChannel implements the lnwire.Message
129
// interface.
130
var _ Message = (*AcceptChannel)(nil)
131

132
// A compile time check to ensure AcceptChannel implements the lnwire.SizeableMessage
133
// interface.
134
var _ SizeableMessage = (*AcceptChannel)(nil)
135

136
// Encode serializes the target AcceptChannel into the passed io.Writer
137
// implementation. Serialization will observe the rules defined by the passed
138
// protocol version.
139
//
140
// This is part of the lnwire.Message interface.
141
func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error {
3✔
142
        recordProducers := []tlv.RecordProducer{&a.UpfrontShutdownScript}
3✔
143
        if a.ChannelType != nil {
6✔
144
                recordProducers = append(recordProducers, a.ChannelType)
3✔
145
        }
3✔
146
        if a.LeaseExpiry != nil {
6✔
147
                recordProducers = append(recordProducers, a.LeaseExpiry)
3✔
148
        }
3✔
149
        a.LocalNonce.WhenSome(func(localNonce Musig2NonceTLV) {
6✔
150
                recordProducers = append(recordProducers, &localNonce)
3✔
151
        })
3✔
152
        err := EncodeMessageExtraData(&a.ExtraData, recordProducers...)
3✔
153
        if err != nil {
3✔
154
                return err
×
155
        }
×
156

157
        if err := WriteBytes(w, a.PendingChannelID[:]); err != nil {
3✔
158
                return err
×
159
        }
×
160

161
        if err := WriteSatoshi(w, a.DustLimit); err != nil {
3✔
162
                return err
×
163
        }
×
164

165
        if err := WriteMilliSatoshi(w, a.MaxValueInFlight); err != nil {
3✔
166
                return err
×
167
        }
×
168

169
        if err := WriteSatoshi(w, a.ChannelReserve); err != nil {
3✔
170
                return err
×
171
        }
×
172

173
        if err := WriteMilliSatoshi(w, a.HtlcMinimum); err != nil {
3✔
174
                return err
×
175
        }
×
176

177
        if err := WriteUint32(w, a.MinAcceptDepth); err != nil {
3✔
178
                return err
×
179
        }
×
180

181
        if err := WriteUint16(w, a.CsvDelay); err != nil {
3✔
182
                return err
×
183
        }
×
184

185
        if err := WriteUint16(w, a.MaxAcceptedHTLCs); err != nil {
3✔
186
                return err
×
187
        }
×
188

189
        if err := WritePublicKey(w, a.FundingKey); err != nil {
3✔
190
                return err
×
191
        }
×
192

193
        if err := WritePublicKey(w, a.RevocationPoint); err != nil {
3✔
194
                return err
×
195
        }
×
196

197
        if err := WritePublicKey(w, a.PaymentPoint); err != nil {
3✔
198
                return err
×
199
        }
×
200

201
        if err := WritePublicKey(w, a.DelayedPaymentPoint); err != nil {
3✔
202
                return err
×
203
        }
×
204

205
        if err := WritePublicKey(w, a.HtlcPoint); err != nil {
3✔
206
                return err
×
207
        }
×
208

209
        if err := WritePublicKey(w, a.FirstCommitmentPoint); err != nil {
3✔
210
                return err
×
211
        }
×
212

213
        return WriteBytes(w, a.ExtraData)
3✔
214
}
215

216
// Decode deserializes the serialized AcceptChannel stored in the passed
217
// io.Reader into the target AcceptChannel using the deserialization rules
218
// defined by the passed protocol version.
219
//
220
// This is part of the lnwire.Message interface.
221
func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error {
3✔
222
        // Read all the mandatory fields in the accept message.
3✔
223
        err := ReadElements(r,
3✔
224
                a.PendingChannelID[:],
3✔
225
                &a.DustLimit,
3✔
226
                &a.MaxValueInFlight,
3✔
227
                &a.ChannelReserve,
3✔
228
                &a.HtlcMinimum,
3✔
229
                &a.MinAcceptDepth,
3✔
230
                &a.CsvDelay,
3✔
231
                &a.MaxAcceptedHTLCs,
3✔
232
                &a.FundingKey,
3✔
233
                &a.RevocationPoint,
3✔
234
                &a.PaymentPoint,
3✔
235
                &a.DelayedPaymentPoint,
3✔
236
                &a.HtlcPoint,
3✔
237
                &a.FirstCommitmentPoint,
3✔
238
        )
3✔
239
        if err != nil {
3✔
UNCOV
240
                return err
×
UNCOV
241
        }
×
242

243
        // For backwards compatibility, the optional extra data blob for
244
        // AcceptChannel must contain an entry for the upfront shutdown script.
245
        // We'll read it out and attempt to parse it.
246
        var tlvRecords ExtraOpaqueData
3✔
247
        if err := ReadElements(r, &tlvRecords); err != nil {
3✔
248
                return err
×
249
        }
×
250

251
        // Next we'll parse out the set of known records, keeping the raw tlv
252
        // bytes untouched to ensure we don't drop any bytes erroneously.
253
        var (
3✔
254
                chanType    ChannelType
3✔
255
                leaseExpiry LeaseExpiry
3✔
256
                localNonce  = a.LocalNonce.Zero()
3✔
257
        )
3✔
258
        typeMap, err := tlvRecords.ExtractRecords(
3✔
259
                &a.UpfrontShutdownScript, &chanType, &leaseExpiry,
3✔
260
                &localNonce,
3✔
261
        )
3✔
262
        if err != nil {
3✔
UNCOV
263
                return err
×
UNCOV
264
        }
×
265

266
        // Set the corresponding TLV types if they were included in the stream.
267
        if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil {
6✔
268
                a.ChannelType = &chanType
3✔
269
        }
3✔
270
        if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil {
6✔
271
                a.LeaseExpiry = &leaseExpiry
3✔
272
        }
3✔
273
        if val, ok := typeMap[a.LocalNonce.TlvType()]; ok && val == nil {
6✔
274
                a.LocalNonce = tlv.SomeRecordT(localNonce)
3✔
275
        }
3✔
276

277
        a.ExtraData = tlvRecords
3✔
278

3✔
279
        return nil
3✔
280
}
281

282
// MsgType returns the MessageType code which uniquely identifies this message
283
// as an AcceptChannel on the wire.
284
//
285
// This is part of the lnwire.Message interface.
286
func (a *AcceptChannel) MsgType() MessageType {
3✔
287
        return MsgAcceptChannel
3✔
288
}
3✔
289

290
// SerializedSize returns the serialized size of the message in bytes.
291
//
292
// This is part of the lnwire.SizeableMessage interface.
NEW
293
func (a *AcceptChannel) SerializedSize() (uint32, error) {
×
NEW
294
        return MessageSerializedSize(a)
×
NEW
295
}
×
296

297
// A compile time check to ensure AcceptChannel implements the TestMessage interface.
298
var _ TestMessage = (*AcceptChannel)(nil)
299

300
// RandTestMessage populates the message with random data suitable for testing.
301
// It uses the rapid testing framework to generate random values.
302
//
303
// This is part of the TestMessage interface.
NEW
304
func (a *AcceptChannel) RandTestMessage(t *rapid.T) Message {
×
NEW
305
        var pendingChanID [32]byte
×
NEW
306
        pendingChanIDBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(
×
NEW
307
                t, "pendingChanID",
×
NEW
308
        )
×
NEW
309
        copy(pendingChanID[:], pendingChanIDBytes)
×
NEW
310

×
NEW
311
        var channelType *ChannelType
×
NEW
312
        includeChannelType := rapid.Bool().Draw(t, "includeChannelType")
×
NEW
313
        includeLeaseExpiry := rapid.Bool().Draw(t, "includeLeaseExpiry")
×
NEW
314
        includeLocalNonce := rapid.Bool().Draw(t, "includeLocalNonce")
×
NEW
315

×
NEW
316
        if includeChannelType {
×
NEW
317
                channelType = RandChannelType(t)
×
NEW
318
        }
×
319

NEW
320
        var leaseExpiry *LeaseExpiry
×
NEW
321
        if includeLeaseExpiry {
×
NEW
322
                leaseExpiry = RandLeaseExpiry(t)
×
NEW
323
        }
×
324

NEW
325
        var localNonce OptMusig2NonceTLV
×
NEW
326
        if includeLocalNonce {
×
NEW
327
                nonce := RandMusig2Nonce(t)
×
NEW
328
                localNonce = tlv.SomeRecordT(
×
NEW
329
                        tlv.NewRecordT[NonceRecordTypeT, Musig2Nonce](nonce),
×
NEW
330
                )
×
NEW
331
        }
×
332

NEW
333
        return &AcceptChannel{
×
NEW
334
                PendingChannelID: pendingChanID,
×
NEW
335
                DustLimit: btcutil.Amount(
×
NEW
336
                        rapid.IntRange(100, 1000).Draw(t, "dustLimit"),
×
NEW
337
                ),
×
NEW
338
                MaxValueInFlight: MilliSatoshi(
×
NEW
339
                        rapid.IntRange(10000, 1000000).Draw(
×
NEW
340
                                t, "maxValueInFlight",
×
NEW
341
                        ),
×
NEW
342
                ),
×
NEW
343
                ChannelReserve: btcutil.Amount(
×
NEW
344
                        rapid.IntRange(1000, 10000).Draw(t, "channelReserve"),
×
NEW
345
                ),
×
NEW
346
                HtlcMinimum: MilliSatoshi(
×
NEW
347
                        rapid.IntRange(1, 1000).Draw(t, "htlcMinimum"),
×
NEW
348
                ),
×
NEW
349
                MinAcceptDepth: uint32(
×
NEW
350
                        rapid.IntRange(1, 10).Draw(t, "minAcceptDepth"),
×
NEW
351
                ),
×
NEW
352
                CsvDelay: uint16(
×
NEW
353
                        rapid.IntRange(144, 1000).Draw(t, "csvDelay"),
×
NEW
354
                ),
×
NEW
355
                MaxAcceptedHTLCs: uint16(
×
NEW
356
                        rapid.IntRange(10, 500).Draw(t, "maxAcceptedHTLCs"),
×
NEW
357
                ),
×
NEW
358
                FundingKey:            RandPubKey(t),
×
NEW
359
                RevocationPoint:       RandPubKey(t),
×
NEW
360
                PaymentPoint:          RandPubKey(t),
×
NEW
361
                DelayedPaymentPoint:   RandPubKey(t),
×
NEW
362
                HtlcPoint:             RandPubKey(t),
×
NEW
363
                FirstCommitmentPoint:  RandPubKey(t),
×
NEW
364
                UpfrontShutdownScript: RandDeliveryAddress(t),
×
NEW
365
                ChannelType:           channelType,
×
NEW
366
                LeaseExpiry:           leaseExpiry,
×
NEW
367
                LocalNonce:            localNonce,
×
NEW
368
                ExtraData:             RandExtraOpaqueData(t, nil),
×
NEW
369
        }
×
370
}
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