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

lightningnetwork / lnd / 13980275562

20 Mar 2025 10:06PM UTC coverage: 58.6% (-10.2%) from 68.789%
13980275562

Pull #9623

github

web-flow
Merge b9b960345 into 09b674508
Pull Request #9623: Size msg test msg

0 of 1518 new or added lines in 42 files covered. (0.0%)

26603 existing lines in 443 files now uncovered.

96807 of 165200 relevant lines covered (58.6%)

1.82 hits per line

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

5.38
/lnwire/channel_update_2.go
1
package lnwire
2

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

8
        "github.com/btcsuite/btcd/chaincfg"
9
        "github.com/btcsuite/btcd/chaincfg/chainhash"
10
        "github.com/lightningnetwork/lnd/tlv"
11
        "pgregory.net/rapid"
12
)
13

14
const (
15
        defaultCltvExpiryDelta           = uint16(80)
16
        defaultHtlcMinMsat               = MilliSatoshi(1)
17
        defaultFeeBaseMsat               = uint32(1000)
18
        defaultFeeProportionalMillionths = uint32(1)
19
)
20

21
// ChannelUpdate2 message is used after taproot channel has been initially
22
// announced. Each side independently announces its fees and minimum expiry for
23
// HTLCs and other parameters. This message is also used to redeclare initially
24
// set channel parameters.
25
type ChannelUpdate2 struct {
26
        // Signature is used to validate the announced data and prove the
27
        // ownership of node id.
28
        Signature Sig
29

30
        // ChainHash denotes the target chain that this channel was opened
31
        // within. This value should be the genesis hash of the target chain.
32
        // Along with the short channel ID, this uniquely identifies the
33
        // channel globally in a blockchain.
34
        ChainHash tlv.RecordT[tlv.TlvType0, chainhash.Hash]
35

36
        // ShortChannelID is the unique description of the funding transaction.
37
        ShortChannelID tlv.RecordT[tlv.TlvType2, ShortChannelID]
38

39
        // BlockHeight allows ordering in the case of multiple announcements. We
40
        // should ignore the message if block height is not greater than the
41
        // last-received. The block height must always be greater or equal to
42
        // the block height that the channel funding transaction was confirmed
43
        // in.
44
        BlockHeight tlv.RecordT[tlv.TlvType4, uint32]
45

46
        // DisabledFlags is an optional bitfield that describes various reasons
47
        // that the node is communicating that the channel should be considered
48
        // disabled.
49
        DisabledFlags tlv.RecordT[tlv.TlvType6, ChanUpdateDisableFlags]
50

51
        // SecondPeer is used to indicate which node the channel node has
52
        // created and signed this message. If this field is present, it was
53
        // node 2 otherwise it was node 1.
54
        SecondPeer tlv.OptionalRecordT[tlv.TlvType8, TrueBoolean]
55

56
        // CLTVExpiryDelta is the minimum number of blocks this node requires to
57
        // be added to the expiry of HTLCs. This is a security parameter
58
        // determined by the node operator. This value represents the required
59
        // gap between the time locks of the incoming and outgoing HTLC's set
60
        // to this node.
61
        CLTVExpiryDelta tlv.RecordT[tlv.TlvType10, uint16]
62

63
        // HTLCMinimumMsat is the minimum HTLC value which will be accepted.
64
        HTLCMinimumMsat tlv.RecordT[tlv.TlvType12, MilliSatoshi]
65

66
        // HtlcMaximumMsat is the maximum HTLC value which will be accepted.
67
        HTLCMaximumMsat tlv.RecordT[tlv.TlvType14, MilliSatoshi]
68

69
        // FeeBaseMsat is the base fee that must be used for incoming HTLC's to
70
        // this particular channel. This value will be tacked onto the required
71
        // for a payment independent of the size of the payment.
72
        FeeBaseMsat tlv.RecordT[tlv.TlvType16, uint32]
73

74
        // FeeProportionalMillionths is the fee rate that will be charged per
75
        // millionth of a satoshi.
76
        FeeProportionalMillionths tlv.RecordT[tlv.TlvType18, uint32]
77

78
        // ExtraOpaqueData is the set of data that was appended to this message
79
        // to fill out the full maximum transport message size. These fields can
80
        // be used to specify optional data such as custom TLV fields.
81
        ExtraOpaqueData ExtraOpaqueData
82
}
83

