From f74d1ce53b0642f7a9f087601f650e5746260533 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 3 Jun 2024 22:56:06 -0700 Subject: [PATCH] contractcourt: add CommitBlob to taprootBriefcase This'll be used to store the extra resolution information for the commitment outputs. --- contractcourt/briefcase.go | 12 ++++++++ contractcourt/taproot_briefcase.go | 41 +++++++++++++++++++++++-- contractcourt/taproot_briefcase_test.go | 10 ++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/contractcourt/briefcase.go b/contractcourt/briefcase.go index 2132da6de..26df50b30 100644 --- a/contractcourt/briefcase.go +++ b/contractcourt/briefcase.go @@ -10,9 +10,11 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/fn" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/tlv" ) // ContractResolutions is a wrapper struct around the two forms of resolutions @@ -1554,6 +1556,12 @@ func encodeTaprootAuxData(w io.Writer, c *ContractResolutions) error { commitSignDesc := commitResolution.SelfOutputSignDesc //nolint:lll tapCase.CtrlBlocks.Val.CommitSweepCtrlBlock = commitSignDesc.ControlBlock + + c.CommitResolution.ResolutionBlob.WhenSome(func(b []byte) { + tapCase.SettledCommitBlob = tlv.SomeRecordT( + tlv.NewPrimitiveRecord[tlv.TlvType2](b), + ) + }) } for _, htlc := range c.HtlcResolutions.IncomingHTLCs { @@ -1640,6 +1648,10 @@ func decodeTapRootAuxData(r io.Reader, c *ContractResolutions) error { if c.CommitResolution != nil { c.CommitResolution.SelfOutputSignDesc.ControlBlock = tapCase.CtrlBlocks.Val.CommitSweepCtrlBlock + + tapCase.SettledCommitBlob.WhenSomeV(func(b []byte) { + c.CommitResolution.ResolutionBlob = fn.Some(b) + }) } for i := range c.HtlcResolutions.IncomingHTLCs { diff --git a/contractcourt/taproot_briefcase.go b/contractcourt/taproot_briefcase.go index 8544582c0..0a2beeff7 100644 --- a/contractcourt/taproot_briefcase.go +++ b/contractcourt/taproot_briefcase.go @@ -29,6 +29,17 @@ type taprootBriefcase struct { // are to be spent via a keyspend path. This includes anchors, and any // revocation paths. TapTweaks tlv.RecordT[tlv.TlvType1, tapTweaks] + + // SettledCommitBlob is an optional record that contains an opaque blob + // that may be used to properly sweep commitment outputs on a force + // close transaction. + SettledCommitBlob tlv.OptionalRecordT[tlv.TlvType2, tlv.Blob] + + // BreachCommitBlob is an optional record that contains an opaque blob + // used to sweep a remote party's breached output. + BreachedCommitBlob tlv.OptionalRecordT[tlv.TlvType3, tlv.Blob] + + // TODO(roasbeef): htlc blobs } // TODO(roasbeef): morph into new tlv record @@ -48,6 +59,18 @@ func (t *taprootBriefcase) EncodeRecords() []tlv.Record { t.CtrlBlocks.Record(), t.TapTweaks.Record(), } + + t.SettledCommitBlob.WhenSome( + func(r tlv.RecordT[tlv.TlvType2, tlv.Blob]) { + records = append(records, r.Record()) + }, + ) + t.BreachedCommitBlob.WhenSome( + func(r tlv.RecordT[tlv.TlvType3, tlv.Blob]) { + records = append(records, r.Record()) + }, + ) + return records } @@ -71,16 +94,30 @@ func (t *taprootBriefcase) Encode(w io.Writer) error { // Decode decodes the given reader into the target struct. func (t *taprootBriefcase) Decode(r io.Reader) error { - stream, err := tlv.NewStream(t.DecodeRecords()...) + settledCommitBlob := t.SettledCommitBlob.Zero() + breachedCommitBlob := t.BreachedCommitBlob.Zero() + records := append( + t.DecodeRecords(), + settledCommitBlob.Record(), + breachedCommitBlob.Record(), + ) + stream, err := tlv.NewStream(records...) if err != nil { return err } - _, err = stream.DecodeWithParsedTypes(r) + typeMap, err := stream.DecodeWithParsedTypes(r) if err != nil { return err } + if val, ok := typeMap[t.SettledCommitBlob.TlvType()]; ok && val == nil { + t.SettledCommitBlob = tlv.SomeRecordT(settledCommitBlob) + } + if v, ok := typeMap[t.BreachedCommitBlob.TlvType()]; ok && v == nil { + t.BreachedCommitBlob = tlv.SomeRecordT(breachedCommitBlob) + } + return nil } diff --git a/contractcourt/taproot_briefcase_test.go b/contractcourt/taproot_briefcase_test.go index 1b0d0b399..a7d52d963 100644 --- a/contractcourt/taproot_briefcase_test.go +++ b/contractcourt/taproot_briefcase_test.go @@ -70,6 +70,10 @@ func TestTaprootBriefcase(t *testing.T) { _, err = rand.Read(anchorTweak[:]) require.NoError(t, err) + var commitBlob [100]byte + _, err = rand.Read(commitBlob[:]) + require.NoError(t, err) + testCase := &taprootBriefcase{ CtrlBlocks: tlv.NewRecordT[tlv.TlvType0](ctrlBlocks{ CommitSweepCtrlBlock: sweepCtrlBlock[:], @@ -83,6 +87,12 @@ func TestTaprootBriefcase(t *testing.T) { BreachedHtlcTweaks: randHtlcTweaks(t), BreachedSecondLevelHltcTweaks: randHtlcTweaks(t), }), + SettledCommitBlob: tlv.SomeRecordT( + tlv.NewPrimitiveRecord[tlv.TlvType2](commitBlob[:]), + ), + BreachedCommitBlob: tlv.SomeRecordT( + tlv.NewPrimitiveRecord[tlv.TlvType3](commitBlob[:]), + ), } var b bytes.Buffer