@@ -3,14 +3,21 @@ package query
33import (
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+ }
0 commit comments