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

lightningnetwork / lnd / 16293817609

15 Jul 2025 12:53PM UTC coverage: 57.584% (-9.8%) from 67.338%
16293817609

Pull #10031

github

web-flow
Merge 8fd26da8b into df6c02e3a
Pull Request #10031: Skip unnecessary disconnect and wait for disconnect to finish in shutdown

36 of 40 new or added lines in 2 files covered. (90.0%)

28482 existing lines in 458 files now uncovered.

98681 of 171370 relevant lines covered (57.58%)

1.79 hits per line

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

0.0
/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.
UNCOV
68
func (dp *DynPropose) Encode(w *bytes.Buffer, _ uint32) error {
×
UNCOV
69
        if err := WriteChannelID(w, dp.ChanID); err != nil {
×
70
                return err
×
71
        }
×
72

UNCOV
73
        producers := dynProposeRecords(dp)
×
UNCOV
74

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

UNCOV
80
        return WriteBytes(w, dp.ExtraData)
×
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.
UNCOV
88
func (dp *DynPropose) Decode(r io.Reader, _ uint32) error {
×
UNCOV
89
        // Parse out the only required field.
×
UNCOV
90
        if err := ReadElements(r, &dp.ChanID); err != nil {
×
UNCOV
91
                return err
×
UNCOV
92
        }
×
93

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

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

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

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

UNCOV
149
        if len(tlvRecords) != 0 {
×
UNCOV
150
                dp.ExtraData = tlvRecords
×
UNCOV
151
        }
×
152

UNCOV
153
        return nil
×
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.
UNCOV
160
func (dp *DynPropose) MsgType() MessageType {
×
UNCOV
161
        return MsgDynPropose
×
UNCOV
162
}
×
163

164
// SerializedSize returns the serialized size of the message in bytes.
165
//
166
// This is part of the lnwire.SizeableMessage interface.
167
func (dp *DynPropose) SerializedSize() (uint32, error) {
×
168
        return MessageSerializedSize(dp)
×
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

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

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

UNCOV
237
        return recordProducers
×
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