diff --git a/interop/executor.go b/interop/executor.go index 16246865..9382049f 100644 --- a/interop/executor.go +++ b/interop/executor.go @@ -163,9 +163,16 @@ func (e *Executor) Execute(ctx context.Context, signedTx tx.SignedTx) error { } log.Debugf("get batch by number: %v", batch) + if batch == nil { + return fmt.Errorf( + "unable to perform soundness check because batch with number %d is undefined", + signedTx.Tx.NewVerifiedBatch, + ) + } + if batch.StateRoot != signedTx.Tx.ZKP.NewStateRoot || batch.LocalExitRoot != signedTx.Tx.ZKP.NewLocalExitRoot { return fmt.Errorf( - "Mismatch detected, expected local exit root: %s actual: %s. expected state root: %s actual: %s", + "Mismatch detected, expected local exit root: %s actual: %s. expected state root: %s actual: %s", signedTx.Tx.ZKP.NewLocalExitRoot.Hex(), batch.LocalExitRoot.Hex(), signedTx.Tx.ZKP.NewStateRoot.Hex(), diff --git a/interop/executor_test.go b/interop/executor_test.go index 6d746f27..528b0100 100644 --- a/interop/executor_test.go +++ b/interop/executor_test.go @@ -3,6 +3,7 @@ package interop import ( "context" "errors" + "fmt" "math/big" "testing" @@ -163,12 +164,7 @@ func TestExecutor_VerifySignature(t *testing.T) { } func TestExecutor_Execute(t *testing.T) { - cfg := &config.Config{} - interopAdminAddr := common.HexToAddress("0x1234567890abcdef") - etherman := mocks.NewEthermanMock(t) - ethTxManager := mocks.NewEthTxManagerMock(t) - - executor := New(log.WithFields("test", "test"), cfg, interopAdminAddr, etherman, ethTxManager) + t.Parallel() // Create a sample signed transaction for testing signedTx := tx.SignedTx{ @@ -176,31 +172,75 @@ func TestExecutor_Execute(t *testing.T) { LastVerifiedBatch: 0, NewVerifiedBatch: 1, ZKP: tx.ZKP{ - NewStateRoot: common.BytesToHash([]byte("sampleNewStateRoot")), - Proof: []byte("sampleProof"), + NewStateRoot: common.BytesToHash([]byte("sampleNewStateRoot")), + NewLocalExitRoot: common.BytesToHash([]byte("sampleNewLocalExitRoot")), + Proof: []byte("sampleProof"), }, }, } - // Mock the ZkEVMClientCreator.NewClient method - mockZkEVMClientCreator := mocks.NewZkEVMClientClientCreatorMock(t) - mockZkEVMClient := mocks.NewZkEVMClientMock(t) - - mockZkEVMClientCreator.On("NewClient", mock.Anything).Return(mockZkEVMClient).Once() - mockZkEVMClient.On("BatchByNumber", mock.Anything, big.NewInt(int64(signedTx.Tx.NewVerifiedBatch))). - Return(&rpctypes.Batch{ - StateRoot: signedTx.Tx.ZKP.NewStateRoot, - LocalExitRoot: signedTx.Tx.ZKP.NewLocalExitRoot, - // Add other necessary fields here - }, nil).Once() - - // Set the ZkEVMClientCreator to return the mock ZkEVMClient - executor.ZkEVMClientCreator = mockZkEVMClientCreator - - err := executor.Execute(context.Background(), signedTx) - require.NoError(t, err) - mockZkEVMClientCreator.AssertExpectations(t) - mockZkEVMClient.AssertExpectations(t) + t.Run("Batch is not nil and roots match", func(t *testing.T) { + t.Parallel() + + cfg := &config.Config{} + interopAdminAddr := common.HexToAddress("0x1234567890abcdef") + etherman := mocks.NewEthermanMock(t) + ethTxManager := mocks.NewEthTxManagerMock(t) + + executor := New(log.WithFields("test", "test"), cfg, interopAdminAddr, etherman, ethTxManager) + + // Mock the ZkEVMClientCreator.NewClient method + mockZkEVMClientCreator := mocks.NewZkEVMClientClientCreatorMock(t) + mockZkEVMClient := mocks.NewZkEVMClientMock(t) + + mockZkEVMClientCreator.On("NewClient", mock.Anything).Return(mockZkEVMClient).Once() + mockZkEVMClient.On("BatchByNumber", mock.Anything, big.NewInt(int64(signedTx.Tx.NewVerifiedBatch))). + Return(&rpctypes.Batch{ + StateRoot: signedTx.Tx.ZKP.NewStateRoot, + LocalExitRoot: signedTx.Tx.ZKP.NewLocalExitRoot, + // Add other necessary fields here + }, nil).Once() + + // Set the ZkEVMClientCreator to return the mock ZkEVMClient + executor.ZkEVMClientCreator = mockZkEVMClientCreator + + err := executor.Execute(context.Background(), signedTx) + require.NoError(t, err) + mockZkEVMClientCreator.AssertExpectations(t) + mockZkEVMClient.AssertExpectations(t) + }) + + t.Run("Returns expected error when Batch is nil", func(t *testing.T) { + t.Parallel() + + cfg := &config.Config{} + interopAdminAddr := common.HexToAddress("0x1234567890abcdef") + etherman := mocks.NewEthermanMock(t) + ethTxManager := mocks.NewEthTxManagerMock(t) + + executor := New(log.WithFields("test", "test"), cfg, interopAdminAddr, etherman, ethTxManager) + + // Mock the ZkEVMClientCreator.NewClient method + mockZkEVMClientCreator := mocks.NewZkEVMClientClientCreatorMock(t) + mockZkEVMClient := mocks.NewZkEVMClientMock(t) + + mockZkEVMClientCreator.On("NewClient", mock.Anything).Return(mockZkEVMClient).Once() + mockZkEVMClient.On("BatchByNumber", mock.Anything, big.NewInt(int64(signedTx.Tx.NewVerifiedBatch))). + Return(nil, nil).Once() + + // Set the ZkEVMClientCreator to return the mock ZkEVMClient + executor.ZkEVMClientCreator = mockZkEVMClientCreator + + err := executor.Execute(context.Background(), signedTx) + require.Error(t, err) + expectedError := fmt.Sprintf( + "unable to perform soundness check because batch with number %d is undefined", + signedTx.Tx.NewVerifiedBatch, + ) + assert.Contains(t, err.Error(), expectedError) + mockZkEVMClientCreator.AssertExpectations(t) + mockZkEVMClient.AssertExpectations(t) + }) } func TestExecutor_Settle(t *testing.T) {