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

lightningnetwork / lnd / 16048076081

03 Jul 2025 10:31AM UTC coverage: 67.53% (-0.06%) from 67.589%
16048076081

Pull #10018

github

web-flow
Merge b10bc9e36 into 8a0341419
Pull Request #10018: Refactor link's long methods

530 of 808 new or added lines in 1 file covered. (65.59%)

140 existing lines in 29 files now uncovered.

135096 of 200052 relevant lines covered (67.53%)

21807.17 hits per line

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

78.74
/lnwire/dyn_propose.go
1
package lnwire
2

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

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

11
// DynPropose is a message that is sent during a dynamic commitments negotiation
12
// process. It is sent by both parties to propose new channel parameters.
13
type DynPropose struct {
14
        // ChanID identifies the channel whose parameters we are trying to
15
        // re-negotiate.
16
        ChanID ChannelID
17

18
        // DustLimit, if not nil, proposes a change to the dust_limit_satoshis
19
        // for the sender's commitment transaction.
20
        DustLimit tlv.OptionalRecordT[tlv.TlvType0, btcutil.Amount]
21

22
        // MaxValueInFlight, if not nil, proposes a change to the
23
        // max_htlc_value_in_flight_msat limit of the sender.
24
        MaxValueInFlight tlv.OptionalRecordT[tlv.TlvType2, MilliSatoshi]
25

26
        // HtlcMinimum, if not nil, proposes a change to the htlc_minimum_msat
27
        // floor of the sender.
28
        HtlcMinimum tlv.OptionalRecordT[tlv.TlvType4, MilliSatoshi]
29

30
        // ChannelReserve, if not nil, proposes a change to the
31
        // channel_reserve_satoshis requirement of the recipient.
32
        ChannelReserve tlv.OptionalRecordT[tlv.TlvType6, btcutil.Amount]
33

34
        // CsvDelay, if not nil, proposes a change to the to_self_delay
35
        // requirement of the recipient.
36
        CsvDelay tlv.OptionalRecordT[tlv.TlvType8, uint16]
37

38
        // MaxAcceptedHTLCs, if not nil, proposes a change to the
39
        // max_accepted_htlcs limit of the sender.
40
        MaxAcceptedHTLCs tlv.OptionalRecordT[tlv.TlvType10, uint16]
41

42
        // ChannelType, if not nil, proposes a change to the channel_type
43
        // parameter.
44
        ChannelType tlv.OptionalRecordT[tlv.TlvType12, ChannelType]
45

46
        // ExtraData is the set of data that was appended to this message to
47
        // fill out the full maximum transport message size. These fields can
48
        // be used to specify optional data such as custom TLV fields.
49
        //
50
        // NOTE: Since the fields in this structure are part of the TLV stream,
51
        // ExtraData will contain all TLV records _except_ the ones that are
52
        // present in earlier parts of this structure.
53
        ExtraData ExtraOpaqueData
54
}
55

56
// A compile time check to ensure DynPropose implements the lnwire.Message
57
// interface.
58
var _ Message = (*DynPropose)(nil)
59

60
// A compile time check to ensure DynPropose implements the
61
// lnwire.SizeableMessage interface.
62
var _ SizeableMessage = (*DynPropose)(nil)
63

64
// Encode serializes the target DynPropose into the passed io.Writer.
65
// Serialization will observe the rules defined by the passed protocol version.
66
//
67
// This is a part of the lnwire.Message interface.
68
func (dp *DynPropose) Encode(w *bytes.Buffer, _ uint32) error {
103✔
69
        if err := WriteChannelID(w, dp.ChanID); err != nil {
103✔
70
                return err
×
71
        }
×
72

73
        producers := dynProposeRecords(dp)
103✔
74

103✔
75
        err := EncodeMessageExtraData(&dp.ExtraData, producers...)
103✔
76
        if err != nil {
103✔
77
                return err
×
78
        }
×
79

80
        return WriteBytes(w, dp.ExtraData)
103✔
81
}
82

