@@ -11,6 +11,7 @@ import (
1111 "github.com/btcsuite/btcd/btcec/v2"
1212 "github.com/btcsuite/btcd/wire"
1313 "github.com/lightninglabs/taproot-assets/asset"
14+ "github.com/lightninglabs/taproot-assets/commitment"
1415 "github.com/lightninglabs/taproot-assets/fn"
1516 "github.com/lightningnetwork/lnd/tlv"
1617)
@@ -346,6 +347,102 @@ func CommitmentProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error
346347 return tlv .NewTypeForEncodingErr (val , "*CommitmentProof" )
347348}
348349
350+ func CommitmentProofsEncoder (w io.Writer , val any , buf * [8 ]byte ) error {
351+ if t , ok := val .(* map [asset.SerializedKey ]commitment.Proof ); ok {
352+ numProofs := uint64 (len (* t ))
353+ if err := tlv .WriteVarInt (w , numProofs , buf ); err != nil {
354+ return err
355+ }
356+
357+ var proofBuf bytes.Buffer
358+ for key , proof := range * t {
359+ var keyBytes [33 ]byte
360+ copy (keyBytes [:], key [:])
361+
362+ err := tlv .EBytes33 (w , & keyBytes , buf )
363+ if err != nil {
364+ return err
365+ }
366+
367+ if err := proof .Encode (& proofBuf ); err != nil {
368+ return err
369+ }
370+
371+ proofBytes := proofBuf .Bytes ()
372+ err = asset .InlineVarBytesEncoder (w , & proofBytes , buf )
373+ if err != nil {
374+ return err
375+ }
376+
377+ proofBuf .Reset ()
378+ }
379+ return nil
380+ }
381+
382+ return tlv .NewTypeForEncodingErr (
383+ val , "map[asset.SerializedKey]CommitmentProof" ,
384+ )
385+ }
386+
387+ func CommitmentProofsDecoder (r io.Reader , val any , buf * [8 ]byte ,
388+ _ uint64 ) error {
389+
390+ if typ , ok := val .(* map [asset.SerializedKey ]commitment.Proof ); ok {
391+ numProofs , err := tlv .ReadVarInt (r , buf )
392+ if err != nil {
393+ return err
394+ }
395+
396+ // Avoid OOM by limiting the number of commitment proofs we
397+ // accept.
398+ if numProofs > MaxNumTaprootProofs {
399+ return fmt .Errorf ("%w: too many commitment proofs" ,
400+ ErrProofInvalid )
401+ }
402+
403+ proofs := make (
404+ map [asset.SerializedKey ]commitment.Proof , numProofs ,
405+ )
406+ for i := uint64 (0 ); i < numProofs ; i ++ {
407+ var keyBytes [33 ]byte
408+
409+ err := tlv .DBytes33 (
410+ r , & keyBytes , buf ,
411+ btcec .PubKeyBytesLenCompressed ,
412+ )
413+ if err != nil {
414+ return err
415+ }
416+
417+ var proofBytes []byte
418+ err = asset .InlineVarBytesDecoder (
419+ r , & proofBytes , buf , MaxTaprootProofSizeBytes ,
420+ )
421+ if err != nil {
422+ return err
423+ }
424+
425+ var key asset.SerializedKey
426+ copy (key [:], keyBytes [:])
427+
428+ var proof commitment.Proof
429+ err = proof .Decode (bytes .NewReader (proofBytes ))
430+ if err != nil {
431+ return err
432+ }
433+
434+ proofs [key ] = proof
435+ }
436+
437+ * typ = proofs
438+ return nil
439+ }
440+
441+ return tlv .NewTypeForEncodingErr (
442+ val , "map[asset.SerializedKey]CommitmentProof" ,
443+ )
444+ }
445+
349446func TapscriptProofEncoder (w io.Writer , val any , buf * [8 ]byte ) error {
350447 if t , ok := val .(* * TapscriptProof ); ok {
351448 return (* t ).Encode (w )
0 commit comments