Skip to content

Commit 9d39297

Browse files
feat: some UTs
1 parent 9282aa0 commit 9d39297

File tree

3 files changed

+219
-3
lines changed

3 files changed

+219
-3
lines changed

aggsender/query/ger_query.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ import (
1313
"github.com/ethereum/go-ethereum/common"
1414
)
1515

16+
var createAgglayerGERL1func = func(gerAddr common.Address, l1Client aggkittypes.BaseEthereumClienter) (types.AgglayerGER, error) {
17+
return agglayerger.NewAgglayerger(gerAddr, l1Client)
18+
}
19+
1620
var _ types.L2GERQuerier = (*l2GERDataQuerier)(nil)
1721

1822
// l2GERDataQuerier is a struct that holds the logic to query the GER (Global Exit Root) data
@@ -118,7 +122,7 @@ func NewL1GERDataQuerier(
118122
blockFinality aggkittypes.BlockNumberFinality,
119123
l1Client aggkittypes.BaseEthereumClienter,
120124
) (types.L1GERQuerier, error) {
121-
agglayerGER, err := agglayerger.NewAgglayerger(l1AgglayerGERAddr, l1Client)
125+
agglayerGER, err := createAgglayerGERL1func(l1AgglayerGERAddr, l1Client)
122126
if err != nil {
123127
return nil, fmt.Errorf("failed to initialize L1 GER manager contract: %v", err)
124128
}

aggsender/query/ger_query_test.go

Lines changed: 172 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@ package query
33
import (
44
"context"
55
"errors"
6+
"math/big"
67
"testing"
78

89
agglayertypes "github.com/agglayer/aggkit/agglayer/types"
910
"github.com/agglayer/aggkit/aggsender/mocks"
11+
"github.com/agglayer/aggkit/aggsender/types"
1012
"github.com/agglayer/aggkit/l1infotreesync"
1113
"github.com/agglayer/aggkit/l2gersync"
1214
treetypes "github.com/agglayer/aggkit/tree/types"
15+
aggkittypes "github.com/agglayer/aggkit/types"
16+
aggkittypesmocks "github.com/agglayer/aggkit/types/mocks"
17+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
1318
"github.com/ethereum/go-ethereum/common"
19+
ethtypes "github.com/ethereum/go-ethereum/core/types"
20+
"github.com/stretchr/testify/mock"
1421
"github.com/stretchr/testify/require"
1522
)
1623

@@ -88,7 +95,6 @@ func Test_GetInjectedGERsProofs(t *testing.T) {
8895
}
8996

9097
for _, tc := range testCases {
91-
tc := tc
9298
t.Run(tc.name, func(t *testing.T) {
9399
t.Parallel()
94100

@@ -198,7 +204,6 @@ func Test_GetRemovedGERsForRange(t *testing.T) {
198204
}
199205

200206
for _, tc := range testCases {
201-
tc := tc
202207
t.Run(tc.name, func(t *testing.T) {
203208
t.Parallel()
204209

@@ -220,3 +225,168 @@ func Test_GetRemovedGERsForRange(t *testing.T) {
220225
})
221226
}
222227
}
228+
229+
func Test_NewL1GERDataQuerier(t *testing.T) {
230+
t.Run("error initializing L1 GER manager contract", func(t *testing.T) {
231+
createAgglayerGERL1func = func(_ common.Address, _ aggkittypes.BaseEthereumClienter) (types.AgglayerGER, error) {
232+
return nil, errors.New("some error")
233+
}
234+
235+
_, err := NewL1GERDataQuerier(
236+
common.HexToAddress("0x1"),
237+
aggkittypes.FinalizedBlock,
238+
aggkittypesmocks.NewBaseEthereumClienter(t),
239+
)
240+
require.ErrorContains(t, err, "failed to initialize L1 GER manager contract: some error")
241+
})
242+
243+
t.Run("success", func(t *testing.T) {
244+
createAgglayerGERL1func = func(_ common.Address, _ aggkittypes.BaseEthereumClienter) (types.AgglayerGER, error) {
245+
return mocks.NewAgglayerGER(t), nil
246+
}
247+
248+
gerQuerier, err := NewL1GERDataQuerier(
249+
common.HexToAddress("0x1"),
250+
aggkittypes.FinalizedBlock,
251+
aggkittypesmocks.NewBaseEthereumClienter(t),
252+
)
253+
require.NoError(t, err)
254+
require.NotNil(t, gerQuerier)
255+
})
256+
}
257+
258+
func Test_L1GERDataQuerier_DoesGERExistOnContract(t *testing.T) {
259+
t.Parallel()
260+
261+
testCases := []struct {
262+
name string
263+
ger common.Hash
264+
blockFinality *aggkittypes.BlockNumberFinality
265+
mockFn func(*mocks.AgglayerGER, *aggkittypesmocks.BaseEthereumClienter)
266+
expectedExist bool
267+
expectedError string
268+
}{
269+
{
270+
name: "error getting block number for finality",
271+
ger: common.HexToHash("0x1"),
272+
mockFn: func(mockAgglayerGER *mocks.AgglayerGER, mockL1Client *aggkittypesmocks.BaseEthereumClienter) {
273+
mockL1Client.EXPECT().HeaderByNumber(
274+
t.Context(),
275+
big.NewInt(int64(aggkittypes.Finalized)),
276+
).Return(nil, errors.New("some error"))
277+
},
278+
expectedError: "error getting block number for finality FinalizedBlock: some error",
279+
},
280+
{
281+
name: "error querying GER existence on contract",
282+
ger: common.HexToHash("0x1"),
283+
mockFn: func(mockAgglayerGER *mocks.AgglayerGER, mockL1Client *aggkittypesmocks.BaseEthereumClienter) {
284+
mockL1Client.EXPECT().HeaderByNumber(
285+
t.Context(),
286+
big.NewInt(int64(aggkittypes.Finalized)),
287+
).Return(&ethtypes.Header{Number: big.NewInt(100)}, nil)
288+
mockAgglayerGER.EXPECT().GlobalExitRootMap(
289+
&bind.CallOpts{
290+
Context: t.Context(),
291+
BlockNumber: big.NewInt(100),
292+
},
293+
mock.Anything,
294+
).Return(nil, errors.New("some error"))
295+
},
296+
expectedError: "error querying GER existence on contract: some error",
297+
},
298+
{
299+
name: "GER does not exist",
300+
ger: common.HexToHash("0x1"),
301+
mockFn: func(mockAgglayerGER *mocks.AgglayerGER, mockL1Client *aggkittypesmocks.BaseEthereumClienter) {
302+
mockL1Client.EXPECT().HeaderByNumber(
303+
t.Context(),
304+
big.NewInt(int64(aggkittypes.Finalized)),
305+
).Return(&ethtypes.Header{Number: big.NewInt(100)}, nil)
306+
mockAgglayerGER.EXPECT().GlobalExitRootMap(
307+
&bind.CallOpts{
308+
Context: t.Context(),
309+
BlockNumber: big.NewInt(100),
310+
},
311+
mock.Anything,
312+
).Return(common.Big0, nil)
313+
},
314+
expectedExist: false,
315+
},
316+
{
317+
name: "GER exists",
318+
ger: common.HexToHash("0x1"),
319+
mockFn: func(mockAgglayerGER *mocks.AgglayerGER, mockL1Client *aggkittypesmocks.BaseEthereumClienter) {
320+
mockL1Client.EXPECT().HeaderByNumber(
321+
t.Context(),
322+
big.NewInt(int64(aggkittypes.Finalized)),
323+
).Return(&ethtypes.Header{Number: big.NewInt(100)}, nil)
324+
mockAgglayerGER.EXPECT().GlobalExitRootMap(
325+
&bind.CallOpts{
326+
Context: t.Context(),
327+
BlockNumber: big.NewInt(100),
328+
},
329+
mock.Anything,
330+
).Return(big.NewInt(12345), nil)
331+
},
332+
expectedExist: true,
333+
},
334+
{
335+
name: "GER exists with block finality with offset",
336+
ger: common.HexToHash("0x1"),
337+
blockFinality: &aggkittypes.BlockNumberFinality{
338+
Block: aggkittypes.Latest,
339+
Offset: -6,
340+
},
341+
mockFn: func(mockAgglayerGER *mocks.AgglayerGER, mockL1Client *aggkittypesmocks.BaseEthereumClienter) {
342+
mockL1Client.EXPECT().HeaderByNumber(
343+
t.Context(),
344+
(*big.Int)(nil),
345+
).Return(&ethtypes.Header{Number: big.NewInt(200)}, nil)
346+
mockAgglayerGER.EXPECT().GlobalExitRootMap(
347+
&bind.CallOpts{
348+
Context: t.Context(),
349+
BlockNumber: big.NewInt(194),
350+
},
351+
mock.Anything,
352+
).Return(big.NewInt(67890), nil)
353+
},
354+
expectedExist: true,
355+
},
356+
}
357+
358+
for _, tc := range testCases {
359+
t.Run(tc.name, func(t *testing.T) {
360+
t.Parallel()
361+
362+
mockAgglayerGER := mocks.NewAgglayerGER(t)
363+
mockL1Client := aggkittypesmocks.NewBaseEthereumClienter(t)
364+
365+
blockFinality := aggkittypes.FinalizedBlock
366+
if tc.blockFinality != nil {
367+
blockFinality = *tc.blockFinality
368+
}
369+
370+
gerQuerier := &l1GERDataQuerier{
371+
blockFinality: blockFinality,
372+
agglayerGER: mockAgglayerGER,
373+
l1Client: mockL1Client,
374+
}
375+
376+
if tc.mockFn != nil {
377+
tc.mockFn(mockAgglayerGER, mockL1Client)
378+
}
379+
380+
exists, err := gerQuerier.DoesGERExistOnContract(t.Context(), tc.ger)
381+
if tc.expectedError != "" {
382+
require.ErrorContains(t, err, tc.expectedError)
383+
} else {
384+
require.NoError(t, err)
385+
require.Equal(t, tc.expectedExist, exists)
386+
}
387+
388+
mockAgglayerGER.AssertExpectations(t)
389+
mockL1Client.AssertExpectations(t)
390+
})
391+
}
392+
}

aggsender/validator/config_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
aggsendertypes "github.com/agglayer/aggkit/aggsender/types"
99
"github.com/agglayer/aggkit/config/types"
1010
"github.com/agglayer/aggkit/grpc"
11+
aggkittypes "github.com/agglayer/aggkit/types"
1112
"github.com/ethereum/go-ethereum/common"
1213
"github.com/stretchr/testify/require"
1314
)
@@ -24,6 +25,10 @@ func TestValidatorConfigValidate(t *testing.T) {
2425
name: "Valid PessimisticProof mode",
2526
config: Config{
2627
Mode: aggsendertypes.PessimisticProofMode,
28+
GERValidateConfig: GERValidateConfig{
29+
GlobalExitRootL1Addr: common.HexToAddress("0x2"),
30+
BlockFinality: aggkittypes.FinalizedBlock,
31+
},
2732
AgglayerClient: agglayer.ClientConfig{GRPC: &grpc.ClientConfig{
2833
URL: "http://localhost:9090",
2934
MinConnectTimeout: types.NewDuration(5 * time.Second),
@@ -37,11 +42,48 @@ func TestValidatorConfigValidate(t *testing.T) {
3742
FEPConfig: FEPConfig{
3843
SovereignRollupAddr: common.HexToAddress("0x1"),
3944
},
45+
GERValidateConfig: GERValidateConfig{
46+
GlobalExitRootL1Addr: common.HexToAddress("0x2"),
47+
BlockFinality: aggkittypes.FinalizedBlock,
48+
},
49+
AgglayerClient: agglayer.ClientConfig{GRPC: &grpc.ClientConfig{
50+
URL: "http://localhost:9090",
51+
MinConnectTimeout: types.NewDuration(5 * time.Second),
52+
}},
53+
},
54+
},
55+
{
56+
name: "Invalid GERValidateConfig - zero address",
57+
config: Config{
58+
Mode: aggsendertypes.PessimisticProofMode,
59+
GERValidateConfig: GERValidateConfig{
60+
GlobalExitRootL1Addr: common.HexToAddress("0x0"), // Zero address
61+
BlockFinality: aggkittypes.FinalizedBlock,
62+
},
63+
AgglayerClient: agglayer.ClientConfig{GRPC: &grpc.ClientConfig{
64+
URL: "http://localhost:9090",
65+
MinConnectTimeout: types.NewDuration(5 * time.Second),
66+
}},
67+
},
68+
expectedErr: "GlobalExitRootL1Addr must be set",
69+
},
70+
{
71+
name: "Invalid GERValidateConfig - block finality non valid",
72+
config: Config{
73+
Mode: aggsendertypes.PessimisticProofMode,
74+
GERValidateConfig: GERValidateConfig{
75+
GlobalExitRootL1Addr: common.HexToAddress("0x2"),
76+
BlockFinality: aggkittypes.BlockNumberFinality{
77+
Block: aggkittypes.Finalized,
78+
Offset: aggkittypes.MaxPositiveOffsetFinalized + 1, // Invalid offset
79+
},
80+
},
4081
AgglayerClient: agglayer.ClientConfig{GRPC: &grpc.ClientConfig{
4182
URL: "http://localhost:9090",
4283
MinConnectTimeout: types.NewDuration(5 * time.Second),
4384
}},
4485
},
86+
expectedErr: "invalid BlockFinality configuration",
4587
},
4688
{
4789
name: "Invalid AggchainProof mode",

0 commit comments

Comments
 (0)