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

lightningnetwork / lnd / 13211764208

08 Feb 2025 03:08AM UTC coverage: 49.288% (-9.5%) from 58.815%
13211764208

Pull #9489

github

calvinrzachman
itest: verify switchrpc server enforces send then track

We prevent the rpc server from allowing onion dispatches for
attempt IDs which have already been tracked by rpc clients.

This helps protect the client from leaking a duplicate onion
attempt. NOTE: This is not the only method for solving this
issue! The issue could be addressed via careful client side
programming which accounts for the uncertainty and async
nature of dispatching onions to a remote process via RPC.
This would require some lnd ChannelRouter changes for how
we intend to use these RPCs though.
Pull Request #9489: multi: add BuildOnion, SendOnion, and TrackOnion RPCs

474 of 990 new or added lines in 11 files covered. (47.88%)

27321 existing lines in 435 files now uncovered.

101192 of 205306 relevant lines covered (49.29%)

1.54 hits per line

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

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

186
        if err := WriteBytes(w, o.ChainHash[:]); err != nil {
3✔
187
                return err
×
188
        }
×
189

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

194
        if err := WriteSatoshi(w, o.FundingAmount); err != nil {
3✔
195
                return err
×
196
        }
×
197

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

258
        return WriteBytes(w, o.ExtraData)
3✔
259
}
260

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

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

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

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

326
        o.ExtraData = tlvRecords
3✔
327

3✔
328
        return nil
3✔
329
}
330

331
// MsgType returns the MessageType code which uniquely identifies this message
332
// as an OpenChannel on the wire.
333
//
334
// This is part of the lnwire.Message interface.
335
func (o *OpenChannel) MsgType() MessageType {
3✔
336
        return MsgOpenChannel
3✔
337
}
3✔
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