84
// Decode deserializes a serialized ChannelUpdate2 stored in the passed
85
// io.Reader observing the specified protocol version.
86
//
87
// This is part of the lnwire.Message interface.
UNCOV
88
func (c *ChannelUpdate2) Decode(r io.Reader, _ uint32) error {
×
UNCOV
89
        err := ReadElement(r, &c.Signature)
×
UNCOV
90
        if err != nil {
×
UNCOV
91
                return err
×
UNCOV
92
        }
×
UNCOV
93
        c.Signature.ForceSchnorr()
×
UNCOV
94

×
UNCOV
95
        return c.DecodeTLVRecords(r)
×
96
}
97

98
// DecodeTLVRecords decodes only the TLV section of the message.
UNCOV
99
func (c *ChannelUpdate2) DecodeTLVRecords(r io.Reader) error {
×
UNCOV
100
        // First extract into extra opaque data.
×
UNCOV
101
        var tlvRecords ExtraOpaqueData
×
UNCOV
102
        if err := ReadElements(r, &tlvRecords); err != nil {
×
103
                return err
×
104
        }
×
105

UNCOV
106
        var (
×
UNCOV
107
                chainHash  = tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
×
UNCOV
108
                secondPeer = tlv.ZeroRecordT[tlv.TlvType8, TrueBoolean]()
×
UNCOV
109
        )
×
UNCOV
110
        typeMap, err := tlvRecords.ExtractRecords(
×
UNCOV
111
                &chainHash, &c.ShortChannelID, &c.BlockHeight, &c.DisabledFlags,
×
UNCOV
112
                &secondPeer, &c.CLTVExpiryDelta, &c.HTLCMinimumMsat,
×
UNCOV
113
                &c.HTLCMaximumMsat, &c.FeeBaseMsat,
×
UNCOV
114
                &c.FeeProportionalMillionths,
×
UNCOV
115
        )
×
UNCOV
116
        if err != nil {
×
UNCOV
117
                return err
×
UNCOV
118
        }
×
119

120
        // By default, the chain-hash is the bitcoin mainnet genesis block hash.
UNCOV
121
        c.ChainHash.Val = *chaincfg.MainNetParams.GenesisHash
×
UNCOV
122
        if _, ok := typeMap[c.ChainHash.TlvType()]; ok {
×
UNCOV
123
                c.ChainHash.Val = chainHash.Val
×
UNCOV
124
        }
×
125

126
        // The presence of the second_peer tlv type indicates "true".
UNCOV
127
        if _, ok := typeMap[c.SecondPeer.TlvType()]; ok {
×
UNCOV
128
                c.SecondPeer = tlv.SomeRecordT(secondPeer)
×
UNCOV
129
        }
×
130

131
        // If the CLTV expiry delta was not encoded, then set it to the default
132
        // value.
UNCOV
133
        if _, ok := typeMap[c.CLTVExpiryDelta.TlvType()]; !ok {
×
UNCOV
134
                c.CLTVExpiryDelta.Val = defaultCltvExpiryDelta
×
UNCOV
135
        }
×
136

137
        // If the HTLC Minimum msat was not encoded, then set it to the default
138
        // value.
UNCOV
139
        if _, ok := typeMap[c.HTLCMinimumMsat.TlvType()]; !ok {
×
UNCOV
140
                c.HTLCMinimumMsat.Val = defaultHtlcMinMsat
×
UNCOV
141
        }
×
142

143
        // If the base fee was not encoded, then set it to the default value.
UNCOV
144
        if _, ok := typeMap[c.FeeBaseMsat.TlvType()]; !ok {
×
UNCOV
145
                c.FeeBaseMsat.Val = defaultFeeBaseMsat
×
UNCOV
146
        }
×
147

148
        // If the proportional fee was not encoded, then set it to the default
149
        // value.
UNCOV
150
        if _, ok := typeMap[c.FeeProportionalMillionths.TlvType()]; !ok {
×
UNCOV
151
                c.FeeProportionalMillionths.Val = defaultFeeProportionalMillionths //nolint:ll
×
UNCOV
152
        }
×
153

UNCOV
154
        if len(tlvRecords) != 0 {
×
UNCOV
155
                c.ExtraOpaqueData = tlvRecords
×
UNCOV
156
        }
×
157

UNCOV
158
        return nil
×
159
}
160

