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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

80.1
/contractcourt/taproot_briefcase.go
1
package contractcourt
2

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

7
        "github.com/lightningnetwork/lnd/tlv"
8
)
9

10
const (
11
        taprootCtrlBlockType tlv.Type = 0
12
        taprootTapTweakType  tlv.Type = 1
13

14
        commitCtrlBlockType       tlv.Type = 0
15
        revokeCtrlBlockType       tlv.Type = 1
16
        outgoingHtlcCtrlBlockType tlv.Type = 2
17
        incomingHtlcCtrlBlockType tlv.Type = 3
18
        secondLevelCtrlBlockType  tlv.Type = 4
19

20
        anchorTapTweakType                tlv.Type = 0
21
        htlcTweakCtrlBlockType            tlv.Type = 1
22
        secondLevelHtlcTweakCtrlBlockType tlv.Type = 2
23
)
24

25
// taprootBriefcase is a supplemental storage struct that contains all the
26
// information we need to sweep taproot outputs.
27
type taprootBriefcase struct {
28
        // CtrlBlock is the set of control block for the taproot outputs.
29
        CtrlBlocks *ctrlBlocks
30

31
        // TapTweaks is the set of taproot tweaks for the taproot outputs that
32
        // are to be spent via a keyspend path. This includes anchors, and any
33
        // revocation paths.
34
        TapTweaks *tapTweaks
35
}
36

37
// newTaprootBriefcase returns a new instance of the taproot specific briefcase
38
// variant.
39
func newTaprootBriefcase() *taprootBriefcase {
40
        return &taprootBriefcase{
41
                CtrlBlocks: newCtrlBlocks(),
42
                TapTweaks:  newTapTweaks(),
43
        }
44
}
45

46
// EncodeRecords returns a slice of TLV records that should be encoded.
47
func (t *taprootBriefcase) EncodeRecords() []tlv.Record {
48
        return []tlv.Record{
UNCOV
49
                newCtrlBlocksRecord(&t.CtrlBlocks),
×
UNCOV
50
                newTapTweaksRecord(&t.TapTweaks),
×
UNCOV
51
        }
×
UNCOV
52
}
×
UNCOV
53

×
UNCOV
54
// DecodeRecords returns a slice of TLV records that should be decoded.
×
55
func (t *taprootBriefcase) DecodeRecords() []tlv.Record {
56
        return []tlv.Record{
57
                newCtrlBlocksRecord(&t.CtrlBlocks),
1✔
58
                newTapTweaksRecord(&t.TapTweaks),
1✔
59
        }
1✔
60
}
1✔
61

1✔
62
// Encode records returns a slice of TLV records that should be encoded.
1✔
63
func (t *taprootBriefcase) Encode(w io.Writer) error {
1✔
64
        stream, err := tlv.NewStream(t.EncodeRecords()...)
2✔
65
        if err != nil {
1✔
66
                return err
1✔
67
        }
68

1✔
69
        return stream.Encode(w)
2✔
70
}
1✔
71

1✔
72
// Decode decodes the given reader into the target struct.
73
func (t *taprootBriefcase) Decode(r io.Reader) error {
74
        stream, err := tlv.NewStream(t.DecodeRecords()...)
1✔
75
        if err != nil {
76
                return err
77
        }
78

1✔
79
        return stream.Decode(r)
1✔
80
}
1✔
81

1✔
82
// resolverCtrlBlocks is a map of resolver IDs to their corresponding control
1✔
83
// block.
1✔
84
type resolverCtrlBlocks map[resolverID][]byte
85

86
// newResolverCtrlBlockss returns a new instance of the resolverCtrlBlocks.
1✔
87
func newResolverCtrlBlocks() resolverCtrlBlocks {
1✔
88
        return make(resolverCtrlBlocks)
1✔
UNCOV
89
}
×
UNCOV
90

×
91
// recordSize returns the size of the record in bytes.
92
func (r *resolverCtrlBlocks) recordSize() uint64 {
1✔
93
        // Each record will be serialized as: <num_total_records> || <record>,
94
        // where <record> is serialized as: <resolver_key> || <length> ||
95
        // <ctrl_block>.
96
        numBlocks := uint64(len(*r))
1✔
97
        baseSize := tlv.VarIntSize(numBlocks)
1✔
98

1✔
99
        recordSize := baseSize
1✔
100
        for _, ctrlBlock := range *r {
1✔
101
                recordSize += resolverIDLen
1✔
102
                recordSize += tlv.VarIntSize(uint64(len(ctrlBlock)))
1✔
103
                recordSize += uint64(len(ctrlBlock))
1✔
104
        }
1✔
105

1✔
UNCOV
106
        return recordSize
×
UNCOV
107
}
×
108

