Skip to content

Commit 729f7c6

Browse files
committed
tapgarden: add tests for mint supply commit delegation key filtering
This commit introduces comprehensive test coverage for the delegation key filtering functionality in the BatchCaretaker. The tests verify that mint supply commitment events are only sent for assets where we control the delegation key. The test suite covers three key scenarios: all assets having delegation keys, partial delegation key ownership, and no delegation keys. Mock implementations of the MintCommitter and DelegationKeyChecker interfaces enable isolated testing of the filtering logic without requiring actual key management infrastructure.
1 parent 624f647 commit 729f7c6

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed

tapgarden/supply_commit_test.go

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package tapgarden
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/btcsuite/btcd/wire"
9+
"github.com/lightninglabs/taproot-assets/asset"
10+
"github.com/lightninglabs/taproot-assets/proof"
11+
"github.com/lightninglabs/taproot-assets/universe"
12+
"github.com/stretchr/testify/mock"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
// MockSupplyCommitManager is a mock implementation of the SupplyCommitManager
17+
// interface for testing.
18+
type MockSupplyCommitManager struct {
19+
mock.Mock
20+
}
21+
22+
// MockDelegationKeyChecker is a mock implementation of the DelegationKeyChecker
23+
// interface for testing.
24+
type MockDelegationKeyChecker struct {
25+
mock.Mock
26+
}
27+
28+
// HasDelegationKey implements the DelegationKeyChecker interface.
29+
func (m *MockDelegationKeyChecker) HasDelegationKey(ctx context.Context,
30+
assetID asset.ID) (bool, error) {
31+
32+
args := m.Called(ctx, assetID)
33+
return args.Bool(0), args.Error(1)
34+
}
35+
36+
// SendEvent implements the SupplyCommitManager interface.
37+
func (m *MockSupplyCommitManager) SendEvent(ctx context.Context,
38+
assetSpec asset.Specifier, event interface{}) error {
39+
40+
args := m.Called(ctx, assetSpec, event)
41+
return args.Error(0)
42+
}
43+
44+
// SendMintEvent implements the SupplyCommitManager interface.
45+
func (m *MockSupplyCommitManager) SendMintEvent(ctx context.Context,
46+
assetSpec asset.Specifier, leafKey universe.UniqueLeafKey,
47+
issuanceProof universe.Leaf) error {
48+
49+
args := m.Called(ctx, assetSpec, leafKey, issuanceProof)
50+
return args.Error(0)
51+
}
52+
53+
// SendBurnEvent implements the SupplyCommitManager interface.
54+
func (m *MockSupplyCommitManager) SendBurnEvent(ctx context.Context,
55+
assetSpec asset.Specifier, burnLeaf universe.BurnLeaf) error {
56+
57+
args := m.Called(ctx, assetSpec, burnLeaf)
58+
return args.Error(0)
59+
}
60+
61+
// TestSupplyCommitDelegationKeyFiltering tests that supply commit events
62+
// are only sent for assets where we control the delegation key.
63+
func TestSupplyCommitDelegationKeyFiltering(t *testing.T) {
64+
t.Parallel()
65+
66+
ctx := context.Background()
67+
68+
// Create test assets
69+
asset1 := asset.RandAsset(t, asset.Normal)
70+
asset2 := asset.RandAsset(t, asset.Normal)
71+
asset3 := asset.RandAsset(t, asset.Normal)
72+
73+
tests := []struct {
74+
name string
75+
assets []*asset.Asset
76+
delegationKeyResponses map[asset.ID]bool
77+
expectedCallCount int
78+
}{
79+
{
80+
name: "all assets have delegation key",
81+
assets: []*asset.Asset{asset1, asset2},
82+
delegationKeyResponses: map[asset.ID]bool{
83+
asset1.ID(): true,
84+
asset2.ID(): true,
85+
},
86+
expectedCallCount: 2,
87+
},
88+
{
89+
name: "only one asset has delegation key",
90+
assets: []*asset.Asset{asset1, asset2, asset3},
91+
delegationKeyResponses: map[asset.ID]bool{
92+
asset1.ID(): true,
93+
asset2.ID(): false,
94+
asset3.ID(): true,
95+
},
96+
expectedCallCount: 2,
97+
},
98+
{
99+
name: "no assets have delegation key",
100+
assets: []*asset.Asset{asset1, asset2},
101+
delegationKeyResponses: map[asset.ID]bool{
102+
asset1.ID(): false,
103+
asset2.ID(): false,
104+
},
105+
expectedCallCount: 0,
106+
},
107+
}
108+
109+
for _, tc := range tests {
110+
tc := tc
111+
t.Run(tc.name, func(t *testing.T) {
112+
t.Parallel()
113+
114+
// First, we'll set up our series of mocks, and then
115+
// record the intended responses for each of them.
116+
mockCommitter := &MockSupplyCommitManager{}
117+
mockDelegationChecker := &MockDelegationKeyChecker{}
118+
119+
// Set up delegation key checker responses
120+
for assetID, hasKey := range tc.delegationKeyResponses {
121+
mockDelegationChecker.On(
122+
"HasDelegationKey", ctx, assetID,
123+
).Return(hasKey, nil)
124+
}
125+
126+
// If we're expecting any calls, then we'll make sure to
127+
// register that here.
128+
if tc.expectedCallCount > 0 {
129+
//nolint:lll
130+
mockCommitter.On("SendMintEvent",
131+
ctx,
132+
mock.AnythingOfType("asset.Specifier"),
133+
mock.AnythingOfType("universe.AssetLeafKey"),
134+
mock.AnythingOfType("universe.Leaf")).
135+
Return(nil).
136+
Times(tc.expectedCallCount)
137+
}
138+
139+
// With the mocks registered above, we'll create a new
140+
// care taker instance that uses them.
141+
caretaker := &BatchCaretaker{
142+
cfg: &BatchCaretakerConfig{
143+
GardenKit: GardenKit{
144+
MintCommitter: mockCommitter,
145+
DelegationKeyChecker: mockDelegationChecker,
146+
},
147+
},
148+
}
149+
150+
// Next, we'll create a series of proofs for each of the
151+
// assets.
152+
proofs := make(proof.AssetProofs)
153+
dummyTx := &wire.MsgTx{
154+
Version: 2,
155+
TxIn: []*wire.TxIn{{
156+
PreviousOutPoint: wire.OutPoint{},
157+
SignatureScript: []byte{},
158+
Sequence: 0xffffffff,
159+
}},
160+
}
161+
block := wire.MsgBlock{
162+
Header: wire.BlockHeader{
163+
Version: 1,
164+
Timestamp: time.Now(),
165+
Bits: 0x207fffff,
166+
},
167+
Transactions: []*wire.MsgTx{dummyTx},
168+
}
169+
for i, a := range tc.assets {
170+
scriptKey := asset.ToSerialized(
171+
a.ScriptKey.PubKey,
172+
)
173+
testProof := proof.RandProof(
174+
t, a.Genesis, a.ScriptKey.PubKey, block,
175+
0, uint32(i),
176+
)
177+
proofs[scriptKey] = &testProof
178+
}
179+
180+
// Call the internal method, then verify the expected
181+
// calls were made.
182+
err := caretaker.sendSupplyCommitEvents(
183+
ctx, tc.assets, nil, proofs,
184+
)
185+
require.NoError(t, err)
186+
mockCommitter.AssertExpectations(t)
187+
mockDelegationChecker.AssertExpectations(t)
188+
})
189+
}
190+
}
191+

0 commit comments

Comments
 (0)