161
// Encode serializes the target ChannelUpdate2 into the passed io.Writer
162
// observing the protocol version specified.
163
//
164
// This is part of the lnwire.Message interface.
UNCOV
165
func (c *ChannelUpdate2) Encode(w *bytes.Buffer, _ uint32) error {
×
UNCOV
166
        _, err := w.Write(c.Signature.RawBytes())
×
UNCOV
167
        if err != nil {
×
168
                return err
×
169
        }
×
170

UNCOV
171
        _, err = c.DataToSign()
×
UNCOV
172
        if err != nil {
×
173
                return err
×
174
        }
×
175

UNCOV
176
        return WriteBytes(w, c.ExtraOpaqueData)
×
177
}
178

179
// DataToSign is used to retrieve part of the announcement message which should
180
// be signed. For the ChannelUpdate2 message, this includes the serialised TLV
181
// records.
UNCOV
182
func (c *ChannelUpdate2) DataToSign() ([]byte, error) {
×
UNCOV
183
        // The chain-hash record is only included if it is _not_ equal to the
×
UNCOV
184
        // bitcoin mainnet genisis block hash.
×
UNCOV
185
        var recordProducers []tlv.RecordProducer
×
UNCOV
186
        if !c.ChainHash.Val.IsEqual(chaincfg.MainNetParams.GenesisHash) {
×
UNCOV
187
                hash := tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
×
UNCOV
188
                hash.Val = c.ChainHash.Val
×
UNCOV
189

×
UNCOV
190
                recordProducers = append(recordProducers, &hash)
×
UNCOV
191
        }
×
192

UNCOV
193
        recordProducers = append(recordProducers,
×
UNCOV
194
                &c.ShortChannelID, &c.BlockHeight,
×
UNCOV
195
        )
×
UNCOV
196

×
UNCOV
197
        // Only include the disable flags if any bit is set.
×
UNCOV
198
        if !c.DisabledFlags.Val.IsEnabled() {
×
UNCOV
199
                recordProducers = append(recordProducers, &c.DisabledFlags)
×
UNCOV
200
        }
×
201

202
        // We only need to encode the second peer boolean if it is true
UNCOV
203
        c.SecondPeer.WhenSome(func(r tlv.RecordT[tlv.TlvType8, TrueBoolean]) {
×
UNCOV
204
                recordProducers = append(recordProducers, &r)
×
UNCOV
205
        })
×
206

207
        // We only encode the cltv expiry delta if it is not equal to the
208
        // default.
UNCOV
209
        if c.CLTVExpiryDelta.Val != defaultCltvExpiryDelta {
×
UNCOV
210
                recordProducers = append(recordProducers, &c.CLTVExpiryDelta)
×
UNCOV
211
        }
×
212

UNCOV
213
        if c.HTLCMinimumMsat.Val != defaultHtlcMinMsat {
×
UNCOV
214
                recordProducers = append(recordProducers, &c.HTLCMinimumMsat)
×
UNCOV
215
        }
×
216

UNCOV
217
        recordProducers = append(recordProducers, &c.HTLCMaximumMsat)
×
UNCOV
218

×
UNCOV
219
        if c.FeeBaseMsat.Val != defaultFeeBaseMsat {
×
UNCOV
220
                recordProducers = append(recordProducers, &c.FeeBaseMsat)
×
UNCOV
221
        }
×
222

UNCOV
223
        if c.FeeProportionalMillionths.Val != defaultFeeProportionalMillionths {
×
UNCOV
224
                recordProducers = append(
×
UNCOV
225
                        recordProducers, &c.FeeProportionalMillionths,
×
UNCOV
226
                )
×
UNCOV
227
        }
×
228

UNCOV
229
        err := EncodeMessageExtraData(&c.ExtraOpaqueData, recordProducers...)
×
UNCOV
230
        if err != nil {
×
231
                return nil, err
×
232
        }
×
233

UNCOV
234
        return c.ExtraOpaqueData, nil
×
235
}
236