109
// Encode encodes the control blocks into the target writer.
1✔
110
func (r *resolverCtrlBlocks) Encode(w io.Writer) error {
1✔
UNCOV
111
        numBlocks := uint64(len(*r))
×
UNCOV
112

×
113
        var buf [8]byte
114
        if err := tlv.WriteVarInt(w, numBlocks, &buf); err != nil {
2✔
115
                return err
1✔
116
        }
1✔
117

2✔
118
        for id, ctrlBlock := range *r {
1✔
119
                ctrlBlock := ctrlBlock
1✔
120

121
                if _, err := w.Write(id[:]); err != nil {
1✔
122
                        return err
123
                }
124

125
                if err := varBytesEncoder(w, &ctrlBlock, &buf); err != nil {
126
                        return err
127
                }
128
        }
129

3✔
130
        return nil
3✔
131
}
3✔
132

133
// Decode decodes the given reader into the target struct.
134
func (r *resolverCtrlBlocks) Decode(reader io.Reader) error {
6✔
135
        var buf [8]byte
6✔
136

6✔
137
        numBlocks, err := tlv.ReadVarInt(reader, &buf)
6✔
138
        if err != nil {
6✔
139
                return err
6✔
140
        }
6✔
141

6✔
142
        for i := uint64(0); i < numBlocks; i++ {
980✔
143
                var id resolverID
974✔
144
                if _, err := io.ReadFull(reader, id[:]); err != nil {
974✔
145
                        return err
974✔
146
                }
974✔
147

148
                var ctrlBlock []byte
6✔
149
                err := varBytesDecoder(reader, &ctrlBlock, &buf, 0)
150
                if err != nil {
151
                        return err
152
                }
6✔
153

6✔
154
                (*r)[id] = ctrlBlock
6✔
155
        }
6✔
156

6✔
UNCOV
157
        return nil
×
UNCOV
158
}
×
159

160
// resolverCtrlBlocksEncoder is a custom TLV encoder for the
980✔
161
// resolverCtrlBlocks.
974✔
162
func resolverCtrlBlocksEncoder(w io.Writer, val any, _ *[8]byte) error {
974✔
163
        if typ, ok := val.(*resolverCtrlBlocks); ok {
974✔
UNCOV
164
                return (*typ).Encode(w)
×
UNCOV
165
        }
×
166

167
        return tlv.NewTypeForEncodingErr(val, "resolverCtrlBlocks")
974✔
UNCOV
168
}
×
UNCOV
169

×
170
// rsolverCtrlBlocksDecoder is a custom TLV decoder for the resolverCtrlBlocks.
171
func resolverCtrlBlocksDecoder(r io.Reader, val any, _ *[8]byte,
172
        l uint64) error {
6✔
173

174
        if typ, ok := val.(*resolverCtrlBlocks); ok {
175
                blockReader := io.LimitReader(r, int64(l))
176

3✔
177
                resolverBlocks := newResolverCtrlBlocks()
3✔
178
                err := resolverBlocks.Decode(blockReader)
3✔
179
                if err != nil {
3✔
180
                        return err
3✔
181
                }
×
UNCOV
182

×
183
                *typ = resolverBlocks
184

490✔
185
                return nil
487✔
186
        }
487✔
UNCOV
187

×
188
        return tlv.NewTypeForDecodingErr(val, "resolverCtrlBlocks", l, l)
×
189
}
190

