diff --git a/aggoracle/chaingersender/evm.go b/aggoracle/chaingersender/evm.go index 0965178d..adfb1950 100644 --- a/aggoracle/chaingersender/evm.go +++ b/aggoracle/chaingersender/evm.go @@ -43,6 +43,10 @@ type EthTxManager interface { ) (common.Hash, error) } +type L2GERManager interface { + GlobalExitRootMap(opts *bind.CallOpts, ger [common.HashLength]byte) (*big.Int, error) +} + type EVMConfig struct { GlobalExitRootL2Addr common.Address `mapstructure:"GlobalExitRootL2"` URLRPCL2 string `mapstructure:"URLRPCL2"` @@ -55,7 +59,7 @@ type EVMConfig struct { type EVMChainGERSender struct { logger *log.Logger - l2GERManager *globalexitrootmanagerl2sovereignchain.Globalexitrootmanagerl2sovereignchain + l2GERManager L2GERManager l2GERManagerAddr common.Address l2GERManagerAbi *abi.ABI diff --git a/aggoracle/chaingersender/evm_test.go b/aggoracle/chaingersender/evm_test.go index db5d7a62..ad1cb5af 100644 --- a/aggoracle/chaingersender/evm_test.go +++ b/aggoracle/chaingersender/evm_test.go @@ -35,8 +35,6 @@ func TestEVMChainGERSender_InjectGER(t *testing.T) { l2GERManagerAbi, err := abi.JSON(strings.NewReader(insertGERFuncABI)) require.NoError(t, err) - gasOffset := uint64(1000) - ger := common.HexToHash("0x456") txID := common.HexToHash("0x789") @@ -88,15 +86,18 @@ func TestEVMChainGERSender_InjectGER(t *testing.T) { defer cancelFn() ethTxMan := new(mocks.EthTxManagerMock) - ethTxMan.On("Add", ctx, &l2GERManagerAddr, common.Big0, mock.Anything, gasOffset, mock.Anything).Return(tt.addReturnTxID, tt.addReturnErr) - ethTxMan.On("Result", ctx, tt.addReturnTxID).Return(tt.resultReturn, tt.resultReturnErr) + ethTxMan. + On("Add", ctx, &l2GERManagerAddr, common.Big0, mock.Anything, mock.Anything, mock.Anything). + Return(tt.addReturnTxID, tt.addReturnErr) + ethTxMan. + On("Result", ctx, tt.addReturnTxID). + Return(tt.resultReturn, tt.resultReturnErr) sender := &EVMChainGERSender{ logger: log.GetDefaultLogger(), l2GERManagerAddr: l2GERManagerAddr, l2GERManagerAbi: &l2GERManagerAbi, ethTxMan: ethTxMan, - gasOffset: gasOffset, waitPeriodMonitorTx: time.Millisecond * 10, } @@ -110,3 +111,58 @@ func TestEVMChainGERSender_InjectGER(t *testing.T) { }) } } + +func TestEVMChainGERSender_IsGERInjected(t *testing.T) { + tests := []struct { + name string + mockReturn *big.Int + mockError error + expectedResult bool + expectedErrMsg string + }{ + { + name: "GER is injected", + mockReturn: big.NewInt(1), + mockError: nil, + expectedResult: true, + expectedErrMsg: "", + }, + { + name: "GER is not injected", + mockReturn: big.NewInt(0), + mockError: nil, + expectedResult: false, + expectedErrMsg: "", + }, + { + name: "Error checking GER injection", + mockReturn: nil, + mockError: errors.New("some error"), + expectedResult: false, + expectedErrMsg: "failed to check if global exit root is injected", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockL2GERManager := new(mocks.L2GERManagerMock) + mockL2GERManager.On("GlobalExitRootMap", mock.Anything, mock.Anything). + Return(tt.mockReturn, tt.mockError) + + evmChainGERSender := &EVMChainGERSender{ + l2GERManager: mockL2GERManager, + } + + ger := common.HexToHash("0x12345") + result, err := evmChainGERSender.IsGERInjected(ger) + if tt.expectedErrMsg != "" { + require.ErrorContains(t, err, tt.expectedErrMsg) + } else { + require.NoError(t, err) + } + require.Equal(t, tt.expectedResult, result) + + mockL2GERManager.AssertExpectations(t) + }) + } +} diff --git a/aggoracle/mocks/mock_l2germanager.go b/aggoracle/mocks/mock_l2germanager.go new file mode 100644 index 00000000..a7ec0296 --- /dev/null +++ b/aggoracle/mocks/mock_l2germanager.go @@ -0,0 +1,97 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + big "math/big" + + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + + mock "github.com/stretchr/testify/mock" +) + +// L2GERManagerMock is an autogenerated mock type for the L2GERManager type +type L2GERManagerMock struct { + mock.Mock +} + +type L2GERManagerMock_Expecter struct { + mock *mock.Mock +} + +func (_m *L2GERManagerMock) EXPECT() *L2GERManagerMock_Expecter { + return &L2GERManagerMock_Expecter{mock: &_m.Mock} +} + +// GlobalExitRootMap provides a mock function with given fields: opts, ger +func (_m *L2GERManagerMock) GlobalExitRootMap(opts *bind.CallOpts, ger [32]byte) (*big.Int, error) { + ret := _m.Called(opts, ger) + + if len(ret) == 0 { + panic("no return value specified for GlobalExitRootMap") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) (*big.Int, error)); ok { + return rf(opts, ger) + } + if rf, ok := ret.Get(0).(func(*bind.CallOpts, [32]byte) *big.Int); ok { + r0 = rf(opts, ger) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*bind.CallOpts, [32]byte) error); ok { + r1 = rf(opts, ger) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// L2GERManagerMock_GlobalExitRootMap_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GlobalExitRootMap' +type L2GERManagerMock_GlobalExitRootMap_Call struct { + *mock.Call +} + +// GlobalExitRootMap is a helper method to define mock.On call +// - opts *bind.CallOpts +// - ger [32]byte +func (_e *L2GERManagerMock_Expecter) GlobalExitRootMap(opts interface{}, ger interface{}) *L2GERManagerMock_GlobalExitRootMap_Call { + return &L2GERManagerMock_GlobalExitRootMap_Call{Call: _e.mock.On("GlobalExitRootMap", opts, ger)} +} + +func (_c *L2GERManagerMock_GlobalExitRootMap_Call) Run(run func(opts *bind.CallOpts, ger [32]byte)) *L2GERManagerMock_GlobalExitRootMap_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bind.CallOpts), args[1].([32]byte)) + }) + return _c +} + +func (_c *L2GERManagerMock_GlobalExitRootMap_Call) Return(_a0 *big.Int, _a1 error) *L2GERManagerMock_GlobalExitRootMap_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *L2GERManagerMock_GlobalExitRootMap_Call) RunAndReturn(run func(*bind.CallOpts, [32]byte) (*big.Int, error)) *L2GERManagerMock_GlobalExitRootMap_Call { + _c.Call.Return(run) + return _c +} + +// NewL2GERManagerMock creates a new instance of L2GERManagerMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewL2GERManagerMock(t interface { + mock.TestingT + Cleanup(func()) +}) *L2GERManagerMock { + mock := &L2GERManagerMock{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/test/Makefile b/test/Makefile index ebb6d28c..38bf5013 100644 --- a/test/Makefile +++ b/test/Makefile @@ -47,6 +47,7 @@ generate-mocks-helpers: ## Generates mocks for helpers, using mockery tool generate-mocks-aggoracle: ## Generates mocks for aggoracle, using mockery tool rm -Rf ../aggoracle/mocks export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthTxManager --dir ../aggoracle/chaingersender --output ../aggoracle/mocks --outpkg mocks --structname=EthTxManagerMock --filename=mock_ethtxmanager.go ${COMMON_MOCKERY_PARAMS} + export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=L2GERManager --dir ../aggoracle/chaingersender --output ../aggoracle/mocks --outpkg mocks --structname=L2GERManagerMock --filename=mock_l2germanager.go ${COMMON_MOCKERY_PARAMS} .PHONY: generate-mocks-sync generate-mocks-sync: ## Generates mocks for sync, using mockery tool