237
// MsgType returns the integer uniquely identifying this message type on the
238
// wire.
239
//
240
// This is part of the lnwire.Message interface.
UNCOV
241
func (c *ChannelUpdate2) MsgType() MessageType {
×
UNCOV
242
        return MsgChannelUpdate2
×
UNCOV
243
}
×
244

245
// SerializedSize returns the serialized size of the message in bytes.
246
//
247
// This is part of the lnwire.SizeableMessage interface.
NEW
248
func (c *ChannelUpdate2) SerializedSize() (uint32, error) {
×
NEW
249
        return MessageSerializedSize(c)
×
NEW
250
}
×
251

252
func (c *ChannelUpdate2) ExtraData() ExtraOpaqueData {
×
253
        return c.ExtraOpaqueData
×
254
}
×
255

256
// A compile time check to ensure ChannelUpdate2 implements the
257
// lnwire.Message interface.
258
var _ Message = (*ChannelUpdate2)(nil)
259

260
// A compile time check to ensure ChannelUpdate2 implements the
261
// lnwire.TestMessage interface.
262
var _ TestMessage = (*ChannelUpdate2)(nil)
263

264
// SCID returns the ShortChannelID of the channel that the update applies to.
265
//
266
// NOTE: this is part of the ChannelUpdate interface.
267
func (c *ChannelUpdate2) SCID() ShortChannelID {
×
268
        return c.ShortChannelID.Val
×
269
}
×
270

271
// IsNode1 is true if the update was produced by node 1 of the channel peers.
272
// Node 1 is the node with the lexicographically smaller public key.
273
//
274
// NOTE: this is part of the ChannelUpdate interface.
275
func (c *ChannelUpdate2) IsNode1() bool {
×
276
        return c.SecondPeer.IsNone()
×
277
}
×
278

279
// IsDisabled is true if the update is announcing that the channel should be
280
// considered disabled.
281
//
282
// NOTE: this is part of the ChannelUpdate interface.
283
func (c *ChannelUpdate2) IsDisabled() bool {
×
284
        return !c.DisabledFlags.Val.IsEnabled()
×
285
}
×
286

287
// GetChainHash returns the hash of the chain that the message is referring to.
288
//
289
// NOTE: this is part of the ChannelUpdate interface.
290
func (c *ChannelUpdate2) GetChainHash() chainhash.Hash {
×
291
        return c.ChainHash.Val
×
292
}
×
293