487✔
191
// ctrlBlocks is the set of control blocks we need to sweep all the output for
487✔
192
// a taproot/musig2 channel.
487✔
UNCOV
193
type ctrlBlocks struct {
×
UNCOV
194
        // CommitSweepCtrlBlock is the serialized control block needed to sweep
×
195
        // our commitment output.
196
        CommitSweepCtrlBlock []byte
487✔
197

198
        // RevokeSweepCtrlBlock is the serialized control block that's used to
199
        // sweep the reovked output of a breaching party.
3✔
200
        RevokeSweepCtrlBlock []byte
201

202
        // OutgoingHtlcCtrlBlocks is the set of serialized control blocks for
203
        // all outgoing HTLCs. This is the set of HTLCs that we offered to the
204
        // remote party. Depending on which commitment transaction was
6✔
205
        // broadcast, we'll either sweep here and be done, or also need to go
12✔
206
        // to the second level.
6✔
207
        OutgoingHtlcCtrlBlocks resolverCtrlBlocks
6✔
208

UNCOV
209
        // IncomingHtlcCtrlBlocks is the set of serialized control blocks for
×
210
        // all incoming HTLCs
211
        IncomingHtlcCtrlBlocks resolverCtrlBlocks
212

213
        // SecondLevelCtrlBlocks is the set of serialized control blocks for
214
        // need to sweep the second level HTLCs on our commitment transaction.
3✔
215
        SecondLevelCtrlBlocks resolverCtrlBlocks
3✔
216
}
6✔
217

3✔
218
// newCtrlBlocks returns a new instance of the ctrlBlocks struct.
3✔
219
func newCtrlBlocks() *ctrlBlocks {
3✔
220
        return &ctrlBlocks{
3✔
221
                OutgoingHtlcCtrlBlocks: newResolverCtrlBlocks(),
3✔
UNCOV
222
                IncomingHtlcCtrlBlocks: newResolverCtrlBlocks(),
×
UNCOV
223
                SecondLevelCtrlBlocks:  newResolverCtrlBlocks(),
×
224
        }
225
}
3✔
226

3✔
227
// varBytesEncoder is a custom TLV encoder for a variable length byte slice.
3✔
228
func varBytesEncoder(w io.Writer, val any, buf *[8]byte) error {
229
        if t, ok := val.(*[]byte); ok {
UNCOV
230
                if err := tlv.WriteVarInt(w, uint64(len(*t)), buf); err != nil {
×
231
                        return err
232
                }
233

234
                return tlv.EVarBytes(w, t, buf)
235
        }
236

237
        return tlv.NewTypeForEncodingErr(val, "[]byte")
238
}
239

240
// varBytesDecoder is a custom TLV decoder for a variable length byte slice.
241
func varBytesDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error {
242
        if typ, ok := val.(*[]byte); ok {
243
                bytesLen, err := tlv.ReadVarInt(r, buf)
244
                if err != nil {
245
                        return err
246
                }
247

248
                var bytes []byte
249
                if err := tlv.DVarBytes(r, &bytes, buf, bytesLen); err != nil {
250
                        return err
251
                }
252

253
                *typ = bytes
254

255
                return nil
256
        }
257

258
        return tlv.NewTypeForDecodingErr(val, "[]byte", l, l)
259
}
260

UNCOV
261
// ctrlBlockEncoder is a custom TLV encoder for the ctrlBlocks struct.
×
UNCOV
262
func ctrlBlockEncoder(w io.Writer, val any, _ *[8]byte) error {
×
UNCOV
263
        if t, ok := val.(**ctrlBlocks); ok {
×
UNCOV
264
                return (*t).Encode(w)
×
UNCOV
265
        }
×
UNCOV
266

×
267
        return tlv.NewTypeForEncodingErr(val, "ctrlBlocks")
×
268
}
269

270
// ctrlBlockDecoder is a custom TLV decoder for the ctrlBlocks struct.
974✔
271
func ctrlBlockDecoder(r io.Reader, val any, _ *[8]byte, l uint64) error {
1,948✔
272
        if typ, ok := val.(**ctrlBlocks); ok {
974✔
UNCOV
273
                ctrlReader := io.LimitReader(r, int64(l))
×
UNCOV
274

×
275
                var ctrlBlocks ctrlBlocks
276
                err := ctrlBlocks.Decode(ctrlReader)
974✔
277
                if err != nil {
278
                        return err
279
                }
×
280

281
                *typ = &ctrlBlocks
282

283
                return nil
487✔
284
        }
974✔
285

487✔
286
        return tlv.NewTypeForDecodingErr(val, "ctrlBlocks", l, l)
487✔
UNCOV
287
}
×
UNCOV
288

