Skip to content

Commit 71ef2af

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 b1abe3a commit 71ef2af

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+
asset1 := asset.RandAsset(t, asset.Normal)
69+
asset2 := asset.RandAsset(t, asset.Normal)
70+
asset3 := asset.RandAsset(t, asset.Normal)
71+
72+
tests := []struct {
73+
name string
74+
assets []*asset.Asset
75+
delegationKeyResponses map[asset.ID]bool
76+
expectedCallCount int
77+
}{
78+
{
79+
name: "all assets have delegation key",
80+
assets: []*asset.Asset{asset1, asset2},
81+
delegationKeyResponses: map[asset.ID]bool{
82+
asset1.ID(): true,
83+
asset2.ID(): true,
84+
},
85+
expectedCallCount: 2,
86+
},
87+
{
88+
name: "only one asset has delegation key",
89+
assets: []*asset.Asset{asset1, asset2, asset3},
90+
delegationKeyResponses: map[asset.ID]bool{
91+
asset1.ID(): true,
92+
asset2.ID(): false,
93+
asset3.ID(): true,
94+
},
95+
expectedCallCount: 2,
96+
},
97+
{
98+
name: "no assets have delegation key",
99+
assets: []*asset.Asset{asset1, asset2},
100+
delegationKeyResponses: map[asset.ID]bool{
101+
asset1.ID(): false,
102+
asset2.ID(): false,
103+
},
104+
expectedCallCount: 0,
105+
},
106+
}
107+
108+
for _, tc := range tests {
109+
tc := tc
110+
t.Run(tc.name, func(t *testing.T) {
111+
t.Parallel()
112+
113+
// First, we'll set up our series of mocks, and then
114+
// record the intended responses for each of them.
115+
mockCommitter := &MockSupplyCommitManager{}
116+
mockDelegationChecker := &MockDelegationKeyChecker{}
117+
118+
// Set up delegation key checker responses
119+
for assetID, hasKey := range tc.delegationKeyResponses {
120+
mockDelegationChecker.On(
121+
"HasDelegationKey", ctx, assetID,
122+
).Return(hasKey, nil)
123+
}
124+
125+
// If we're expecting any calls, then we'll make sure to
126+
// register that here.
127+
if tc.expectedCallCount > 0 {
128+
//nolint:lll
129+
mockCommitter.On("SendMintEvent",
130+
ctx,
131+
mock.AnythingOfType("asset.Specifier"),
132+
mock.AnythingOfType(
133+
"universe.AssetLeafKey",
134+
),
135+
mock.AnythingOfType("universe.Leaf")).
136+
Return(nil).
137+
Times(tc.expectedCallCount)
138+
}
139+
140+
// With the mocks registered above, we'll create a new
141+
// care taker instance that uses them.
142+
caretaker := &BatchCaretaker{
143+
cfg: &BatchCaretakerConfig{ //nolint:lll
144+
GardenKit: GardenKit{
145+
MintSupplyCommitter: mockCommitter,
146+
DelegationKeyChecker: mockDelegationChecker,
147+
},
148+
},
149+
}
150+
151+
// Next, we'll create a series of proofs for each of the
152+
// assets.
153+
proofs := make(proof.AssetProofs)
154+
dummyTx := &wire.MsgTx{
155+
Version: 2,
156+
TxIn: []*wire.TxIn{{
157+
PreviousOutPoint: wire.OutPoint{},
158+
SignatureScript: []byte{},
159+
Sequence: 0xffffffff,
160+
}},
161+
}
162+
block := wire.MsgBlock{
163+
Header: wire.BlockHeader{
164+
Version: 1,
165+
Timestamp: time.Now(),
166+
Bits: 0x207fffff,
167+
},
168+
Transactions: []*wire.MsgTx{dummyTx},
169+
}
170+
for i, a := range tc.assets {
171+
scriptKey := asset.ToSerialized(
172+
a.ScriptKey.PubKey,
173+
)
174+
testProof := proof.RandProof(
175+
t, a.Genesis, a.ScriptKey.PubKey, block,
176+
0, uint32(i),
177+
)
178+
proofs[scriptKey] = &testProof
179+
}
180+
181+
// Call the internal method, then verify the expected
182+
// calls were made.
183+
err := caretaker.sendSupplyCommitEvents(
184+
ctx, tc.assets, nil, proofs,
185+
)
186+
require.NoError(t, err)
187+
mockCommitter.AssertExpectations(t)
188+
mockDelegationChecker.AssertExpectations(t)
189+
})
190+
}
191+
}

0 commit comments

Comments
 (0)