github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/jsonrpc/endpoints_zkevm_test.go (about)

     1  package jsonrpc
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"math/big"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/0xPolygon/supernets2-node/hex"
    13  	"github.com/0xPolygon/supernets2-node/jsonrpc/types"
    14  	"github.com/0xPolygon/supernets2-node/state"
    15  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    16  	"github.com/ethereum/go-ethereum/common"
    17  	ethTypes "github.com/ethereum/go-ethereum/core/types"
    18  	"github.com/ethereum/go-ethereum/crypto"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestConsolidatedBlockNumber(t *testing.T) {
    24  	s, m, _ := newSequencerMockedServer(t)
    25  	defer s.Stop()
    26  
    27  	type testCase struct {
    28  		Name           string
    29  		ExpectedResult *uint64
    30  		ExpectedError  types.Error
    31  		SetupMocks     func(m *mocksWrapper)
    32  	}
    33  
    34  	testCases := []testCase{
    35  		{
    36  			Name:           "Get consolidated block number successfully",
    37  			ExpectedResult: ptrUint64(10),
    38  			SetupMocks: func(m *mocksWrapper) {
    39  				m.DbTx.
    40  					On("Commit", context.Background()).
    41  					Return(nil).
    42  					Once()
    43  
    44  				m.State.
    45  					On("BeginStateTransaction", context.Background()).
    46  					Return(m.DbTx, nil).
    47  					Once()
    48  
    49  				m.State.
    50  					On("GetLastConsolidatedL2BlockNumber", context.Background(), m.DbTx).
    51  					Return(uint64(10), nil).
    52  					Once()
    53  			},
    54  		},
    55  		{
    56  			Name:           "failed to get consolidated block number",
    57  			ExpectedResult: nil,
    58  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to get last consolidated block number from state"),
    59  			SetupMocks: func(m *mocksWrapper) {
    60  				m.DbTx.
    61  					On("Rollback", context.Background()).
    62  					Return(nil).
    63  					Once()
    64  
    65  				m.State.
    66  					On("BeginStateTransaction", context.Background()).
    67  					Return(m.DbTx, nil).
    68  					Once()
    69  
    70  				m.State.
    71  					On("GetLastConsolidatedL2BlockNumber", context.Background(), m.DbTx).
    72  					Return(uint64(0), errors.New("failed to get last consolidated block number")).
    73  					Once()
    74  			},
    75  		},
    76  	}
    77  
    78  	for _, testCase := range testCases {
    79  		t.Run(testCase.Name, func(t *testing.T) {
    80  			tc := testCase
    81  			tc.SetupMocks(m)
    82  
    83  			res, err := s.JSONRPCCall("zkevm_consolidatedBlockNumber")
    84  			require.NoError(t, err)
    85  
    86  			if res.Result != nil {
    87  				var result types.ArgUint64
    88  				err = json.Unmarshal(res.Result, &result)
    89  				require.NoError(t, err)
    90  				assert.Equal(t, *tc.ExpectedResult, uint64(result))
    91  			}
    92  
    93  			if res.Error != nil || tc.ExpectedError != nil {
    94  				assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
    95  				assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
    96  			}
    97  		})
    98  	}
    99  }
   100  
   101  func TestIsBlockConsolidated(t *testing.T) {
   102  	s, m, _ := newSequencerMockedServer(t)
   103  	defer s.Stop()
   104  
   105  	type testCase struct {
   106  		Name           string
   107  		ExpectedResult bool
   108  		ExpectedError  types.Error
   109  		SetupMocks     func(m *mocksWrapper)
   110  	}
   111  
   112  	testCases := []testCase{
   113  		{
   114  			Name:           "Query status of block number successfully",
   115  			ExpectedResult: true,
   116  			SetupMocks: func(m *mocksWrapper) {
   117  				m.DbTx.
   118  					On("Commit", context.Background()).
   119  					Return(nil).
   120  					Once()
   121  
   122  				m.State.
   123  					On("BeginStateTransaction", context.Background()).
   124  					Return(m.DbTx, nil).
   125  					Once()
   126  
   127  				m.State.
   128  					On("IsL2BlockConsolidated", context.Background(), uint64(1), m.DbTx).
   129  					Return(true, nil).
   130  					Once()
   131  			},
   132  		},
   133  		{
   134  			Name:           "Failed to query the consolidation status",
   135  			ExpectedResult: false,
   136  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to check if the block is consolidated"),
   137  			SetupMocks: func(m *mocksWrapper) {
   138  				m.DbTx.
   139  					On("Rollback", context.Background()).
   140  					Return(nil).
   141  					Once()
   142  
   143  				m.State.
   144  					On("BeginStateTransaction", context.Background()).
   145  					Return(m.DbTx, nil).
   146  					Once()
   147  
   148  				m.State.
   149  					On("IsL2BlockConsolidated", context.Background(), uint64(1), m.DbTx).
   150  					Return(false, errors.New("failed to check if the block is consolidated")).
   151  					Once()
   152  			},
   153  		},
   154  	}
   155  
   156  	for _, testCase := range testCases {
   157  		t.Run(testCase.Name, func(t *testing.T) {
   158  			tc := testCase
   159  			tc.SetupMocks(m)
   160  
   161  			res, err := s.JSONRPCCall("zkevm_isBlockConsolidated", "0x1")
   162  			require.NoError(t, err)
   163  
   164  			if res.Result != nil {
   165  				var result bool
   166  				err = json.Unmarshal(res.Result, &result)
   167  				require.NoError(t, err)
   168  				assert.Equal(t, tc.ExpectedResult, result)
   169  			}
   170  
   171  			if res.Error != nil || tc.ExpectedError != nil {
   172  				assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
   173  				assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
   174  			}
   175  		})
   176  	}
   177  }
   178  
   179  func TestIsBlockVirtualized(t *testing.T) {
   180  	s, m, _ := newSequencerMockedServer(t)
   181  	defer s.Stop()
   182  
   183  	type testCase struct {
   184  		Name           string
   185  		ExpectedResult bool
   186  		ExpectedError  types.Error
   187  		SetupMocks     func(m *mocksWrapper)
   188  	}
   189  
   190  	testCases := []testCase{
   191  		{
   192  			Name:           "Query status of block number successfully",
   193  			ExpectedResult: true,
   194  			SetupMocks: func(m *mocksWrapper) {
   195  				m.DbTx.
   196  					On("Commit", context.Background()).
   197  					Return(nil).
   198  					Once()
   199  
   200  				m.State.
   201  					On("BeginStateTransaction", context.Background()).
   202  					Return(m.DbTx, nil).
   203  					Once()
   204  
   205  				m.State.
   206  					On("IsL2BlockVirtualized", context.Background(), uint64(1), m.DbTx).
   207  					Return(true, nil).
   208  					Once()
   209  			},
   210  		},
   211  		{
   212  			Name:           "Failed to query the virtualization status",
   213  			ExpectedResult: false,
   214  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to check if the block is virtualized"),
   215  			SetupMocks: func(m *mocksWrapper) {
   216  				m.DbTx.
   217  					On("Rollback", context.Background()).
   218  					Return(nil).
   219  					Once()
   220  
   221  				m.State.
   222  					On("BeginStateTransaction", context.Background()).
   223  					Return(m.DbTx, nil).
   224  					Once()
   225  
   226  				m.State.
   227  					On("IsL2BlockVirtualized", context.Background(), uint64(1), m.DbTx).
   228  					Return(false, errors.New("failed to check if the block is virtualized")).
   229  					Once()
   230  			},
   231  		},
   232  	}
   233  
   234  	for _, testCase := range testCases {
   235  		t.Run(testCase.Name, func(t *testing.T) {
   236  			tc := testCase
   237  			tc.SetupMocks(m)
   238  
   239  			res, err := s.JSONRPCCall("zkevm_isBlockVirtualized", "0x1")
   240  			require.NoError(t, err)
   241  
   242  			if res.Result != nil {
   243  				var result bool
   244  				err = json.Unmarshal(res.Result, &result)
   245  				require.NoError(t, err)
   246  				assert.Equal(t, tc.ExpectedResult, result)
   247  			}
   248  
   249  			if res.Error != nil || tc.ExpectedError != nil {
   250  				assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
   251  				assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
   252  			}
   253  		})
   254  	}
   255  }
   256  
   257  func TestBatchNumberByBlockNumber(t *testing.T) {
   258  	s, m, _ := newSequencerMockedServer(t)
   259  	defer s.Stop()
   260  	blockNumber := uint64(1)
   261  	batchNumber := uint64(1)
   262  
   263  	type testCase struct {
   264  		Name           string
   265  		ExpectedResult *uint64
   266  		ExpectedError  types.Error
   267  		SetupMocks     func(m *mocksWrapper)
   268  	}
   269  
   270  	testCases := []testCase{
   271  		{
   272  			Name:           "get batch number by block number successfully",
   273  			ExpectedResult: &batchNumber,
   274  			SetupMocks: func(m *mocksWrapper) {
   275  				m.DbTx.
   276  					On("Commit", context.Background()).
   277  					Return(nil).
   278  					Once()
   279  
   280  				m.State.
   281  					On("BeginStateTransaction", context.Background()).
   282  					Return(m.DbTx, nil).
   283  					Once()
   284  
   285  				m.State.
   286  					On("BatchNumberByL2BlockNumber", context.Background(), blockNumber, m.DbTx).
   287  					Return(batchNumber, nil).
   288  					Once()
   289  			},
   290  		},
   291  		{
   292  			Name:           "failed to get batch number",
   293  			ExpectedResult: nil,
   294  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to get batch number from block number"),
   295  			SetupMocks: func(m *mocksWrapper) {
   296  				m.DbTx.
   297  					On("Rollback", context.Background()).
   298  					Return(nil).
   299  					Once()
   300  
   301  				m.State.
   302  					On("BeginStateTransaction", context.Background()).
   303  					Return(m.DbTx, nil).
   304  					Once()
   305  
   306  				m.State.
   307  					On("BatchNumberByL2BlockNumber", context.Background(), blockNumber, m.DbTx).
   308  					Return(uint64(0), errors.New("failed to get batch number of l2 batchNum")).
   309  					Once()
   310  			},
   311  		},
   312  		{
   313  			Name:           "batch number not found",
   314  			ExpectedResult: nil,
   315  			ExpectedError:  nil,
   316  			SetupMocks: func(m *mocksWrapper) {
   317  				m.DbTx.
   318  					On("Commit", context.Background()).
   319  					Return(nil).
   320  					Once()
   321  
   322  				m.State.
   323  					On("BeginStateTransaction", context.Background()).
   324  					Return(m.DbTx, nil).
   325  					Once()
   326  
   327  				m.State.
   328  					On("BatchNumberByL2BlockNumber", context.Background(), blockNumber, m.DbTx).
   329  					Return(uint64(0), state.ErrNotFound).
   330  					Once()
   331  			},
   332  		},
   333  	}
   334  
   335  	for _, testCase := range testCases {
   336  		t.Run(testCase.Name, func(t *testing.T) {
   337  			tc := testCase
   338  			tc.SetupMocks(m)
   339  
   340  			res, err := s.JSONRPCCall("zkevm_batchNumberByBlockNumber", hex.EncodeUint64(blockNumber))
   341  			require.NoError(t, err)
   342  
   343  			if tc.ExpectedResult != nil {
   344  				var result types.ArgUint64
   345  				err = json.Unmarshal(res.Result, &result)
   346  				require.NoError(t, err)
   347  				assert.Equal(t, *tc.ExpectedResult, uint64(result))
   348  			} else {
   349  				if res.Result == nil {
   350  					assert.Nil(t, res.Result)
   351  				} else {
   352  					var result *uint64
   353  					err = json.Unmarshal(res.Result, &result)
   354  					require.NoError(t, err)
   355  					assert.Nil(t, result)
   356  				}
   357  			}
   358  
   359  			if tc.ExpectedError != nil {
   360  				assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
   361  				assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
   362  			} else {
   363  				assert.Nil(t, res.Error)
   364  			}
   365  		})
   366  	}
   367  }
   368  
   369  func TestBatchNumber(t *testing.T) {
   370  	s, m, _ := newSequencerMockedServer(t)
   371  	defer s.Stop()
   372  
   373  	type testCase struct {
   374  		Name           string
   375  		ExpectedResult uint64
   376  		ExpectedError  types.Error
   377  		SetupMocks     func(m *mocksWrapper)
   378  	}
   379  
   380  	testCases := []testCase{
   381  		{
   382  			Name:           "get batch number successfully",
   383  			ExpectedError:  nil,
   384  			ExpectedResult: 10,
   385  			SetupMocks: func(m *mocksWrapper) {
   386  				m.DbTx.
   387  					On("Commit", context.Background()).
   388  					Return(nil).
   389  					Once()
   390  
   391  				m.State.
   392  					On("BeginStateTransaction", context.Background()).
   393  					Return(m.DbTx, nil).
   394  					Once()
   395  
   396  				m.State.
   397  					On("GetLastBatchNumber", context.Background(), m.DbTx).
   398  					Return(uint64(10), nil).
   399  					Once()
   400  			},
   401  		},
   402  		{
   403  			Name:           "failed to get batch number",
   404  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to get the last batch number from state"),
   405  			ExpectedResult: 0,
   406  			SetupMocks: func(m *mocksWrapper) {
   407  				m.DbTx.
   408  					On("Rollback", context.Background()).
   409  					Return(nil).
   410  					Once()
   411  
   412  				m.State.
   413  					On("BeginStateTransaction", context.Background()).
   414  					Return(m.DbTx, nil).
   415  					Once()
   416  
   417  				m.State.
   418  					On("GetLastBatchNumber", context.Background(), m.DbTx).
   419  					Return(uint64(0), errors.New("failed to get last batch number")).
   420  					Once()
   421  			},
   422  		},
   423  	}
   424  
   425  	for _, testCase := range testCases {
   426  		t.Run(testCase.Name, func(t *testing.T) {
   427  			tc := testCase
   428  			tc.SetupMocks(m)
   429  
   430  			res, err := s.JSONRPCCall("zkevm_batchNumber")
   431  			require.NoError(t, err)
   432  
   433  			if res.Result != nil {
   434  				var result types.ArgUint64
   435  				err = json.Unmarshal(res.Result, &result)
   436  				require.NoError(t, err)
   437  				assert.Equal(t, tc.ExpectedResult, uint64(result))
   438  			}
   439  
   440  			if res.Error != nil || tc.ExpectedError != nil {
   441  				assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
   442  				assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
   443  			}
   444  		})
   445  	}
   446  }
   447  
   448  func TestVirtualBatchNumber(t *testing.T) {
   449  	s, m, _ := newSequencerMockedServer(t)
   450  	defer s.Stop()
   451  
   452  	type testCase struct {
   453  		Name           string
   454  		ExpectedResult uint64
   455  		ExpectedError  types.Error
   456  		SetupMocks     func(m *mocksWrapper)
   457  	}
   458  
   459  	testCases := []testCase{
   460  		{
   461  			Name:           "get virtual batch number successfully",
   462  			ExpectedError:  nil,
   463  			ExpectedResult: 10,
   464  			SetupMocks: func(m *mocksWrapper) {
   465  				m.DbTx.
   466  					On("Commit", context.Background()).
   467  					Return(nil).
   468  					Once()
   469  
   470  				m.State.
   471  					On("BeginStateTransaction", context.Background()).
   472  					Return(m.DbTx, nil).
   473  					Once()
   474  
   475  				m.State.
   476  					On("GetLastVirtualBatchNum", context.Background(), m.DbTx).
   477  					Return(uint64(10), nil).
   478  					Once()
   479  			},
   480  		},
   481  		{
   482  			Name:           "failed to get virtual batch number",
   483  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to get the last virtual batch number from state"),
   484  			ExpectedResult: 0,
   485  			SetupMocks: func(m *mocksWrapper) {
   486  				m.DbTx.
   487  					On("Rollback", context.Background()).
   488  					Return(nil).
   489  					Once()
   490  
   491  				m.State.
   492  					On("BeginStateTransaction", context.Background()).
   493  					Return(m.DbTx, nil).
   494  					Once()
   495  
   496  				m.State.
   497  					On("GetLastVirtualBatchNum", context.Background(), m.DbTx).
   498  					Return(uint64(0), errors.New("failed to get last batch number")).
   499  					Once()
   500  			},
   501  		},
   502  	}
   503  
   504  	for _, testCase := range testCases {
   505  		t.Run(testCase.Name, func(t *testing.T) {
   506  			tc := testCase
   507  			tc.SetupMocks(m)
   508  
   509  			res, err := s.JSONRPCCall("zkevm_virtualBatchNumber")
   510  			require.NoError(t, err)
   511  
   512  			if res.Result != nil {
   513  				var result types.ArgUint64
   514  				err = json.Unmarshal(res.Result, &result)
   515  				require.NoError(t, err)
   516  				assert.Equal(t, tc.ExpectedResult, uint64(result))
   517  			}
   518  
   519  			if res.Error != nil || tc.ExpectedError != nil {
   520  				assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
   521  				assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
   522  			}
   523  		})
   524  	}
   525  }
   526  
   527  func TestVerifiedBatchNumber(t *testing.T) {
   528  	s, m, _ := newSequencerMockedServer(t)
   529  	defer s.Stop()
   530  
   531  	type testCase struct {
   532  		Name           string
   533  		ExpectedResult uint64
   534  		ExpectedError  types.Error
   535  		SetupMocks     func(m *mocksWrapper)
   536  	}
   537  
   538  	testCases := []testCase{
   539  		{
   540  			Name:           "get verified batch number successfully",
   541  			ExpectedError:  nil,
   542  			ExpectedResult: 10,
   543  			SetupMocks: func(m *mocksWrapper) {
   544  				m.DbTx.
   545  					On("Commit", context.Background()).
   546  					Return(nil).
   547  					Once()
   548  
   549  				m.State.
   550  					On("BeginStateTransaction", context.Background()).
   551  					Return(m.DbTx, nil).
   552  					Once()
   553  
   554  				m.State.
   555  					On("GetLastVerifiedBatch", context.Background(), m.DbTx).
   556  					Return(&state.VerifiedBatch{BatchNumber: uint64(10)}, nil).
   557  					Once()
   558  			},
   559  		},
   560  		{
   561  			Name:           "failed to get verified batch number",
   562  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to get the last verified batch number from state"),
   563  			ExpectedResult: 0,
   564  			SetupMocks: func(m *mocksWrapper) {
   565  				m.DbTx.
   566  					On("Rollback", context.Background()).
   567  					Return(nil).
   568  					Once()
   569  
   570  				m.State.
   571  					On("BeginStateTransaction", context.Background()).
   572  					Return(m.DbTx, nil).
   573  					Once()
   574  
   575  				m.State.
   576  					On("GetLastVerifiedBatch", context.Background(), m.DbTx).
   577  					Return(nil, errors.New("failed to get last batch number")).
   578  					Once()
   579  			},
   580  		},
   581  	}
   582  
   583  	for _, testCase := range testCases {
   584  		t.Run(testCase.Name, func(t *testing.T) {
   585  			tc := testCase
   586  			tc.SetupMocks(m)
   587  
   588  			res, err := s.JSONRPCCall("zkevm_verifiedBatchNumber")
   589  			require.NoError(t, err)
   590  
   591  			if res.Result != nil {
   592  				var result types.ArgUint64
   593  				err = json.Unmarshal(res.Result, &result)
   594  				require.NoError(t, err)
   595  				assert.Equal(t, tc.ExpectedResult, uint64(result))
   596  			}
   597  
   598  			if res.Error != nil || tc.ExpectedError != nil {
   599  				assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
   600  				assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
   601  			}
   602  		})
   603  	}
   604  }
   605  
   606  func TestGetBatchByNumber(t *testing.T) {
   607  	type testCase struct {
   608  		Name           string
   609  		Number         string
   610  		WithTxDetail   bool
   611  		ExpectedResult *types.Batch
   612  		ExpectedError  types.Error
   613  		SetupMocks     func(*mockedServer, *mocksWrapper, *testCase)
   614  	}
   615  
   616  	testCases := []testCase{
   617  		{
   618  			Name:           "Batch not found",
   619  			Number:         "0x123",
   620  			ExpectedResult: nil,
   621  			ExpectedError:  nil,
   622  			SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
   623  				m.DbTx.
   624  					On("Commit", context.Background()).
   625  					Return(nil).
   626  					Once()
   627  
   628  				m.State.
   629  					On("BeginStateTransaction", context.Background()).
   630  					Return(m.DbTx, nil).
   631  					Once()
   632  
   633  				m.State.
   634  					On("GetBatchByNumber", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   635  					Return(nil, state.ErrNotFound)
   636  			},
   637  		},
   638  		{
   639  			Name:         "get specific batch successfully with tx detail",
   640  			Number:       "0x345",
   641  			WithTxDetail: true,
   642  			ExpectedResult: &types.Batch{
   643  				Number:              1,
   644  				Coinbase:            common.HexToAddress("0x1"),
   645  				StateRoot:           common.HexToHash("0x2"),
   646  				AccInputHash:        common.HexToHash("0x3"),
   647  				GlobalExitRoot:      common.HexToHash("0x4"),
   648  				Timestamp:           1,
   649  				SendSequencesTxHash: ptrHash(common.HexToHash("0x10")),
   650  				VerifyBatchTxHash:   ptrHash(common.HexToHash("0x20")),
   651  			},
   652  			ExpectedError: nil,
   653  			SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
   654  				m.DbTx.
   655  					On("Commit", context.Background()).
   656  					Return(nil).
   657  					Once()
   658  
   659  				m.State.
   660  					On("BeginStateTransaction", context.Background()).
   661  					Return(m.DbTx, nil).
   662  					Once()
   663  
   664  				batch := &state.Batch{
   665  					BatchNumber:    1,
   666  					Coinbase:       common.HexToAddress("0x1"),
   667  					StateRoot:      common.HexToHash("0x2"),
   668  					AccInputHash:   common.HexToHash("0x3"),
   669  					GlobalExitRoot: common.HexToHash("0x4"),
   670  					Timestamp:      time.Unix(1, 0),
   671  				}
   672  
   673  				m.State.
   674  					On("GetBatchByNumber", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   675  					Return(batch, nil).
   676  					Once()
   677  
   678  				virtualBatch := &state.VirtualBatch{
   679  					TxHash: common.HexToHash("0x10"),
   680  				}
   681  
   682  				m.State.
   683  					On("GetVirtualBatch", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   684  					Return(virtualBatch, nil).
   685  					Once()
   686  
   687  				verifiedBatch := &state.VerifiedBatch{
   688  					TxHash: common.HexToHash("0x20"),
   689  				}
   690  
   691  				m.State.
   692  					On("GetVerifiedBatch", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   693  					Return(verifiedBatch, nil).
   694  					Once()
   695  
   696  				ger := state.GlobalExitRoot{
   697  					MainnetExitRoot: common.HexToHash("0x4"),
   698  					RollupExitRoot:  common.HexToHash("0x4"),
   699  					GlobalExitRoot:  common.HexToHash("0x4"),
   700  				}
   701  				m.State.
   702  					On("GetExitRootByGlobalExitRoot", context.Background(), batch.GlobalExitRoot, m.DbTx).
   703  					Return(&ger, nil).
   704  					Once()
   705  
   706  				txs := []*ethTypes.Transaction{
   707  					signTx(ethTypes.NewTransaction(1001, common.HexToAddress("0x1000"), big.NewInt(1000), 1001, big.NewInt(1002), []byte("1003")), s.ChainID()),
   708  					signTx(ethTypes.NewTransaction(1002, common.HexToAddress("0x1000"), big.NewInt(1000), 1001, big.NewInt(1002), []byte("1003")), s.ChainID()),
   709  				}
   710  
   711  				batchTxs := make([]ethTypes.Transaction, 0, len(txs))
   712  
   713  				tc.ExpectedResult.Transactions = []types.TransactionOrHash{}
   714  
   715  				for i, tx := range txs {
   716  					blockNumber := big.NewInt(int64(i))
   717  					blockHash := common.HexToHash(hex.EncodeUint64(uint64(i)))
   718  					receipt := ethTypes.NewReceipt([]byte{}, false, uint64(0))
   719  					receipt.TxHash = tx.Hash()
   720  					receipt.TransactionIndex = uint(i)
   721  					receipt.BlockNumber = blockNumber
   722  					receipt.BlockHash = blockHash
   723  					m.State.
   724  						On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx).
   725  						Return(receipt, nil).
   726  						Once()
   727  
   728  					from, _ := state.GetSender(*tx)
   729  					V, R, S := tx.RawSignatureValues()
   730  
   731  					tc.ExpectedResult.Transactions = append(tc.ExpectedResult.Transactions,
   732  						types.TransactionOrHash{
   733  							Tx: &types.Transaction{
   734  								Nonce:       types.ArgUint64(tx.Nonce()),
   735  								GasPrice:    types.ArgBig(*tx.GasPrice()),
   736  								Gas:         types.ArgUint64(tx.Gas()),
   737  								To:          tx.To(),
   738  								Value:       types.ArgBig(*tx.Value()),
   739  								Input:       tx.Data(),
   740  								Hash:        tx.Hash(),
   741  								From:        from,
   742  								BlockNumber: ptrArgUint64FromUint64(blockNumber.Uint64()),
   743  								BlockHash:   ptrHash(receipt.BlockHash),
   744  								TxIndex:     ptrArgUint64FromUint(receipt.TransactionIndex),
   745  								ChainID:     types.ArgBig(*tx.ChainId()),
   746  								Type:        types.ArgUint64(tx.Type()),
   747  								V:           types.ArgBig(*V),
   748  								R:           types.ArgBig(*R),
   749  								S:           types.ArgBig(*S),
   750  							},
   751  						},
   752  					)
   753  
   754  					batchTxs = append(batchTxs, *tx)
   755  				}
   756  				m.State.
   757  					On("GetTransactionsByBatchNumber", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   758  					Return(batchTxs, nil).
   759  					Once()
   760  				batchL2Data, err := state.EncodeTransactions(batchTxs)
   761  				require.NoError(t, err)
   762  				tc.ExpectedResult.BatchL2Data = batchL2Data
   763  			},
   764  		},
   765  		{
   766  			Name:         "get specific batch successfully without tx detail",
   767  			Number:       "0x345",
   768  			WithTxDetail: false,
   769  			ExpectedResult: &types.Batch{
   770  				Number:              1,
   771  				Coinbase:            common.HexToAddress("0x1"),
   772  				StateRoot:           common.HexToHash("0x2"),
   773  				AccInputHash:        common.HexToHash("0x3"),
   774  				GlobalExitRoot:      common.HexToHash("0x4"),
   775  				Timestamp:           1,
   776  				SendSequencesTxHash: ptrHash(common.HexToHash("0x10")),
   777  				VerifyBatchTxHash:   ptrHash(common.HexToHash("0x20")),
   778  			},
   779  			ExpectedError: nil,
   780  			SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
   781  				m.DbTx.
   782  					On("Commit", context.Background()).
   783  					Return(nil).
   784  					Once()
   785  
   786  				m.State.
   787  					On("BeginStateTransaction", context.Background()).
   788  					Return(m.DbTx, nil).
   789  					Once()
   790  
   791  				batch := &state.Batch{
   792  					BatchNumber:    1,
   793  					Coinbase:       common.HexToAddress("0x1"),
   794  					StateRoot:      common.HexToHash("0x2"),
   795  					AccInputHash:   common.HexToHash("0x3"),
   796  					GlobalExitRoot: common.HexToHash("0x4"),
   797  					Timestamp:      time.Unix(1, 0),
   798  				}
   799  
   800  				m.State.
   801  					On("GetBatchByNumber", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   802  					Return(batch, nil).
   803  					Once()
   804  
   805  				virtualBatch := &state.VirtualBatch{
   806  					TxHash: common.HexToHash("0x10"),
   807  				}
   808  
   809  				m.State.
   810  					On("GetVirtualBatch", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   811  					Return(virtualBatch, nil).
   812  					Once()
   813  
   814  				verifiedBatch := &state.VerifiedBatch{
   815  					TxHash: common.HexToHash("0x20"),
   816  				}
   817  
   818  				m.State.
   819  					On("GetVerifiedBatch", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   820  					Return(verifiedBatch, nil).
   821  					Once()
   822  
   823  				ger := state.GlobalExitRoot{
   824  					MainnetExitRoot: common.HexToHash("0x4"),
   825  					RollupExitRoot:  common.HexToHash("0x4"),
   826  					GlobalExitRoot:  common.HexToHash("0x4"),
   827  				}
   828  				m.State.
   829  					On("GetExitRootByGlobalExitRoot", context.Background(), batch.GlobalExitRoot, m.DbTx).
   830  					Return(&ger, nil).
   831  					Once()
   832  
   833  				txs := []*ethTypes.Transaction{
   834  					signTx(ethTypes.NewTransaction(1001, common.HexToAddress("0x1000"), big.NewInt(1000), 1001, big.NewInt(1002), []byte("1003")), s.ChainID()),
   835  					signTx(ethTypes.NewTransaction(1002, common.HexToAddress("0x1000"), big.NewInt(1000), 1001, big.NewInt(1002), []byte("1003")), s.ChainID()),
   836  				}
   837  
   838  				batchTxs := make([]ethTypes.Transaction, 0, len(txs))
   839  
   840  				tc.ExpectedResult.Transactions = []types.TransactionOrHash{}
   841  
   842  				for i, tx := range txs {
   843  					blockNumber := big.NewInt(int64(i))
   844  					blockHash := common.HexToHash(hex.EncodeUint64(uint64(i)))
   845  					receipt := ethTypes.NewReceipt([]byte{}, false, uint64(0))
   846  					receipt.TxHash = tx.Hash()
   847  					receipt.TransactionIndex = uint(i)
   848  					receipt.BlockNumber = blockNumber
   849  					receipt.BlockHash = blockHash
   850  					m.State.
   851  						On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx).
   852  						Return(receipt, nil).
   853  						Once()
   854  
   855  					tc.ExpectedResult.Transactions = append(tc.ExpectedResult.Transactions,
   856  						types.TransactionOrHash{
   857  							Hash: state.HashPtr(tx.Hash()),
   858  						},
   859  					)
   860  
   861  					batchTxs = append(batchTxs, *tx)
   862  				}
   863  				m.State.
   864  					On("GetTransactionsByBatchNumber", context.Background(), hex.DecodeBig(tc.Number).Uint64(), m.DbTx).
   865  					Return(batchTxs, nil).
   866  					Once()
   867  				batchL2Data, err := state.EncodeTransactions(batchTxs)
   868  				require.NoError(t, err)
   869  				tc.ExpectedResult.BatchL2Data = batchL2Data
   870  			},
   871  		},
   872  		{
   873  			Name:         "get latest batch successfully",
   874  			Number:       "latest",
   875  			WithTxDetail: true,
   876  			ExpectedResult: &types.Batch{
   877  				Number:              1,
   878  				Coinbase:            common.HexToAddress("0x1"),
   879  				StateRoot:           common.HexToHash("0x2"),
   880  				AccInputHash:        common.HexToHash("0x3"),
   881  				GlobalExitRoot:      common.HexToHash("0x4"),
   882  				Timestamp:           1,
   883  				SendSequencesTxHash: ptrHash(common.HexToHash("0x10")),
   884  				VerifyBatchTxHash:   ptrHash(common.HexToHash("0x20")),
   885  			},
   886  			ExpectedError: nil,
   887  			SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
   888  				m.DbTx.
   889  					On("Commit", context.Background()).
   890  					Return(nil).
   891  					Once()
   892  
   893  				m.State.
   894  					On("BeginStateTransaction", context.Background()).
   895  					Return(m.DbTx, nil).
   896  					Once()
   897  
   898  				m.State.
   899  					On("GetLastBatchNumber", context.Background(), m.DbTx).
   900  					Return(uint64(tc.ExpectedResult.Number), nil).
   901  					Once()
   902  
   903  				batch := &state.Batch{
   904  					BatchNumber:    1,
   905  					Coinbase:       common.HexToAddress("0x1"),
   906  					StateRoot:      common.HexToHash("0x2"),
   907  					AccInputHash:   common.HexToHash("0x3"),
   908  					GlobalExitRoot: common.HexToHash("0x4"),
   909  					Timestamp:      time.Unix(1, 0),
   910  				}
   911  
   912  				m.State.
   913  					On("GetBatchByNumber", context.Background(), uint64(tc.ExpectedResult.Number), m.DbTx).
   914  					Return(batch, nil).
   915  					Once()
   916  
   917  				virtualBatch := &state.VirtualBatch{
   918  					TxHash: common.HexToHash("0x10"),
   919  				}
   920  
   921  				m.State.
   922  					On("GetVirtualBatch", context.Background(), uint64(tc.ExpectedResult.Number), m.DbTx).
   923  					Return(virtualBatch, nil).
   924  					Once()
   925  
   926  				verifiedBatch := &state.VerifiedBatch{
   927  					TxHash: common.HexToHash("0x20"),
   928  				}
   929  
   930  				m.State.
   931  					On("GetVerifiedBatch", context.Background(), uint64(tc.ExpectedResult.Number), m.DbTx).
   932  					Return(verifiedBatch, nil).
   933  					Once()
   934  
   935  				ger := state.GlobalExitRoot{
   936  					MainnetExitRoot: common.HexToHash("0x4"),
   937  					RollupExitRoot:  common.HexToHash("0x4"),
   938  					GlobalExitRoot:  common.HexToHash("0x4"),
   939  				}
   940  				m.State.
   941  					On("GetExitRootByGlobalExitRoot", context.Background(), batch.GlobalExitRoot, m.DbTx).
   942  					Return(&ger, nil).
   943  					Once()
   944  
   945  				txs := []*ethTypes.Transaction{
   946  					signTx(ethTypes.NewTransaction(1001, common.HexToAddress("0x1000"), big.NewInt(1000), 1001, big.NewInt(1002), []byte("1003")), s.ChainID()),
   947  					signTx(ethTypes.NewTransaction(1002, common.HexToAddress("0x1000"), big.NewInt(1000), 1001, big.NewInt(1002), []byte("1003")), s.ChainID()),
   948  				}
   949  
   950  				batchTxs := make([]ethTypes.Transaction, 0, len(txs))
   951  
   952  				tc.ExpectedResult.Transactions = []types.TransactionOrHash{}
   953  
   954  				for i, tx := range txs {
   955  					blockNumber := big.NewInt(int64(i))
   956  					blockHash := common.HexToHash(hex.EncodeUint64(uint64(i)))
   957  					receipt := ethTypes.NewReceipt([]byte{}, false, uint64(0))
   958  					receipt.TxHash = tx.Hash()
   959  					receipt.TransactionIndex = uint(i)
   960  					receipt.BlockNumber = blockNumber
   961  					receipt.BlockHash = blockHash
   962  					m.State.
   963  						On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx).
   964  						Return(receipt, nil).
   965  						Once()
   966  
   967  					from, _ := state.GetSender(*tx)
   968  					V, R, S := tx.RawSignatureValues()
   969  
   970  					tc.ExpectedResult.Transactions = append(tc.ExpectedResult.Transactions,
   971  						types.TransactionOrHash{
   972  							Tx: &types.Transaction{
   973  								Nonce:       types.ArgUint64(tx.Nonce()),
   974  								GasPrice:    types.ArgBig(*tx.GasPrice()),
   975  								Gas:         types.ArgUint64(tx.Gas()),
   976  								To:          tx.To(),
   977  								Value:       types.ArgBig(*tx.Value()),
   978  								Input:       tx.Data(),
   979  								Hash:        tx.Hash(),
   980  								From:        from,
   981  								BlockNumber: ptrArgUint64FromUint64(blockNumber.Uint64()),
   982  								BlockHash:   ptrHash(receipt.BlockHash),
   983  								TxIndex:     ptrArgUint64FromUint(receipt.TransactionIndex),
   984  								ChainID:     types.ArgBig(*tx.ChainId()),
   985  								Type:        types.ArgUint64(tx.Type()),
   986  								V:           types.ArgBig(*V),
   987  								R:           types.ArgBig(*R),
   988  								S:           types.ArgBig(*S),
   989  							},
   990  						},
   991  					)
   992  
   993  					batchTxs = append(batchTxs, *tx)
   994  				}
   995  				m.State.
   996  					On("GetTransactionsByBatchNumber", context.Background(), uint64(tc.ExpectedResult.Number), m.DbTx).
   997  					Return(batchTxs, nil).
   998  					Once()
   999  				batchL2Data, err := state.EncodeTransactions(batchTxs)
  1000  				require.NoError(t, err)
  1001  				tc.ExpectedResult.BatchL2Data = batchL2Data
  1002  			},
  1003  		},
  1004  		{
  1005  			Name:           "get latest batch fails to compute batch number",
  1006  			Number:         "latest",
  1007  			ExpectedResult: nil,
  1008  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "failed to get the last batch number from state"),
  1009  			SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
  1010  				m.DbTx.
  1011  					On("Rollback", context.Background()).
  1012  					Return(nil).
  1013  					Once()
  1014  
  1015  				m.State.
  1016  					On("BeginStateTransaction", context.Background()).
  1017  					Return(m.DbTx, nil).
  1018  					Once()
  1019  
  1020  				m.State.
  1021  					On("GetLastBatchNumber", context.Background(), m.DbTx).
  1022  					Return(uint64(0), errors.New("failed to get last batch number")).
  1023  					Once()
  1024  			},
  1025  		},
  1026  		{
  1027  			Name:           "get latest batch fails to load batch by number",
  1028  			Number:         "latest",
  1029  			ExpectedResult: nil,
  1030  			ExpectedError:  types.NewRPCError(types.DefaultErrorCode, "couldn't load batch from state by number 1"),
  1031  			SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
  1032  				m.DbTx.
  1033  					On("Rollback", context.Background()).
  1034  					Return(nil).
  1035  					Once()
  1036  
  1037  				m.State.
  1038  					On("BeginStateTransaction", context.Background()).
  1039  					Return(m.DbTx, nil).
  1040  					Once()
  1041  
  1042  				m.State.
  1043  					On("GetLastBatchNumber", context.Background(), m.DbTx).
  1044  					Return(uint64(1), nil).
  1045  					Once()
  1046  
  1047  				m.State.
  1048  					On("GetBatchByNumber", context.Background(), uint64(1), m.DbTx).
  1049  					Return(nil, errors.New("failed to load batch by number")).
  1050  					Once()
  1051  			},
  1052  		},
  1053  	}
  1054  
  1055  	s, m, _ := newSequencerMockedServer(t)
  1056  	defer s.Stop()
  1057  
  1058  	for _, testCase := range testCases {
  1059  		t.Run(testCase.Name, func(t *testing.T) {
  1060  			tc := testCase
  1061  			testCase.SetupMocks(s, m, &tc)
  1062  
  1063  			res, err := s.JSONRPCCall("zkevm_getBatchByNumber", tc.Number, tc.WithTxDetail)
  1064  			require.NoError(t, err)
  1065  			assert.Equal(t, float64(1), res.ID)
  1066  			assert.Equal(t, "2.0", res.JSONRPC)
  1067  
  1068  			if res.Result != nil {
  1069  				var result interface{}
  1070  				err = json.Unmarshal(res.Result, &result)
  1071  				require.NoError(t, err)
  1072  
  1073  				if result != nil || testCase.ExpectedResult != nil {
  1074  					var batch map[string]interface{}
  1075  					err = json.Unmarshal(res.Result, &batch)
  1076  					require.NoError(t, err)
  1077  					assert.Equal(t, tc.ExpectedResult.Number.Hex(), batch["number"].(string))
  1078  					assert.Equal(t, tc.ExpectedResult.Coinbase.String(), batch["coinbase"].(string))
  1079  					assert.Equal(t, tc.ExpectedResult.StateRoot.String(), batch["stateRoot"].(string))
  1080  					assert.Equal(t, tc.ExpectedResult.GlobalExitRoot.String(), batch["globalExitRoot"].(string))
  1081  					assert.Equal(t, tc.ExpectedResult.LocalExitRoot.String(), batch["localExitRoot"].(string))
  1082  					assert.Equal(t, tc.ExpectedResult.AccInputHash.String(), batch["accInputHash"].(string))
  1083  					assert.Equal(t, tc.ExpectedResult.Timestamp.Hex(), batch["timestamp"].(string))
  1084  					assert.Equal(t, tc.ExpectedResult.SendSequencesTxHash.String(), batch["sendSequencesTxHash"].(string))
  1085  					assert.Equal(t, tc.ExpectedResult.VerifyBatchTxHash.String(), batch["verifyBatchTxHash"].(string))
  1086  					batchTxs := batch["transactions"].([]interface{})
  1087  					for i, txOrHash := range tc.ExpectedResult.Transactions {
  1088  						switch batchTxOrHash := batchTxs[i].(type) {
  1089  						case string:
  1090  							assert.Equal(t, txOrHash.Hash.String(), batchTxOrHash)
  1091  						case map[string]interface{}:
  1092  							tx := txOrHash.Tx
  1093  							assert.Equal(t, tx.Nonce.Hex(), batchTxOrHash["nonce"].(string))
  1094  							assert.Equal(t, tx.GasPrice.Hex(), batchTxOrHash["gasPrice"].(string))
  1095  							assert.Equal(t, tx.Gas.Hex(), batchTxOrHash["gas"].(string))
  1096  							assert.Equal(t, tx.To.String(), batchTxOrHash["to"].(string))
  1097  							assert.Equal(t, tx.Value.Hex(), batchTxOrHash["value"].(string))
  1098  							assert.Equal(t, tx.Input.Hex(), batchTxOrHash["input"].(string))
  1099  							assert.Equal(t, tx.V.Hex(), batchTxOrHash["v"].(string))
  1100  							assert.Equal(t, tx.R.Hex(), batchTxOrHash["r"].(string))
  1101  							assert.Equal(t, tx.S.Hex(), batchTxOrHash["s"].(string))
  1102  							assert.Equal(t, tx.Hash.String(), batchTxOrHash["hash"].(string))
  1103  							assert.Equal(t, strings.ToLower(tx.From.String()), strings.ToLower(batchTxOrHash["from"].(string)))
  1104  							assert.Equal(t, tx.BlockHash.String(), batchTxOrHash["blockHash"].(string))
  1105  							assert.Equal(t, tx.BlockNumber.Hex(), batchTxOrHash["blockNumber"].(string))
  1106  							assert.Equal(t, tx.TxIndex.Hex(), batchTxOrHash["transactionIndex"].(string))
  1107  							assert.Equal(t, tx.ChainID.Hex(), batchTxOrHash["chainId"].(string))
  1108  							assert.Equal(t, tx.Type.Hex(), batchTxOrHash["type"].(string))
  1109  						}
  1110  					}
  1111  					expectedBatchL2DataHex := "0x" + common.Bytes2Hex(testCase.ExpectedResult.BatchL2Data)
  1112  					assert.Equal(t, expectedBatchL2DataHex, batch["batchL2Data"].(string))
  1113  				}
  1114  			}
  1115  
  1116  			if res.Error != nil || testCase.ExpectedError != nil {
  1117  				assert.Equal(t, testCase.ExpectedError.ErrorCode(), res.Error.Code)
  1118  				assert.Equal(t, testCase.ExpectedError.Error(), res.Error.Message)
  1119  			}
  1120  		})
  1121  	}
  1122  }
  1123  
  1124  func ptrUint64(n uint64) *uint64 {
  1125  	return &n
  1126  }
  1127  
  1128  func ptrArgUint64FromUint(n uint) *types.ArgUint64 {
  1129  	tmp := types.ArgUint64(n)
  1130  	return &tmp
  1131  }
  1132  
  1133  func ptrArgUint64FromUint64(n uint64) *types.ArgUint64 {
  1134  	tmp := types.ArgUint64(n)
  1135  	return &tmp
  1136  }
  1137  
  1138  func ptrHash(h common.Hash) *common.Hash {
  1139  	return &h
  1140  }
  1141  
  1142  func signTx(tx *ethTypes.Transaction, chainID uint64) *ethTypes.Transaction {
  1143  	privateKey, _ := crypto.GenerateKey()
  1144  	auth, _ := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(0).SetUint64(chainID))
  1145  	signedTx, _ := auth.Signer(auth.From, tx)
  1146  	return signedTx
  1147  }