×
289
// newCtrlBlocksRecord returns a new TLV record that can be used to
290
// encode/decode the set of cotrol blocks for the taproot outputs for a
487✔
291
// channel.
487✔
UNCOV
292
func newCtrlBlocksRecord(blks **ctrlBlocks) tlv.Record {
×
UNCOV
293
        recordSize := func() uint64 {
×
294
                var (
295
                        b   bytes.Buffer
487✔
296
                        buf [8]byte
487✔
297
                )
487✔
298
                if err := ctrlBlockEncoder(&b, blks, &buf); err != nil {
299
                        panic(err)
UNCOV
300
                }
×
301

302
                return uint64(len(b.Bytes()))
303
        }
304

2✔
305
        return tlv.MakeDynamicRecord(
4✔
306
                taprootCtrlBlockType, blks, recordSize, ctrlBlockEncoder,
2✔
307
                ctrlBlockDecoder,
2✔
308
        )
UNCOV
309
}
×
310

311
// EncodeRecords returns the set of TLV records that encode the control block
312
// for the commitment transaction.
313
func (c *ctrlBlocks) EncodeRecords() []tlv.Record {
1✔
314
        var records []tlv.Record
2✔
315

1✔
316
        if len(c.CommitSweepCtrlBlock) > 0 {
1✔
317
                records = append(records, tlv.MakePrimitiveRecord(
1✔
318
                        commitCtrlBlockType, &c.CommitSweepCtrlBlock,
1✔
319
                ))
1✔
UNCOV
320
        }
×
UNCOV
321

×
322
        if len(c.RevokeSweepCtrlBlock) > 0 {
323
                records = append(records, tlv.MakePrimitiveRecord(
1✔
324
                        revokeCtrlBlockType, &c.RevokeSweepCtrlBlock,
1✔
325
                ))
1✔
326
        }
327

UNCOV
328
        if c.OutgoingHtlcCtrlBlocks != nil {
×
329
                records = append(records, tlv.MakeDynamicRecord(
330
                        outgoingHtlcCtrlBlockType, &c.OutgoingHtlcCtrlBlocks,
331
                        c.OutgoingHtlcCtrlBlocks.recordSize,
332
                        resolverCtrlBlocksEncoder, resolverCtrlBlocksDecoder,
333
                ))
2✔
334
        }
2✔
335

2✔
336
        if c.IncomingHtlcCtrlBlocks != nil {
4✔
337
                records = append(records, tlv.MakeDynamicRecord(
2✔
338
                        incomingHtlcCtrlBlockType, &c.IncomingHtlcCtrlBlocks,
2✔
339
                        c.IncomingHtlcCtrlBlocks.recordSize,
2✔
340
                        resolverCtrlBlocksEncoder, resolverCtrlBlocksDecoder,
2✔
341
                ))
342
        }
4✔
343

2✔
344
        if c.SecondLevelCtrlBlocks != nil {
2✔
345
                records = append(records, tlv.MakeDynamicRecord(
2✔
346
                        secondLevelCtrlBlockType, &c.SecondLevelCtrlBlocks,
2✔
347
                        c.SecondLevelCtrlBlocks.recordSize,
348
                        resolverCtrlBlocksEncoder, resolverCtrlBlocksDecoder,
4✔
349
                ))
2✔
350
        }
2✔
351

2✔
352
        return records
2✔
353
}
2✔
354

2✔
355
// DecodeRecords returns the set of TLV records that decode the control block.
356
func (c *ctrlBlocks) DecodeRecords() []tlv.Record {
4✔
357
        return []tlv.Record{
2✔
358
                tlv.MakePrimitiveRecord(
2✔
359
                        commitCtrlBlockType, &c.CommitSweepCtrlBlock,
2✔
360
                ),
2✔
361
                tlv.MakePrimitiveRecord(
2✔
362
                        revokeCtrlBlockType, &c.RevokeSweepCtrlBlock,
2✔
363
                ),
364
                tlv.MakeDynamicRecord(
4✔
365
                        outgoingHtlcCtrlBlockType, &c.OutgoingHtlcCtrlBlocks,
2✔
366
                        c.OutgoingHtlcCtrlBlocks.recordSize,
2✔
367
                        resolverCtrlBlocksEncoder, resolverCtrlBlocksDecoder,
2✔
368
                ),
2✔
369
                tlv.MakeDynamicRecord(
2✔
370
                        incomingHtlcCtrlBlockType, &c.IncomingHtlcCtrlBlocks,
2✔
371
                        c.IncomingHtlcCtrlBlocks.recordSize,
372
                        resolverCtrlBlocksEncoder, resolverCtrlBlocksDecoder,
2✔
373
                ),
374
                tlv.MakeDynamicRecord(
375
                        secondLevelCtrlBlockType, &c.SecondLevelCtrlBlocks,
376
                        c.SecondLevelCtrlBlocks.recordSize,
1✔
377
                        resolverCtrlBlocksEncoder, resolverCtrlBlocksDecoder,
1✔
378
                ),
1✔
379
        }
1✔
380
}
1✔
381

