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

lightningnetwork / lnd / 13999301927

21 Mar 2025 07:18PM UTC coverage: 68.989% (+9.9%) from 59.126%
13999301927

push

github

web-flow
Merge pull request #9623 from Roasbeef/size-msg-test-msg

Size msg test msg

1461 of 1572 new or added lines in 43 files covered. (92.94%)

28 existing lines in 6 files now uncovered.

132898 of 192637 relevant lines covered (68.99%)

22200.59 hits per line

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

91.89
/lnwire/dyn_propose.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/fn/v2"
10
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
11
        "github.com/lightningnetwork/lnd/tlv"
12
)
13

14
const (
15
        // DPDustLimitSatoshis is the TLV type number that identifies the record
16
        // for DynPropose.DustLimit.
17
        DPDustLimitSatoshis tlv.Type = 0
18

19
        // DPMaxHtlcValueInFlightMsat is the TLV type number that identifies the
20
        // record for DynPropose.MaxValueInFlight.
21
        DPMaxHtlcValueInFlightMsat tlv.Type = 1
22

23
        // DPChannelReserveSatoshis is the TLV type number that identifies the
24
        // for DynPropose.ChannelReserve.
25
        DPChannelReserveSatoshis tlv.Type = 2
26

27
        // DPToSelfDelay is the TLV type number that identifies the record for
28
        // DynPropose.CsvDelay.
29
        DPToSelfDelay tlv.Type = 3
30

31
        // DPMaxAcceptedHtlcs is the TLV type number that identifies the record
32
        // for DynPropose.MaxAcceptedHTLCs.
33
        DPMaxAcceptedHtlcs tlv.Type = 4
34

35
        // DPFundingPubkey is the TLV type number that identifies the record for
36
        // DynPropose.FundingKey.
37
        DPFundingPubkey tlv.Type = 5
38

39
        // DPChannelType is the TLV type number that identifies the record for
40
        // DynPropose.ChannelType.
41
        DPChannelType tlv.Type = 6
42

43
        // DPKickoffFeerate is the TLV type number that identifies the record
44
        // for DynPropose.KickoffFeerate.
45
        DPKickoffFeerate tlv.Type = 7
46
)
47

48
// DynPropose is a message that is sent during a dynamic commitments negotiation
49
// process. It is sent by both parties to propose new channel parameters.
50
type DynPropose struct {
51
        // ChanID identifies the channel whose parameters we are trying to
52
        // re-negotiate.
53
        ChanID ChannelID
54

55
        // Initiator is a byte that identifies whether this message was sent as
56
        // the initiator of a dynamic commitment negotiation or the responder
57
        // of a dynamic commitment negotiation. bool true indicates it is the
58
        // initiator
59
        Initiator bool
60

61
        // DustLimit, if not nil, proposes a change to the dust_limit_satoshis
62
        // for the sender's commitment transaction.
63
        DustLimit fn.Option[btcutil.Amount]
64

65
        // MaxValueInFlight, if not nil, proposes a change to the
66
        // max_htlc_value_in_flight_msat limit of the sender.
67
        MaxValueInFlight fn.Option[MilliSatoshi]
68

69
        // ChannelReserve, if not nil, proposes a change to the
70
        // channel_reserve_satoshis requirement of the recipient.
71
        ChannelReserve fn.Option[btcutil.Amount]
72

73
        // CsvDelay, if not nil, proposes a change to the to_self_delay
74
        // requirement of the recipient.
75
        CsvDelay fn.Option[uint16]
76

77
        // MaxAcceptedHTLCs, if not nil, proposes a change to the
78
        // max_accepted_htlcs limit of the sender.
79
        MaxAcceptedHTLCs fn.Option[uint16]
80

81
        // FundingKey, if not nil, proposes a change to the funding_pubkey
82
        // parameter of the sender.
83
        FundingKey fn.Option[btcec.PublicKey]
84

85
        // ChannelType, if not nil, proposes a change to the channel_type
86
        // parameter.
87
        ChannelType fn.Option[ChannelType]
88

89
        // KickoffFeerate proposes the fee rate in satoshis per kw that it
90
        // is offering for a ChannelType conversion that requires a kickoff
91
        // transaction.
92
        KickoffFeerate fn.Option[chainfee.SatPerKWeight]
93

94
        // ExtraData is the set of data that was appended to this message to
95
        // fill out the full maximum transport message size. These fields can
96
        // be used to specify optional data such as custom TLV fields.
97
        //
98
        // NOTE: Since the fields in this structure are part of the TLV stream,
99
        // ExtraData will contain all TLV records _except_ the ones that are
100
        // present in earlier parts of this structure.
101
        ExtraData ExtraOpaqueData
102
}
103

