From 518a68063525b0f6f8f51980b19f4a1e1843a89c Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 7 Feb 2024 10:24:04 +0100 Subject: [PATCH] tappsbt: add ProofSuffix field to VOutput We need a way to transport proofs that are complete in terms of MS-SMT proofs committing to the correct asset but incomplete in terms of the asset witness (in the ASSET_VERSION_V1 case). The virtual transaction output is as good a place as any other. This will also allow us to simplify some of the data structures around passive assets, as currently we need to carry those proofs around in a separate map. --- tappsbt/decode.go | 6 +++++- tappsbt/encode.go | 6 +++++- tappsbt/interface.go | 27 ++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tappsbt/decode.go b/tappsbt/decode.go index 7840512e7..85d93ab69 100644 --- a/tappsbt/decode.go +++ b/tappsbt/decode.go @@ -278,11 +278,15 @@ func (o *VOutput) decode(pOut psbt.POutput, txOut *wire.TxOut) error { ), }, { - key: PsbtKeyTypeOutputAssetVersion, + key: PsbtKeyTypeOutputTapAssetVersion, decoder: tlvDecoder( &o.AssetVersion, vOutputAssetVersionDecoder, ), }, + { + key: PsbtKeyTypeOutputTapAssetProofSuffix, + decoder: tlvDecoder(&o.ProofSuffix, tlv.DVarBytes), + }, } for idx := range mapping { diff --git a/tappsbt/encode.go b/tappsbt/encode.go index 75a042302..fbe181519 100644 --- a/tappsbt/encode.go +++ b/tappsbt/encode.go @@ -277,11 +277,15 @@ func (o *VOutput) encode(coinType uint32) (psbt.POutput, *wire.TxOut, error) { ), }, { - key: PsbtKeyTypeOutputAssetVersion, + key: PsbtKeyTypeOutputTapAssetVersion, encoder: tlvEncoder( &o.AssetVersion, vOutputAssetVersionEncoder, ), }, + { + key: PsbtKeyTypeOutputTapAssetProofSuffix, + encoder: tlvEncoder(&o.ProofSuffix, tlv.EVarBytes), + }, } for idx := range mapping { diff --git a/tappsbt/interface.go b/tappsbt/interface.go index 3cb6fcb5d..a782b1b18 100644 --- a/tappsbt/interface.go +++ b/tappsbt/interface.go @@ -50,7 +50,8 @@ var ( PsbtKeyTypeOutputTapAsset = []byte{0x76} PsbtKeyTypeOutputTapSplitAsset = []byte{0x77} PsbtKeyTypeOutputTapAnchorTapscriptSibling = []byte{0x78} - PsbtKeyTypeOutputAssetVersion = []byte{0x79} + PsbtKeyTypeOutputTapAssetVersion = []byte{0x79} + PsbtKeyTypeOutputTapAssetProofSuffix = []byte{0x7a} ) // The following keys are used as custom fields on the BTC level anchor @@ -529,6 +530,14 @@ type VOutput struct { // serialized, this will be stored in the TaprootInternalKey and // TaprootDerivationPath fields of the PSBT output. ScriptKey asset.ScriptKey + + // ProofSuffix is the optional new transition proof blob that is created + // once the asset output was successfully committed to the anchor + // transaction referenced above. The proof suffix is not yet complete + // since the header information needs to be added once the anchor + // transaction was confirmed in a block. This field cannot be of type + // proof.Proof directly because that would cause a circular dependency. + ProofSuffix []byte } // SplitLocator creates a split locator from the output. The asset ID is passed @@ -750,3 +759,19 @@ func deserializeTweakedScriptKey(pOut psbt.POutput) (*asset.TweakedScriptKey, Tweak: tweak, }, nil } + +// Encode encodes the virtual packet into a byte slice. +func Encode(vPkt *VPacket) ([]byte, error) { + var buf bytes.Buffer + err := vPkt.Serialize(&buf) + if err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +// Decode decodes a virtual packet from a byte slice. +func Decode(encoded []byte) (*VPacket, error) { + return NewFromRawBytes(bytes.NewReader(encoded), false) +}