1✔
382
// Record returns a TLV record that can be used to encode/decode the control
1✔
383
// blocks.  type from a given TLV stream.
1✔
384
func (c *ctrlBlocks) Record() tlv.Record {
1✔
385
        return tlv.MakePrimitiveRecord(commitCtrlBlockType, c)
1✔
386
}
1✔
387

1✔
388
// Encode encodes the set of control blocks.
1✔
389
func (c *ctrlBlocks) Encode(w io.Writer) error {
1✔
390
        stream, err := tlv.NewStream(c.EncodeRecords()...)
1✔
391
        if err != nil {
1✔
392
                return err
1✔
393
        }
1✔
394

1✔
395
        return stream.Encode(w)
1✔
396
}
1✔
397

1✔
398
// Decode decodes the set of control blocks.
1✔
399
func (c *ctrlBlocks) Decode(r io.Reader) error {
1✔
400
        stream, err := tlv.NewStream(c.DecodeRecords()...)
1✔
401
        if err != nil {
402
                return err
403
        }
404

2✔
405
        return stream.Decode(r)
3✔
406
}
1✔
407

1✔
408
// htlcTapTweakss maps an outpoint (the same format as the resolver ID) to the
1✔
409
// tap tweak needed to sweep a breached HTLC output. This is used for both the
1✔
410
// first and second level HTLC outputs.
1✔
UNCOV
411
type htlcTapTweaks map[resolverID][32]byte
×
412

413
// newHtlcTapTweaks returns a new instance of the htlcTapTweaks struct.
414
func newHtlcTapTweaks() htlcTapTweaks {
1✔
415
        return make(htlcTapTweaks)
416
}
417

2✔
418
// recordSize returns the size of the record in bytes.
2✔
419
func (h *htlcTapTweaks) recordSize() uint64 {
2✔
420
        // Each record will be serialized as: <num_tweaks> || <tweak>, where
421
        // <tweak> is serialized as: <resolver_key> || <tweak>.
422
        numTweaks := uint64(len(*h))
423
        baseSize := tlv.VarIntSize(numTweaks)
2✔
424

2✔
425
        recordSize := baseSize
2✔
UNCOV
426
        for range *h {
×
UNCOV
427
                // Each tweak is a fixed 32 bytes, so we just tally that an the
×
428
                // size of the resolver ID.
429
                recordSize += resolverIDLen
2✔
430
                recordSize += 32
431
        }
432

433
        return recordSize
1✔
434
}
1✔
435

1✔
UNCOV
436
// Encode encodes the tap tweaks into the target writer.
×
UNCOV
437
func (h *htlcTapTweaks) Encode(w io.Writer) error {
×
438
        numTweaks := uint64(len(*h))
439

1✔
440
        var buf [8]byte
441
        if err := tlv.WriteVarInt(w, numTweaks, &buf); err != nil {
442
                return err
443
        }
444

445
        for id, tweak := range *h {
446
                tweak := tweak
447

448
                if _, err := w.Write(id[:]); err != nil {
2✔
449
                        return err
2✔
450
                }
2✔
451

452
                if _, err := w.Write(tweak[:]); err != nil {
453
                        return err
4✔
454
                }
4✔
455
        }
4✔
456

4✔
457
        return nil
4✔
458
}
4✔
459

4✔
460
// htlcTapTweaksEncoder is a custom TLV encoder for the htlcTapTweaks struct.
212✔
461
func htlcTapTweaksEncoder(w io.Writer, val any, _ *[8]byte) error {
208✔
462
        if t, ok := val.(*htlcTapTweaks); ok {
208✔
463
                return (*t).Encode(w)
208✔
464
        }
208✔
465

208✔
466
        return tlv.NewTypeForEncodingErr(val, "htlcTapTweaks")
467
}
4✔
468

