@@ -1994,30 +1994,158 @@ func dVpktList(r io.Reader, val interface{}, buf *[8]byte, _ uint64) error {
19941994 return tlv .NewTypeForEncodingErr (val , "*VpktList" )
19951995}
19961996
1997+ // TapscriptSigDesc contains the information needed to re-sign for a given set
1998+ // of vPkts. For normal tapscript outputs, this is the taptweak and also the
1999+ // serialized control block. These are needed for second level HTLC outputs, as
2000+ // we can't sign the vPkts until we know the sweeping transaction.
2001+ type TapscriptSigDesc struct {
2002+ TapTweak tlv.RecordT [tlv.TlvType0 , []byte ]
2003+
2004+ CtrlBlock tlv.RecordT [tlv.TlvType1 , []byte ]
2005+ }
2006+
2007+ // NewTapscriptSigDesc creates a new tapscriptSigDesc with the given tap tweak
2008+ // and ctrlBlock.
2009+ func NewTapscriptSigDesc (tapTweak , ctrlBlock []byte ) TapscriptSigDesc {
2010+ return TapscriptSigDesc {
2011+ TapTweak : tlv.NewPrimitiveRecord [tlv.TlvType0 ](tapTweak ),
2012+ CtrlBlock : tlv.NewPrimitiveRecord [tlv.TlvType1 ](ctrlBlock ),
2013+ }
2014+ }
2015+
2016+ // Encode attempts to encode the target tapscriptSigDesc into the passed
2017+ // io.Writer.
2018+ func (t * TapscriptSigDesc ) Encode (w io.Writer ) error {
2019+ tlvStream , err := tlv .NewStream (
2020+ t .TapTweak .Record (), t .CtrlBlock .Record (),
2021+ )
2022+ if err != nil {
2023+ return err
2024+ }
2025+
2026+ return tlvStream .Encode (w )
2027+ }
2028+
2029+ // Decode attempts to decode the target tapscriptSigDesc from the passed
2030+ // io.Reader.
2031+ func (t * TapscriptSigDesc ) Decode (r io.Reader ) error {
2032+ tlvStream , err := tlv .NewStream (
2033+ t .TapTweak .Record (), t .CtrlBlock .Record (),
2034+ )
2035+ if err != nil {
2036+ return err
2037+ }
2038+
2039+ return tlvStream .Decode (r )
2040+ }
2041+
2042+ // eTapscriptSigDesc is an encoder for tapscriptSigDesc.
2043+ func eTapscriptSigDesc (w io.Writer , val interface {}, _ * [8 ]byte ) error {
2044+ if v , ok := val .(* TapscriptSigDesc ); ok {
2045+ return v .Encode (w )
2046+ }
2047+
2048+ return tlv .NewTypeForEncodingErr (val , "*tapscriptSigDesc" )
2049+ }
2050+
2051+ // dTapscriptSigDesc is a decoder for tapscriptSigDesc.
2052+ func dTapscriptSigDesc (r io.Reader , val interface {},
2053+ _ * [8 ]byte , _ uint64 ) error {
2054+
2055+ if typ , ok := val .(* TapscriptSigDesc ); ok {
2056+ return typ .Decode (r )
2057+ }
2058+
2059+ return tlv .NewTypeForEncodingErr (val , "*tapscriptSigDesc" )
2060+ }
2061+
2062+ // Record returns a tlv.Record that represents the tapscriptSigDesc.
2063+ func (t * TapscriptSigDesc ) Record () tlv.Record {
2064+ size := func () uint64 {
2065+ var (
2066+ buf bytes.Buffer
2067+ scratch [8 ]byte
2068+ )
2069+ err := eTapscriptSigDesc (& buf , t , & scratch )
2070+ if err != nil {
2071+ panic (err )
2072+ }
2073+
2074+ return uint64 (buf .Len ())
2075+ }
2076+
2077+ return tlv .MakeDynamicRecord (
2078+ 0 , t , size , eTapscriptSigDesc , dTapscriptSigDesc ,
2079+ )
2080+ }
2081+
19972082// ContractResolution houses all the information we need to resolve a contract
19982083// on chain. This includes a series of pre-populated and pre-signed vPackets.
19992084// The internal key, and other on-chain anchor information may be missing from
20002085// these packets.
20012086type ContractResolution struct {
2002- // SweepVpkts is a list of pre-signed vPackets that can be anchored
2003- // into an output in a transaction where the refrnced previous inputs
2004- // are spent to sweep an asset.
2005- SweepVpkts tlv.RecordT [tlv.TlvType0 , VpktList ]
2087+ // firstLevelSweepVpkts is a list of pre-signed vPackets that can be
2088+ // anchored into an output in a transaction where the referenced
2089+ // previous inputs are spent to sweep an asset.
2090+ firstLevelSweepVpkts tlv.RecordT [tlv.TlvType0 , VpktList ]
2091+
2092+ // secondLevelSweepVpkts is a list of pre-signed vPackets that can be
2093+ // anchored into an output in a transaction where the referenced
2094+ // previous inputs are spent to sweep an asset.
2095+ secondLevelSweepVpkts tlv.OptionalRecordT [tlv.TlvType1 , VpktList ]
2096+
2097+ // secondLevelSigDescs is a list of tapscriptSigDescs that contain the
2098+ // information we need to sign for each second level vPkt once the
2099+ // sweeping transaction is known.
2100+ secondLevelSigDescs tlv.OptionalRecordT [tlv.TlvType2 , TapscriptSigDesc ]
20062101}
20072102
20082103// NewContractResolution creates a new ContractResolution with the given list
20092104// of vpkts.
2010- func NewContractResolution (pkts []* tappsbt.VPacket ) ContractResolution {
2011- return ContractResolution {
2012- SweepVpkts : tlv.NewRecordT [tlv.TlvType0 ](NewVpktList (pkts )),
2105+ func NewContractResolution (firstLevelPkts , secondLevelPkts []* tappsbt.VPacket ,
2106+ secondLevelSweepDesc lfn.Option [TapscriptSigDesc ]) ContractResolution {
2107+
2108+ c := ContractResolution {
2109+ firstLevelSweepVpkts : tlv.NewRecordT [tlv.TlvType0 ](
2110+ NewVpktList (firstLevelPkts ),
2111+ ),
2112+ }
2113+
2114+ if len (secondLevelPkts ) != 0 {
2115+ c .secondLevelSweepVpkts = tlv .SomeRecordT (
2116+ tlv.NewRecordT [tlv.TlvType1 ](
2117+ NewVpktList (secondLevelPkts ),
2118+ ),
2119+ )
20132120 }
2121+
2122+ secondLevelSweepDesc .WhenSome (func (sigDesc TapscriptSigDesc ) {
2123+ c .secondLevelSigDescs = tlv .SomeRecordT (
2124+ tlv.NewRecordT [tlv.TlvType2 ](sigDesc ),
2125+ )
2126+ })
2127+
2128+ return c
20142129}
20152130
20162131// Records returns the records that make up the ContractResolution.
20172132func (c * ContractResolution ) Records () []tlv.Record {
2018- return []tlv.Record {
2019- c .SweepVpkts .Record (),
2133+ records := []tlv.Record {
2134+ c .firstLevelSweepVpkts .Record (),
20202135 }
2136+
2137+ c .secondLevelSweepVpkts .WhenSome (
2138+ func (r tlv.RecordT [tlv.TlvType1 , VpktList ]) {
2139+ records = append (records , r .Record ())
2140+ },
2141+ )
2142+ c .secondLevelSigDescs .WhenSome (
2143+ func (r tlv.RecordT [tlv.TlvType2 , TapscriptSigDesc ]) {
2144+ records = append (records , r .Record ())
2145+ },
2146+ )
2147+
2148+ return records
20212149}
20222150
20232151// Encode serializes the ContractResolution to the given io.Writer.
@@ -2032,15 +2160,44 @@ func (c *ContractResolution) Encode(w io.Writer) error {
20322160
20332161// Decode deserializes the ContractResolution from the given io.Reader.
20342162func (c * ContractResolution ) Decode (r io.Reader ) error {
2035- tlvStream , err := tlv .NewStream (c .Records ()... )
2163+ sweepZero := c .secondLevelSweepVpkts .Zero ()
2164+ sigZero := c .secondLevelSigDescs .Zero ()
2165+
2166+ tlvStream , err := tlv .NewStream (
2167+ c .firstLevelSweepVpkts .Record (),
2168+ sweepZero .Record (),
2169+ sigZero .Record (),
2170+ )
20362171 if err != nil {
20372172 return err
20382173 }
20392174
2040- return tlvStream .Decode (r )
2175+ tlvs , err := tlvStream .DecodeWithParsedTypes (r )
2176+ if err != nil {
2177+ return err
2178+ }
2179+
2180+ if _ , ok := tlvs [sweepZero .TlvType ()]; ok {
2181+ c .secondLevelSweepVpkts = tlv .SomeRecordT (sweepZero )
2182+ }
2183+ if _ , ok := tlvs [sigZero .TlvType ()]; ok {
2184+ c .secondLevelSigDescs = tlv .SomeRecordT (sigZero )
2185+ }
2186+
2187+ return nil
2188+ }
2189+
2190+ // Vpkts1 returns the set of first level Vpkts.
2191+ func (c * ContractResolution ) Vpkts1 () []* tappsbt.VPacket {
2192+ return c .firstLevelSweepVpkts .Val .Pkts
20412193}
20422194
2043- // VPkts returns the list of vPkts in the ContractResolution.
2044- func (c * ContractResolution ) VPkts () []* tappsbt.VPacket {
2045- return c .SweepVpkts .Val .Pkts
2195+ // Vpkts2 returns the set of first level Vpkts.
2196+ func (c * ContractResolution ) Vpkts2 () []* tappsbt.VPacket {
2197+ var vPkts []* tappsbt.VPacket
2198+ c .secondLevelSweepVpkts .WhenSomeV (func (v VpktList ) {
2199+ vPkts = v .Pkts
2200+ })
2201+
2202+ return vPkts
20462203}
0 commit comments