83
// Decode deserializes the serialized DynPropose stored in the passed io.Reader
84
// into the target DynPropose using the deserialization rules defined by the
85
// passed protocol version.
86
//
87
// This is a part of the lnwire.Message interface.
88
func (dp *DynPropose) Decode(r io.Reader, _ uint32) error {
208✔
89
        // Parse out the only required field.
208✔
90
        if err := ReadElements(r, &dp.ChanID); err != nil {
210✔
91
                return err
2✔
92
        }
2✔
93

94
        // Parse out TLV stream.
95
        var tlvRecords ExtraOpaqueData
206✔
96
        if err := ReadElements(r, &tlvRecords); err != nil {
206✔
97
                return err
×
98
        }
×
99

100
        // Prepare receiving buffers to be filled by TLV extraction.
101
        var dustLimit tlv.RecordT[tlv.TlvType0, uint64]
206✔
102
        var maxValue tlv.RecordT[tlv.TlvType2, uint64]
206✔
103
        var htlcMin tlv.RecordT[tlv.TlvType4, uint64]
206✔
104
        var reserve tlv.RecordT[tlv.TlvType6, uint64]
206✔
105
        csvDelay := dp.CsvDelay.Zero()
206✔
106
        maxHtlcs := dp.MaxAcceptedHTLCs.Zero()
206✔
107
        chanType := dp.ChannelType.Zero()
206✔
108

206✔
109
        typeMap, err := tlvRecords.ExtractRecords(
206✔
110
                &dustLimit, &maxValue, &htlcMin, &reserve, &csvDelay, &maxHtlcs,
206✔
111
                &chanType,
206✔
112
        )
206✔
113
        if err != nil {
306✔
114
                return err
100✔
115
        }
100✔
116

117
        // Check the results of the TLV Stream decoding and appropriately set
118
        // message fields.
119
        if val, ok := typeMap[dp.DustLimit.TlvType()]; ok && val == nil {
161✔
120
                var rec tlv.RecordT[tlv.TlvType0, btcutil.Amount]
55✔
121
                rec.Val = btcutil.Amount(dustLimit.Val)
55✔
122
                dp.DustLimit = tlv.SomeRecordT(rec)
55✔
123
        }
55✔
124
        if val, ok := typeMap[dp.MaxValueInFlight.TlvType()]; ok && val == nil {
157✔
125
                var rec tlv.RecordT[tlv.TlvType2, MilliSatoshi]
51✔
126
                rec.Val = MilliSatoshi(maxValue.Val)
51✔
127
                dp.MaxValueInFlight = tlv.SomeRecordT(rec)
51✔
128
        }
51✔
129
        if val, ok := typeMap[dp.HtlcMinimum.TlvType()]; ok && val == nil {
106✔
130
                var rec tlv.RecordT[tlv.TlvType4, MilliSatoshi]
×
131
                rec.Val = MilliSatoshi(htlcMin.Val)
×
132
                dp.HtlcMinimum = tlv.SomeRecordT(rec)
×
133
        }
×
134
        if val, ok := typeMap[dp.ChannelReserve.TlvType()]; ok && val == nil {
149✔
135
                var rec tlv.RecordT[tlv.TlvType6, btcutil.Amount]
43✔
136
                rec.Val = btcutil.Amount(reserve.Val)
43✔
137
                dp.ChannelReserve = tlv.SomeRecordT(rec)
43✔
138
        }
43✔
139
        if val, ok := typeMap[dp.CsvDelay.TlvType()]; ok && val == nil {
159✔
140
                dp.CsvDelay = tlv.SomeRecordT(csvDelay)
53✔
141
        }
53✔
142
        if val, ok := typeMap[dp.MaxAcceptedHTLCs.TlvType()]; ok && val == nil {
157✔
143
                dp.MaxAcceptedHTLCs = tlv.SomeRecordT(maxHtlcs)
51✔
144
        }
51✔
145
        if val, ok := typeMap[dp.ChannelType.TlvType()]; ok && val == nil {
156✔
146
                dp.ChannelType = tlv.SomeRecordT(chanType)
50✔
147
        }
50✔
148

149
        if len(tlvRecords) != 0 {
208✔
150
                dp.ExtraData = tlvRecords
102✔
151
        }
102✔
152

153
        return nil
106✔
154
}
155