104
// A compile time check to ensure DynPropose implements the lnwire.Message
105
// interface.
106
var _ Message = (*DynPropose)(nil)
107

108
// A compile time check to ensure DynPropose implements the
109
// lnwire.SizeableMessage interface.
110
var _ SizeableMessage = (*DynPropose)(nil)
111

112
// Encode serializes the target DynPropose into the passed io.Writer.
113
// Serialization will observe the rules defined by the passed protocol version.
114
//
115
// This is a part of the lnwire.Message interface.
116
func (dp *DynPropose) Encode(w *bytes.Buffer, _ uint32) error {
141✔
117
        var tlvRecords []tlv.Record
141✔
118
        dp.DustLimit.WhenSome(func(dl btcutil.Amount) {
198✔
119
                protoSats := uint64(dl)
57✔
120
                tlvRecords = append(
57✔
121
                        tlvRecords, tlv.MakePrimitiveRecord(
57✔
122
                                DPDustLimitSatoshis, &protoSats,
57✔
123
                        ),
57✔
124
                )
57✔
125
        })
57✔
126
        dp.MaxValueInFlight.WhenSome(func(max MilliSatoshi) {
193✔
127
                protoSats := uint64(max)
52✔
128
                tlvRecords = append(
52✔
129
                        tlvRecords, tlv.MakePrimitiveRecord(
52✔
130
                                DPMaxHtlcValueInFlightMsat, &protoSats,
52✔
131
                        ),
52✔
132
                )
52✔
133
        })
52✔
134
        dp.ChannelReserve.WhenSome(func(min btcutil.Amount) {
198✔
135
                channelReserve := uint64(min)
57✔
136
                tlvRecords = append(
57✔
137
                        tlvRecords, tlv.MakePrimitiveRecord(
57✔
138
                                DPChannelReserveSatoshis, &channelReserve,
57✔
139
                        ),
57✔
140
                )
57✔
141
        })
57✔
142
        dp.CsvDelay.WhenSome(func(wait uint16) {
193✔
143
                tlvRecords = append(
52✔
144
                        tlvRecords, tlv.MakePrimitiveRecord(
52✔
145
                                DPToSelfDelay, &wait,
52✔
146
                        ),
52✔
147
                )
52✔
148
        })
52✔
149
        dp.MaxAcceptedHTLCs.WhenSome(func(max uint16) {
195✔
150
                tlvRecords = append(
54✔
151
                        tlvRecords, tlv.MakePrimitiveRecord(
54✔
152
                                DPMaxAcceptedHtlcs, &max,
54✔
153
                        ),
54✔
154
                )
54✔
155
        })
54✔
156
        dp.FundingKey.WhenSome(func(key btcec.PublicKey) {
187✔
157
                keyScratch := &key
46✔
158
                tlvRecords = append(
46✔
159
                        tlvRecords, tlv.MakePrimitiveRecord(
46✔
160
                                DPFundingPubkey, &keyScratch,
46✔
161
                        ),
46✔
162
                )
46✔
163
        })
46✔
164
        dp.ChannelType.WhenSome(func(ty ChannelType) {
225✔
165
                tlvRecords = append(
84✔
166
                        tlvRecords, tlv.MakeDynamicRecord(
84✔
167
                                DPChannelType, &ty,
84✔
168
                                ty.featureBitLen,
84✔
169
                                channelTypeEncoder, channelTypeDecoder,
84✔
170
                        ),
84✔
171
                )
84✔
172
        })
84✔
173
        dp.KickoffFeerate.WhenSome(func(kickoffFeerate chainfee.SatPerKWeight) {
194✔
174
                protoSats := uint32(kickoffFeerate)
53✔
175
                tlvRecords = append(
53✔
176
                        tlvRecords, tlv.MakePrimitiveRecord(
53✔
177
                                DPKickoffFeerate, &protoSats,
53✔
178
                        ),
53✔
179
                )
53✔
180
        })
53✔
181
        tlv.SortRecords(tlvRecords)
141✔
182

141✔
183
        tlvStream, err := tlv.NewStream(tlvRecords...)
141✔
184
        if err != nil {
141✔
185
                return err
×
186
        }
×
187

188
        var extraBytesWriter bytes.Buffer
141✔
189
        if err := tlvStream.Encode(&extraBytesWriter); err != nil {
141✔
190
                return err
×
191
        }
×
192
        dp.ExtraData = ExtraOpaqueData(extraBytesWriter.Bytes())
141✔
193

141✔
194
        if err := WriteChannelID(w, dp.ChanID); err != nil {
141✔
195
                return err
×
196
        }
×
197

198
        if err := WriteBool(w, dp.Initiator); err != nil {
141✔
199
                return err
×
200
        }
×
201

202
        return WriteBytes(w, dp.ExtraData)
141✔
203
}
204