294
// ForwardingPolicy returns the set of forwarding constraints of the update.
295
//
296
// NOTE: this is part of the ChannelUpdate interface.
297
func (c *ChannelUpdate2) ForwardingPolicy() *ForwardingPolicy {
×
298
        return &ForwardingPolicy{
×
299
                TimeLockDelta: c.CLTVExpiryDelta.Val,
×
300
                BaseFee:       MilliSatoshi(c.FeeBaseMsat.Val),
×
301
                FeeRate:       MilliSatoshi(c.FeeProportionalMillionths.Val),
×
302
                MinHTLC:       c.HTLCMinimumMsat.Val,
×
303
                HasMaxHTLC:    true,
×
304
                MaxHTLC:       c.HTLCMaximumMsat.Val,
×
305
        }
×
306
}
×
307

308
// CmpAge can be used to determine if the update is older or newer than the
309
// passed update. It returns 1 if this update is newer, -1 if it is older, and
310
// 0 if they are the same age.
311
//
312
// NOTE: this is part of the ChannelUpdate interface.
313
func (c *ChannelUpdate2) CmpAge(update ChannelUpdate) (CompareResult, error) {
×
314
        other, ok := update.(*ChannelUpdate2)
×
315
        if !ok {
×
316
                return 0, fmt.Errorf("expected *ChannelUpdate2, got: %T",
×
317
                        update)
×
318
        }
×
319

320
        switch {
×
321
        case c.BlockHeight.Val > other.BlockHeight.Val:
×
322
                return GreaterThan, nil
×
323
        case c.BlockHeight.Val < other.BlockHeight.Val:
×
324
                return LessThan, nil
×
325
        default:
×
326
                return EqualTo, nil
×
327
        }
328
}
329

330
// SetDisabledFlag can be used to adjust the disabled flag of an update.
331
//
332
// NOTE: this is part of the ChannelUpdate interface.
333
func (c *ChannelUpdate2) SetDisabledFlag(disabled bool) {
×
334
        if disabled {
×
335
                c.DisabledFlags.Val |= ChanUpdateDisableIncoming
×
336
                c.DisabledFlags.Val |= ChanUpdateDisableOutgoing
×
337
        } else {
×
338
                c.DisabledFlags.Val &^= ChanUpdateDisableIncoming
×
339
                c.DisabledFlags.Val &^= ChanUpdateDisableOutgoing
×
340
        }
×
341
}
342

343
// SetSCID can be used to overwrite the SCID of the update.
344
//
345
// NOTE: this is part of the ChannelUpdate interface.
346
func (c *ChannelUpdate2) SetSCID(scid ShortChannelID) {
×
347
        c.ShortChannelID.Val = scid
×
348
}
×
349

350
// A compile time check to ensure ChannelUpdate2 implements the
351
// lnwire.ChannelUpdate interface.
352
var _ ChannelUpdate = (*ChannelUpdate2)(nil)
353

354
// ChanUpdateDisableFlags is a bit vector that can be used to indicate various
355
// reasons for the channel being marked as disabled.
356
type ChanUpdateDisableFlags uint8
357

358
const (
359
        // ChanUpdateDisableIncoming is a bit indicates that a channel is
360
        // disabled in the inbound direction meaning that the node broadcasting
361
        // the update is communicating that they cannot receive funds.
362
        ChanUpdateDisableIncoming ChanUpdateDisableFlags = 1 << iota
363

364
        // ChanUpdateDisableOutgoing is a bit indicates that a channel is
365
        // disabled in the outbound direction meaning that the node broadcasting
366
        // the update is communicating that they cannot send or route funds.
367
        ChanUpdateDisableOutgoing = 2
368
)
369

370
// IncomingDisabled returns true if the ChanUpdateDisableIncoming bit is set.
371
func (c ChanUpdateDisableFlags) IncomingDisabled() bool {
×
372
        return c&ChanUpdateDisableIncoming == ChanUpdateDisableIncoming
×
373
}
×
374

375
// OutgoingDisabled returns true if the ChanUpdateDisableOutgoing bit is set.
376
func (c ChanUpdateDisableFlags) OutgoingDisabled() bool {
×
377
        return c&ChanUpdateDisableOutgoing == ChanUpdateDisableOutgoing
×
378
}
×
379

