@@ -10,6 +10,7 @@ import (
1010 "strings"
1111 "testing"
1212
13+ "github.com/btcsuite/btcd/btcutil/psbt"
1314 "github.com/lightninglabs/taproot-assets/address"
1415 "github.com/lightninglabs/taproot-assets/asset"
1516 "github.com/lightninglabs/taproot-assets/commitment"
@@ -70,6 +71,73 @@ func assertEqualPackets(t *testing.T, expected, actual *VPacket) {
7071 }
7172}
7273
74+ // TestGlobalUnknownFields tests that the global Unknown fields mandatory for a
75+ // valid VPacket are present for an encoded VPacket. We also test that when
76+ // decoding a VPacket from a Packet, a Packet with missing mandatory fields is
77+ // rejected, and extra global Unknown fields are permitted.
78+ func TestGlobalUnknownFields (t * testing.T ) {
79+ // Make a random packet.
80+ pkg := RandPacket (t , false , false )
81+
82+ // An encoded valid packet should have exactly three global Unknown
83+ // fields.
84+ packet , err := pkg .EncodeAsPsbt ()
85+ require .NoError (t , err )
86+ require .Len (t , packet .Unknowns , 3 )
87+
88+ // Specifically, the isVirtual marker, HRP, and Version must be present.
89+ requiredKeys := [][]byte {
90+ PsbtKeyTypeGlobalTapIsVirtualTx ,
91+ PsbtKeyTypeGlobalTapChainParamsHRP ,
92+ PsbtKeyTypeGlobalTapPsbtVersion ,
93+ }
94+ for _ , key := range requiredKeys {
95+ _ , err := findCustomFieldsByKeyPrefix (packet .Unknowns , key )
96+ require .NoError (t , err )
97+ }
98+
99+ // Decoding a VPacket from this minimal Packet must succeed.
100+ _ , err = NewFromPsbt (packet )
101+ require .NoError (t , err )
102+
103+ var packetBuf bytes.Buffer
104+ err = packet .Serialize (& packetBuf )
105+ require .NoError (t , err )
106+
107+ cloneBuffer := func (b * bytes.Buffer ) * bytes.Buffer {
108+ return bytes .NewBuffer (bytes .Clone (b .Bytes ()))
109+ }
110+
111+ // If we remove a mandatory VPacket field from the Packet, decoding
112+ // must fail.
113+ invalidPacketBytes := cloneBuffer (& packetBuf )
114+ invalidPacket , err := psbt .NewFromRawBytes (invalidPacketBytes , false )
115+ require .NoError (t , err )
116+
117+ invalidPacket .Unknowns = invalidPacket .Unknowns [1 :]
118+ _ , err = NewFromPsbt (invalidPacket )
119+ require .Error (t , err )
120+
121+ // If we add a global Unknown field to the valid Packet, decoding must
122+ // still succeed.
123+ extraPacketBytes := cloneBuffer (& packetBuf )
124+ extraPacket , err := psbt .NewFromRawBytes (extraPacketBytes , false )
125+ require .NoError (t , err )
126+
127+ // The VPacket global Unknown keys start at 0x70, so we'll use a key
128+ // value very far from that.
129+ extraUnknown := & psbt.Unknown {
130+ Key : []byte {0xaa },
131+ Value : []byte ("really_cool_unknown_value" ),
132+ }
133+ extraPacket .Unknowns = append (extraPacket .Unknowns , extraUnknown )
134+
135+ // The decoded VPacket should not contain the extra Unknown field, but
136+ // the decoder should succeed.
137+ _ , err = NewFromPsbt (extraPacket )
138+ require .NoError (t , err )
139+ }
140+
73141// TestEncodingDecoding tests the decoding of a virtual packet from raw bytes.
74142func TestEncodingDecoding (t * testing.T ) {
75143 t .Parallel ()
0 commit comments