156
// MsgType returns the MessageType code which uniquely identifies this message
157
// as a DynPropose on the wire.
158
//
159
// This is part of the lnwire.Message interface.
160
func (dp *DynPropose) MsgType() MessageType {
103✔
161
        return MsgDynPropose
103✔
162
}
103✔
163

164
// SerializedSize returns the serialized size of the message in bytes.
165
//
166
// This is part of the lnwire.SizeableMessage interface.
UNCOV
167
func (dp *DynPropose) SerializedSize() (uint32, error) {
×
UNCOV
168
        return MessageSerializedSize(dp)
×
UNCOV
169
}
×
170

171
// SerializeTlvData takes just the TLV data of DynPropose (which covers all of
172
// the parameters on deck for changing) and serializes just this component. The
173
// main purpose of this is to make it easier to validate the DynAck signature.
174
func (dp *DynPropose) SerializeTlvData() ([]byte, error) {
×
175
        producers := dynProposeRecords(dp)
×
176

×
177
        var extra ExtraOpaqueData
×
178
        err := extra.PackRecords(producers...)
×
179
        if err != nil {
×
180
                return nil, err
×
181
        }
×
182

183
        return extra, nil
×
184
}
185

186
func dynProposeRecords(dp *DynPropose) []tlv.RecordProducer {
203✔
187
        recordProducers := make([]tlv.RecordProducer, 0, 7)
203✔
188

203✔
189
        dp.DustLimit.WhenSome(
203✔
190
                func(dl tlv.RecordT[tlv.TlvType0, btcutil.Amount]) {
313✔
191
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType0](
110✔
192
                                uint64(dl.Val),
110✔
193
                        )
110✔
194
                        recordProducers = append(recordProducers, &rec)
110✔
195
                },
110✔
196
        )
197
        dp.MaxValueInFlight.WhenSome(
203✔
198
                func(mvif tlv.RecordT[tlv.TlvType2, MilliSatoshi]) {
303✔
199
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType2](
100✔
200
                                uint64(mvif.Val),
100✔
201
                        )
100✔
202
                        recordProducers = append(recordProducers, &rec)
100✔
203
                },
100✔
204
        )
205
        dp.HtlcMinimum.WhenSome(
203✔
206
                func(hm tlv.RecordT[tlv.TlvType4, MilliSatoshi]) {
203✔
207
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType4](
×
208
                                uint64(hm.Val),
×
209
                        )
×
210
                        recordProducers = append(recordProducers, &rec)
×
211
                },
×
212
        )
213
        dp.ChannelReserve.WhenSome(
203✔
214
                func(reserve tlv.RecordT[tlv.TlvType6, btcutil.Amount]) {
300✔
215
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType6](
97✔
216
                                uint64(reserve.Val),
97✔
217
                        )
97✔
218
                        recordProducers = append(recordProducers, &rec)
97✔
219
                },
97✔
220
        )
221
        dp.CsvDelay.WhenSome(
203✔
222
                func(wait tlv.RecordT[tlv.TlvType8, uint16]) {
305✔
223
                        recordProducers = append(recordProducers, &wait)
102✔
224
                },
102✔
225
        )
226
        dp.MaxAcceptedHTLCs.WhenSome(
203✔
227
                func(mah tlv.RecordT[tlv.TlvType10, uint16]) {
304✔
228
                        recordProducers = append(recordProducers, &mah)
101✔
229
                },
101✔
230
        )
231
        dp.ChannelType.WhenSome(
203✔
232
                func(ty tlv.RecordT[tlv.TlvType12, ChannelType]) {
307✔
233
                        recordProducers = append(recordProducers, &ty)
104✔
234
                },
104✔
235
        )
236

237
        return recordProducers
203✔
238
}
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