github.com/iotexproject/iotex-core@v1.14.1-rc1/api/grpcserver_integrity_test.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package api 7 8 import ( 9 "bytes" 10 "context" 11 "encoding/hex" 12 "math" 13 "math/big" 14 "regexp" 15 "strconv" 16 "testing" 17 "time" 18 19 "github.com/golang/mock/gomock" 20 "github.com/iotexproject/go-pkgs/hash" 21 "github.com/iotexproject/iotex-address/address" 22 "github.com/iotexproject/iotex-election/test/mock/mock_committee" 23 "github.com/iotexproject/iotex-proto/golang/iotexapi" 24 "github.com/iotexproject/iotex-proto/golang/iotextypes" 25 "github.com/pkg/errors" 26 "github.com/stretchr/testify/require" 27 "google.golang.org/grpc/codes" 28 "google.golang.org/grpc/status" 29 "google.golang.org/protobuf/proto" 30 "google.golang.org/protobuf/types/known/timestamppb" 31 32 "github.com/iotexproject/iotex-core/action" 33 "github.com/iotexproject/iotex-core/action/protocol" 34 "github.com/iotexproject/iotex-core/action/protocol/poll" 35 "github.com/iotexproject/iotex-core/actpool" 36 "github.com/iotexproject/iotex-core/blockchain/block" 37 "github.com/iotexproject/iotex-core/blockchain/genesis" 38 "github.com/iotexproject/iotex-core/consensus" 39 "github.com/iotexproject/iotex-core/db" 40 "github.com/iotexproject/iotex-core/pkg/unit" 41 "github.com/iotexproject/iotex-core/pkg/version" 42 "github.com/iotexproject/iotex-core/state" 43 "github.com/iotexproject/iotex-core/test/identityset" 44 "github.com/iotexproject/iotex-core/test/mock/mock_blockchain" 45 "github.com/iotexproject/iotex-core/testutil" 46 ) 47 48 const lld = "lifeLongDelegates" 49 50 var ( 51 _testTransfer, _ = action.SignedTransfer(identityset.Address(28).String(), 52 identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, testutil.TestGasLimit, 53 big.NewInt(testutil.TestGasPriceInt64)) 54 55 _testTransferHash, _ = _testTransfer.Hash() 56 _testTransferPb = _testTransfer.Proto() 57 58 _testExecution, _ = action.SignedExecution(identityset.Address(29).String(), 59 identityset.PrivateKey(29), 1, big.NewInt(0), testutil.TestGasLimit, 60 big.NewInt(testutil.TestGasPriceInt64), []byte{}) 61 62 _testExecutionHash, _ = _testExecution.Hash() 63 _testExecutionPb = _testExecution.Proto() 64 65 // invalid nounce 66 _testTransferInvalid1, _ = action.SignedTransfer(identityset.Address(28).String(), 67 identityset.PrivateKey(28), 2, big.NewInt(10), []byte{}, testutil.TestGasLimit, 68 big.NewInt(testutil.TestGasPriceInt64)) 69 _testTransferInvalid1Pb = _testTransferInvalid1.Proto() 70 71 // invalid gas price 72 _testTransferInvalid2, _ = action.SignedTransfer(identityset.Address(28).String(), 73 identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, testutil.TestGasLimit, 74 big.NewInt(-1)) 75 _testTransferInvalid2Pb = _testTransferInvalid2.Proto() 76 77 // invalid balance 78 _testTransferInvalid3, _ = action.SignedTransfer(identityset.Address(29).String(), 79 identityset.PrivateKey(29), 3, big.NewInt(29), []byte{}, testutil.TestGasLimit, 80 big.NewInt(testutil.TestGasPriceInt64)) 81 _testTransferInvalid3Pb = _testTransferInvalid3.Proto() 82 83 // nonce is too high 84 _testTransferInvalid4, _ = action.SignedTransfer(identityset.Address(28).String(), 85 identityset.PrivateKey(28), actpool.DefaultConfig.MaxNumActsPerAcct+10, big.NewInt(1), 86 []byte{}, uint64(100000), big.NewInt(0)) 87 _testTransferInvalid4Pb = _testTransferInvalid4.Proto() 88 89 // replace act with lower gas 90 _testTransferInvalid5, _ = action.SignedTransfer(identityset.Address(28).String(), 91 identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, 10000, 92 big.NewInt(testutil.TestGasPriceInt64)) 93 _testTransferInvalid5Pb = _testTransferInvalid5.Proto() 94 95 // gas is too low 96 _testTransferInvalid6, _ = action.SignedTransfer(identityset.Address(28).String(), 97 identityset.PrivateKey(28), 3, big.NewInt(10), []byte{}, 100, 98 big.NewInt(testutil.TestGasPriceInt64)) 99 _testTransferInvalid6Pb = _testTransferInvalid6.Proto() 100 101 // negative transfer amout 102 _testTransferInvalid7, _ = action.SignedTransfer(identityset.Address(28).String(), 103 identityset.PrivateKey(28), 3, big.NewInt(-10), []byte{}, 10000, 104 big.NewInt(testutil.TestGasPriceInt64)) 105 _testTransferInvalid7Pb = _testTransferInvalid7.Proto() 106 107 // gas is too large 108 _largeData = make([]byte, 1e2) 109 _testTransferInvalid8, _ = action.SignedTransfer(identityset.Address(28).String(), 110 identityset.PrivateKey(28), 3, big.NewInt(10), _largeData, 10000, 111 big.NewInt(testutil.TestGasPriceInt64)) 112 _testTransferInvalid8Pb = _testTransferInvalid8.Proto() 113 ) 114 115 var ( 116 _delegates = []genesis.Delegate{ 117 { 118 OperatorAddrStr: identityset.Address(0).String(), 119 VotesStr: "10", 120 }, 121 { 122 OperatorAddrStr: identityset.Address(1).String(), 123 VotesStr: "10", 124 }, 125 { 126 OperatorAddrStr: identityset.Address(2).String(), 127 VotesStr: "10", 128 }, 129 } 130 ) 131 132 var ( 133 _getAccountTests = []struct { 134 in string 135 address string 136 balance string 137 nonce uint64 138 pendingNonce uint64 139 numActions uint64 140 }{ 141 {identityset.Address(30).String(), 142 "io1d4c5lp4ea4754wy439g2t99ue7wryu5r2lslh2", 143 "3", 144 0, 145 9, 146 9, 147 }, 148 { 149 identityset.Address(27).String(), 150 "io1mflp9m6hcgm2qcghchsdqj3z3eccrnekx9p0ms", 151 "9999999999999999999999898950", 152 0, 153 6, 154 6, 155 }, 156 } 157 158 _getActionsTests = []struct { 159 start uint64 160 count uint64 161 numActions int 162 }{ 163 { 164 1, 165 11, 166 11, 167 }, 168 { 169 11, 170 5, 171 4, 172 }, 173 { 174 1, 175 0, 176 0, 177 }, 178 } 179 180 _getActionTests = []struct { 181 // Arguments 182 checkPending bool 183 in string 184 // Expected Values 185 nonce uint64 186 senderPubKey string 187 blkNumber uint64 188 }{ 189 { 190 checkPending: false, 191 in: hex.EncodeToString(_transferHash1[:]), 192 nonce: 1, 193 senderPubKey: _testTransfer1.SrcPubkey().HexString(), 194 blkNumber: 1, 195 }, 196 { 197 checkPending: false, 198 in: hex.EncodeToString(_transferHash2[:]), 199 nonce: 5, 200 senderPubKey: _testTransfer2.SrcPubkey().HexString(), 201 blkNumber: 2, 202 }, 203 { 204 checkPending: false, 205 in: hex.EncodeToString(_executionHash1[:]), 206 nonce: 6, 207 senderPubKey: _testExecution1.SrcPubkey().HexString(), 208 blkNumber: 2, 209 }, 210 } 211 212 _getActionsByAddressTests = []struct { 213 address string 214 start uint64 215 count uint64 216 numActions int 217 }{ 218 { 219 identityset.Address(27).String(), 220 0, 221 3, 222 2, 223 }, 224 { 225 identityset.Address(30).String(), 226 1, 227 8, 228 8, 229 }, 230 { 231 identityset.Address(33).String(), 232 2, 233 1, 234 0, 235 }, 236 } 237 238 _getUnconfirmedActionsByAddressTests = []struct { 239 address string 240 start uint64 241 count uint64 242 numActions int 243 }{ 244 { 245 identityset.Address(27).String(), 246 0, 247 4, 248 4, 249 }, 250 { 251 identityset.Address(27).String(), 252 2, 253 0, 254 0, 255 }, 256 } 257 258 _getActionsByBlockTests = []struct { 259 blkHeight uint64 260 start uint64 261 count uint64 262 numActions int 263 firstTxGas string 264 }{ 265 { 266 2, 267 0, 268 7, 269 7, 270 "0", 271 }, 272 { 273 4, 274 2, 275 5, 276 3, 277 "0", 278 }, 279 { 280 3, 281 0, 282 0, 283 0, 284 "", 285 }, 286 { 287 1, 288 0, 289 math.MaxUint64, 290 2, 291 "0", 292 }, 293 } 294 295 _getBlockMetasTests = []struct { 296 start, count uint64 297 numBlks int 298 gasLimit, gasUsed uint64 299 }{ 300 { 301 1, 302 4, 303 4, 304 20000, 305 10000, 306 }, 307 { 308 2, 309 5, 310 3, 311 120000, 312 60100, 313 }, 314 { 315 1, 316 0, 317 0, 318 20000, 319 10000, 320 }, 321 // genesis block 322 { 323 0, 324 1, 325 1, 326 0, 327 0, 328 }, 329 } 330 331 _getBlockMetaTests = []struct { 332 blkHeight uint64 333 numActions int64 334 transferAmount string 335 logsBloom string 336 }{ 337 { 338 2, 339 7, 340 "6", 341 "", 342 }, 343 { 344 4, 345 5, 346 "2", 347 "", 348 }, 349 } 350 351 _getChainMetaTests = []struct { 352 // Arguments 353 emptyChain bool 354 tpsWindow int 355 pollProtocolType string 356 // Expected values 357 height uint64 358 numActions int64 359 tps int64 360 tpsFloat float32 361 epoch *iotextypes.EpochData 362 }{ 363 { 364 emptyChain: true, 365 }, 366 367 { 368 false, 369 1, 370 lld, 371 4, 372 15, 373 1, 374 5 / 10.0, 375 &iotextypes.EpochData{ 376 Num: 1, 377 Height: 1, 378 GravityChainStartHeight: 1, 379 }, 380 }, 381 { 382 false, 383 5, 384 "governanceChainCommittee", 385 4, 386 15, 387 2, 388 15 / 13.0, 389 &iotextypes.EpochData{ 390 Num: 1, 391 Height: 1, 392 GravityChainStartHeight: 100, 393 }, 394 }, 395 } 396 397 _sendActionTests = []struct { 398 // Arguments 399 actionPb *iotextypes.Action 400 // Expected Values 401 actionHash string 402 }{ 403 { 404 _testTransferPb, 405 hex.EncodeToString(_testTransferHash[:]), 406 }, 407 { 408 _testExecutionPb, 409 hex.EncodeToString(_testExecutionHash[:]), 410 }, 411 } 412 413 _getReceiptByActionTests = []struct { 414 in string 415 status uint64 416 blkHeight uint64 417 }{ 418 { 419 hex.EncodeToString(_transferHash1[:]), 420 uint64(iotextypes.ReceiptStatus_Success), 421 1, 422 }, 423 { 424 hex.EncodeToString(_transferHash2[:]), 425 uint64(iotextypes.ReceiptStatus_Success), 426 2, 427 }, 428 { 429 hex.EncodeToString(_executionHash1[:]), 430 uint64(iotextypes.ReceiptStatus_Success), 431 2, 432 }, 433 { 434 hex.EncodeToString(_executionHash3[:]), 435 uint64(iotextypes.ReceiptStatus_Success), 436 4, 437 }, 438 } 439 440 _readContractTests = []struct { 441 execHash string 442 callerAddr string 443 actionHash string 444 retValue string 445 gasConsumed uint64 446 }{ 447 { 448 hex.EncodeToString(_executionHash1[:]), 449 "", 450 "08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4", 451 "", 452 10100, 453 }, 454 } 455 456 _suggestGasPriceTests = []struct { 457 defaultGasPrice uint64 458 suggestedGasPrice uint64 459 }{ 460 { 461 1, 462 1, 463 }, 464 } 465 466 _estimateGasForActionTests = []struct { 467 actionHash string 468 estimatedGas uint64 469 }{ 470 { 471 hex.EncodeToString(_transferHash1[:]), 472 10000, 473 }, 474 { 475 hex.EncodeToString(_transferHash2[:]), 476 10000, 477 }, 478 } 479 480 _readUnclaimedBalanceTests = []struct { 481 // Arguments 482 protocolID string 483 methodName string 484 addr string 485 // Expected values 486 returnErr bool 487 balance *big.Int 488 }{ 489 { 490 protocolID: "rewarding", 491 methodName: "UnclaimedBalance", 492 addr: identityset.Address(0).String(), 493 returnErr: false, 494 balance: unit.ConvertIotxToRau(64), // 4 block * 36 IOTX reward by default = 144 IOTX 495 }, 496 { 497 protocolID: "rewarding", 498 methodName: "UnclaimedBalance", 499 addr: identityset.Address(1).String(), 500 returnErr: false, 501 balance: unit.ConvertIotxToRau(0), // 4 block * 36 IOTX reward by default = 144 IOTX 502 }, 503 { 504 protocolID: "Wrong ID", 505 methodName: "UnclaimedBalance", 506 addr: identityset.Address(27).String(), 507 returnErr: true, 508 }, 509 { 510 protocolID: "rewarding", 511 methodName: "Wrong Method", 512 addr: identityset.Address(27).String(), 513 returnErr: true, 514 }, 515 } 516 517 _readCandidatesByEpochTests = []struct { 518 // Arguments 519 protocolID string 520 protocolType string 521 methodName string 522 epoch uint64 523 // Expected Values 524 numDelegates int 525 }{ 526 { 527 protocolID: "poll", 528 protocolType: lld, 529 methodName: "CandidatesByEpoch", 530 epoch: 1, 531 numDelegates: 3, 532 }, 533 { 534 protocolID: "poll", 535 protocolType: "governanceChainCommittee", 536 methodName: "CandidatesByEpoch", 537 epoch: 1, 538 numDelegates: 2, 539 }, 540 } 541 542 _readBlockProducersByEpochTests = []struct { 543 // Arguments 544 protocolID string 545 protocolType string 546 methodName string 547 epoch uint64 548 numCandidateDelegates uint64 549 // Expected Values 550 numBlockProducers int 551 }{ 552 { 553 protocolID: "poll", 554 protocolType: lld, 555 methodName: "BlockProducersByEpoch", 556 epoch: 1, 557 numBlockProducers: 3, 558 }, 559 { 560 protocolID: "poll", 561 protocolType: "governanceChainCommittee", 562 methodName: "BlockProducersByEpoch", 563 epoch: 1, 564 numCandidateDelegates: 2, 565 numBlockProducers: 2, 566 }, 567 { 568 protocolID: "poll", 569 protocolType: "governanceChainCommittee", 570 methodName: "BlockProducersByEpoch", 571 epoch: 1, 572 numCandidateDelegates: 1, 573 numBlockProducers: 1, 574 }, 575 } 576 577 _readActiveBlockProducersByEpochTests = []struct { 578 // Arguments 579 protocolID string 580 protocolType string 581 methodName string 582 epoch uint64 583 numDelegates uint64 584 // Expected Values 585 numActiveBlockProducers int 586 }{ 587 { 588 protocolID: "poll", 589 protocolType: lld, 590 methodName: "ActiveBlockProducersByEpoch", 591 epoch: 1, 592 numActiveBlockProducers: 3, 593 }, 594 { 595 protocolID: "poll", 596 protocolType: "governanceChainCommittee", 597 methodName: "ActiveBlockProducersByEpoch", 598 epoch: 1, 599 numDelegates: 2, 600 numActiveBlockProducers: 2, 601 }, 602 { 603 protocolID: "poll", 604 protocolType: "governanceChainCommittee", 605 methodName: "ActiveBlockProducersByEpoch", 606 epoch: 1, 607 numDelegates: 1, 608 numActiveBlockProducers: 1, 609 }, 610 } 611 612 _readRollDPoSMetaTests = []struct { 613 // Arguments 614 protocolID string 615 methodName string 616 height uint64 617 // Expected Values 618 result uint64 619 }{ 620 { 621 protocolID: "rolldpos", 622 methodName: "NumCandidateDelegates", 623 result: 36, 624 }, 625 { 626 protocolID: "rolldpos", 627 methodName: "NumDelegates", 628 result: 24, 629 }, 630 } 631 632 _readEpochCtxTests = []struct { 633 // Arguments 634 protocolID string 635 methodName string 636 argument uint64 637 // Expected Values 638 result uint64 639 }{ 640 { 641 protocolID: "rolldpos", 642 methodName: "NumSubEpochs", 643 argument: 1, 644 result: 2, 645 }, 646 { 647 protocolID: "rolldpos", 648 methodName: "NumSubEpochs", 649 argument: 1816201, 650 result: 30, 651 }, 652 { 653 protocolID: "rolldpos", 654 methodName: "EpochNumber", 655 argument: 100, 656 result: 3, 657 }, 658 { 659 protocolID: "rolldpos", 660 methodName: "EpochHeight", 661 argument: 5, 662 result: 193, 663 }, 664 { 665 protocolID: "rolldpos", 666 methodName: "EpochLastHeight", 667 argument: 1000, 668 result: 48000, 669 }, 670 { 671 protocolID: "rolldpos", 672 methodName: "SubEpochNumber", 673 argument: 121, 674 result: 1, 675 }, 676 } 677 678 _getEpochMetaTests = []struct { 679 // Arguments 680 EpochNumber uint64 681 pollProtocolType string 682 // Expected Values 683 epochData *iotextypes.EpochData 684 numBlksInEpoch int 685 numConsenusBlockProducers int 686 numActiveCensusBlockProducers int 687 }{ 688 { 689 1, 690 lld, 691 &iotextypes.EpochData{ 692 Num: 1, 693 Height: 1, 694 GravityChainStartHeight: 1, 695 }, 696 4, 697 24, 698 24, 699 }, 700 { 701 1, 702 "governanceChainCommittee", 703 &iotextypes.EpochData{ 704 Num: 1, 705 Height: 1, 706 GravityChainStartHeight: 100, 707 }, 708 4, 709 6, 710 6, 711 }, 712 } 713 714 _getRawBlocksTest = []struct { 715 // Arguments 716 startHeight uint64 717 count uint64 718 withReceipts bool 719 // Expected Values 720 numBlks int 721 numActions int 722 numReceipts int 723 }{ 724 { 725 1, 726 1, 727 false, 728 1, 729 2, 730 0, 731 }, 732 { 733 1, 734 2, 735 true, 736 2, 737 9, 738 9, 739 }, 740 // genesis block 741 { 742 0, 743 1, 744 true, 745 1, 746 0, 747 0, 748 }, 749 } 750 751 _getLogsByRangeTest = []struct { 752 // Arguments 753 address []string 754 topics []*iotexapi.Topics 755 fromBlock uint64 756 count uint64 757 // Expected Values 758 numLogs int 759 }{ 760 { 761 address: []string{}, 762 topics: []*iotexapi.Topics{}, 763 fromBlock: 1, 764 count: 100, 765 numLogs: 4, 766 }, 767 { 768 address: []string{}, 769 topics: []*iotexapi.Topics{}, 770 fromBlock: 1, 771 count: 100, 772 numLogs: 4, 773 }, 774 } 775 776 _getImplicitLogByBlockHeightTest = []struct { 777 height uint64 778 code codes.Code 779 }{ 780 { 781 1, codes.OK, 782 }, 783 { 784 2, codes.OK, 785 }, 786 { 787 3, codes.OK, 788 }, 789 { 790 4, codes.OK, 791 }, 792 { 793 5, codes.InvalidArgument, 794 }, 795 } 796 797 _getActionByActionHashTest = []struct { 798 h hash.Hash256 799 expectedNounce uint64 800 }{ 801 { 802 _transferHash1, 803 1, 804 }, 805 { 806 _transferHash2, 807 5, 808 }, 809 { 810 _executionHash1, 811 6, 812 }, 813 { 814 _executionHash3, 815 2, 816 }, 817 } 818 ) 819 820 func TestGrpcServer_GetAccountIntegrity(t *testing.T) { 821 require := require.New(t) 822 cfg := newConfig() 823 cfg.api.GRPCPort = testutil.RandomPort() 824 svr, bc, dao, _, _, actPool, bfIndexFile, err := createServerV2(cfg, true) 825 require.NoError(err) 826 grpcHandler := newGRPCHandler(svr.core) 827 defer func() { 828 testutil.CleanupPath(bfIndexFile) 829 }() 830 831 // deploy a contract 832 contractCode := "6080604052348015600f57600080fd5b5060de8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b60008082409050807f2d93f7749862d33969fb261757410b48065a1bc86a56da5c47820bd063e2338260405160405180910390a28091505091905056fea265627a7a723158200a258cd08ea99ee11aa68c78b6d2bf7ea912615a1e64a81b90a2abca2dd59cfa64736f6c634300050c0032" 833 contract, err := deployContractV2(bc, dao, actPool, identityset.PrivateKey(13), 1, bc.TipHeight(), contractCode) 834 require.NoError(err) 835 require.True(len(contract) > 0) 836 837 // read contract address 838 request := &iotexapi.GetAccountRequest{Address: contract} 839 res, err := grpcHandler.GetAccount(context.Background(), request) 840 require.NoError(err) 841 accountMeta := res.AccountMeta 842 require.Equal(contract, accountMeta.Address) 843 require.Equal("0", accountMeta.Balance) 844 require.EqualValues(0, accountMeta.Nonce) 845 require.EqualValues(1, accountMeta.PendingNonce) 846 require.EqualValues(0, accountMeta.NumActions) 847 require.True(accountMeta.IsContract) 848 require.True(len(accountMeta.ContractByteCode) > 0) 849 require.Contains(contractCode, hex.EncodeToString(accountMeta.ContractByteCode)) 850 851 // success 852 for _, test := range _getAccountTests { 853 request := &iotexapi.GetAccountRequest{Address: test.in} 854 res, err := grpcHandler.GetAccount(context.Background(), request) 855 require.NoError(err) 856 accountMeta := res.AccountMeta 857 require.Equal(test.address, accountMeta.Address) 858 require.Equal(test.balance, accountMeta.Balance) 859 require.Equal(test.nonce, accountMeta.Nonce) 860 require.Equal(test.pendingNonce, accountMeta.PendingNonce) 861 require.Equal(test.numActions, accountMeta.NumActions) 862 require.EqualValues(5, res.BlockIdentifier.Height) 863 require.NotZero(res.BlockIdentifier.Hash) 864 } 865 // failure 866 _, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{}) 867 require.Error(err) 868 // error account 869 _, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{Address: "io3fn88lge6hyzmruh40cn6l3e49dfkqzqk3lgtq3"}) 870 require.Error(err) 871 872 // success: reward pool 873 res, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{Address: address.RewardingPoolAddr}) 874 require.NoError(err) 875 require.Equal(address.RewardingPoolAddr, res.AccountMeta.Address) 876 require.Equal("200000000000000000000101000", res.AccountMeta.Balance) 877 require.EqualValues(5, res.BlockIdentifier.Height) 878 require.NotZero(res.BlockIdentifier.Hash) 879 880 //failure: protocol staking isn't registered 881 res, err = grpcHandler.GetAccount(context.Background(), &iotexapi.GetAccountRequest{Address: address.StakingBucketPoolAddr}) 882 require.Contains(err.Error(), "protocol staking isn't registered") 883 } 884 885 func TestGrpcServer_GetActionsIntegrity(t *testing.T) { 886 require := require.New(t) 887 cfg := newConfig() 888 cfg.api.GRPCPort = testutil.RandomPort() 889 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 890 require.NoError(err) 891 grpcHandler := newGRPCHandler(svr.core) 892 defer func() { 893 testutil.CleanupPath(bfIndexFile) 894 }() 895 896 for _, test := range _getActionsTests { 897 request := &iotexapi.GetActionsRequest{ 898 Lookup: &iotexapi.GetActionsRequest_ByIndex{ 899 ByIndex: &iotexapi.GetActionsByIndexRequest{ 900 Start: test.start, 901 Count: test.count, 902 }, 903 }, 904 } 905 906 res, err := grpcHandler.GetActions(context.Background(), request) 907 if test.count == 0 { 908 require.Error(err) 909 } else { 910 require.NoError(err) 911 require.Equal(test.numActions, len(res.ActionInfo)) 912 } 913 914 // TODO (huof6829): create a core service with hasActionIndex disabled to test 915 } 916 917 // failure: empty request 918 _, err = grpcHandler.GetActions(context.Background(), &iotexapi.GetActionsRequest{}) 919 require.Error(err) 920 921 // failure: range exceed limit 922 _, err = grpcHandler.GetActions(context.Background(), 923 &iotexapi.GetActionsRequest{ 924 Lookup: &iotexapi.GetActionsRequest_ByIndex{ 925 ByIndex: &iotexapi.GetActionsByIndexRequest{ 926 Start: 1, 927 Count: 100000, 928 }, 929 }, 930 }) 931 require.Error(err) 932 933 // failure: start exceed limit 934 _, err = grpcHandler.GetActions(context.Background(), 935 &iotexapi.GetActionsRequest{ 936 Lookup: &iotexapi.GetActionsRequest_ByIndex{ 937 ByIndex: &iotexapi.GetActionsByIndexRequest{ 938 Start: 100000, 939 Count: 1, 940 }, 941 }, 942 }) 943 require.Error(err) 944 } 945 946 func TestGrpcServer_GetActionIntegrity(t *testing.T) { 947 require := require.New(t) 948 cfg := newConfig() 949 cfg.api.GRPCPort = testutil.RandomPort() 950 svr, _, dao, _, _, _, bfIndexFile, err := createServerV2(cfg, true) 951 require.NoError(err) 952 grpcHandler := newGRPCHandler(svr.core) 953 defer func() { 954 testutil.CleanupPath(bfIndexFile) 955 }() 956 957 for _, test := range _getActionTests { 958 request := &iotexapi.GetActionsRequest{ 959 Lookup: &iotexapi.GetActionsRequest_ByHash{ 960 ByHash: &iotexapi.GetActionByHashRequest{ 961 ActionHash: test.in, 962 CheckPending: test.checkPending, 963 }, 964 }, 965 } 966 res, err := grpcHandler.GetActions(context.Background(), request) 967 require.NoError(err) 968 require.Equal(1, len(res.ActionInfo)) 969 act := res.ActionInfo[0] 970 require.Equal(test.nonce, act.Action.GetCore().GetNonce()) 971 require.Equal(test.senderPubKey, hex.EncodeToString(act.Action.SenderPubKey)) 972 if !test.checkPending { 973 blk, err := dao.GetBlockByHeight(test.blkNumber) 974 require.NoError(err) 975 timeStamp := blk.Header.Proto().GetCore().GetTimestamp() 976 _blkHash := blk.HashBlock() 977 require.Equal(hex.EncodeToString(_blkHash[:]), act.BlkHash) 978 require.Equal(test.blkNumber, act.BlkHeight) 979 require.Equal(timeStamp, act.Timestamp) 980 } else { 981 require.Equal(hex.EncodeToString(hash.ZeroHash256[:]), act.BlkHash) 982 require.Nil(act.Timestamp) 983 require.Equal(uint64(0), act.BlkHeight) 984 } 985 } 986 987 // failure: invalid hash 988 _, err = grpcHandler.GetActions(context.Background(), 989 &iotexapi.GetActionsRequest{ 990 Lookup: &iotexapi.GetActionsRequest_ByHash{ 991 ByHash: &iotexapi.GetActionByHashRequest{ 992 ActionHash: "0x58df1e9cb0572fea48e8ce9d9b787ae557c304657d01890f4fc5ea88a1f44c3e", 993 CheckPending: true, 994 }, 995 }, 996 }) 997 require.Error(err) 998 } 999 1000 func TestGrpcServer_GetActionsByAddressIntegrity(t *testing.T) { 1001 require := require.New(t) 1002 cfg := newConfig() 1003 cfg.api.GRPCPort = testutil.RandomPort() 1004 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1005 require.NoError(err) 1006 grpcHandler := newGRPCHandler(svr.core) 1007 defer func() { 1008 testutil.CleanupPath(bfIndexFile) 1009 }() 1010 1011 for _, test := range _getActionsByAddressTests { 1012 request := &iotexapi.GetActionsRequest{ 1013 Lookup: &iotexapi.GetActionsRequest_ByAddr{ 1014 ByAddr: &iotexapi.GetActionsByAddressRequest{ 1015 Address: test.address, 1016 Start: test.start, 1017 Count: test.count, 1018 }, 1019 }, 1020 } 1021 res, err := grpcHandler.GetActions(context.Background(), request) 1022 require.NoError(err) 1023 require.Equal(test.numActions, len(res.ActionInfo)) 1024 if test.numActions == 0 { 1025 // returns empty response body in case of no result 1026 require.Equal(&iotexapi.GetActionsResponse{}, res) 1027 } 1028 var prevAct *iotexapi.ActionInfo 1029 for _, act := range res.ActionInfo { 1030 if prevAct != nil { 1031 require.True(act.Timestamp.GetSeconds() >= prevAct.Timestamp.GetSeconds()) 1032 } 1033 prevAct = act 1034 } 1035 if test.start > 0 && len(res.ActionInfo) > 0 { 1036 request = &iotexapi.GetActionsRequest{ 1037 Lookup: &iotexapi.GetActionsRequest_ByAddr{ 1038 ByAddr: &iotexapi.GetActionsByAddressRequest{ 1039 Address: test.address, 1040 Start: 0, 1041 Count: test.start, 1042 }, 1043 }, 1044 } 1045 prevRes, err := grpcHandler.GetActions(context.Background(), request) 1046 require.NoError(err) 1047 require.True(prevRes.ActionInfo[len(prevRes.ActionInfo)-1].Timestamp.GetSeconds() <= res.ActionInfo[0].Timestamp.GetSeconds()) 1048 } 1049 } 1050 } 1051 1052 func TestGrpcServer_GetUnconfirmedActionsByAddressIntegrity(t *testing.T) { 1053 require := require.New(t) 1054 cfg := newConfig() 1055 cfg.api.GRPCPort = testutil.RandomPort() 1056 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, true) 1057 require.NoError(err) 1058 grpcHandler := newGRPCHandler(svr.core) 1059 defer func() { 1060 testutil.CleanupPath(bfIndexFile) 1061 }() 1062 1063 for _, test := range _getUnconfirmedActionsByAddressTests { 1064 request := &iotexapi.GetActionsRequest{ 1065 Lookup: &iotexapi.GetActionsRequest_UnconfirmedByAddr{ 1066 UnconfirmedByAddr: &iotexapi.GetUnconfirmedActionsByAddressRequest{ 1067 Address: test.address, 1068 Start: test.start, 1069 Count: test.count, 1070 }, 1071 }, 1072 } 1073 res, err := grpcHandler.GetActions(context.Background(), request) 1074 if test.count == 0 { 1075 require.Error(err) 1076 continue 1077 } 1078 require.NoError(err) 1079 require.Equal(test.numActions, len(res.ActionInfo)) 1080 require.Equal(test.address, res.ActionInfo[0].Sender) 1081 } 1082 } 1083 1084 func TestGrpcServer_GetActionsByBlockIntegrity(t *testing.T) { 1085 require := require.New(t) 1086 cfg := newConfig() 1087 cfg.api.GRPCPort = testutil.RandomPort() 1088 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1089 require.NoError(err) 1090 grpcHandler := newGRPCHandler(svr.core) 1091 defer func() { 1092 testutil.CleanupPath(bfIndexFile) 1093 }() 1094 1095 for _, test := range _getActionsByBlockTests { 1096 request := &iotexapi.GetActionsRequest{ 1097 Lookup: &iotexapi.GetActionsRequest_ByBlk{ 1098 ByBlk: &iotexapi.GetActionsByBlockRequest{ 1099 BlkHash: _blkHash[test.blkHeight], 1100 Start: test.start, 1101 Count: test.count, 1102 }, 1103 }, 1104 } 1105 res, err := grpcHandler.GetActions(context.Background(), request) 1106 if test.count == 0 { 1107 require.Error(err) 1108 continue 1109 } 1110 require.NoError(err) 1111 require.Equal(test.numActions, len(res.ActionInfo)) 1112 if test.numActions > 0 { 1113 require.Equal(test.firstTxGas, res.ActionInfo[0].GasFee) 1114 } 1115 for _, v := range res.ActionInfo { 1116 require.Equal(test.blkHeight, v.BlkHeight) 1117 require.Equal(_blkHash[test.blkHeight], v.BlkHash) 1118 } 1119 } 1120 } 1121 1122 func TestGrpcServer_GetBlockMetasIntegrity(t *testing.T) { 1123 require := require.New(t) 1124 cfg := newConfig() 1125 cfg.api.GRPCPort = testutil.RandomPort() 1126 genesis.SetGenesisTimestamp(cfg.genesis.Timestamp) 1127 block.LoadGenesisHash(&cfg.genesis) 1128 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1129 require.NoError(err) 1130 grpcHandler := newGRPCHandler(svr.core) 1131 defer func() { 1132 testutil.CleanupPath(bfIndexFile) 1133 }() 1134 1135 for _, test := range _getBlockMetasTests { 1136 request := &iotexapi.GetBlockMetasRequest{ 1137 Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{ 1138 ByIndex: &iotexapi.GetBlockMetasByIndexRequest{ 1139 Start: test.start, 1140 Count: test.count, 1141 }, 1142 }, 1143 } 1144 res, err := grpcHandler.GetBlockMetas(context.Background(), request) 1145 if test.count == 0 { 1146 require.Error(err) 1147 continue 1148 } 1149 require.NoError(err) 1150 require.Equal(test.numBlks, len(res.BlkMetas)) 1151 meta := res.BlkMetas[0] 1152 require.Equal(test.gasLimit, meta.GasLimit) 1153 require.Equal(test.gasUsed, meta.GasUsed) 1154 if test.start == 0 { 1155 // genesis block 1156 h := block.GenesisHash() 1157 require.Equal(meta.Hash, hex.EncodeToString(h[:])) 1158 } 1159 var prevBlkPb *iotextypes.BlockMeta 1160 for _, blkPb := range res.BlkMetas { 1161 if prevBlkPb != nil { 1162 require.True(blkPb.Height > prevBlkPb.Height) 1163 } 1164 prevBlkPb = blkPb 1165 } 1166 } 1167 // failure: empty request 1168 _, err = grpcHandler.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{}) 1169 require.Error(err) 1170 1171 _, err = grpcHandler.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{ 1172 Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{ 1173 ByIndex: &iotexapi.GetBlockMetasByIndexRequest{Start: 10, Count: 1}, 1174 }, 1175 }) 1176 require.Error(err) 1177 1178 _, err = grpcHandler.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{ 1179 Lookup: &iotexapi.GetBlockMetasRequest_ByHash{ 1180 ByHash: &iotexapi.GetBlockMetaByHashRequest{BlkHash: "0xa2e8e0c9cafbe93f2b7f7c9d32534bc6fde95f2185e5f2aaa6bf7ebdf1a6610a"}, 1181 }, 1182 }) 1183 require.Error(err) 1184 } 1185 1186 func TestGrpcServer_GetBlockMetaIntegrity(t *testing.T) { 1187 require := require.New(t) 1188 cfg := newConfig() 1189 cfg.api.GRPCPort = testutil.RandomPort() 1190 svr, bc, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1191 require.NoError(err) 1192 grpcHandler := newGRPCHandler(svr.core) 1193 defer func() { 1194 testutil.CleanupPath(bfIndexFile) 1195 }() 1196 1197 for _, test := range _getBlockMetaTests { 1198 header, err := bc.BlockHeaderByHeight(test.blkHeight) 1199 require.NoError(err) 1200 _blkHash := header.HashBlock() 1201 request := &iotexapi.GetBlockMetasRequest{ 1202 Lookup: &iotexapi.GetBlockMetasRequest_ByHash{ 1203 ByHash: &iotexapi.GetBlockMetaByHashRequest{ 1204 BlkHash: hex.EncodeToString(_blkHash[:]), 1205 }, 1206 }, 1207 } 1208 res, err := grpcHandler.GetBlockMetas(context.Background(), request) 1209 require.NoError(err) 1210 require.Equal(1, len(res.BlkMetas)) 1211 blkPb := res.BlkMetas[0] 1212 require.Equal(test.blkHeight, blkPb.Height) 1213 require.Equal(test.numActions, blkPb.NumActions) 1214 require.Equal(test.transferAmount, blkPb.TransferAmount) 1215 require.Equal(header.LogsBloomfilter(), nil) 1216 require.Equal(test.logsBloom, blkPb.LogsBloom) 1217 } 1218 } 1219 1220 func TestGrpcServer_GetChainMetaIntegrity(t *testing.T) { 1221 require := require.New(t) 1222 ctrl := gomock.NewController(t) 1223 1224 var pol poll.Protocol 1225 for _, test := range _getChainMetaTests { 1226 cfg := newConfig() 1227 if test.pollProtocolType == lld { 1228 pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates) 1229 } else if test.pollProtocolType == "governanceChainCommittee" { 1230 committee := mock_committee.NewMockCommittee(ctrl) 1231 slasher, _ := poll.NewSlasher( 1232 func(uint64, uint64) (map[string]uint64, error) { 1233 return nil, nil 1234 }, 1235 nil, 1236 nil, 1237 nil, 1238 nil, 1239 cfg.genesis.NumCandidateDelegates, 1240 cfg.genesis.NumDelegates, 1241 cfg.genesis.DardanellesNumSubEpochs, 1242 cfg.genesis.ProductivityThreshold, 1243 cfg.genesis.ProbationEpochPeriod, 1244 cfg.genesis.UnproductiveDelegateMaxCacheSize, 1245 cfg.genesis.ProbationIntensityRate) 1246 pol, _ = poll.NewGovernanceChainCommitteeProtocol( 1247 nil, 1248 committee, 1249 uint64(123456), 1250 func(uint64) (time.Time, error) { return time.Now(), nil }, 1251 cfg.chain.PollInitialCandidatesInterval, 1252 slasher) 1253 committee.EXPECT().HeightByTime(gomock.Any()).Return(test.epoch.GravityChainStartHeight, nil) 1254 } 1255 1256 cfg.api.GRPCPort = testutil.RandomPort() 1257 cfg.api.TpsWindow = test.tpsWindow 1258 svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false) 1259 require.NoError(err) 1260 grpcHandler := newGRPCHandler(svr.core) 1261 defer func() { 1262 testutil.CleanupPath(bfIndexFile) 1263 }() 1264 if pol != nil { 1265 require.NoError(pol.ForceRegister(registry)) 1266 } 1267 if test.emptyChain { 1268 mbc := mock_blockchain.NewMockBlockchain(ctrl) 1269 mbc.EXPECT().TipHeight().Return(uint64(0)).Times(1) 1270 mbc.EXPECT().ChainID().Return(uint32(1)).Times(1) 1271 coreService, ok := svr.core.(*coreService) 1272 require.True(ok) 1273 // TODO: create a core service with empty chain to test 1274 coreService.bc = mbc 1275 } 1276 res, err := grpcHandler.GetChainMeta(context.Background(), &iotexapi.GetChainMetaRequest{}) 1277 require.NoError(err) 1278 chainMetaPb := res.ChainMeta 1279 require.Equal(test.height, chainMetaPb.Height) 1280 require.Equal(test.numActions, chainMetaPb.NumActions) 1281 require.Equal(test.tps, chainMetaPb.Tps) 1282 if test.epoch != nil { 1283 require.Equal(test.epoch.Num, chainMetaPb.Epoch.Num) 1284 require.Equal(test.epoch.Height, chainMetaPb.Epoch.Height) 1285 require.Equal(test.epoch.GravityChainStartHeight, chainMetaPb.Epoch.GravityChainStartHeight) 1286 } 1287 } 1288 } 1289 1290 func TestGrpcServer_SendActionIntegrity(t *testing.T) { 1291 require := require.New(t) 1292 cfg := newConfig() 1293 cfg.api.GRPCPort = testutil.RandomPort() 1294 cfg.genesis.MidwayBlockHeight = 10 1295 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, true) 1296 require.NoError(err) 1297 grpcHandler := newGRPCHandler(svr.core) 1298 defer func() { 1299 testutil.CleanupPath(bfIndexFile) 1300 }() 1301 1302 coreService, ok := svr.core.(*coreService) 1303 require.True(ok) 1304 broadcastHandlerCount := 0 1305 coreService.broadcastHandler = func(_ context.Context, _ uint32, _ proto.Message) error { 1306 broadcastHandlerCount++ 1307 return nil 1308 } 1309 coreService.messageBatcher = nil 1310 1311 for i, test := range _sendActionTests { 1312 request := &iotexapi.SendActionRequest{Action: test.actionPb} 1313 res, err := grpcHandler.SendAction(context.Background(), request) 1314 require.NoError(err) 1315 require.Equal(i+1, broadcastHandlerCount) 1316 require.Equal(test.actionHash, res.ActionHash) 1317 } 1318 1319 // 3 failure cases 1320 ctx := context.Background() 1321 tests := []struct { 1322 cfg func() testConfig 1323 action *iotextypes.Action 1324 err string 1325 }{ 1326 { 1327 func() testConfig { 1328 return newConfig() 1329 }, 1330 &iotextypes.Action{}, 1331 "invalid signature length", 1332 }, 1333 { 1334 func() testConfig { 1335 return newConfig() 1336 }, 1337 &iotextypes.Action{ 1338 Signature: action.ValidSig, 1339 }, 1340 "empty action proto to load", 1341 }, 1342 /* TODO: revise unit test 1343 { 1344 func() testConfig { 1345 cfg := newConfig() 1346 cfg.actPoll.MaxNumActsPerPool = 8 1347 return cfg 1348 }, 1349 _testTransferPb, 1350 action.ErrTxPoolOverflow.Error(), 1351 }, 1352 */ 1353 { 1354 func() testConfig { 1355 return newConfig() 1356 }, 1357 _testTransferInvalid1Pb, 1358 action.ErrNonceTooLow.Error(), 1359 }, 1360 { 1361 func() testConfig { 1362 return newConfig() 1363 }, 1364 _testTransferInvalid2Pb, 1365 action.ErrUnderpriced.Error(), 1366 }, 1367 { 1368 func() testConfig { 1369 return newConfig() 1370 }, 1371 _testTransferInvalid3Pb, 1372 action.ErrInsufficientFunds.Error(), 1373 }, 1374 } 1375 1376 for _, test := range tests { 1377 request := &iotexapi.SendActionRequest{Action: test.action} 1378 cfg := test.cfg() 1379 cfg.api.GRPCPort = testutil.RandomPort() 1380 svr, _, _, _, _, _, file, err := createServerV2(cfg, true) 1381 require.NoError(err) 1382 grpcHandler := newGRPCHandler(svr.core) 1383 defer func() { 1384 testutil.CleanupPath(file) 1385 }() 1386 1387 _, err = grpcHandler.SendAction(ctx, request) 1388 require.Contains(err.Error(), test.err) 1389 } 1390 } 1391 1392 func TestGrpcServer_StreamLogsIntegrity(t *testing.T) { 1393 require := require.New(t) 1394 cfg := newConfig() 1395 cfg.api.GRPCPort = testutil.RandomPort() 1396 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, true) 1397 require.NoError(err) 1398 grpcHandler := newGRPCHandler(svr.core) 1399 defer func() { 1400 testutil.CleanupPath(bfIndexFile) 1401 }() 1402 1403 err = grpcHandler.StreamLogs(&iotexapi.StreamLogsRequest{}, nil) 1404 require.Error(err) 1405 } 1406 1407 func TestGrpcServer_GetReceiptByActionIntegrity(t *testing.T) { 1408 require := require.New(t) 1409 cfg := newConfig() 1410 cfg.api.GRPCPort = testutil.RandomPort() 1411 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1412 require.NoError(err) 1413 grpcHandler := newGRPCHandler(svr.core) 1414 defer func() { 1415 testutil.CleanupPath(bfIndexFile) 1416 }() 1417 1418 for _, test := range _getReceiptByActionTests { 1419 request := &iotexapi.GetReceiptByActionRequest{ActionHash: test.in} 1420 res, err := grpcHandler.GetReceiptByAction(context.Background(), request) 1421 require.NoError(err) 1422 receiptPb := res.ReceiptInfo.Receipt 1423 require.Equal(test.status, receiptPb.Status) 1424 require.Equal(test.blkHeight, receiptPb.BlkHeight) 1425 require.NotEqual(hash.ZeroHash256, res.ReceiptInfo.BlkHash) 1426 } 1427 1428 // failure: empty request 1429 _, err = grpcHandler.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{ActionHash: "0x"}) 1430 require.Error(err) 1431 // failure: wrong hash 1432 _, err = grpcHandler.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{ActionHash: "b7faffcb8b01fa9f32112155bcb93d714f599eab3178e577e88dafd2140bfc5a"}) 1433 require.Error(err) 1434 1435 } 1436 1437 func TestGrpcServer_GetServerMetaIntegrity(t *testing.T) { 1438 require := require.New(t) 1439 cfg := newConfig() 1440 cfg.api.GRPCPort = testutil.RandomPort() 1441 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1442 require.NoError(err) 1443 grpcHandler := newGRPCHandler(svr.core) 1444 defer func() { 1445 testutil.CleanupPath(bfIndexFile) 1446 }() 1447 1448 resProto, err := grpcHandler.GetServerMeta(context.Background(), &iotexapi.GetServerMetaRequest{}) 1449 res := resProto.GetServerMeta() 1450 require.Equal(res.BuildTime, version.BuildTime) 1451 require.Equal(res.GoVersion, version.GoVersion) 1452 require.Equal(res.GitStatus, version.GitStatus) 1453 require.Equal(res.PackageCommitID, version.PackageCommitID) 1454 require.Equal(res.PackageVersion, version.PackageVersion) 1455 } 1456 1457 func TestGrpcServer_ReadContractIntegrity(t *testing.T) { 1458 require := require.New(t) 1459 cfg := newConfig() 1460 cfg.api.GRPCPort = testutil.RandomPort() 1461 svr, _, dao, indexer, _, _, bfIndexFile, err := createServerV2(cfg, false) 1462 require.NoError(err) 1463 grpcHandler := newGRPCHandler(svr.core) 1464 defer func() { 1465 testutil.CleanupPath(bfIndexFile) 1466 }() 1467 1468 for _, test := range _readContractTests { 1469 hash, err := hash.HexStringToHash256(test.execHash) 1470 require.NoError(err) 1471 ai, err := indexer.GetActionIndex(hash[:]) 1472 require.NoError(err) 1473 blk, err := dao.GetBlockByHeight(ai.BlockHeight()) 1474 require.NoError(err) 1475 exec, _, err := blk.ActionByHash(hash) 1476 require.NoError(err) 1477 request := &iotexapi.ReadContractRequest{ 1478 Execution: exec.Proto().GetCore().GetExecution(), 1479 CallerAddress: test.callerAddr, 1480 GasLimit: exec.GasLimit(), 1481 GasPrice: big.NewInt(unit.Qev).String(), 1482 } 1483 1484 res, err := grpcHandler.ReadContract(context.Background(), request) 1485 require.NoError(err) 1486 require.Equal(test.retValue, res.Data) 1487 require.EqualValues(1, res.Receipt.Status) 1488 require.Equal(test.actionHash, hex.EncodeToString(res.Receipt.ActHash)) 1489 require.Equal(test.gasConsumed, res.Receipt.GasConsumed) 1490 } 1491 } 1492 1493 func TestGrpcServer_SuggestGasPriceIntegrity(t *testing.T) { 1494 require := require.New(t) 1495 cfg := newConfig() 1496 cfg.api.GRPCPort = testutil.RandomPort() 1497 for _, test := range _suggestGasPriceTests { 1498 cfg.api.GasStation.DefaultGas = test.defaultGasPrice 1499 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1500 require.NoError(err) 1501 grpcHandler := newGRPCHandler(svr.core) 1502 defer func() { 1503 testutil.CleanupPath(bfIndexFile) 1504 }() 1505 res, err := grpcHandler.SuggestGasPrice(context.Background(), &iotexapi.SuggestGasPriceRequest{}) 1506 require.NoError(err) 1507 require.Equal(test.suggestedGasPrice, res.GasPrice) 1508 } 1509 } 1510 1511 func TestGrpcServer_EstimateGasForActionIntegrity(t *testing.T) { 1512 require := require.New(t) 1513 cfg := newConfig() 1514 cfg.api.GRPCPort = testutil.RandomPort() 1515 svr, _, dao, indexer, _, _, bfIndexFile, err := createServerV2(cfg, false) 1516 require.NoError(err) 1517 grpcHandler := newGRPCHandler(svr.core) 1518 defer func() { 1519 testutil.CleanupPath(bfIndexFile) 1520 }() 1521 1522 for _, test := range _estimateGasForActionTests { 1523 hash, err := hash.HexStringToHash256(test.actionHash) 1524 require.NoError(err) 1525 ai, err := indexer.GetActionIndex(hash[:]) 1526 require.NoError(err) 1527 blk, err := dao.GetBlockByHeight(ai.BlockHeight()) 1528 require.NoError(err) 1529 act, _, err := blk.ActionByHash(hash) 1530 require.NoError(err) 1531 request := &iotexapi.EstimateGasForActionRequest{Action: act.Proto()} 1532 1533 res, err := grpcHandler.EstimateGasForAction(context.Background(), request) 1534 require.NoError(err) 1535 require.Equal(test.estimatedGas, res.Gas) 1536 } 1537 } 1538 1539 func TestGrpcServer_EstimateActionGasConsumptionIntegrity(t *testing.T) { 1540 require := require.New(t) 1541 cfg := newConfig() 1542 cfg.api.GRPCPort = testutil.RandomPort() 1543 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1544 require.NoError(err) 1545 grpcHandler := newGRPCHandler(svr.core) 1546 defer func() { 1547 testutil.CleanupPath(bfIndexFile) 1548 }() 1549 1550 // test for contract deploy 1551 data := "608060405234801561001057600080fd5b50610123600102600281600019169055503373ffffffffffffffffffffffffffffffffffffffff166001026003816000191690555060035460025417600481600019169055506102ae806100656000396000f300608060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630cc0e1fb1461007d57806328f371aa146100b05780636b1d752b146100df578063d4b8399214610112578063daea85c514610145578063eb6fd96a14610188575b600080fd5b34801561008957600080fd5b506100926101bb565b60405180826000191660001916815260200191505060405180910390f35b3480156100bc57600080fd5b506100c56101c1565b604051808215151515815260200191505060405180910390f35b3480156100eb57600080fd5b506100f46101d7565b60405180826000191660001916815260200191505060405180910390f35b34801561011e57600080fd5b506101276101dd565b60405180826000191660001916815260200191505060405180910390f35b34801561015157600080fd5b50610186600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101e3565b005b34801561019457600080fd5b5061019d61027c565b60405180826000191660001916815260200191505060405180910390f35b60035481565b6000600454600019166001546000191614905090565b60025481565b60045481565b3373ffffffffffffffffffffffffffffffffffffffff166001028173ffffffffffffffffffffffffffffffffffffffff16600102176001816000191690555060016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600154815600a165627a7a7230582089b5f99476d642b66a213c12cd198207b2e813bb1caf3bd75e22be535ebf5d130029" 1552 byteCodes, err := hex.DecodeString(data) 1553 require.NoError(err) 1554 execution, err := action.NewExecution("", 1, big.NewInt(0), 0, big.NewInt(0), byteCodes) 1555 require.NoError(err) 1556 request := &iotexapi.EstimateActionGasConsumptionRequest{ 1557 Action: &iotexapi.EstimateActionGasConsumptionRequest_Execution{ 1558 Execution: execution.Proto(), 1559 }, 1560 CallerAddress: identityset.Address(0).String(), 1561 } 1562 res, err := grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1563 require.NoError(err) 1564 require.Equal(uint64(286579), res.Gas) 1565 1566 // test for transfer 1567 tran, err := action.NewTransfer(0, big.NewInt(0), "", []byte("123"), 0, big.NewInt(0)) 1568 require.NoError(err) 1569 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1570 Action: &iotexapi.EstimateActionGasConsumptionRequest_Transfer{ 1571 Transfer: tran.Proto(), 1572 }, 1573 CallerAddress: identityset.Address(0).String(), 1574 } 1575 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1576 require.NoError(err) 1577 require.Equal(uint64(10300), res.Gas) 1578 1579 var ( 1580 gaslimit = uint64(1000000) 1581 gasprice = big.NewInt(10) 1582 canAddress = "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza" 1583 payload = []byte("123") 1584 amount = big.NewInt(10) 1585 nonce = uint64(0) 1586 duration = uint32(1000) 1587 autoStake = true 1588 index = uint64(10) 1589 ) 1590 1591 // staking related 1592 // case I: test for StakeCreate 1593 cs, err := action.NewCreateStake(nonce, canAddress, amount.String(), duration, autoStake, payload, gaslimit, gasprice) 1594 require.NoError(err) 1595 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1596 Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeCreate{ 1597 StakeCreate: cs.Proto(), 1598 }, 1599 CallerAddress: identityset.Address(0).String(), 1600 } 1601 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1602 require.NoError(err) 1603 require.Equal(uint64(10300), res.Gas) 1604 1605 // case II: test for StakeUnstake 1606 us, err := action.NewUnstake(nonce, index, payload, gaslimit, gasprice) 1607 require.NoError(err) 1608 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1609 Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeUnstake{ 1610 StakeUnstake: us.Proto(), 1611 }, 1612 CallerAddress: identityset.Address(0).String(), 1613 } 1614 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1615 require.NoError(err) 1616 require.Equal(uint64(10300), res.Gas) 1617 1618 // case III: test for StakeWithdraw 1619 ws, err := action.NewWithdrawStake(nonce, index, payload, gaslimit, gasprice) 1620 require.NoError(err) 1621 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1622 Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeWithdraw{ 1623 StakeWithdraw: ws.Proto(), 1624 }, 1625 CallerAddress: identityset.Address(0).String(), 1626 } 1627 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1628 require.NoError(err) 1629 require.Equal(uint64(10300), res.Gas) 1630 1631 // Case IV: test for StakeDeposit 1632 ds, err := action.NewDepositToStake(nonce, 1, amount.String(), payload, gaslimit, gasprice) 1633 require.NoError(err) 1634 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1635 Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeAddDeposit{ 1636 StakeAddDeposit: ds.Proto(), 1637 }, 1638 CallerAddress: identityset.Address(0).String(), 1639 } 1640 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1641 require.NoError(err) 1642 require.Equal(uint64(10300), res.Gas) 1643 1644 // Case V: test for StakeChangeCandidate 1645 cc, err := action.NewChangeCandidate(nonce, canAddress, index, payload, gaslimit, gasprice) 1646 require.NoError(err) 1647 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1648 Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeChangeCandidate{ 1649 StakeChangeCandidate: cc.Proto(), 1650 }, 1651 CallerAddress: identityset.Address(0).String(), 1652 } 1653 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1654 require.NoError(err) 1655 require.Equal(uint64(10300), res.Gas) 1656 1657 // Case VI: test for StakeRestake 1658 rs, err := action.NewRestake(nonce, index, duration, autoStake, payload, gaslimit, gasprice) 1659 require.NoError(err) 1660 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1661 Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeRestake{ 1662 StakeRestake: rs.Proto(), 1663 }, 1664 CallerAddress: identityset.Address(0).String(), 1665 } 1666 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1667 require.NoError(err) 1668 require.Equal(uint64(10300), res.Gas) 1669 1670 // Case VII: test for StakeTransfer 1671 ts, err := action.NewTransferStake(nonce, canAddress, index, payload, gaslimit, gasprice) 1672 require.NoError(err) 1673 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1674 Action: &iotexapi.EstimateActionGasConsumptionRequest_StakeTransferOwnership{ 1675 StakeTransferOwnership: ts.Proto(), 1676 }, 1677 CallerAddress: identityset.Address(0).String(), 1678 } 1679 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1680 require.NoError(err) 1681 require.Equal(uint64(10300), res.Gas) 1682 1683 // Case VIII: test for CandidateRegister 1684 cr, err := action.NewCandidateRegister(nonce, canAddress, canAddress, canAddress, canAddress, amount.String(), duration, autoStake, payload, gaslimit, gasprice) 1685 require.NoError(err) 1686 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1687 Action: &iotexapi.EstimateActionGasConsumptionRequest_CandidateRegister{ 1688 CandidateRegister: cr.Proto(), 1689 }, 1690 CallerAddress: identityset.Address(0).String(), 1691 } 1692 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1693 require.NoError(err) 1694 require.Equal(uint64(10300), res.Gas) 1695 1696 // Case IX: test for CandidateUpdate 1697 cu, err := action.NewCandidateUpdate(nonce, canAddress, canAddress, canAddress, gaslimit, gasprice) 1698 require.NoError(err) 1699 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1700 Action: &iotexapi.EstimateActionGasConsumptionRequest_CandidateUpdate{ 1701 CandidateUpdate: cu.Proto(), 1702 }, 1703 CallerAddress: identityset.Address(0).String(), 1704 } 1705 res, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1706 require.NoError(err) 1707 require.Equal(uint64(10000), res.Gas) 1708 1709 // Case X: test for action nil 1710 request = &iotexapi.EstimateActionGasConsumptionRequest{ 1711 Action: nil, 1712 CallerAddress: identityset.Address(0).String(), 1713 } 1714 _, err = grpcHandler.EstimateActionGasConsumption(context.Background(), request) 1715 require.Error(err) 1716 } 1717 1718 func TestGrpcServer_ReadUnclaimedBalanceIntegrity(t *testing.T) { 1719 require := require.New(t) 1720 cfg := newConfig() 1721 cfg.api.GRPCPort = testutil.RandomPort() 1722 cfg.consensus.Scheme = consensus.RollDPoSScheme 1723 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1724 require.NoError(err) 1725 grpcHandler := newGRPCHandler(svr.core) 1726 defer func() { 1727 testutil.CleanupPath(bfIndexFile) 1728 }() 1729 1730 for _, test := range _readUnclaimedBalanceTests { 1731 out, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 1732 ProtocolID: []byte(test.protocolID), 1733 MethodName: []byte(test.methodName), 1734 Arguments: [][]byte{[]byte(test.addr)}, 1735 }) 1736 if test.returnErr { 1737 require.Error(err) 1738 continue 1739 } 1740 require.NoError(err) 1741 val, ok := new(big.Int).SetString(string(out.Data), 10) 1742 require.True(ok) 1743 require.Equal(test.balance, val) 1744 } 1745 } 1746 1747 func TestGrpcServer_TotalBalanceIntegrity(t *testing.T) { 1748 require := require.New(t) 1749 cfg := newConfig() 1750 cfg.api.GRPCPort = testutil.RandomPort() 1751 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1752 require.NoError(err) 1753 grpcHandler := newGRPCHandler(svr.core) 1754 defer func() { 1755 testutil.CleanupPath(bfIndexFile) 1756 }() 1757 1758 out, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 1759 ProtocolID: []byte("rewarding"), 1760 MethodName: []byte("TotalBalance"), 1761 Arguments: nil, 1762 }) 1763 require.NoError(err) 1764 val, ok := new(big.Int).SetString(string(out.Data), 10) 1765 require.True(ok) 1766 require.Equal(unit.ConvertIotxToRau(200000000), val) 1767 } 1768 1769 func TestGrpcServer_AvailableBalanceIntegrity(t *testing.T) { 1770 require := require.New(t) 1771 cfg := newConfig() 1772 cfg.consensus.Scheme = consensus.RollDPoSScheme 1773 cfg.api.GRPCPort = testutil.RandomPort() 1774 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 1775 require.NoError(err) 1776 grpcHandler := newGRPCHandler(svr.core) 1777 defer func() { 1778 testutil.CleanupPath(bfIndexFile) 1779 }() 1780 1781 out, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 1782 ProtocolID: []byte("rewarding"), 1783 MethodName: []byte("AvailableBalance"), 1784 Arguments: nil, 1785 }) 1786 require.NoError(err) 1787 val, ok := new(big.Int).SetString(string(out.Data), 10) 1788 require.True(ok) 1789 require.Equal(unit.ConvertIotxToRau(199999936), val) 1790 } 1791 1792 func TestGrpcServer_ReadCandidatesByEpochIntegrity(t *testing.T) { 1793 require := require.New(t) 1794 cfg := newConfig() 1795 cfg.api.GRPCPort = testutil.RandomPort() 1796 1797 ctrl := gomock.NewController(t) 1798 committee := mock_committee.NewMockCommittee(ctrl) 1799 candidates := []*state.Candidate{ 1800 { 1801 Address: "address1", 1802 Votes: big.NewInt(1), 1803 RewardAddress: "rewardAddress", 1804 }, 1805 { 1806 Address: "address2", 1807 Votes: big.NewInt(1), 1808 RewardAddress: "rewardAddress", 1809 }, 1810 } 1811 1812 for _, test := range _readCandidatesByEpochTests { 1813 var pol poll.Protocol 1814 if test.protocolType == lld { 1815 cfg.genesis.Delegates = _delegates 1816 pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates) 1817 } else { 1818 indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore()) 1819 require.NoError(err) 1820 slasher, _ := poll.NewSlasher( 1821 func(uint64, uint64) (map[string]uint64, error) { 1822 return nil, nil 1823 }, 1824 func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) { 1825 return candidates, 0, nil 1826 }, 1827 nil, 1828 nil, 1829 indexer, 1830 cfg.genesis.NumCandidateDelegates, 1831 cfg.genesis.NumDelegates, 1832 cfg.genesis.DardanellesNumSubEpochs, 1833 cfg.genesis.ProductivityThreshold, 1834 cfg.genesis.ProbationEpochPeriod, 1835 cfg.genesis.UnproductiveDelegateMaxCacheSize, 1836 cfg.genesis.ProbationIntensityRate) 1837 pol, _ = poll.NewGovernanceChainCommitteeProtocol( 1838 indexer, 1839 committee, 1840 uint64(123456), 1841 func(uint64) (time.Time, error) { return time.Now(), nil }, 1842 cfg.chain.PollInitialCandidatesInterval, 1843 slasher) 1844 } 1845 svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false) 1846 require.NoError(err) 1847 grpcHandler := newGRPCHandler(svr.core) 1848 defer func() { 1849 testutil.CleanupPath(bfIndexFile) 1850 }() 1851 require.NoError(pol.ForceRegister(registry)) 1852 1853 res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 1854 ProtocolID: []byte(test.protocolID), 1855 MethodName: []byte(test.methodName), 1856 Arguments: [][]byte{[]byte(strconv.FormatUint(test.epoch, 10))}, 1857 }) 1858 require.NoError(err) 1859 var _delegates state.CandidateList 1860 require.NoError(_delegates.Deserialize(res.Data)) 1861 require.Equal(test.numDelegates, len(_delegates)) 1862 } 1863 } 1864 1865 func TestGrpcServer_ReadBlockProducersByEpochIntegrity(t *testing.T) { 1866 require := require.New(t) 1867 cfg := newConfig() 1868 cfg.api.GRPCPort = testutil.RandomPort() 1869 1870 ctrl := gomock.NewController(t) 1871 committee := mock_committee.NewMockCommittee(ctrl) 1872 candidates := []*state.Candidate{ 1873 { 1874 Address: "address1", 1875 Votes: big.NewInt(1), 1876 RewardAddress: "rewardAddress", 1877 }, 1878 { 1879 Address: "address2", 1880 Votes: big.NewInt(1), 1881 RewardAddress: "rewardAddress", 1882 }, 1883 } 1884 1885 for _, test := range _readBlockProducersByEpochTests { 1886 var pol poll.Protocol 1887 if test.protocolType == lld { 1888 cfg.genesis.Delegates = _delegates 1889 pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates) 1890 } else { 1891 indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore()) 1892 require.NoError(err) 1893 slasher, _ := poll.NewSlasher( 1894 func(uint64, uint64) (map[string]uint64, error) { 1895 return nil, nil 1896 }, 1897 func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) { 1898 return candidates, 0, nil 1899 }, 1900 nil, 1901 nil, 1902 indexer, 1903 test.numCandidateDelegates, 1904 cfg.genesis.NumDelegates, 1905 cfg.genesis.DardanellesNumSubEpochs, 1906 cfg.genesis.ProductivityThreshold, 1907 cfg.genesis.ProbationEpochPeriod, 1908 cfg.genesis.UnproductiveDelegateMaxCacheSize, 1909 cfg.genesis.ProbationIntensityRate) 1910 1911 pol, _ = poll.NewGovernanceChainCommitteeProtocol( 1912 indexer, 1913 committee, 1914 uint64(123456), 1915 func(uint64) (time.Time, error) { return time.Now(), nil }, 1916 cfg.chain.PollInitialCandidatesInterval, 1917 slasher) 1918 } 1919 svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false) 1920 require.NoError(err) 1921 grpcHandler := newGRPCHandler(svr.core) 1922 defer func() { 1923 testutil.CleanupPath(bfIndexFile) 1924 }() 1925 require.NoError(pol.ForceRegister(registry)) 1926 res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 1927 ProtocolID: []byte(test.protocolID), 1928 MethodName: []byte(test.methodName), 1929 Arguments: [][]byte{[]byte(strconv.FormatUint(test.epoch, 10))}, 1930 }) 1931 require.NoError(err) 1932 var blockProducers state.CandidateList 1933 require.NoError(blockProducers.Deserialize(res.Data)) 1934 require.Equal(test.numBlockProducers, len(blockProducers)) 1935 } 1936 } 1937 1938 func TestGrpcServer_ReadActiveBlockProducersByEpochIntegrity(t *testing.T) { 1939 require := require.New(t) 1940 cfg := newConfig() 1941 cfg.api.GRPCPort = testutil.RandomPort() 1942 1943 ctrl := gomock.NewController(t) 1944 committee := mock_committee.NewMockCommittee(ctrl) 1945 candidates := []*state.Candidate{ 1946 { 1947 Address: "address1", 1948 Votes: big.NewInt(1), 1949 RewardAddress: "rewardAddress", 1950 }, 1951 { 1952 Address: "address2", 1953 Votes: big.NewInt(1), 1954 RewardAddress: "rewardAddress", 1955 }, 1956 } 1957 1958 for _, test := range _readActiveBlockProducersByEpochTests { 1959 var pol poll.Protocol 1960 if test.protocolType == lld { 1961 cfg.genesis.Delegates = _delegates 1962 pol = poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates) 1963 } else { 1964 indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore()) 1965 require.NoError(err) 1966 slasher, _ := poll.NewSlasher( 1967 func(uint64, uint64) (map[string]uint64, error) { 1968 return nil, nil 1969 }, 1970 func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) { 1971 return candidates, 0, nil 1972 }, 1973 nil, 1974 nil, 1975 indexer, 1976 cfg.genesis.NumCandidateDelegates, 1977 test.numDelegates, 1978 cfg.genesis.DardanellesNumSubEpochs, 1979 cfg.genesis.ProductivityThreshold, 1980 cfg.genesis.ProbationEpochPeriod, 1981 cfg.genesis.UnproductiveDelegateMaxCacheSize, 1982 cfg.genesis.ProbationIntensityRate) 1983 pol, _ = poll.NewGovernanceChainCommitteeProtocol( 1984 indexer, 1985 committee, 1986 uint64(123456), 1987 func(uint64) (time.Time, error) { return time.Now(), nil }, 1988 cfg.chain.PollInitialCandidatesInterval, 1989 slasher) 1990 } 1991 svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false) 1992 require.NoError(err) 1993 grpcHandler := newGRPCHandler(svr.core) 1994 defer func() { 1995 testutil.CleanupPath(bfIndexFile) 1996 }() 1997 require.NoError(pol.ForceRegister(registry)) 1998 1999 res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 2000 ProtocolID: []byte(test.protocolID), 2001 MethodName: []byte(test.methodName), 2002 Arguments: [][]byte{[]byte(strconv.FormatUint(test.epoch, 10))}, 2003 }) 2004 require.NoError(err) 2005 var activeBlockProducers state.CandidateList 2006 require.NoError(activeBlockProducers.Deserialize(res.Data)) 2007 require.Equal(test.numActiveBlockProducers, len(activeBlockProducers)) 2008 } 2009 } 2010 2011 func TestGrpcServer_ReadRollDPoSMetaIntegrity(t *testing.T) { 2012 require := require.New(t) 2013 cfg := newConfig() 2014 cfg.api.GRPCPort = testutil.RandomPort() 2015 for _, test := range _readRollDPoSMetaTests { 2016 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2017 require.NoError(err) 2018 grpcHandler := newGRPCHandler(svr.core) 2019 defer func() { 2020 testutil.CleanupPath(bfIndexFile) 2021 }() 2022 res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 2023 ProtocolID: []byte(test.protocolID), 2024 MethodName: []byte(test.methodName), 2025 }) 2026 require.NoError(err) 2027 result, err := strconv.ParseUint(string(res.Data), 10, 64) 2028 require.NoError(err) 2029 require.Equal(test.result, result) 2030 } 2031 } 2032 2033 func TestGrpcServer_ReadEpochCtxIntegrity(t *testing.T) { 2034 require := require.New(t) 2035 cfg := newConfig() 2036 cfg.api.GRPCPort = testutil.RandomPort() 2037 for _, test := range _readEpochCtxTests { 2038 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2039 require.NoError(err) 2040 grpcHandler := newGRPCHandler(svr.core) 2041 defer func() { 2042 testutil.CleanupPath(bfIndexFile) 2043 }() 2044 res, err := grpcHandler.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 2045 ProtocolID: []byte(test.protocolID), 2046 MethodName: []byte(test.methodName), 2047 Arguments: [][]byte{[]byte(strconv.FormatUint(test.argument, 10))}, 2048 }) 2049 require.NoError(err) 2050 result, err := strconv.ParseUint(string(res.Data), 10, 64) 2051 require.NoError(err) 2052 require.Equal(test.result, result) 2053 } 2054 } 2055 2056 func TestGrpcServer_GetEpochMetaIntegrity(t *testing.T) { 2057 require := require.New(t) 2058 ctrl := gomock.NewController(t) 2059 cfg := newConfig() 2060 cfg.api.GRPCPort = testutil.RandomPort() 2061 svr, _, _, _, registry, _, bfIndexFile, err := createServerV2(cfg, false) 2062 require.NoError(err) 2063 grpcHandler := newGRPCHandler(svr.core) 2064 defer func() { 2065 testutil.CleanupPath(bfIndexFile) 2066 }() 2067 for _, test := range _getEpochMetaTests { 2068 if test.pollProtocolType == lld { 2069 pol := poll.NewLifeLongDelegatesProtocol(cfg.genesis.Delegates) 2070 require.NoError(pol.ForceRegister(registry)) 2071 } else if test.pollProtocolType == "governanceChainCommittee" { 2072 committee := mock_committee.NewMockCommittee(ctrl) 2073 mbc := mock_blockchain.NewMockBlockchain(ctrl) 2074 mbc.EXPECT().Genesis().Return(cfg.genesis).Times(3) 2075 indexer, err := poll.NewCandidateIndexer(db.NewMemKVStore()) 2076 require.NoError(err) 2077 slasher, _ := poll.NewSlasher( 2078 func(uint64, uint64) (map[string]uint64, error) { 2079 return nil, nil 2080 }, 2081 func(protocol.StateReader, uint64, bool, bool) ([]*state.Candidate, uint64, error) { 2082 return []*state.Candidate{ 2083 { 2084 Address: identityset.Address(1).String(), 2085 Votes: big.NewInt(6), 2086 RewardAddress: "rewardAddress", 2087 }, 2088 { 2089 Address: identityset.Address(2).String(), 2090 Votes: big.NewInt(5), 2091 RewardAddress: "rewardAddress", 2092 }, 2093 { 2094 Address: identityset.Address(3).String(), 2095 Votes: big.NewInt(4), 2096 RewardAddress: "rewardAddress", 2097 }, 2098 { 2099 Address: identityset.Address(4).String(), 2100 Votes: big.NewInt(3), 2101 RewardAddress: "rewardAddress", 2102 }, 2103 { 2104 Address: identityset.Address(5).String(), 2105 Votes: big.NewInt(2), 2106 RewardAddress: "rewardAddress", 2107 }, 2108 { 2109 Address: identityset.Address(6).String(), 2110 Votes: big.NewInt(1), 2111 RewardAddress: "rewardAddress", 2112 }, 2113 }, 0, nil 2114 }, 2115 nil, 2116 nil, 2117 indexer, 2118 cfg.genesis.NumCandidateDelegates, 2119 cfg.genesis.NumDelegates, 2120 cfg.genesis.DardanellesNumSubEpochs, 2121 cfg.genesis.ProductivityThreshold, 2122 cfg.genesis.ProbationEpochPeriod, 2123 cfg.genesis.UnproductiveDelegateMaxCacheSize, 2124 cfg.genesis.ProbationIntensityRate) 2125 pol, _ := poll.NewGovernanceChainCommitteeProtocol( 2126 indexer, 2127 committee, 2128 uint64(123456), 2129 func(uint64) (time.Time, error) { return time.Now(), nil }, 2130 cfg.chain.PollInitialCandidatesInterval, 2131 slasher) 2132 require.NoError(pol.ForceRegister(registry)) 2133 committee.EXPECT().HeightByTime(gomock.Any()).Return(test.epochData.GravityChainStartHeight, nil) 2134 2135 mbc.EXPECT().TipHeight().Return(uint64(4)).Times(4) 2136 mbc.EXPECT().BlockHeaderByHeight(gomock.Any()).DoAndReturn(func(height uint64) (*block.Header, error) { 2137 if height > 0 && height <= 4 { 2138 pk := identityset.PrivateKey(int(height)) 2139 blk, err := block.NewBuilder( 2140 block.NewRunnableActionsBuilder().Build(), 2141 ). 2142 SetHeight(height). 2143 SetTimestamp(time.Time{}). 2144 SignAndBuild(pk) 2145 if err != nil { 2146 return &block.Header{}, err 2147 } 2148 return &blk.Header, nil 2149 } 2150 return &block.Header{}, errors.Errorf("invalid block height %d", height) 2151 }).AnyTimes() 2152 coreService, ok := svr.core.(*coreService) 2153 require.True(ok) 2154 // TODO: create a core service to test 2155 coreService.bc = mbc 2156 } 2157 2158 coreService, ok := svr.core.(*coreService) 2159 require.True(ok) 2160 coreService.readCache.Clear() 2161 res, err := grpcHandler.GetEpochMeta(context.Background(), &iotexapi.GetEpochMetaRequest{EpochNumber: test.EpochNumber}) 2162 require.NoError(err) 2163 require.Equal(test.epochData.Num, res.EpochData.Num) 2164 require.Equal(test.epochData.Height, res.EpochData.Height) 2165 require.Equal(test.epochData.GravityChainStartHeight, res.EpochData.GravityChainStartHeight) 2166 require.Equal(test.numBlksInEpoch, int(res.TotalBlocks)) 2167 require.Equal(test.numConsenusBlockProducers, len(res.BlockProducersInfo)) 2168 var numActiveBlockProducers int 2169 var prevInfo *iotexapi.BlockProducerInfo 2170 for _, bp := range res.BlockProducersInfo { 2171 if bp.Active { 2172 numActiveBlockProducers++ 2173 } 2174 if prevInfo != nil { 2175 prevVotes, _ := strconv.Atoi(prevInfo.Votes) 2176 currVotes, _ := strconv.Atoi(bp.Votes) 2177 require.True(prevVotes >= currVotes) 2178 } 2179 prevInfo = bp 2180 } 2181 require.Equal(test.numActiveCensusBlockProducers, numActiveBlockProducers) 2182 } 2183 2184 // failure: epoch number 2185 _, err = grpcHandler.GetEpochMeta(context.Background(), &iotexapi.GetEpochMetaRequest{EpochNumber: 0}) 2186 require.Error(err) 2187 } 2188 2189 func TestGrpcServer_GetRawBlocksIntegrity(t *testing.T) { 2190 require := require.New(t) 2191 cfg := newConfig() 2192 cfg.api.GRPCPort = testutil.RandomPort() 2193 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2194 require.NoError(err) 2195 grpcHandler := newGRPCHandler(svr.core) 2196 defer func() { 2197 testutil.CleanupPath(bfIndexFile) 2198 }() 2199 2200 for _, test := range _getRawBlocksTest { 2201 request := &iotexapi.GetRawBlocksRequest{ 2202 StartHeight: test.startHeight, 2203 Count: test.count, 2204 WithReceipts: test.withReceipts, 2205 } 2206 res, err := grpcHandler.GetRawBlocks(context.Background(), request) 2207 require.NoError(err) 2208 blkInfos := res.Blocks 2209 require.Equal(test.numBlks, len(blkInfos)) 2210 if test.startHeight == 0 { 2211 // verify genesis block 2212 header := blkInfos[0].Block.Header.Core 2213 require.EqualValues(version.ProtocolVersion, header.Version) 2214 require.Zero(header.Height) 2215 ts := timestamppb.New(time.Unix(genesis.Timestamp(), 0)) 2216 require.Equal(ts, header.Timestamp) 2217 require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.PrevBlockHash)) 2218 require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.TxRoot)) 2219 require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.DeltaStateDigest)) 2220 require.Equal(0, bytes.Compare(hash.ZeroHash256[:], header.ReceiptRoot)) 2221 } 2222 var numActions, numReceipts int 2223 for _, blkInfo := range blkInfos { 2224 numActions += len(blkInfo.Block.Body.Actions) 2225 numReceipts += len(blkInfo.Receipts) 2226 } 2227 require.Equal(test.numActions, numActions) 2228 require.Equal(test.numReceipts, numReceipts) 2229 } 2230 2231 // failure: invalid count 2232 _, err = grpcHandler.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{ 2233 StartHeight: 1, 2234 Count: 0, 2235 WithReceipts: true, 2236 }) 2237 require.Error(err) 2238 2239 // failure: invalid startHeight 2240 _, err = grpcHandler.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{ 2241 StartHeight: 1000000, 2242 Count: 10, 2243 WithReceipts: true, 2244 }) 2245 require.Error(err) 2246 2247 // failure: invalid endHeight 2248 _, err = grpcHandler.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{ 2249 StartHeight: 3, 2250 Count: 1000, 2251 WithReceipts: true, 2252 }) 2253 require.Error(err) 2254 2255 } 2256 2257 func TestGrpcServer_GetLogsIntegrity(t *testing.T) { 2258 require := require.New(t) 2259 cfg := newConfig() 2260 cfg.api.GRPCPort = testutil.RandomPort() 2261 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2262 require.NoError(err) 2263 grpcHandler := newGRPCHandler(svr.core) 2264 defer func() { 2265 testutil.CleanupPath(bfIndexFile) 2266 }() 2267 2268 for _, test := range _getLogsByRangeTest { 2269 request := &iotexapi.GetLogsRequest{ 2270 Filter: &iotexapi.LogsFilter{ 2271 Address: test.address, 2272 Topics: test.topics, 2273 }, 2274 Lookup: &iotexapi.GetLogsRequest_ByRange{ 2275 ByRange: &iotexapi.GetLogsByRange{ 2276 FromBlock: test.fromBlock, 2277 ToBlock: test.fromBlock + test.count - 1, 2278 }, 2279 }, 2280 } 2281 res, err := grpcHandler.GetLogs(context.Background(), request) 2282 require.NoError(err) 2283 logs := res.Logs 2284 require.Equal(test.numLogs, len(logs)) 2285 } 2286 2287 for _, v := range _blkHash { 2288 h, _ := hash.HexStringToHash256(v) 2289 request := &iotexapi.GetLogsRequest{ 2290 Filter: &iotexapi.LogsFilter{ 2291 Address: []string{}, 2292 Topics: []*iotexapi.Topics{}, 2293 }, 2294 Lookup: &iotexapi.GetLogsRequest_ByBlock{ 2295 ByBlock: &iotexapi.GetLogsByBlock{ 2296 BlockHash: h[:], 2297 }, 2298 }, 2299 } 2300 res, err := grpcHandler.GetLogs(context.Background(), request) 2301 require.NoError(err) 2302 logs := res.Logs 2303 require.Equal(1, len(logs)) 2304 } 2305 2306 // failure: empty request 2307 _, err = grpcHandler.GetLogs(context.Background(), &iotexapi.GetLogsRequest{ 2308 Filter: &iotexapi.LogsFilter{}, 2309 }) 2310 require.Error(err) 2311 2312 // failure: empty filter 2313 _, err = grpcHandler.GetLogs(context.Background(), &iotexapi.GetLogsRequest{}) 2314 require.Error(err) 2315 } 2316 2317 func TestGrpcServer_GetElectionBucketsIntegrity(t *testing.T) { 2318 require := require.New(t) 2319 cfg := newConfig() 2320 cfg.api.GRPCPort = testutil.RandomPort() 2321 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2322 require.NoError(err) 2323 grpcHandler := newGRPCHandler(svr.core) 2324 defer func() { 2325 testutil.CleanupPath(bfIndexFile) 2326 }() 2327 2328 // failure: no native election 2329 request := &iotexapi.GetElectionBucketsRequest{ 2330 EpochNum: 0, 2331 } 2332 _, err = grpcHandler.GetElectionBuckets(context.Background(), request) 2333 require.Error(err) 2334 } 2335 2336 func TestGrpcServer_GetActionByActionHashIntegrity(t *testing.T) { 2337 require := require.New(t) 2338 cfg := newConfig() 2339 cfg.api.GRPCPort = testutil.RandomPort() 2340 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2341 require.NoError(err) 2342 defer func() { 2343 testutil.CleanupPath(bfIndexFile) 2344 }() 2345 2346 for _, test := range _getActionByActionHashTest { 2347 ret, _, _, err := svr.core.ActionByActionHash(test.h) 2348 require.NoError(err) 2349 require.Equal(test.expectedNounce, ret.Envelope.Nonce()) 2350 } 2351 } 2352 2353 func TestGrpcServer_GetTransactionLogByActionHashIntegrity(t *testing.T) { 2354 require := require.New(t) 2355 cfg := newConfig() 2356 cfg.api.GRPCPort = testutil.RandomPort() 2357 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2358 require.NoError(err) 2359 grpcHandler := newGRPCHandler(svr.core) 2360 defer func() { 2361 testutil.CleanupPath(bfIndexFile) 2362 }() 2363 2364 request := &iotexapi.GetTransactionLogByActionHashRequest{ 2365 ActionHash: hex.EncodeToString(hash.ZeroHash256[:]), 2366 } 2367 _, err = grpcHandler.GetTransactionLogByActionHash(context.Background(), request) 2368 require.Error(err) 2369 sta, ok := status.FromError(err) 2370 require.Equal(true, ok) 2371 require.Equal(codes.NotFound, sta.Code()) 2372 2373 for h, log := range _implicitLogs { 2374 request.ActionHash = hex.EncodeToString(h[:]) 2375 res, err := grpcHandler.GetTransactionLogByActionHash(context.Background(), request) 2376 require.NoError(err) 2377 require.Equal(log.Proto(), res.TransactionLog) 2378 } 2379 2380 // TODO (huof6829): Re-enable this test 2381 /* 2382 // check implicit transfer receiver balance 2383 state, err := accountutil.LoadAccount(svr.core.StateFactory(), identityset.Address(31)) 2384 require.NoError(err) 2385 require.Equal(big.NewInt(5), state.Balance) 2386 */ 2387 } 2388 2389 func TestGrpcServer_GetEvmTransfersByBlockHeightIntegrity(t *testing.T) { 2390 require := require.New(t) 2391 cfg := newConfig() 2392 cfg.api.GRPCPort = testutil.RandomPort() 2393 svr, _, _, _, _, _, bfIndexFile, err := createServerV2(cfg, false) 2394 require.NoError(err) 2395 grpcHandler := newGRPCHandler(svr.core) 2396 defer func() { 2397 testutil.CleanupPath(bfIndexFile) 2398 }() 2399 2400 request := &iotexapi.GetTransactionLogByBlockHeightRequest{} 2401 for _, test := range _getImplicitLogByBlockHeightTest { 2402 request.BlockHeight = test.height 2403 res, err := grpcHandler.GetTransactionLogByBlockHeight(context.Background(), request) 2404 if test.code != codes.OK { 2405 require.Error(err) 2406 sta, ok := status.FromError(err) 2407 require.Equal(true, ok) 2408 require.Equal(test.code, sta.Code()) 2409 } else { 2410 require.NotNil(res) 2411 // verify log 2412 for _, log := range res.TransactionLogs.Logs { 2413 l, ok := _implicitLogs[hash.BytesToHash256(log.ActionHash)] 2414 require.True(ok) 2415 require.Equal(l.Proto(), log) 2416 } 2417 require.Equal(test.height, res.BlockIdentifier.Height) 2418 require.Equal(_blkHash[test.height], res.BlockIdentifier.Hash) 2419 } 2420 } 2421 } 2422 2423 func TestGrpcServer_GetActPoolActionsIntegrity(t *testing.T) { 2424 require := require.New(t) 2425 cfg := newConfig() 2426 cfg.api.GRPCPort = testutil.RandomPort() 2427 ctx := genesis.WithGenesisContext(context.Background(), cfg.genesis) 2428 svr, _, _, _, _, actPool, bfIndexFile, err := createServerV2(cfg, false) 2429 require.NoError(err) 2430 grpcHandler := newGRPCHandler(svr.core) 2431 defer func() { 2432 testutil.CleanupPath(bfIndexFile) 2433 }() 2434 2435 res, err := grpcHandler.GetActPoolActions(ctx, &iotexapi.GetActPoolActionsRequest{}) 2436 require.NoError(err) 2437 require.Equal(len(actPool.PendingActionMap()[identityset.Address(27).String()]), len(res.Actions)) 2438 2439 tsf1, err := action.SignedTransfer(identityset.Address(28).String(), identityset.PrivateKey(27), 2, 2440 big.NewInt(20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)) 2441 require.NoError(err) 2442 tsf2, err := action.SignedTransfer(identityset.Address(27).String(), identityset.PrivateKey(27), 3, 2443 big.NewInt(20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)) 2444 require.NoError(err) 2445 tsf3, err := action.SignedTransfer(identityset.Address(29).String(), identityset.PrivateKey(27), 4, 2446 big.NewInt(20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)) 2447 require.NoError(err) 2448 execution1, err := action.SignedExecution(identityset.Address(31).String(), identityset.PrivateKey(27), 5, 2449 big.NewInt(1), testutil.TestGasLimit, big.NewInt(10), []byte{1}) 2450 require.NoError(err) 2451 2452 require.NoError(actPool.Add(ctx, tsf1)) 2453 require.NoError(actPool.Add(ctx, tsf2)) 2454 require.NoError(actPool.Add(ctx, execution1)) 2455 2456 var requests []string 2457 h1, err := tsf1.Hash() 2458 require.NoError(err) 2459 requests = append(requests, hex.EncodeToString(h1[:])) 2460 2461 res, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{}) 2462 require.NoError(err) 2463 require.Equal(len(actPool.PendingActionMap()[identityset.Address(27).String()]), len(res.Actions)) 2464 2465 res, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{ActionHashes: requests}) 2466 require.NoError(err) 2467 require.Equal(1, len(res.Actions)) 2468 2469 h2, err := tsf2.Hash() 2470 require.NoError(err) 2471 requests = append(requests, hex.EncodeToString(h2[:])) 2472 res, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{ActionHashes: requests}) 2473 require.NoError(err) 2474 require.Equal(2, len(res.Actions)) 2475 2476 h3, err := tsf3.Hash() 2477 require.NoError(err) 2478 _, err = grpcHandler.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{ActionHashes: []string{hex.EncodeToString(h3[:])}}) 2479 require.Error(err) 2480 } 2481 2482 func TestGrpcServer_GetEstimateGasSpecialIntegrity(t *testing.T) { 2483 require := require.New(t) 2484 cfg := newConfig() 2485 cfg.api.GRPCPort = testutil.RandomPort() 2486 svr, bc, dao, _, _, actPool, bfIndexFile, err := createServerV2(cfg, true) 2487 require.NoError(err) 2488 grpcHandler := newGRPCHandler(svr.core) 2489 defer func() { 2490 testutil.CleanupPath(bfIndexFile) 2491 }() 2492 2493 // deploy self-desturct contract 2494 contractCode := "608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610196806100606000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632e64cec11461004657806343d726d6146100645780636057361d1461006e575b600080fd5b61004e61008a565b60405161005b9190610124565b60405180910390f35b61006c610094565b005b610088600480360381019061008391906100ec565b6100cd565b005b6000600154905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b8060018190555050565b6000813590506100e681610149565b92915050565b6000602082840312156100fe57600080fd5b600061010c848285016100d7565b91505092915050565b61011e8161013f565b82525050565b60006020820190506101396000830184610115565b92915050565b6000819050919050565b6101528161013f565b811461015d57600080fd5b5056fea264697066735822122060e7a28baea4232a95074b94b50009d1d7b99302ef6556a1f3ce7f46a49f8cc064736f6c63430008000033" 2495 contract, err := deployContractV2(bc, dao, actPool, identityset.PrivateKey(13), 1, bc.TipHeight(), contractCode) 2496 2497 require.NoError(err) 2498 require.True(len(contract) > 0) 2499 2500 // call self-destuct func, which will invoke gas refund policy 2501 data := "43d726d6" 2502 byteCodes, err := hex.DecodeString(data) 2503 require.NoError(err) 2504 execution, err := action.NewExecution(contract, 2, big.NewInt(0), 0, big.NewInt(0), byteCodes) 2505 require.NoError(err) 2506 request := &iotexapi.EstimateActionGasConsumptionRequest{ 2507 Action: &iotexapi.EstimateActionGasConsumptionRequest_Execution{ 2508 Execution: execution.Proto(), 2509 }, 2510 CallerAddress: identityset.Address(13).String(), 2511 } 2512 res, err := grpcHandler.EstimateActionGasConsumption(context.Background(), request) 2513 require.NoError(err) 2514 require.Equal(uint64(10777), res.Gas) 2515 } 2516 2517 func TestChainlinkErrIntegrity(t *testing.T) { 2518 require := require.New(t) 2519 2520 gethFatal := regexp.MustCompile(`(: |^)(exceeds block gas limit|invalid sender|negative value|oversized data|gas uint64 overflow|intrinsic gas too low|nonce too high)$`) 2521 2522 tests := []struct { 2523 testName string 2524 cfg func() testConfig 2525 actions []*iotextypes.Action 2526 errRegex *regexp.Regexp 2527 }{ 2528 { 2529 "NonceTooLow", 2530 func() testConfig { 2531 return newConfig() 2532 }, 2533 []*iotextypes.Action{_testTransferInvalid1Pb}, 2534 regexp.MustCompile(`(: |^)nonce too low$`), 2535 }, 2536 { 2537 "TerminallyUnderpriced", 2538 func() testConfig { 2539 return newConfig() 2540 }, 2541 []*iotextypes.Action{_testTransferInvalid2Pb}, 2542 regexp.MustCompile(`(: |^)transaction underpriced$`), 2543 }, 2544 { 2545 "InsufficientEth", 2546 func() testConfig { 2547 return newConfig() 2548 }, 2549 []*iotextypes.Action{_testTransferInvalid3Pb}, 2550 regexp.MustCompile(`(: |^)(insufficient funds for transfer|insufficient funds for gas \* price \+ value|insufficient balance for transfer)$`), 2551 }, 2552 2553 { 2554 "NonceTooHigh", 2555 func() testConfig { 2556 return newConfig() 2557 }, 2558 []*iotextypes.Action{_testTransferInvalid4Pb}, 2559 gethFatal, 2560 }, 2561 { 2562 "TransactionAlreadyInMempool", 2563 func() testConfig { 2564 return newConfig() 2565 }, 2566 []*iotextypes.Action{_testTransferPb, _testTransferPb}, 2567 regexp.MustCompile(`(: |^)(?i)(known transaction|already known)`), 2568 }, 2569 { 2570 "ReplacementTransactionUnderpriced", 2571 func() testConfig { 2572 return newConfig() 2573 }, 2574 []*iotextypes.Action{_testTransferPb, _testTransferInvalid5Pb}, 2575 regexp.MustCompile(`(: |^)replacement transaction underpriced$`), 2576 }, 2577 { 2578 "IntrinsicGasTooLow", 2579 func() testConfig { 2580 return newConfig() 2581 }, 2582 []*iotextypes.Action{_testTransferInvalid6Pb}, 2583 gethFatal, 2584 }, 2585 { 2586 "NegativeValue", 2587 func() testConfig { 2588 return newConfig() 2589 }, 2590 []*iotextypes.Action{_testTransferInvalid7Pb}, 2591 gethFatal, 2592 }, 2593 { 2594 "ExceedsBlockGasLimit", 2595 func() testConfig { 2596 cfg := newConfig() 2597 cfg.actPoll.MaxGasLimitPerPool = 1e5 2598 return cfg 2599 }, 2600 []*iotextypes.Action{_testTransferInvalid8Pb}, 2601 gethFatal, 2602 }, 2603 } 2604 2605 for i, test := range tests { 2606 t.Run(strconv.Itoa(i), func(t *testing.T) { 2607 cfg := test.cfg() 2608 cfg.api.GRPCPort = testutil.RandomPort() 2609 svr, _, _, _, _, _, file, err := createServerV2(cfg, true) 2610 require.NoError(err) 2611 grpcHandler := newGRPCHandler(svr.core) 2612 defer func() { 2613 testutil.CleanupPath(file) 2614 }() 2615 2616 for _, action := range test.actions { 2617 _, err = grpcHandler.SendAction(context.Background(), &iotexapi.SendActionRequest{Action: action}) 2618 if err != nil { 2619 break 2620 } 2621 } 2622 s, ok := status.FromError(err) 2623 require.True(ok) 2624 require.True(test.errRegex.MatchString(s.Message())) 2625 }) 2626 } 2627 } 2628 2629 func TestGrpcServer_TraceTransactionStructLogsIntegrity(t *testing.T) { 2630 require := require.New(t) 2631 cfg := newConfig() 2632 cfg.api.GRPCPort = testutil.RandomPort() 2633 svr, bc, _, _, _, actPool, bfIndexFile, err := createServerV2(cfg, true) 2634 require.NoError(err) 2635 grpcHandler := newGRPCHandler(svr.core) 2636 defer func() { 2637 testutil.CleanupPath(bfIndexFile) 2638 }() 2639 2640 request := &iotexapi.TraceTransactionStructLogsRequest{ 2641 ActionHash: hex.EncodeToString(hash.ZeroHash256[:]), 2642 } 2643 _, err = grpcHandler.TraceTransactionStructLogs(context.Background(), request) 2644 require.Error(err) 2645 2646 //unsupport type 2647 request.ActionHash = hex.EncodeToString(_transferHash1[:]) 2648 _, err = grpcHandler.TraceTransactionStructLogs(context.Background(), request) 2649 require.Error(err) 2650 2651 // deploy a contract 2652 contractCode := "6080604052348015600f57600080fd5b5060de8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b60008082409050807f2d93f7749862d33969fb261757410b48065a1bc86a56da5c47820bd063e2338260405160405180910390a28091505091905056fea265627a7a723158200a258cd08ea99ee11aa68c78b6d2bf7ea912615a1e64a81b90a2abca2dd59cfa64736f6c634300050c0032" 2653 2654 data, _ := hex.DecodeString(contractCode) 2655 ex1, err := action.SignedExecution(action.EmptyAddress, identityset.PrivateKey(13), 1, big.NewInt(0), 500000, big.NewInt(testutil.TestGasPriceInt64), data) 2656 require.NoError(err) 2657 actPool.Add(context.Background(), ex1) 2658 require.NoError(err) 2659 blk, err := bc.MintNewBlock(testutil.TimestampNow()) 2660 require.NoError(err) 2661 bc.CommitBlock(blk) 2662 require.NoError(err) 2663 actPool.Reset() 2664 ex1Hash, _ := ex1.Hash() 2665 request.ActionHash = hex.EncodeToString(ex1Hash[:]) 2666 ret, err := grpcHandler.TraceTransactionStructLogs(context.Background(), request) 2667 require.NoError(err) 2668 require.Equal(len(ret.StructLogs), 17) 2669 log := ret.StructLogs[0] 2670 require.Equal(log.Depth, int32(1)) 2671 require.Equal(log.Gas, uint64(0x717a0)) 2672 require.Equal(log.GasCost, uint64(0x3)) 2673 require.Equal(log.Op, uint64(0x60)) 2674 require.Equal(log.OpName, "PUSH1") 2675 }