Skip to content

Commit cef2567

Browse files
committed
tapgarden: add unit test for MintingBatch.validateUniCommitment
Add unit tests to verify that `MintingBatch.validateUniCommitment` correctly determines whether a candidate seedling can be included in a batch, based on the restrictions imposed by universe commitments.
1 parent 13ee407 commit cef2567

File tree

2 files changed

+443
-0
lines changed

2 files changed

+443
-0
lines changed

tapgarden/batch_test.go

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
package tapgarden
2+
3+
import (
4+
"testing"
5+
6+
"github.com/lightninglabs/taproot-assets/asset"
7+
"github.com/lightninglabs/taproot-assets/fn"
8+
"github.com/lightningnetwork/lnd/keychain"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
// TestValidateUniCommitment tests the mint batch method validateUniCommitment.
13+
func TestValidateUniCommitment(t *testing.T) {
14+
t.Parallel()
15+
16+
// Define test cases.
17+
type TestCase struct {
18+
name string
19+
candidateSeedling Seedling
20+
batch *MintingBatch
21+
expectErr bool
22+
}
23+
24+
testCases := []TestCase{
25+
{
26+
// Verifies that a group anchor candidate seedling with
27+
// universe commitments cannot be added to a batch with
28+
// the universe commitments feature enabled
29+
// if the batch already contains a group anchor
30+
// seedling.
31+
name: "populated batch with universe commitments; " +
32+
"batch already includes group anchor; " +
33+
"candidate seedling is also group anchor; " +
34+
"is not valid",
35+
36+
candidateSeedling: RandGroupAnchorSeedling(
37+
t, "new-group-anchor", true,
38+
),
39+
batch: RandMintingBatch(
40+
t, WithTotalGroups([]int{2}),
41+
WithUniverseCommitments(true),
42+
),
43+
expectErr: true,
44+
},
45+
{
46+
// Ensures that a group anchor candidate seedling with
47+
// universe commitments cannot be added to a batch that
48+
// already contains seedlings and has the universe
49+
// commitments feature disabled.
50+
name: "populated batch without universe commitments; " +
51+
"batch already includes group anchor; " +
52+
"candidate seedling is also group anchor; " +
53+
"is not valid",
54+
55+
candidateSeedling: RandGroupAnchorSeedling(
56+
t, "new-group-anchor", true,
57+
),
58+
batch: RandMintingBatch(
59+
t, WithTotalGroups([]int{2}),
60+
WithUniverseCommitments(false),
61+
),
62+
expectErr: true,
63+
},
64+
{
65+
// Ensures that a group candidate seedling (non-anchor)
66+
// with universe commitments cannot be added to a batch
67+
// that already contains seedlings and has the universe
68+
// commitments feature disabled.
69+
name: "populated batch without universe commitments; " +
70+
"candidate seedling is non-anchor with " +
71+
"universe commitments; is not valid",
72+
73+
candidateSeedling: RandNonAnchorGroupSeedling(
74+
t, asset.V1, asset.Normal, "some-anchor-name",
75+
[]byte{}, fn.None[keychain.KeyDescriptor](),
76+
true,
77+
),
78+
batch: RandMintingBatch(
79+
t, WithTotalGroups([]int{2}),
80+
WithUniverseCommitments(false),
81+
),
82+
expectErr: true,
83+
},
84+
{
85+
// Ensures that a group candidate seedling (non-anchor)
86+
// with universe commitments cannot be added to a batch
87+
// that already contains seedlings and has the universe
88+
// commitments feature enabled.
89+
//
90+
// This is because the anchor seedling for the candidate
91+
// seedling is not already present in the batch.
92+
name: "populated batch with universe commitments; " +
93+
"non-anchor candidate seedling with universe " +
94+
"commitments; anchor not in batch; " +
95+
"is not valid",
96+
97+
candidateSeedling: RandNonAnchorGroupSeedling(
98+
t, asset.V1, asset.Normal, "some-anchor-name",
99+
[]byte{}, fn.None[keychain.KeyDescriptor](),
100+
true,
101+
),
102+
batch: RandMintingBatch(
103+
t, WithTotalGroups([]int{2}),
104+
WithUniverseCommitments(true),
105+
),
106+
expectErr: true,
107+
},
108+
{
109+
// Ensures that a group anchor candidate seedling
110+
// with universe commitments can be added to an empty
111+
// batch.
112+
name: "empty batch; candidate seedling is group " +
113+
"anchor; is valid",
114+
115+
candidateSeedling: RandGroupAnchorSeedling(
116+
t, "some-anchor-name", true,
117+
),
118+
batch: RandMintingBatch(t),
119+
expectErr: false,
120+
},
121+
}
122+
123+
// Construct a test case where a mint batch with universe commitments
124+
// is populated with seedlings and a group anchor seedling is present.
125+
// The candidate seedling is a non-anchor group seedling with
126+
// universe commitments which specifies the batch group anchor seedling
127+
// as its anchor. The candidate seedling should be deemed valid.
128+
batch := RandMintingBatch(
129+
t, WithTotalGroups([]int{2}), WithUniverseCommitments(true),
130+
)
131+
132+
// Identify the anchor seedling in the batch.
133+
var anchorSeedling *Seedling
134+
for idx := range batch.Seedlings {
135+
seedling := batch.Seedlings[idx]
136+
if seedling.GroupAnchor == nil {
137+
anchorSeedling = seedling
138+
break
139+
}
140+
}
141+
142+
// Construct a candidate seedling that is a non-anchor group seedling
143+
// with universe commitments and specifies the batch group anchor
144+
// seedling as its anchor.
145+
candidateSeedling := RandNonAnchorGroupSeedling(
146+
t, anchorSeedling.AssetVersion, anchorSeedling.AssetType,
147+
anchorSeedling.AssetName, anchorSeedling.Meta.Data,
148+
anchorSeedling.DelegationKey,
149+
anchorSeedling.UniverseCommitments,
150+
)
151+
152+
testCases = append(testCases, TestCase{
153+
name: "populated batch with universe commitments; " +
154+
"candidate seedling is non-anchor group seedling " +
155+
"with universe commitments; anchor in batch; " +
156+
"is valid",
157+
candidateSeedling: candidateSeedling,
158+
batch: batch,
159+
expectErr: false,
160+
})
161+
162+
// Construct a test case where an empty but funded mint batch is
163+
// populated with a group anchor seedling. The candidate seedling has
164+
// universe commitments enabled. We expect the candidate seedling to be
165+
// deemed invalid. This is because the batch is already funded and
166+
// therefore the universe commitments feature cannot be enabled.
167+
fundedEmptyBatch := RandMintingBatch(t)
168+
169+
// Set the genesis packet of the empty batch to simulate funding.
170+
fundedEmptyBatch.GenesisPacket = &FundedMintAnchorPsbt{}
171+
172+
testCases = append(testCases, TestCase{
173+
name: "empty funded batch; candidate seedling is anchor " +
174+
"group seedling with universe commitments; is valid",
175+
candidateSeedling: RandGroupAnchorSeedling(
176+
t, "some-anchor-name", true,
177+
),
178+
batch: fundedEmptyBatch,
179+
expectErr: true,
180+
})
181+
182+
// Add a test case where the batch is funded and empty but universe
183+
// commitments is not enabled for the candidate seedling. The candidate
184+
// seedling should be deemed valid. The universe commitment feature
185+
// restriction does not apply in this case.
186+
testCases = append(testCases, TestCase{
187+
name: "empty funded batch; candidate seedling is anchor " +
188+
"group seedling with universe commitments; is valid",
189+
candidateSeedling: RandGroupAnchorSeedling(
190+
t, "some-anchor-name", false,
191+
),
192+
batch: fundedEmptyBatch,
193+
expectErr: false,
194+
})
195+
196+
// Execute test cases.
197+
for idx := range testCases {
198+
tc := testCases[idx]
199+
200+
t.Run(tc.name, func(t *testing.T) {
201+
err := tc.batch.validateUniCommitment(
202+
tc.candidateSeedling,
203+
)
204+
205+
if tc.expectErr {
206+
require.Error(t, err)
207+
return
208+
}
209+
210+
require.NoError(t, err)
211+
})
212+
}
213+
}

0 commit comments

Comments
 (0)