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

lightningnetwork / lnd / 15736109134

18 Jun 2025 02:46PM UTC coverage: 58.197% (-10.1%) from 68.248%
15736109134

Pull #9752

github

web-flow
Merge d2634a68c into 31c74f20f
Pull Request #9752: routerrpc: reject payment to invoice that don't have payment secret or blinded paths

6 of 13 new or added lines in 2 files covered. (46.15%)

28331 existing lines in 455 files now uncovered.

97860 of 168153 relevant lines covered (58.2%)

1.81 hits per line

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

63.57
/lnwire/open_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/btcsuite/btcd/chaincfg/chainhash"
10
        "github.com/lightningnetwork/lnd/tlv"
11
)
12

13
// FundingFlag represents the possible bit mask values for the ChannelFlags
14
// field within the OpenChannel struct.
15
type FundingFlag uint8
16

17
const (
18
        // FFAnnounceChannel is a FundingFlag that when set, indicates the
19
        // initiator of a funding flow wishes to announce the channel to the
20
        // greater network.
21
        FFAnnounceChannel FundingFlag = 1 << iota
22
)
23

24
// OpenChannel is the message Alice sends to Bob if we should like to create a
25
// channel with Bob where she's the sole provider of funds to the channel.
26
// Single funder channels simplify the initial funding workflow, are supported
27
// by nodes backed by SPV Bitcoin clients, and have a simpler security models
28
// than dual funded channels.
29
type OpenChannel struct {
30
        // ChainHash is the target chain that the initiator wishes to open a
31
        // channel within.
32
        ChainHash chainhash.Hash
33

34
        // PendingChannelID serves to uniquely identify the future channel
35
        // created by the initiated single funder workflow.
36
        PendingChannelID [32]byte
37

38
        // FundingAmount is the amount of satoshis that the initiator of the
39
        // channel wishes to use as the total capacity of the channel. The
40
        // initial balance of the funding will be this value minus the push
41
        // amount (if set).
42
        FundingAmount btcutil.Amount
43

44
        // PushAmount is the value that the initiating party wishes to "push"
45
        // to the responding as part of the first commitment state. If the
46
        // responder accepts, then this will be their initial balance.
47
        PushAmount MilliSatoshi
48

49
        // DustLimit is the specific dust limit the sender of this message
50
        // would like enforced on their version of the commitment transaction.
51
        // Any output below this value will be "trimmed" from the commitment
52
        // transaction, with the amount of the HTLC going to dust.
53
        DustLimit btcutil.Amount
54

55
        // MaxValueInFlight represents the maximum amount of coins that can be
56
        // pending within the channel at any given time. If the amount of funds
57
        // in limbo exceeds this amount, then the channel will be failed.
58
        MaxValueInFlight MilliSatoshi
59

60
        // ChannelReserve is the amount of BTC that the receiving party MUST
61
        // maintain a balance above at all times. This is a safety mechanism to
62
        // ensure that both sides always have skin in the game during the
63
        // channel's lifetime.
64
        ChannelReserve btcutil.Amount
65

66
        // HtlcMinimum is the smallest HTLC that the sender of this message
67
        // will accept.
68
        HtlcMinimum MilliSatoshi
69

70
        // FeePerKiloWeight is the initial fee rate that the initiator suggests
71
        // for both commitment transaction. This value is expressed in sat per
72
        // kilo-weight.
73
        //
74
        // TODO(halseth): make SatPerKWeight when fee estimation is in own
75
        // package. Currently this will cause an import cycle.
76
        FeePerKiloWeight uint32
77

78
        // CsvDelay is the number of blocks to use for the relative time lock
79
        // in the pay-to-self output of both commitment transactions.
80
        CsvDelay uint16
81

82
        // MaxAcceptedHTLCs is the total number of incoming HTLC's that the
83
        // sender of this channel will accept.
84
        MaxAcceptedHTLCs uint16
85

86
        // FundingKey is the key that should be used on behalf of the sender
87
        // within the 2-of-2 multi-sig output that it contained within the
88
        // funding transaction.
89
        FundingKey *btcec.PublicKey
90

91
        // RevocationPoint is the base revocation point for the sending party.
92
        // Any commitment transaction belonging to the receiver of this message
93
        // should use this key and their per-commitment point to derive the
94
        // revocation key for the commitment transaction.
95
        RevocationPoint *btcec.PublicKey
96

97
        // PaymentPoint is the base payment point for the sending party. This
98
        // key should be combined with the per commitment point for a
99
        // particular commitment state in order to create the key that should
100
        // be used in any output that pays directly to the sending party, and
101
        // also within the HTLC covenant transactions.
102
        PaymentPoint *btcec.PublicKey
103

104
        // DelayedPaymentPoint is the delay point for the sending party. This
105
        // key should be combined with the per commitment point to derive the
106
        // keys that are used in outputs of the sender's commitment transaction
107
        // where they claim funds.
108
        DelayedPaymentPoint *btcec.PublicKey
109

110
        // HtlcPoint is the base point used to derive the set of keys for this
111
        // party that will be used within the HTLC public key scripts. This
112
        // value is combined with the receiver's revocation base point in order
113
        // to derive the keys that are used within HTLC scripts.
114
        HtlcPoint *btcec.PublicKey
115

116
        // FirstCommitmentPoint is the first commitment point for the sending
117
        // party. This value should be combined with the receiver's revocation
118
        // base point in order to derive the revocation keys that are placed
119
        // within the commitment transaction of the sender.
120
        FirstCommitmentPoint *btcec.PublicKey
121

122
        // ChannelFlags is a bit-field which allows the initiator of the
123
        // channel to specify further behavior surrounding the channel.
124
        // Currently, the least significant bit of this bit field indicates the
125
        // initiator of the channel wishes to advertise this channel publicly.
126
        ChannelFlags FundingFlag
127

128
        // UpfrontShutdownScript is the script to which the channel funds should
129
        // be paid when mutually closing the channel. This field is optional, and
130
        // and has a length prefix, so a zero will be written if it is not set
131
        // and its length followed by the script will be written if it is set.
132
        UpfrontShutdownScript DeliveryAddress
133

134
        // ChannelType is the explicit channel type the initiator wishes to
135
        // open.
136
        ChannelType *ChannelType
137

138
        // LeaseExpiry represents the absolute expiration height of a channel
139
        // lease. This is a custom TLV record that will only apply when a leased
140
        // channel is being opened using the script enforced lease commitment
141
        // type.
142
        LeaseExpiry *LeaseExpiry
143

144
        // LocalNonce is an optional field that transmits the
145
        // local/verification nonce for a party. This nonce will be used to
146
        // verify the very first commitment transaction signature.  This will
147
        // only be populated if the simple taproot channels type was
148
        // negotiated.
149
        LocalNonce OptMusig2NonceTLV
150

151
        // ExtraData is the set of data that was appended to this message to
152
        // fill out the full maximum transport message size. These fields can
153
        // be used to specify optional data such as custom TLV fields.
154
        //
155
        // NOTE: Since the upfront shutdown script MUST be present (though can
156
        // be zero-length) if any TLV data is available, the script will be
157
        // extracted and removed from this blob when decoding. ExtraData will
158
        // contain all TLV records _except_ the DeliveryAddress record in that
159
        // case.
160
        ExtraData ExtraOpaqueData
161
}
162

