Skip to content

Commit 059352c

Browse files
committed
tappsbt: test decode handling of global Unknowns
In this commit, we add a new test to ensure that if a Packet is missing the Unknown values we need to identify VPackets, the decoder fails. We also check that decoding does not fail if Unknown values unrelated to VPackets are included.
1 parent 7cb36e9 commit 059352c

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

tappsbt/decode_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
74142
func TestEncodingDecoding(t *testing.T) {
75143
t.Parallel()

0 commit comments

Comments
 (0)