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

lightningnetwork / lnd / 11393106485

17 Oct 2024 09:10PM UTC coverage: 57.848% (-1.0%) from 58.81%
11393106485

Pull #9148

github

ProofOfKeags
lnwire: convert DynPropose and DynCommit to use typed tlv records
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

142 of 177 new or added lines in 4 files covered. (80.23%)

18983 existing lines in 242 files now uncovered.

99003 of 171143 relevant lines covered (57.85%)

36968.25 hits per line

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

80.65
/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
// Encode serializes the target DynPropose into the passed io.Writer.
61
// Serialization will observe the rules defined by the passed protocol version.
62
//
63
// This is a part of the lnwire.Message interface.
64
func (dp *DynPropose) Encode(w *bytes.Buffer, _ uint32) error {
103✔
65
        if err := WriteChannelID(w, dp.ChanID); err != nil {
103✔
UNCOV
66
                return err
×
67
        }
×
68

69
        producers := dynProposeRecords(dp)
103✔
70

103✔
71
        err := EncodeMessageExtraData(&dp.ExtraData, producers...)
103✔
72
        if err != nil {
103✔
73
                return err
×
74
        }
×
75

76
        return WriteBytes(w, dp.ExtraData)
103✔
77
}
78

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

90
        // Parse out TLV stream.
91
        var tlvRecords ExtraOpaqueData
206✔
92
        if err := ReadElements(r, &tlvRecords); err != nil {
206✔
93
                return err
×
94
        }
×
95

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

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

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

145
        if len(tlvRecords) != 0 {
206✔
146
                dp.ExtraData = tlvRecords
100✔
147
        }
100✔
148

149
        return nil
106✔
150
}
151

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

160
// SerializeTlvData takes just the TLV data of DynPropose (which covers all of
161
// the parameters on deck for changing) and serializes just this component. The
162
// main purpose of this is to make it easier to validate the DynAck signature.
NEW
163
func (dp *DynPropose) SerializeTlvData() ([]byte, error) {
×
NEW
164
        producers := dynProposeRecords(dp)
×
NEW
165

×
NEW
166
        var extra ExtraOpaqueData
×
NEW
167
        err := extra.PackRecords(producers...)
×
NEW
168
        if err != nil {
×
NEW
169
                return nil, err
×
NEW
170
        }
×
171

NEW
172
        return extra, nil
×
173
}
174

175
func dynProposeRecords(dp *DynPropose) []tlv.RecordProducer {
203✔
176
        recordProducers := make([]tlv.RecordProducer, 0, 7)
203✔
177

203✔
178
        dp.DustLimit.WhenSome(
203✔
179
                func(dl tlv.RecordT[tlv.TlvType0, btcutil.Amount]) {
306✔
180
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType0](
103✔
181
                                uint64(dl.Val),
103✔
182
                        )
103✔
183
                        recordProducers = append(recordProducers, &rec)
103✔
184
                },
103✔
185
        )
186
        dp.MaxValueInFlight.WhenSome(
203✔
187
                func(max tlv.RecordT[tlv.TlvType2, MilliSatoshi]) {
298✔
188
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType2](
95✔
189
                                uint64(max.Val),
95✔
190
                        )
95✔
191
                        recordProducers = append(recordProducers, &rec)
95✔
192
                },
95✔
193
        )
194
        dp.HtlcMinimum.WhenSome(
203✔
195
                func(min tlv.RecordT[tlv.TlvType4, MilliSatoshi]) {
203✔
NEW
196
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType4](
×
NEW
197
                                uint64(min.Val),
×
NEW
198
                        )
×
NEW
199
                        recordProducers = append(recordProducers, &rec)
×
NEW
200
                },
×
201
        )
202
        dp.ChannelReserve.WhenSome(
203✔
203
                func(reserve tlv.RecordT[tlv.TlvType6, btcutil.Amount]) {
301✔
204
                        rec := tlv.NewPrimitiveRecord[tlv.TlvType6](
98✔
205
                                uint64(reserve.Val),
98✔
206
                        )
98✔
207
                        recordProducers = append(recordProducers, &rec)
98✔
208
                },
98✔
209
        )
210
        dp.CsvDelay.WhenSome(
203✔
211
                func(wait tlv.RecordT[tlv.TlvType8, uint16]) {
308✔
212
                        recordProducers = append(recordProducers, &wait)
105✔
213
                },
105✔
214
        )
215
        dp.MaxAcceptedHTLCs.WhenSome(
203✔
216
                func(max tlv.RecordT[tlv.TlvType10, uint16]) {
308✔
217
                        recordProducers = append(recordProducers, &max)
105✔
218
                },
105✔
219
        )
220
        dp.ChannelType.WhenSome(
203✔
221
                func(ty tlv.RecordT[tlv.TlvType12, ChannelType]) {
305✔
222
                        recordProducers = append(recordProducers, &ty)
102✔
223
                },
102✔
224
        )
225

226
        return recordProducers
203✔
227
}
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