205
// Decode deserializes the serialized DynPropose stored in the passed io.Reader
206
// into the target DynPropose using the deserialization rules defined by the
207
// passed protocol version.
208
//
209
// This is a part of the lnwire.Message interface.
210
func (dp *DynPropose) Decode(r io.Reader, _ uint32) error {
246✔
211
        // Parse out the only required field.
246✔
212
        if err := ReadElements(r, &dp.ChanID, &dp.Initiator); err != nil {
249✔
213
                return err
3✔
214
        }
3✔
215

216
        // Parse out TLV stream.
217
        var tlvRecords ExtraOpaqueData
243✔
218
        if err := ReadElements(r, &tlvRecords); err != nil {
243✔
219
                return err
×
220
        }
×
221

222
        // Prepare receiving buffers to be filled by TLV extraction.
223
        var dustLimitScratch uint64
243✔
224
        dustLimit := tlv.MakePrimitiveRecord(
243✔
225
                DPDustLimitSatoshis, &dustLimitScratch,
243✔
226
        )
243✔
227

243✔
228
        var maxValueScratch uint64
243✔
229
        maxValue := tlv.MakePrimitiveRecord(
243✔
230
                DPMaxHtlcValueInFlightMsat, &maxValueScratch,
243✔
231
        )
243✔
232

243✔
233
        var reserveScratch uint64
243✔
234
        reserve := tlv.MakePrimitiveRecord(
243✔
235
                DPChannelReserveSatoshis, &reserveScratch,
243✔
236
        )
243✔
237

243✔
238
        var csvDelayScratch uint16
243✔
239
        csvDelay := tlv.MakePrimitiveRecord(DPToSelfDelay, &csvDelayScratch)
243✔
240

243✔
241
        var maxHtlcsScratch uint16
243✔
242
        maxHtlcs := tlv.MakePrimitiveRecord(
243✔
243
                DPMaxAcceptedHtlcs, &maxHtlcsScratch,
243✔
244
        )
243✔
245

243✔
246
        var fundingKeyScratch *btcec.PublicKey
243✔
247
        fundingKey := tlv.MakePrimitiveRecord(
243✔
248
                DPFundingPubkey, &fundingKeyScratch,
243✔
249
        )
243✔
250

243✔
251
        var chanTypeScratch ChannelType
243✔
252
        chanType := tlv.MakeDynamicRecord(
243✔
253
                DPChannelType, &chanTypeScratch, chanTypeScratch.featureBitLen,
243✔
254
                channelTypeEncoder, channelTypeDecoder,
243✔
255
        )
243✔
256

243✔
257
        var kickoffFeerateScratch uint32
243✔
258
        kickoffFeerate := tlv.MakePrimitiveRecord(
243✔
259
                DPKickoffFeerate, &kickoffFeerateScratch,
243✔
260
        )
243✔
261

243✔
262
        // Create set of Records to read TLV bytestream into.
243✔
263
        records := []tlv.Record{
243✔
264
                dustLimit, maxValue, reserve, csvDelay, maxHtlcs, fundingKey,
243✔
265
                chanType, kickoffFeerate,
243✔
266
        }
243✔
267
        tlv.SortRecords(records)
243✔
268

243✔
269
        // Read TLV stream into record set.
243✔
270
        extraBytesReader := bytes.NewReader(tlvRecords)
243✔
271
        tlvStream, err := tlv.NewStream(records...)
243✔
272
        if err != nil {
243✔
273
                return err
×
274
        }
×
275

276
        typeMap, err := tlvStream.DecodeWithParsedTypesP2P(extraBytesReader)
243✔
277
        if err != nil {
304✔
278
                return err
61✔
279
        }
61✔
280

281
        // Check the results of the TLV Stream decoding and appropriately set
282
        // message fields.
283
        if val, ok := typeMap[DPDustLimitSatoshis]; ok && val == nil {
242✔
284
                dp.DustLimit = fn.Some(btcutil.Amount(dustLimitScratch))
60✔
285
        }
60✔
286
        if val, ok := typeMap[DPMaxHtlcValueInFlightMsat]; ok && val == nil {
237✔
287
                dp.MaxValueInFlight = fn.Some(MilliSatoshi(maxValueScratch))
55✔
288
        }
55✔
289
        if val, ok := typeMap[DPChannelReserveSatoshis]; ok && val == nil {
241✔
290
                dp.ChannelReserve = fn.Some(btcutil.Amount(reserveScratch))
59✔
291
        }
59✔
292
        if val, ok := typeMap[DPToSelfDelay]; ok && val == nil {
238✔
293
                dp.CsvDelay = fn.Some(csvDelayScratch)
56✔
294
        }
56✔
295
        if val, ok := typeMap[DPMaxAcceptedHtlcs]; ok && val == nil {
238✔
296
                dp.MaxAcceptedHTLCs = fn.Some(maxHtlcsScratch)
56✔
297
        }
56✔
298
        if val, ok := typeMap[DPFundingPubkey]; ok && val == nil {
231✔
299
                dp.FundingKey = fn.Some(*fundingKeyScratch)
49✔
300
        }
49✔
301
        if val, ok := typeMap[DPChannelType]; ok && val == nil {
292✔
302
                dp.ChannelType = fn.Some(chanTypeScratch)
110✔
303
        }
110✔
304
        if val, ok := typeMap[DPKickoffFeerate]; ok && val == nil {
236✔
305
                dp.KickoffFeerate = fn.Some(
54✔
306
                        chainfee.SatPerKWeight(kickoffFeerateScratch),
54✔
307
                )
54✔
308
        }
54✔
309

310
        if len(tlvRecords) != 0 {
357✔
311
                dp.ExtraData = tlvRecords
175✔
312
        }
175✔
313

314
        return nil
182✔
315
}
316

317
// MsgType returns the MessageType code which uniquely identifies this message
318
// as a DynPropose on the wire.
319
//
320
// This is part of the lnwire.Message interface.
321
func (dp *DynPropose) MsgType() MessageType {
141✔
322
        return MsgDynPropose
141✔
323
}
141✔
324

325
// SerializedSize returns the serialized size of the message in bytes.
326
//
327
// This is part of the lnwire.SizeableMessage interface.
NEW
328
func (dp *DynPropose) SerializedSize() (uint32, error) {
×
NEW
329
        return MessageSerializedSize(dp)
×
NEW
330
}
×
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