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 }