From 093336f82b25547a34cdf421d5896b4fe6f9244f Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 13 Oct 2023 15:45:55 +0200 Subject: [PATCH 1/4] Add listener tests --- Makefile | 3 + chains/evm/listener/listener.go | 13 +- chains/evm/listener/listener_test.go | 311 ++++++++++++--------------- chains/evm/listener/mock/handler.go | 93 ++++++++ chains/evm/listener/mock/listener.go | 153 +++++++++---- 5 files changed, 349 insertions(+), 224 deletions(-) create mode 100644 chains/evm/listener/mock/handler.go diff --git a/Makefile b/Makefile index 30cb182c..2180b72c 100644 --- a/Makefile +++ b/Makefile @@ -42,3 +42,6 @@ genmocks: mockgen -destination=./chains/evm/calls/transactor/itx//mock/minimalForwarder.go -source=./chains/evm/calls/transactor/itx/minimalForwarder.go mockgen -destination=chains/evm/cli/bridge/mock/vote-proposal.go -source=./chains/evm/cli/bridge/vote-proposal.go mockgen -destination=chains/evm/listener/mock/listener.go -source=./chains/evm/listener/event-handler.go + mockgen -destination=chains/evm/cli/bridge/mock/vote-proposal.go -source=./chains/evm/cli/bridge/vote-proposal.go + mockgen -destination=chains/evm/listener/mock/listener.go -source=./chains/evm/listener/event-handler.go + diff --git a/chains/evm/listener/listener.go b/chains/evm/listener/listener.go index 84408ac6..8a910e08 100644 --- a/chains/evm/listener/listener.go +++ b/chains/evm/listener/listener.go @@ -9,7 +9,6 @@ import ( "time" "github.com/ChainSafe/chainbridge-core/relayer/message" - "github.com/ChainSafe/chainbridge-core/store" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -27,13 +26,17 @@ type BlockDeltaMeter interface { TrackBlockDelta(domainID uint8, head *big.Int, current *big.Int) } +type BlockStorer interface { + StoreBlock(block *big.Int, domainID uint8) error +} + type EVMListener struct { client ChainClient eventHandlers []EventHandler metrics BlockDeltaMeter domainID uint8 - blockstore *store.BlockStore + blockstore BlockStorer blockRetryInterval time.Duration blockConfirmations *big.Int blockInterval *big.Int @@ -46,7 +49,7 @@ type EVMListener struct { func NewEVMListener( client ChainClient, eventHandlers []EventHandler, - blockstore *store.BlockStore, + blockstore BlockStorer, metrics BlockDeltaMeter, domainID uint8, blockRetryInterval time.Duration, @@ -70,6 +73,7 @@ func NewEVMListener( // configured for the listener. func (l *EVMListener) ListenToEvents(ctx context.Context, startBlock *big.Int, msgChan chan []*message.Message, errChn chan<- error) { endBlock := big.NewInt(0) +loop: for { select { case <-ctx.Done(): @@ -99,8 +103,9 @@ func (l *EVMListener) ListenToEvents(ctx context.Context, startBlock *big.Int, m err := handler.HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan) if err != nil { l.log.Error().Err(err).Msgf("Unable to handle events") - continue + continue loop } + } //Write to block store. Not a critical operation, no need to retry diff --git a/chains/evm/listener/listener_test.go b/chains/evm/listener/listener_test.go index c4787475..513e6455 100644 --- a/chains/evm/listener/listener_test.go +++ b/chains/evm/listener/listener_test.go @@ -1,209 +1,166 @@ package listener_test import ( - "errors" + "context" + "fmt" "math/big" "testing" + "time" - "github.com/ChainSafe/chainbridge-core/chains/evm/calls/events" "github.com/ChainSafe/chainbridge-core/chains/evm/listener" + mock_listener "github.com/ChainSafe/chainbridge-core/chains/evm/listener/mock" "github.com/ChainSafe/chainbridge-core/relayer/message" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/suite" ) -var errIncorrectCalldataLen = errors.New("invalid calldata length: less than 84 bytes") - type ListenerTestSuite struct { suite.Suite + listener *listener.EVMListener + mockClient *mock_listener.MockChainClient + mockEventHandler *mock_listener.MockEventHandler + mockBlockStorer *mock_listener.MockBlockStorer + mockBlockDeltaMeter *mock_listener.MockBlockDeltaMeter + domainID uint8 } func TestRunTestSuite(t *testing.T) { suite.Run(t, new(ListenerTestSuite)) } -func (s *ListenerTestSuite) TestErc20HandleEvent() { - // 0xf1e58fb17704c2da8479a533f9fad4ad0993ca6b - recipientByteSlice := []byte{241, 229, 143, 177, 119, 4, 194, 218, 132, 121, 165, 51, 249, 250, 212, 173, 9, 147, 202, 107} - - // construct ERC20 deposit data - // follows behavior of solidity tests - // https://github.com/ChainSafe/chainbridge-solidity/blob/develop/test/contractBridge/depositERC20.js#L46-L50 - var calldata []byte - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(2), 32)...) - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(int64(len(recipientByteSlice))), 32)...) - calldata = append(calldata, recipientByteSlice...) - - depositLog := &events.Deposit{ - DestinationDomainID: 0, - ResourceID: [32]byte{0}, - DepositNonce: 1, - SenderAddress: common.HexToAddress("0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485"), - Data: calldata, - HandlerResponse: []byte{}, - } - - sourceID := uint8(1) - amountParsed := calldata[:32] - recipientAddressParsed := calldata[64:] - - expected := &message.Message{ - Source: sourceID, - Destination: depositLog.DestinationDomainID, - DepositNonce: depositLog.DepositNonce, - ResourceId: depositLog.ResourceID, - Type: message.FungibleTransfer, - Payload: []interface{}{ - amountParsed, - recipientAddressParsed, - }, - } - - m, err := listener.Erc20DepositHandler(sourceID, depositLog.DestinationDomainID, depositLog.DepositNonce, depositLog.ResourceID, depositLog.Data, depositLog.HandlerResponse) - s.Nil(err) - s.NotNil(m) - s.Equal(m, expected) +func (s *ListenerTestSuite) SetupTest() { + ctrl := gomock.NewController(s.T()) + s.domainID = 1 + s.mockClient = mock_listener.NewMockChainClient(ctrl) + s.mockEventHandler = mock_listener.NewMockEventHandler(ctrl) + s.mockBlockStorer = mock_listener.NewMockBlockStorer(ctrl) + s.mockBlockDeltaMeter = mock_listener.NewMockBlockDeltaMeter(ctrl) + s.listener = listener.NewEVMListener( + s.mockClient, + []listener.EventHandler{s.mockEventHandler, s.mockEventHandler}, + s.mockBlockStorer, + s.mockBlockDeltaMeter, + s.domainID, + time.Millisecond*75, + big.NewInt(5), + big.NewInt(5)) } -func (s *ListenerTestSuite) TestErc20HandleEventIncorrectCalldataLen() { - // 0xf1e58fb17704c2da8479a533f9fad4ad0993ca6b - recipientByteSlice := []byte{241, 229, 143, 177, 119, 4, 194, 218, 132, 121, 165, 51, 249, 250, 212, 173, 9, 147, 202, 107} - - // construct ERC20 deposit data - // follows behavior of solidity tests - // https://github.com/ChainSafe/chainbridge-solidity/blob/develop/test/contractBridge/depositERC20.js#L46-L50 - var calldata []byte - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(2), 16)...) - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(int64(len(recipientByteSlice))), 16)...) - calldata = append(calldata, recipientByteSlice...) - - depositLog := &events.Deposit{ - DestinationDomainID: 0, - ResourceID: [32]byte{0}, - DepositNonce: 1, - SenderAddress: common.HexToAddress("0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485"), - Data: calldata, - HandlerResponse: []byte{}, - } - - sourceID := uint8(1) - - m, err := listener.Erc20DepositHandler(sourceID, depositLog.DestinationDomainID, depositLog.DepositNonce, depositLog.ResourceID, depositLog.Data, depositLog.HandlerResponse) - s.Nil(m) - s.EqualError(err, errIncorrectCalldataLen.Error()) +func (s *ListenerTestSuite) Test_ListenToEvents_RetriesIfBlockUnavailable() { + s.mockClient.EXPECT().LatestBlock().Return(big.NewInt(0), fmt.Errorf("error")) + + ctx, cancel := context.WithCancel(context.Background()) + msgChan := make(chan []*message.Message, 2) + go s.listener.ListenToEvents(ctx, nil, msgChan, nil) + + time.Sleep(time.Millisecond * 50) + cancel() } -func (s *ListenerTestSuite) TestErc721HandleEvent_WithMetadata_Sucess() { - // 0xf1e58fb17704c2da8479a533f9fad4ad0993ca6b - recipientByteSlice := []byte{241, 229, 143, 177, 119, 4, 194, 218, 132, 121, 165, 51, 249, 250, 212, 173, 9, 147, 202, 107} - - metadataByteSlice := []byte{132, 121, 165, 51, 119, 4, 194, 218, 249, 250, 250, 212, 173, 9, 147, 218, 249, 250, 250, 4, 194, 218, 132, 121, 194, 218, 132, 121, 194, 218, 132, 121} - - var calldata []byte - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(2), 32)...) - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(int64(len(recipientByteSlice))), 32)...) - calldata = append(calldata, recipientByteSlice...) - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(int64(len(metadataByteSlice))), 32)...) - calldata = append(calldata, metadataByteSlice...) - - depositLog := &events.Deposit{ - DestinationDomainID: 0, - ResourceID: [32]byte{0}, - DepositNonce: 1, - SenderAddress: common.HexToAddress("0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485"), - Data: calldata, - HandlerResponse: []byte{}, - } - - sourceID := uint8(1) - tokenIdParsed := calldata[:32] - recipientAddressParsed := calldata[64:84] - metadataParsed := calldata[116:] - - expected := &message.Message{ - Source: sourceID, - Destination: depositLog.DestinationDomainID, - DepositNonce: depositLog.DepositNonce, - ResourceId: depositLog.ResourceID, - Type: message.NonFungibleTransfer, - Payload: []interface{}{ - tokenIdParsed, - recipientAddressParsed, - metadataParsed, - }, - } - - m, err := listener.Erc721DepositHandler(sourceID, depositLog.DestinationDomainID, depositLog.DepositNonce, depositLog.ResourceID, depositLog.Data, depositLog.HandlerResponse) - s.Nil(err) - s.NotNil(m) - s.Equal(expected, m) +func (s *ListenerTestSuite) Test_ListenToEvents_SleepsIfBlockTooNew() { + s.mockClient.EXPECT().LatestBlock().Return(big.NewInt(109), nil) + + ctx, cancel := context.WithCancel(context.Background()) + msgChan := make(chan []*message.Message, 2) + + go s.listener.ListenToEvents(ctx, big.NewInt(100), msgChan, nil) + + time.Sleep(time.Millisecond * 50) + cancel() } -func (s *ListenerTestSuite) TestErc721HandleEvent_WithoutMetadata_Success() { - // 0xf1e58fb17704c2da8479a533f9fad4ad0993ca6b - recipientByteSlice := []byte{241, 229, 143, 177, 119, 4, 194, 218, 132, 121, 165, 51, 249, 250, 212, 173, 9, 147, 202, 107} - - var calldata []byte - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(2), 32)...) - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(int64(len(recipientByteSlice))), 32)...) - calldata = append(calldata, recipientByteSlice...) - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(int64(0)), 32)...) - - depositLog := &events.Deposit{ - DestinationDomainID: 0, - ResourceID: [32]byte{0}, - DepositNonce: 1, - SenderAddress: common.HexToAddress("0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485"), - Data: calldata, - HandlerResponse: []byte{}, - } - - sourceID := uint8(1) - tokenIdParsed := calldata[:32] - recipientAddressParsed := calldata[64:84] - var metadataParsed []byte - - expected := &message.Message{ - Source: sourceID, - Destination: depositLog.DestinationDomainID, - DepositNonce: depositLog.DepositNonce, - ResourceId: depositLog.ResourceID, - Type: message.NonFungibleTransfer, - Payload: []interface{}{ - tokenIdParsed, - recipientAddressParsed, - metadataParsed, - }, - } - - m, err := listener.Erc721DepositHandler(sourceID, depositLog.DestinationDomainID, depositLog.DepositNonce, depositLog.ResourceID, depositLog.Data, depositLog.HandlerResponse) - s.Nil(err) - s.NotNil(m) - s.Equal(expected, m) +func (s *ListenerTestSuite) Test_ListenToEvents_RetriesInCaseOfHandlerFailure() { + startBlock := big.NewInt(100) + endBlock := big.NewInt(105) + head := big.NewInt(110) + msgChan := make(chan []*message.Message, 2) + + // First pass + s.mockClient.EXPECT().LatestBlock().Return(head, nil) + s.mockBlockDeltaMeter.EXPECT().TrackBlockDelta(uint8(1), head, endBlock) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(fmt.Errorf("error")) + // Second pass + s.mockClient.EXPECT().LatestBlock().Return(head, nil) + s.mockBlockDeltaMeter.EXPECT().TrackBlockDelta(uint8(1), head, endBlock) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockBlockStorer.EXPECT().StoreBlock(endBlock, s.domainID).Return(nil) + // third pass + s.mockClient.EXPECT().LatestBlock().Return(head, nil) + + ctx, cancel := context.WithCancel(context.Background()) + + go s.listener.ListenToEvents(ctx, big.NewInt(100), msgChan, nil) + + time.Sleep(time.Millisecond * 50) + cancel() } -func (s *ListenerTestSuite) TestErc721HandleEvent_IncorrectCalldataLen_Failure() { - recipientByteSlice := []byte{241, 229, 143, 177, 119, 4, 194} +func (s *ListenerTestSuite) Test_ListenToEvents_StoresBlockIfEventHandlingSuccessful() { + startBlock := big.NewInt(100) + endBlock := big.NewInt(105) + head := big.NewInt(110) + msgChan := make(chan []*message.Message, 2) + + s.mockClient.EXPECT().LatestBlock().Return(head, nil) + // prevent infinite runs + s.mockClient.EXPECT().LatestBlock().Return(big.NewInt(95), nil) + s.mockBlockDeltaMeter.EXPECT().TrackBlockDelta(uint8(1), head, endBlock) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockBlockStorer.EXPECT().StoreBlock(endBlock, s.domainID).Return(nil) + + ctx, cancel := context.WithCancel(context.Background()) + + go s.listener.ListenToEvents(ctx, big.NewInt(100), msgChan, nil) + + time.Sleep(time.Millisecond * 50) + cancel() +} + +func (s *ListenerTestSuite) Test_ListenToEvents_IgnoresBlocStorerError() { + startBlock := big.NewInt(100) + endBlock := big.NewInt(105) + head := big.NewInt(110) + msgChan := make(chan []*message.Message, 2) + + s.mockClient.EXPECT().LatestBlock().Return(head, nil) + // prevent infinite runs + s.mockClient.EXPECT().LatestBlock().Return(big.NewInt(95), nil) + s.mockBlockDeltaMeter.EXPECT().TrackBlockDelta(uint8(1), head, endBlock) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockBlockStorer.EXPECT().StoreBlock(endBlock, s.domainID).Return(fmt.Errorf("error")) + + ctx, cancel := context.WithCancel(context.Background()) + + go s.listener.ListenToEvents(ctx, big.NewInt(100), msgChan, nil) + + time.Sleep(time.Millisecond * 50) + cancel() +} + +func (s *ListenerTestSuite) Test_ListenToEvents_UsesHeadAsStartBlockIfNilPassed() { + startBlock := big.NewInt(110) + endBlock := big.NewInt(115) + oldHead := big.NewInt(110) + newHead := big.NewInt(120) + msgChan := make(chan []*message.Message, 2) + + s.mockClient.EXPECT().LatestBlock().Return(oldHead, nil) + s.mockClient.EXPECT().LatestBlock().Return(newHead, nil) + s.mockClient.EXPECT().LatestBlock().Return(big.NewInt(65), nil) + + s.mockBlockDeltaMeter.EXPECT().TrackBlockDelta(uint8(1), big.NewInt(120), endBlock) - var calldata []byte - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(2), 32)...) - calldata = append(calldata, math.PaddedBigBytes(big.NewInt(int64(len(recipientByteSlice))), 16)...) - calldata = append(calldata, recipientByteSlice...) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockEventHandler.EXPECT().HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan).Return(nil) + s.mockBlockStorer.EXPECT().StoreBlock(endBlock, s.domainID).Return(nil) - depositLog := &events.Deposit{ - DestinationDomainID: 0, - ResourceID: [32]byte{0}, - DepositNonce: 1, - SenderAddress: common.HexToAddress("0x4CEEf6139f00F9F4535Ad19640Ff7A0137708485"), - Data: calldata, - HandlerResponse: []byte{}, - } + ctx, cancel := context.WithCancel(context.Background()) - sourceID := uint8(1) + go s.listener.ListenToEvents(ctx, nil, msgChan, nil) - m, err := listener.Erc721DepositHandler(sourceID, depositLog.DestinationDomainID, depositLog.DepositNonce, depositLog.ResourceID, depositLog.Data, depositLog.HandlerResponse) - s.Nil(m) - s.EqualError(err, errIncorrectCalldataLen.Error()) + time.Sleep(time.Millisecond * 100) + cancel() } diff --git a/chains/evm/listener/mock/handler.go b/chains/evm/listener/mock/handler.go new file mode 100644 index 00000000..b62f81b3 --- /dev/null +++ b/chains/evm/listener/mock/handler.go @@ -0,0 +1,93 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./chains/evm/listener/event-handler.go + +// Package mock_listener is a generated GoMock package. +package mock_listener + +import ( + context "context" + big "math/big" + reflect "reflect" + + events "github.com/ChainSafe/chainbridge-core/chains/evm/calls/events" + message "github.com/ChainSafe/chainbridge-core/relayer/message" + types "github.com/ChainSafe/chainbridge-core/types" + common "github.com/ethereum/go-ethereum/common" + gomock "github.com/golang/mock/gomock" +) + +// MockEventListener is a mock of EventListener interface. +type MockEventListener struct { + ctrl *gomock.Controller + recorder *MockEventListenerMockRecorder +} + +// MockEventListenerMockRecorder is the mock recorder for MockEventListener. +type MockEventListenerMockRecorder struct { + mock *MockEventListener +} + +// NewMockEventListener creates a new mock instance. +func NewMockEventListener(ctrl *gomock.Controller) *MockEventListener { + mock := &MockEventListener{ctrl: ctrl} + mock.recorder = &MockEventListenerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEventListener) EXPECT() *MockEventListenerMockRecorder { + return m.recorder +} + +// FetchDeposits mocks base method. +func (m *MockEventListener) FetchDeposits(ctx context.Context, address common.Address, startBlock, endBlock *big.Int) ([]*events.Deposit, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchDeposits", ctx, address, startBlock, endBlock) + ret0, _ := ret[0].([]*events.Deposit) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchDeposits indicates an expected call of FetchDeposits. +func (mr *MockEventListenerMockRecorder) FetchDeposits(ctx, address, startBlock, endBlock any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchDeposits", reflect.TypeOf((*MockEventListener)(nil).FetchDeposits), ctx, address, startBlock, endBlock) +} + +// MockDepositHandler is a mock of DepositHandler interface. +type MockDepositHandler struct { + ctrl *gomock.Controller + recorder *MockDepositHandlerMockRecorder +} + +// MockDepositHandlerMockRecorder is the mock recorder for MockDepositHandler. +type MockDepositHandlerMockRecorder struct { + mock *MockDepositHandler +} + +// NewMockDepositHandler creates a new mock instance. +func NewMockDepositHandler(ctrl *gomock.Controller) *MockDepositHandler { + mock := &MockDepositHandler{ctrl: ctrl} + mock.recorder = &MockDepositHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDepositHandler) EXPECT() *MockDepositHandlerMockRecorder { + return m.recorder +} + +// HandleDeposit mocks base method. +func (m *MockDepositHandler) HandleDeposit(sourceID, destID uint8, nonce uint64, resourceID types.ResourceID, calldata, handlerResponse []byte) (*message.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HandleDeposit", sourceID, destID, nonce, resourceID, calldata, handlerResponse) + ret0, _ := ret[0].(*message.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HandleDeposit indicates an expected call of HandleDeposit. +func (mr *MockDepositHandlerMockRecorder) HandleDeposit(sourceID, destID, nonce, resourceID, calldata, handlerResponse any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleDeposit", reflect.TypeOf((*MockDepositHandler)(nil).HandleDeposit), sourceID, destID, nonce, resourceID, calldata, handlerResponse) +} diff --git a/chains/evm/listener/mock/listener.go b/chains/evm/listener/mock/listener.go index 342315bd..0e5a0f2f 100644 --- a/chains/evm/listener/mock/listener.go +++ b/chains/evm/listener/mock/listener.go @@ -1,93 +1,160 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ./chains/evm/listener/event-handler.go +// Source: ./chains/evm/listener/listener.go // Package mock_listener is a generated GoMock package. package mock_listener import ( - context "context" big "math/big" reflect "reflect" - events "github.com/ChainSafe/chainbridge-core/chains/evm/calls/events" message "github.com/ChainSafe/chainbridge-core/relayer/message" - types "github.com/ChainSafe/chainbridge-core/types" - common "github.com/ethereum/go-ethereum/common" gomock "github.com/golang/mock/gomock" ) -// MockEventListener is a mock of EventListener interface. -type MockEventListener struct { +// MockEventHandler is a mock of EventHandler interface. +type MockEventHandler struct { ctrl *gomock.Controller - recorder *MockEventListenerMockRecorder + recorder *MockEventHandlerMockRecorder } -// MockEventListenerMockRecorder is the mock recorder for MockEventListener. -type MockEventListenerMockRecorder struct { - mock *MockEventListener +// MockEventHandlerMockRecorder is the mock recorder for MockEventHandler. +type MockEventHandlerMockRecorder struct { + mock *MockEventHandler } -// NewMockEventListener creates a new mock instance. -func NewMockEventListener(ctrl *gomock.Controller) *MockEventListener { - mock := &MockEventListener{ctrl: ctrl} - mock.recorder = &MockEventListenerMockRecorder{mock} +// NewMockEventHandler creates a new mock instance. +func NewMockEventHandler(ctrl *gomock.Controller) *MockEventHandler { + mock := &MockEventHandler{ctrl: ctrl} + mock.recorder = &MockEventHandlerMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockEventListener) EXPECT() *MockEventListenerMockRecorder { +func (m *MockEventHandler) EXPECT() *MockEventHandlerMockRecorder { return m.recorder } -// FetchDeposits mocks base method. -func (m *MockEventListener) FetchDeposits(ctx context.Context, address common.Address, startBlock, endBlock *big.Int) ([]*events.Deposit, error) { +// HandleEvent mocks base method. +func (m *MockEventHandler) HandleEvent(startBlock, endBlock *big.Int, msgChan chan []*message.Message) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchDeposits", ctx, address, startBlock, endBlock) - ret0, _ := ret[0].([]*events.Deposit) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "HandleEvent", startBlock, endBlock, msgChan) + ret0, _ := ret[0].(error) + return ret0 } -// FetchDeposits indicates an expected call of FetchDeposits. -func (mr *MockEventListenerMockRecorder) FetchDeposits(ctx, address, startBlock, endBlock interface{}) *gomock.Call { +// HandleEvent indicates an expected call of HandleEvent. +func (mr *MockEventHandlerMockRecorder) HandleEvent(startBlock, endBlock, msgChan any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchDeposits", reflect.TypeOf((*MockEventListener)(nil).FetchDeposits), ctx, address, startBlock, endBlock) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleEvent", reflect.TypeOf((*MockEventHandler)(nil).HandleEvent), startBlock, endBlock, msgChan) } -// MockDepositHandler is a mock of DepositHandler interface. -type MockDepositHandler struct { +// MockChainClient is a mock of ChainClient interface. +type MockChainClient struct { ctrl *gomock.Controller - recorder *MockDepositHandlerMockRecorder + recorder *MockChainClientMockRecorder } -// MockDepositHandlerMockRecorder is the mock recorder for MockDepositHandler. -type MockDepositHandlerMockRecorder struct { - mock *MockDepositHandler +// MockChainClientMockRecorder is the mock recorder for MockChainClient. +type MockChainClientMockRecorder struct { + mock *MockChainClient } -// NewMockDepositHandler creates a new mock instance. -func NewMockDepositHandler(ctrl *gomock.Controller) *MockDepositHandler { - mock := &MockDepositHandler{ctrl: ctrl} - mock.recorder = &MockDepositHandlerMockRecorder{mock} +// NewMockChainClient creates a new mock instance. +func NewMockChainClient(ctrl *gomock.Controller) *MockChainClient { + mock := &MockChainClient{ctrl: ctrl} + mock.recorder = &MockChainClientMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockDepositHandler) EXPECT() *MockDepositHandlerMockRecorder { +func (m *MockChainClient) EXPECT() *MockChainClientMockRecorder { return m.recorder } -// HandleDeposit mocks base method. -func (m *MockDepositHandler) HandleDeposit(sourceID, destID uint8, nonce uint64, resourceID types.ResourceID, calldata, handlerResponse []byte) (*message.Message, error) { +// LatestBlock mocks base method. +func (m *MockChainClient) LatestBlock() (*big.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HandleDeposit", sourceID, destID, nonce, resourceID, calldata, handlerResponse) - ret0, _ := ret[0].(*message.Message) + ret := m.ctrl.Call(m, "LatestBlock") + ret0, _ := ret[0].(*big.Int) ret1, _ := ret[1].(error) return ret0, ret1 } -// HandleDeposit indicates an expected call of HandleDeposit. -func (mr *MockDepositHandlerMockRecorder) HandleDeposit(sourceID, destID, nonce, resourceID, calldata, handlerResponse interface{}) *gomock.Call { +// LatestBlock indicates an expected call of LatestBlock. +func (mr *MockChainClientMockRecorder) LatestBlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestBlock", reflect.TypeOf((*MockChainClient)(nil).LatestBlock)) +} + +// MockBlockDeltaMeter is a mock of BlockDeltaMeter interface. +type MockBlockDeltaMeter struct { + ctrl *gomock.Controller + recorder *MockBlockDeltaMeterMockRecorder +} + +// MockBlockDeltaMeterMockRecorder is the mock recorder for MockBlockDeltaMeter. +type MockBlockDeltaMeterMockRecorder struct { + mock *MockBlockDeltaMeter +} + +// NewMockBlockDeltaMeter creates a new mock instance. +func NewMockBlockDeltaMeter(ctrl *gomock.Controller) *MockBlockDeltaMeter { + mock := &MockBlockDeltaMeter{ctrl: ctrl} + mock.recorder = &MockBlockDeltaMeterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBlockDeltaMeter) EXPECT() *MockBlockDeltaMeterMockRecorder { + return m.recorder +} + +// TrackBlockDelta mocks base method. +func (m *MockBlockDeltaMeter) TrackBlockDelta(domainID uint8, head, current *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "TrackBlockDelta", domainID, head, current) +} + +// TrackBlockDelta indicates an expected call of TrackBlockDelta. +func (mr *MockBlockDeltaMeterMockRecorder) TrackBlockDelta(domainID, head, current any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TrackBlockDelta", reflect.TypeOf((*MockBlockDeltaMeter)(nil).TrackBlockDelta), domainID, head, current) +} + +// MockBlockStorer is a mock of BlockStorer interface. +type MockBlockStorer struct { + ctrl *gomock.Controller + recorder *MockBlockStorerMockRecorder +} + +// MockBlockStorerMockRecorder is the mock recorder for MockBlockStorer. +type MockBlockStorerMockRecorder struct { + mock *MockBlockStorer +} + +// NewMockBlockStorer creates a new mock instance. +func NewMockBlockStorer(ctrl *gomock.Controller) *MockBlockStorer { + mock := &MockBlockStorer{ctrl: ctrl} + mock.recorder = &MockBlockStorerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBlockStorer) EXPECT() *MockBlockStorerMockRecorder { + return m.recorder +} + +// StoreBlock mocks base method. +func (m *MockBlockStorer) StoreBlock(block *big.Int, domainID uint8) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StoreBlock", block, domainID) + ret0, _ := ret[0].(error) + return ret0 +} + +// StoreBlock indicates an expected call of StoreBlock. +func (mr *MockBlockStorerMockRecorder) StoreBlock(block, domainID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleDeposit", reflect.TypeOf((*MockDepositHandler)(nil).HandleDeposit), sourceID, destID, nonce, resourceID, calldata, handlerResponse) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreBlock", reflect.TypeOf((*MockBlockStorer)(nil).StoreBlock), block, domainID) } From 472bfc37442b021c164da7bb00dfd6d80110a3d9 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 13 Oct 2023 15:48:28 +0200 Subject: [PATCH 2/4] Fix mocks --- Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2180b72c..37e5d821 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,6 @@ genmocks: mockgen -destination=./chains/evm/calls/transactor/itx/mock/itx.go -source=./chains/evm/calls/transactor/itx/itx.go mockgen -destination=./chains/evm/calls/transactor/itx//mock/minimalForwarder.go -source=./chains/evm/calls/transactor/itx/minimalForwarder.go mockgen -destination=chains/evm/cli/bridge/mock/vote-proposal.go -source=./chains/evm/cli/bridge/vote-proposal.go - mockgen -destination=chains/evm/listener/mock/listener.go -source=./chains/evm/listener/event-handler.go - mockgen -destination=chains/evm/cli/bridge/mock/vote-proposal.go -source=./chains/evm/cli/bridge/vote-proposal.go - mockgen -destination=chains/evm/listener/mock/listener.go -source=./chains/evm/listener/event-handler.go + mockgen -destination=chains/evm/listener/mock/handler.go -source=./chains/evm/listener/event-handler.go + mockgen -destination=chains/evm/listener/mock/listener.go -source=./chains/evm/listener/listener.go From 4459710d0751dff44474bedd4c9405d65c7e1864 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 13 Oct 2023 15:53:34 +0200 Subject: [PATCH 3/4] Regenerate mocks with correct mockgen version --- chains/evm/listener/mock/handler.go | 4 ++-- chains/evm/listener/mock/listener.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/chains/evm/listener/mock/handler.go b/chains/evm/listener/mock/handler.go index b62f81b3..342315bd 100644 --- a/chains/evm/listener/mock/handler.go +++ b/chains/evm/listener/mock/handler.go @@ -49,7 +49,7 @@ func (m *MockEventListener) FetchDeposits(ctx context.Context, address common.Ad } // FetchDeposits indicates an expected call of FetchDeposits. -func (mr *MockEventListenerMockRecorder) FetchDeposits(ctx, address, startBlock, endBlock any) *gomock.Call { +func (mr *MockEventListenerMockRecorder) FetchDeposits(ctx, address, startBlock, endBlock interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchDeposits", reflect.TypeOf((*MockEventListener)(nil).FetchDeposits), ctx, address, startBlock, endBlock) } @@ -87,7 +87,7 @@ func (m *MockDepositHandler) HandleDeposit(sourceID, destID uint8, nonce uint64, } // HandleDeposit indicates an expected call of HandleDeposit. -func (mr *MockDepositHandlerMockRecorder) HandleDeposit(sourceID, destID, nonce, resourceID, calldata, handlerResponse any) *gomock.Call { +func (mr *MockDepositHandlerMockRecorder) HandleDeposit(sourceID, destID, nonce, resourceID, calldata, handlerResponse interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleDeposit", reflect.TypeOf((*MockDepositHandler)(nil).HandleDeposit), sourceID, destID, nonce, resourceID, calldata, handlerResponse) } diff --git a/chains/evm/listener/mock/listener.go b/chains/evm/listener/mock/listener.go index 0e5a0f2f..54109996 100644 --- a/chains/evm/listener/mock/listener.go +++ b/chains/evm/listener/mock/listener.go @@ -44,7 +44,7 @@ func (m *MockEventHandler) HandleEvent(startBlock, endBlock *big.Int, msgChan ch } // HandleEvent indicates an expected call of HandleEvent. -func (mr *MockEventHandlerMockRecorder) HandleEvent(startBlock, endBlock, msgChan any) *gomock.Call { +func (mr *MockEventHandlerMockRecorder) HandleEvent(startBlock, endBlock, msgChan interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleEvent", reflect.TypeOf((*MockEventHandler)(nil).HandleEvent), startBlock, endBlock, msgChan) } @@ -117,7 +117,7 @@ func (m *MockBlockDeltaMeter) TrackBlockDelta(domainID uint8, head, current *big } // TrackBlockDelta indicates an expected call of TrackBlockDelta. -func (mr *MockBlockDeltaMeterMockRecorder) TrackBlockDelta(domainID, head, current any) *gomock.Call { +func (mr *MockBlockDeltaMeterMockRecorder) TrackBlockDelta(domainID, head, current interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TrackBlockDelta", reflect.TypeOf((*MockBlockDeltaMeter)(nil).TrackBlockDelta), domainID, head, current) } @@ -154,7 +154,7 @@ func (m *MockBlockStorer) StoreBlock(block *big.Int, domainID uint8) error { } // StoreBlock indicates an expected call of StoreBlock. -func (mr *MockBlockStorerMockRecorder) StoreBlock(block, domainID any) *gomock.Call { +func (mr *MockBlockStorerMockRecorder) StoreBlock(block, domainID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreBlock", reflect.TypeOf((*MockBlockStorer)(nil).StoreBlock), block, domainID) } From 3f6136c1fcbcf38af52e9d34c6fcb5b25b8682fb Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Mon, 16 Oct 2023 17:32:24 +0200 Subject: [PATCH 4/4] Change unable to handle events to warn as it is not actionable in most cases --- chains/evm/listener/listener.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains/evm/listener/listener.go b/chains/evm/listener/listener.go index 8a910e08..82ebbe9b 100644 --- a/chains/evm/listener/listener.go +++ b/chains/evm/listener/listener.go @@ -102,7 +102,7 @@ loop: for _, handler := range l.eventHandlers { err := handler.HandleEvent(startBlock, new(big.Int).Sub(endBlock, big.NewInt(1)), msgChan) if err != nil { - l.log.Error().Err(err).Msgf("Unable to handle events") + l.log.Warn().Err(err).Msgf("Unable to handle events") continue loop }