163
// A compile time check to ensure OpenChannel implements the lnwire.Message
164
// interface.
165
var _ Message = (*OpenChannel)(nil)
166

167
// A compile time check to ensure OpenChannel implements the
168
// lnwire.SizeableMessage interface.
169
var _ SizeableMessage = (*OpenChannel)(nil)
170

171
// Encode serializes the target OpenChannel into the passed io.Writer
172
// implementation. Serialization will observe the rules defined by the passed
173
// protocol version.
174
func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error {
3✔
175
        recordProducers := []tlv.RecordProducer{&o.UpfrontShutdownScript}
3✔
176
        if o.ChannelType != nil {
6✔
177
                recordProducers = append(recordProducers, o.ChannelType)
3✔
178
        }
3✔
179
        if o.LeaseExpiry != nil {
6✔
180
                recordProducers = append(recordProducers, o.LeaseExpiry)
3✔
181
        }
3✔
182
        o.LocalNonce.WhenSome(func(localNonce Musig2NonceTLV) {
6✔
183
                recordProducers = append(recordProducers, &localNonce)
3✔
184
        })
3✔
185
        err := EncodeMessageExtraData(&o.ExtraData, recordProducers...)
3✔
186
        if err != nil {
3✔
187
                return err
×
188
        }
×
189

190
        if err := WriteBytes(w, o.ChainHash[:]); err != nil {
3✔
191
                return err
×
192
        }
×
193

194
        if err := WriteBytes(w, o.PendingChannelID[:]); err != nil {
3✔
195
                return err
×
196
        }
×
197

198
        if err := WriteSatoshi(w, o.FundingAmount); err != nil {
3✔
199
                return err
×
200
        }
×
201

202
        if err := WriteMilliSatoshi(w, o.PushAmount); err != nil {
3✔
203
                return err
×
204
        }
×
205

206
        if err := WriteSatoshi(w, o.DustLimit); err != nil {
3✔
207
                return err
×
208
        }
×
209

210
        if err := WriteMilliSatoshi(w, o.MaxValueInFlight); err != nil {
3✔
211
                return err
×
212
        }
×
213

214
        if err := WriteSatoshi(w, o.ChannelReserve); err != nil {
3✔
215
                return err
×
216
        }
×
217

218
        if err := WriteMilliSatoshi(w, o.HtlcMinimum); err != nil {
3✔
219
                return err
×
220
        }
×
221

222
        if err := WriteUint32(w, o.FeePerKiloWeight); err != nil {
3✔
223
                return err
×
224
        }
×
225

226
        if err := WriteUint16(w, o.CsvDelay); err != nil {
3✔
227
                return err
×
228
        }
×
229

230
        if err := WriteUint16(w, o.MaxAcceptedHTLCs); err != nil {
3✔
231
                return err
×
232
        }
×
233

234
        if err := WritePublicKey(w, o.FundingKey); err != nil {
3✔
235
                return err
×
236
        }
×
237

238
        if err := WritePublicKey(w, o.RevocationPoint); err != nil {
3✔
239
                return err
×
240
        }
×
241

242
        if err := WritePublicKey(w, o.PaymentPoint); err != nil {
3✔
243
                return err
×
244
        }
×
245

246
        if err := WritePublicKey(w, o.DelayedPaymentPoint); err != nil {
3✔
247
                return err
×
248
        }
×
249

250
        if err := WritePublicKey(w, o.HtlcPoint); err != nil {
3✔
251
                return err
×
252
        }
×
253

254
        if err := WritePublicKey(w, o.FirstCommitmentPoint); err != nil {
3✔
255
                return err
×
256
        }
×
257

258
        if err := WriteFundingFlag(w, o.ChannelFlags); err != nil {
3✔
259
                return err
×
260
        }
×
261

262
        return WriteBytes(w, o.ExtraData)
3✔
263
}
264