380
// IsEnabled returns true if none of the disable bits are set.
UNCOV
381
func (c ChanUpdateDisableFlags) IsEnabled() bool {
×
UNCOV
382
        return c == 0
×
UNCOV
383
}
×
384

385
// String returns the bitfield flags as a string.
386
func (c ChanUpdateDisableFlags) String() string {
×
387
        return fmt.Sprintf("%08b", c)
×
388
}
×
389

390
// Record returns the tlv record for the disable flags.
UNCOV
391
func (c *ChanUpdateDisableFlags) Record() tlv.Record {
×
UNCOV
392
        return tlv.MakeStaticRecord(0, c, 1, encodeDisableFlags,
×
UNCOV
393
                decodeDisableFlags)
×
UNCOV
394
}
×
395

UNCOV
396
func encodeDisableFlags(w io.Writer, val interface{}, buf *[8]byte) error {
×
UNCOV
397
        if v, ok := val.(*ChanUpdateDisableFlags); ok {
×
UNCOV
398
                flagsInt := uint8(*v)
×
UNCOV
399

×
UNCOV
400
                return tlv.EUint8(w, &flagsInt, buf)
×
UNCOV
401
        }
×
402

403
        return tlv.NewTypeForEncodingErr(val, "lnwire.ChanUpdateDisableFlags")
×
404
}
405

406
func decodeDisableFlags(r io.Reader, val interface{}, buf *[8]byte,
UNCOV
407
        l uint64) error {
×
UNCOV
408

×
UNCOV
409
        if v, ok := val.(*ChanUpdateDisableFlags); ok {
×
UNCOV
410
                var flagsInt uint8
×
UNCOV
411
                err := tlv.DUint8(r, &flagsInt, buf, l)
×
UNCOV
412
                if err != nil {
×
UNCOV
413
                        return err
×
UNCOV
414
                }
×
415

UNCOV
416
                *v = ChanUpdateDisableFlags(flagsInt)
×
UNCOV
417

×
UNCOV
418
                return nil
×
419
        }
420

421
        return tlv.NewTypeForDecodingErr(val, "lnwire.ChanUpdateDisableFlags",
×
422
                l, l)
×
423
}
424

425
// TrueBoolean is a record that indicates true or false using the presence of
426
// the record. If the record is absent, it indicates false. If it is present,
427
// it indicates true.
428
type TrueBoolean struct{}
429

430
// Record returns the tlv record for the boolean entry.
431
func (b *TrueBoolean) Record() tlv.Record {
3✔
432
        return tlv.MakeStaticRecord(
3✔
433
                0, b, 0, booleanEncoder, booleanDecoder,
3✔
434
        )
3✔
435
}
3✔
436

437
func booleanEncoder(_ io.Writer, val interface{}, _ *[8]byte) error {
3✔
438
        if _, ok := val.(*TrueBoolean); ok {
6✔
439
                return nil
3✔
440
        }
3✔
441

442
        return tlv.NewTypeForEncodingErr(val, "TrueBoolean")
×
443
}
444

445
func booleanDecoder(_ io.Reader, val interface{}, _ *[8]byte,
446
        l uint64) error {
2✔
447

2✔
448
        if _, ok := val.(*TrueBoolean); ok && (l == 0 || l == 1) {
4✔
449
                return nil
2✔
450
        }
2✔
451

UNCOV
452
        return tlv.NewTypeForEncodingErr(val, "TrueBoolean")
×
453
}
454