469
// htlcTapTweaksDecoder is a custom TLV decoder for the htlcTapTweaks struct.
470
func htlcTapTweaksDecoder(r io.Reader, val any, _ *[8]byte,
471
        l uint64) error {
4✔
472

4✔
473
        if typ, ok := val.(*htlcTapTweaks); ok {
4✔
474
                tweakReader := io.LimitReader(r, int64(l))
4✔
475

4✔
UNCOV
476
                htlcTweaks := newHtlcTapTweaks()
×
UNCOV
477
                err := htlcTweaks.Decode(tweakReader)
×
478
                if err != nil {
479
                        return err
212✔
480
                }
208✔
481

208✔
482
                *typ = htlcTweaks
208✔
UNCOV
483

×
UNCOV
484
                return nil
×
485
        }
486

208✔
487
        return tlv.NewTypeForDecodingErr(val, "htlcTapTweaks", l, l)
×
UNCOV
488
}
×
489

490
// Decode decodes the tap tweaks into the target struct.
491
func (h *htlcTapTweaks) Decode(reader io.Reader) error {
4✔
492
        var buf [8]byte
493

494
        numTweaks, err := tlv.ReadVarInt(reader, &buf)
495
        if err != nil {
4✔
496
                return err
8✔
497
        }
4✔
498

4✔
499
        for i := uint64(0); i < numTweaks; i++ {
UNCOV
500
                var id resolverID
×
501
                if _, err := io.ReadFull(reader, id[:]); err != nil {
502
                        return err
503
                }
504

505
                var tweak [32]byte
2✔
506
                if _, err := io.ReadFull(reader, tweak[:]); err != nil {
2✔
507
                        return err
4✔
508
                }
2✔
509

2✔
510
                (*h)[id] = tweak
2✔
511
        }
2✔
512

2✔
UNCOV
513
        return nil
×
UNCOV
514
}
×
515

516
// tapTweaks stores the set of taptweaks needed to perform keyspends for the
2✔
517
// commitment outputs.
2✔
518
type tapTweaks struct {
2✔
519
        // AnchorTweak is the tweak used to derive the key used to spend the
520
        // anchor output.
UNCOV
521
        AnchorTweak []byte
×
522

523
        // BreachedHtlcTweaks stores the set of tweaks needed to sweep the
524
        // revoked first level output of an HTLC.
525
        BreachedHtlcTweaks htlcTapTweaks
2✔
526

2✔
527
        // BreachedSecondLevelHtlcTweaks stores the set of tweaks needed to
2✔
528
        // sweep the revoked *second* level output of an HTLC.
2✔
529
        BreachedSecondLevelHltcTweaks htlcTapTweaks
2✔
UNCOV
530
}
×
UNCOV
531

×
532
// newTapTweaks returns a new tapTweaks struct.
533
func newTapTweaks() *tapTweaks {
106✔
534
        return &tapTweaks{
104✔
535
                BreachedHtlcTweaks:            make(htlcTapTweaks),
104✔
UNCOV
536
                BreachedSecondLevelHltcTweaks: make(htlcTapTweaks),
×
UNCOV
537
        }
×
538
}
539

104✔
540
// tapTweaksEncoder is a custom TLV encoder for the tapTweaks struct.
104✔
UNCOV
541
func tapTweaksEncoder(w io.Writer, val any, _ *[8]byte) error {
×
UNCOV
542
        if t, ok := val.(**tapTweaks); ok {
×
543
                return (*t).Encode(w)
544
        }
104✔
545

546
        return tlv.NewTypeForEncodingErr(val, "tapTweaks")
547
}
2✔
548

549
// tapTweaksDecoder is a custom TLV decoder for the tapTweaks struct.
550
func tapTweaksDecoder(r io.Reader, val any, _ *[8]byte, l uint64) error {
551
        if typ, ok := val.(**tapTweaks); ok {
552
                tweakReader := io.LimitReader(r, int64(l))
553

554
                var tapTweaks tapTweaks
555
                err := tapTweaks.Decode(tweakReader)
556
                if err != nil {
557
                        return err
558
                }
559

560
                *typ = &tapTweaks
561

562
                return nil
563
        }
564

565
        return tlv.NewTypeForDecodingErr(val, "tapTweaks", l, l)
566
}
UNCOV
567