265
// Decode deserializes the serialized OpenChannel stored in the passed
266
// io.Reader into the target OpenChannel using the deserialization rules
267
// defined by the passed protocol version.
268
//
269
// This is part of the lnwire.Message interface.
270
func (o *OpenChannel) Decode(r io.Reader, pver uint32) error {
3✔
271
        // Read all the mandatory fields in the open message.
3✔
272
        err := ReadElements(r,
3✔
273
                o.ChainHash[:],
3✔
274
                o.PendingChannelID[:],
3✔
275
                &o.FundingAmount,
3✔
276
                &o.PushAmount,
3✔
277
                &o.DustLimit,
3✔
278
                &o.MaxValueInFlight,
3✔
279
                &o.ChannelReserve,
3✔
280
                &o.HtlcMinimum,
3✔
281
                &o.FeePerKiloWeight,
3✔
282
                &o.CsvDelay,
3✔
283
                &o.MaxAcceptedHTLCs,
3✔
284
                &o.FundingKey,
3✔
285
                &o.RevocationPoint,
3✔
286
                &o.PaymentPoint,
3✔
287
                &o.DelayedPaymentPoint,
3✔
288
                &o.HtlcPoint,
3✔
289
                &o.FirstCommitmentPoint,
3✔
290
                &o.ChannelFlags,
3✔
291
        )
3✔
292
        if err != nil {
3✔
UNCOV
293
                return err
×
UNCOV
294
        }
×
295

296
        // For backwards compatibility, the optional extra data blob for
297
        // OpenChannel must contain an entry for the upfront shutdown script.
298
        // We'll read it out and attempt to parse it.
299
        var tlvRecords ExtraOpaqueData
3✔
300
        if err := ReadElements(r, &tlvRecords); err != nil {
3✔
301
                return err
×
302
        }
×
303

304
        // Next we'll parse out the set of known records, keeping the raw tlv
305
        // bytes untouched to ensure we don't drop any bytes erroneously.
306
        var (
3✔
307
                chanType    ChannelType
3✔
308
                leaseExpiry LeaseExpiry
3✔
309
                localNonce  = o.LocalNonce.Zero()
3✔
310
        )
3✔
311
        typeMap, err := tlvRecords.ExtractRecords(
3✔
312
                &o.UpfrontShutdownScript, &chanType, &leaseExpiry,
3✔
313
                &localNonce,
3✔
314
        )
3✔
315
        if err != nil {
3✔
UNCOV
316
                return err
×
UNCOV
317
        }
×
318

319
        // Set the corresponding TLV types if they were included in the stream.
320
        if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil {
6✔
321
                o.ChannelType = &chanType
3✔
322
        }
3✔
323
        if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil {
6✔
324
                o.LeaseExpiry = &leaseExpiry
3✔
325
        }
3✔
326
        if val, ok := typeMap[o.LocalNonce.TlvType()]; ok && val == nil {
6✔
327
                o.LocalNonce = tlv.SomeRecordT(localNonce)
3✔
328
        }
3✔
329

330
        o.ExtraData = tlvRecords
3✔
331

3✔
332
        return nil
3✔
333
}
334

335
// MsgType returns the MessageType code which uniquely identifies this message
336
// as an OpenChannel on the wire.
337
//
338
// This is part of the lnwire.Message interface.
339
func (o *OpenChannel) MsgType() MessageType {
3✔
340
        return MsgOpenChannel
3✔
341
}
3✔
342

343
// SerializedSize returns the serialized size of the message in bytes.
344
//
345
// This is part of the lnwire.SizeableMessage interface.
UNCOV
346
func (o *OpenChannel) SerializedSize() (uint32, error) {
×
UNCOV
347
        return MessageSerializedSize(o)
×
UNCOV
348
}
×
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