455
// RandTestMessage populates the message with random data suitable for testing.
456
// It uses the rapid testing framework to generate random values.
457
//
458
// This is part of the TestMessage interface.
NEW
459
func (c *ChannelUpdate2) RandTestMessage(t *rapid.T) Message {
×
NEW
460
        shortChanID := RandShortChannelID(t)
×
NEW
461
        blockHeight := uint32(rapid.IntRange(0, 1000000).Draw(t, "blockHeight"))
×
NEW
462

×
NEW
463
        var disabledFlags ChanUpdateDisableFlags
×
NEW
464
        if rapid.Bool().Draw(t, "disableIncoming") {
×
NEW
465
                disabledFlags |= ChanUpdateDisableIncoming
×
NEW
466
        }
×
NEW
467
        if rapid.Bool().Draw(t, "disableOutgoing") {
×
NEW
468
                disabledFlags |= ChanUpdateDisableOutgoing
×
NEW
469
        }
×
470

NEW
471
        cltvExpiryDelta := uint16(rapid.IntRange(10, 200).Draw(
×
NEW
472
                t, "cltvExpiryDelta"),
×
NEW
473
        )
×
NEW
474

×
NEW
475
        htlcMinMsat := MilliSatoshi(rapid.IntRange(1, 10000).Draw(
×
NEW
476
                t, "htlcMinMsat"),
×
NEW
477
        )
×
NEW
478
        htlcMaxMsat := MilliSatoshi(rapid.IntRange(10000, 100000000).Draw(
×
NEW
479
                t, "htlcMaxMsat"),
×
NEW
480
        )
×
NEW
481
        feeBaseMsat := uint32(rapid.IntRange(0, 10000).Draw(t, "feeBaseMsat"))
×
NEW
482
        feeProportionalMillionths := uint32(rapid.IntRange(0, 10000).Draw(
×
NEW
483
                t, "feeProportionalMillionths"),
×
NEW
484
        )
×
NEW
485

×
NEW
486
        chainHash := RandChainHash(t)
×
NEW
487
        var chainHashObj chainhash.Hash
×
NEW
488
        copy(chainHashObj[:], chainHash[:])
×
NEW
489

×
NEW
490
        //nolint:ll
×
NEW
491
        msg := &ChannelUpdate2{
×
NEW
492
                Signature:                 RandSignature(t),
×
NEW
493
                ChainHash:                 tlv.NewPrimitiveRecord[tlv.TlvType0, chainhash.Hash](chainHashObj),
×
NEW
494
                ShortChannelID:            tlv.NewRecordT[tlv.TlvType2, ShortChannelID](shortChanID),
×
NEW
495
                BlockHeight:               tlv.NewPrimitiveRecord[tlv.TlvType4, uint32](blockHeight),
×
NEW
496
                DisabledFlags:             tlv.NewPrimitiveRecord[tlv.TlvType6, ChanUpdateDisableFlags](disabledFlags),
×
NEW
497
                CLTVExpiryDelta:           tlv.NewPrimitiveRecord[tlv.TlvType10, uint16](cltvExpiryDelta),
×
NEW
498
                HTLCMinimumMsat:           tlv.NewPrimitiveRecord[tlv.TlvType12, MilliSatoshi](htlcMinMsat),
×
NEW
499
                HTLCMaximumMsat:           tlv.NewPrimitiveRecord[tlv.TlvType14, MilliSatoshi](htlcMaxMsat),
×
NEW
500
                FeeBaseMsat:               tlv.NewPrimitiveRecord[tlv.TlvType16, uint32](feeBaseMsat),
×
NEW
501
                FeeProportionalMillionths: tlv.NewPrimitiveRecord[tlv.TlvType18, uint32](feeProportionalMillionths),
×
NEW
502
                ExtraOpaqueData:           RandExtraOpaqueData(t, nil),
×
NEW
503
        }
×
NEW
504

×
NEW
505
        msg.Signature.ForceSchnorr()
×
NEW
506

×
NEW
507
        if rapid.Bool().Draw(t, "isSecondPeer") {
×
NEW
508
                msg.SecondPeer = tlv.SomeRecordT(tlv.RecordT[tlv.TlvType8, TrueBoolean]{})
×
NEW
509
        }
×
510

NEW
511
        return msg
×
512
}
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