×
UNCOV
568
// newTapTweaksRecord returns a new TLV record that can be used to
×
UNCOV
569
// encode/decode the tap tweak structs.
×
UNCOV
570
func newTapTweaksRecord(tweaks **tapTweaks) tlv.Record {
×
UNCOV
571
        recordSize := func() uint64 {
×
UNCOV
572
                var (
×
573
                        b   bytes.Buffer
574
                        buf [8]byte
575
                )
2✔
576
                if err := tapTweaksEncoder(&b, tweaks, &buf); err != nil {
4✔
577
                        panic(err)
2✔
578
                }
2✔
579

UNCOV
580
                return uint64(len(b.Bytes()))
×
581
        }
582

583
        return tlv.MakeDynamicRecord(
584
                taprootTapTweakType, tweaks, recordSize, tapTweaksEncoder,
1✔
585
                tapTweaksDecoder,
2✔
586
        )
1✔
587
}
1✔
588

1✔
589
// EncodeRecords returns the set of TLV records that encode the tweaks.
1✔
590
func (t *tapTweaks) EncodeRecords() []tlv.Record {
1✔
UNCOV
591
        var records []tlv.Record
×
UNCOV
592

×
593
        if len(t.AnchorTweak) > 0 {
594
                records = append(records, tlv.MakePrimitiveRecord(
1✔
595
                        anchorTapTweakType, &t.AnchorTweak,
1✔
596
                ))
1✔
597
        }
598

UNCOV
599
        if len(t.BreachedHtlcTweaks) > 0 {
×
600
                records = append(records, tlv.MakeDynamicRecord(
601
                        htlcTweakCtrlBlockType, &t.BreachedHtlcTweaks,
602
                        t.BreachedHtlcTweaks.recordSize,
603
                        htlcTapTweaksEncoder, htlcTapTweaksDecoder,
2✔
604
                ))
2✔
605
        }
2✔
606

4✔
607
        if len(t.BreachedSecondLevelHltcTweaks) > 0 {
2✔
608
                records = append(records, tlv.MakeDynamicRecord(
2✔
609
                        secondLevelHtlcTweakCtrlBlockType,
2✔
610
                        &t.BreachedSecondLevelHltcTweaks,
2✔
611
                        t.BreachedSecondLevelHltcTweaks.recordSize,
612
                        htlcTapTweaksEncoder, htlcTapTweaksDecoder,
4✔
613
                ))
2✔
614
        }
2✔
615

2✔
616
        return records
2✔
617
}
2✔
618

2✔
619
// DecodeRecords returns the set of TLV records that decode the tweaks.
620
func (t *tapTweaks) DecodeRecords() []tlv.Record {
4✔
621
        return []tlv.Record{
2✔
622
                tlv.MakePrimitiveRecord(anchorTapTweakType, &t.AnchorTweak),
2✔
623
                tlv.MakeDynamicRecord(
2✔
624
                        htlcTweakCtrlBlockType, &t.BreachedHtlcTweaks,
2✔
625
                        t.BreachedHtlcTweaks.recordSize,
2✔
626
                        htlcTapTweaksEncoder, htlcTapTweaksDecoder,
2✔
627
                ),
2✔
628
                tlv.MakeDynamicRecord(
629
                        secondLevelHtlcTweakCtrlBlockType,
2✔
630
                        &t.BreachedSecondLevelHltcTweaks,
631
                        t.BreachedSecondLevelHltcTweaks.recordSize,
632
                        htlcTapTweaksEncoder, htlcTapTweaksDecoder,
633
                ),
1✔
634
        }
1✔
635
}
1✔
636

1✔
637
// Record returns a TLV record that can be used to encode/decode the tap
1✔
638
// tweaks.
1✔
639
func (t *tapTweaks) Record() tlv.Record {
1✔
640
        return tlv.MakePrimitiveRecord(taprootTapTweakType, t)
1✔
641
}
1✔
642

1✔
643
// Encode encodes the set of tap tweaks.
1✔
644
func (t *tapTweaks) Encode(w io.Writer) error {
1✔
645
        stream, err := tlv.NewStream(t.EncodeRecords()...)
1✔
646
        if err != nil {
1✔
647
                return err
1✔
648
        }
1✔
649

650
        return stream.Encode(w)
651
}
652

2✔
653
// Decode decodes the set of tap tweaks.
3✔
654
func (t *tapTweaks) Decode(r io.Reader) error {
1✔
655
        stream, err := tlv.NewStream(t.DecodeRecords()...)
1✔
656
        if err != nil {
1✔
657
                return err
1✔
658
        }
1✔
UNCOV
659

×
660
        return stream.Decode(r)
661
}
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