github.com/iotexproject/iotex-core@v1.14.1-rc1/api/grpcserver_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 "context" 10 "encoding/hex" 11 "math/big" 12 "testing" 13 14 "github.com/ethereum/go-ethereum/eth/tracers/logger" 15 "github.com/golang/mock/gomock" 16 "github.com/iotexproject/go-pkgs/hash" 17 "github.com/iotexproject/iotex-proto/golang/iotexapi" 18 "github.com/iotexproject/iotex-proto/golang/iotextypes" 19 "github.com/pkg/errors" 20 "github.com/stretchr/testify/require" 21 22 "github.com/iotexproject/iotex-core/action" 23 apitypes "github.com/iotexproject/iotex-core/api/types" 24 "github.com/iotexproject/iotex-core/blockchain/block" 25 "github.com/iotexproject/iotex-core/pkg/version" 26 "github.com/iotexproject/iotex-core/test/identityset" 27 "github.com/iotexproject/iotex-core/test/mock/mock_apicoreservice" 28 mock_apitypes "github.com/iotexproject/iotex-core/test/mock/mock_apiresponder" 29 ) 30 31 func TestGrpcServer_GetAccount(t *testing.T) { 32 require := require.New(t) 33 ctrl := gomock.NewController(t) 34 defer ctrl.Finish() 35 core := mock_apicoreservice.NewMockCoreService(ctrl) 36 grpcSvr := newGRPCHandler(core) 37 38 t.Run("get acccount", func(t *testing.T) { 39 for _, test := range _getAccountTests { 40 accountMeta := &iotextypes.AccountMeta{ 41 Address: test.address, 42 } 43 blockIdentifier := &iotextypes.BlockIdentifier{} 44 request := &iotexapi.GetAccountRequest{ 45 Address: test.address, 46 } 47 48 core.EXPECT().Account(gomock.Any()).Return(accountMeta, blockIdentifier, nil) 49 50 res, err := grpcSvr.GetAccount(context.Background(), request) 51 require.NoError(err) 52 require.Equal(test.address, res.AccountMeta.Address) 53 } 54 }) 55 56 t.Run("failed to get account", func(t *testing.T) { 57 expectedErr := errors.New("failed to get account") 58 request := &iotexapi.GetAccountRequest{ 59 Address: "io1d4c5lp4ea4754wy439g2t99ue7wryu5r2lslh2", 60 } 61 62 core.EXPECT().Account(gomock.Any()).Return(nil, nil, expectedErr) 63 64 _, err := grpcSvr.GetAccount(context.Background(), request) 65 require.Contains(err.Error(), expectedErr.Error()) 66 }) 67 68 t.Run("invalid address", func(t *testing.T) { 69 expectedErr := errors.New("invalid address") 70 request := &iotexapi.GetAccountRequest{ 71 Address: "9254d943485d0fb859ff63c5581acc44f00fc2110343ac0445b99dfe39a6f1a5", 72 } 73 74 _, err := grpcSvr.GetAccount(context.Background(), request) 75 require.Contains(err.Error(), expectedErr.Error()) 76 }) 77 } 78 79 func TestGrpcServer_GetActions(t *testing.T) { 80 require := require.New(t) 81 ctrl := gomock.NewController(t) 82 defer ctrl.Finish() 83 core := mock_apicoreservice.NewMockCoreService(ctrl) 84 grpcSvr := newGRPCHandler(core) 85 86 t.Run("get actions by address tests", func(t *testing.T) { 87 for _, test := range _getActionsByAddressTests { 88 actInfo := &iotexapi.ActionInfo{ 89 Index: 0, 90 ActHash: "test", 91 } 92 response := []*iotexapi.ActionInfo{} 93 for i := 1; i <= test.numActions; i++ { 94 response = append(response, actInfo) 95 } 96 97 requests := []struct { 98 req *iotexapi.GetActionsRequest 99 call func() 100 }{ 101 { 102 req: &iotexapi.GetActionsRequest{ 103 Lookup: &iotexapi.GetActionsRequest_ByAddr{ 104 ByAddr: &iotexapi.GetActionsByAddressRequest{ 105 Address: test.address, 106 Start: test.start, 107 Count: test.count, 108 }, 109 }, 110 }, 111 call: func() { 112 core.EXPECT().ActionsByAddress(gomock.Any(), gomock.Any(), gomock.Any()).Return(response, nil) 113 }, 114 }, 115 { 116 req: &iotexapi.GetActionsRequest{ 117 Lookup: &iotexapi.GetActionsRequest_UnconfirmedByAddr{ 118 UnconfirmedByAddr: &iotexapi.GetUnconfirmedActionsByAddressRequest{ 119 Address: test.address, 120 Start: test.start, 121 Count: test.count, 122 }, 123 }, 124 }, 125 call: func() { 126 core.EXPECT().UnconfirmedActionsByAddress(gomock.Any(), gomock.Any(), gomock.Any()).Return(response, nil) 127 }, 128 }, 129 { 130 req: &iotexapi.GetActionsRequest{ 131 Lookup: &iotexapi.GetActionsRequest_ByIndex{ 132 ByIndex: &iotexapi.GetActionsByIndexRequest{ 133 Start: test.start, 134 Count: test.count, 135 }, 136 }, 137 }, 138 call: func() { 139 core.EXPECT().Actions(gomock.Any(), gomock.Any()).Return(response, nil) 140 }, 141 }, 142 } 143 144 for _, request := range requests { 145 request.call() 146 res, err := grpcSvr.GetActions(context.Background(), request.req) 147 require.NoError(err) 148 require.Equal(uint64(test.numActions), res.Total) 149 } 150 } 151 }) 152 153 t.Run("get actions by hash", func(t *testing.T) { 154 for _, test := range _getActionTests { 155 response := &iotexapi.ActionInfo{ 156 Index: 0, 157 ActHash: "test", 158 BlkHeight: test.blkNumber, 159 } 160 request := &iotexapi.GetActionsRequest{ 161 Lookup: &iotexapi.GetActionsRequest_ByHash{ 162 ByHash: &iotexapi.GetActionByHashRequest{ 163 ActionHash: test.in, 164 CheckPending: test.checkPending, 165 }, 166 }, 167 } 168 169 core.EXPECT().Action(gomock.Any(), gomock.Any()).Return(response, nil) 170 171 res, err := grpcSvr.GetActions(context.Background(), request) 172 require.NoError(err) 173 require.Len(res.ActionInfo, 1) 174 require.Equal(test.blkNumber, res.ActionInfo[0].BlkHeight) 175 } 176 }) 177 178 t.Run("get actions by block test", func(t *testing.T) { 179 addr1 := identityset.Address(28).String() 180 priKey1 := identityset.PrivateKey(28) 181 182 tsf1, err := action.SignedTransfer(addr1, priKey1, uint64(1), big.NewInt(10), []byte{}, uint64(100000), big.NewInt(0)) 183 require.NoError(err) 184 185 for _, test := range _getActionsByBlockTests { 186 gasConsumed, ok := new(big.Int).SetString(test.firstTxGas, 10) 187 if !ok { 188 gasConsumed = big.NewInt(0) 189 } 190 191 response := &apitypes.BlockWithReceipts{ 192 Block: &block.Block{}, 193 Receipts: []*action.Receipt{}, 194 } 195 for i := 1; i <= test.numActions; i++ { 196 response.Block.Actions = append(response.Block.Actions, tsf1) 197 response.Receipts = append(response.Receipts, &action.Receipt{ 198 BlockHeight: test.blkHeight, 199 GasConsumed: gasConsumed.Uint64(), 200 }) 201 } 202 203 request := &iotexapi.GetActionsRequest{ 204 Lookup: &iotexapi.GetActionsRequest_ByBlk{ 205 ByBlk: &iotexapi.GetActionsByBlockRequest{ 206 BlkHash: _blkHash[test.blkHeight], 207 Start: test.start, 208 Count: test.count, 209 }, 210 }, 211 } 212 213 core.EXPECT().BlockByHash(gomock.Any()).Return(response, nil) 214 215 res, err := grpcSvr.GetActions(context.Background(), request) 216 require.NoError(err) 217 require.Equal(test.numActions-int(test.start), int(res.Total)) 218 } 219 }) 220 221 t.Run("invalid GetActionsRequest type", func(t *testing.T) { 222 expectedErr := errors.New("invalid GetActionsRequest type") 223 request := &iotexapi.GetActionsRequest{} 224 225 _, err := grpcSvr.GetActions(context.Background(), request) 226 require.Contains(err.Error(), expectedErr.Error()) 227 }) 228 229 t.Run("failed to get actions", func(t *testing.T) { 230 expectedErr := errors.New("failed to get actions") 231 request := &iotexapi.GetActionsRequest{ 232 Lookup: &iotexapi.GetActionsRequest_ByHash{ 233 ByHash: &iotexapi.GetActionByHashRequest{ 234 ActionHash: hex.EncodeToString(_transferHash1[:]), 235 CheckPending: false, 236 }, 237 }, 238 } 239 240 core.EXPECT().Action(gomock.Any(), gomock.Any()).Return(nil, expectedErr) 241 242 _, err := grpcSvr.GetActions(context.Background(), request) 243 require.Contains(err.Error(), expectedErr.Error()) 244 }) 245 } 246 247 func TestGrpcServer_GetBlockMetas(t *testing.T) { 248 require := require.New(t) 249 ctrl := gomock.NewController(t) 250 defer ctrl.Finish() 251 core := mock_apicoreservice.NewMockCoreService(ctrl) 252 grpcSvr := newGRPCHandler(core) 253 254 errStr := "get block metas mock test error" 255 reqIndex := &iotexapi.GetBlockMetasRequest{ 256 Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{ 257 ByIndex: &iotexapi.GetBlockMetasByIndexRequest{}, 258 }, 259 } 260 reqHash := &iotexapi.GetBlockMetasRequest{ 261 Lookup: &iotexapi.GetBlockMetasRequest_ByHash{ 262 ByHash: &iotexapi.GetBlockMetaByHashRequest{}, 263 }, 264 } 265 ret := &apitypes.BlockWithReceipts{ 266 Block: &block.Block{}, 267 Receipts: []*action.Receipt{ 268 {}, 269 }, 270 } 271 rets := []*apitypes.BlockWithReceipts{ret} 272 273 t.Run("GetBlockMetasInvalidType", func(t *testing.T) { 274 _, err := grpcSvr.GetBlockMetas(context.Background(), &iotexapi.GetBlockMetasRequest{}) 275 require.Contains(err.Error(), "invalid GetBlockMetasRequest type") 276 }) 277 t.Run("GetBlockMetasByIndexFailed", func(t *testing.T) { 278 core.EXPECT().BlockByHeightRange(gomock.Any(), gomock.Any()).Return(nil, errors.New(errStr)) 279 _, err := grpcSvr.GetBlockMetas(context.Background(), reqIndex) 280 require.Contains(err.Error(), errStr) 281 }) 282 t.Run("GetBlockMetasByIndexSuccess", func(t *testing.T) { 283 core.EXPECT().BlockByHeightRange(gomock.Any(), gomock.Any()).Return(rets, nil) 284 res, err := grpcSvr.GetBlockMetas(context.Background(), reqIndex) 285 require.NoError(err) 286 require.Equal(res.Total, uint64(1)) 287 }) 288 t.Run("GetBlockMetasByHashFailed", func(t *testing.T) { 289 core.EXPECT().BlockByHash(gomock.Any()).Return(nil, errors.New(errStr)) 290 _, err := grpcSvr.GetBlockMetas(context.Background(), reqHash) 291 require.Contains(err.Error(), errStr) 292 }) 293 t.Run("GetBlockMetasByHashSuccess", func(t *testing.T) { 294 core.EXPECT().BlockByHash(gomock.Any()).Return(ret, nil) 295 res, err := grpcSvr.GetBlockMetas(context.Background(), reqHash) 296 require.NoError(err) 297 require.Equal(res.Total, uint64(1)) 298 }) 299 } 300 301 func TestGrpcServer_GetChainMeta(t *testing.T) { 302 require := require.New(t) 303 ctrl := gomock.NewController(t) 304 defer ctrl.Finish() 305 core := mock_apicoreservice.NewMockCoreService(ctrl) 306 grpcSvr := newGRPCHandler(core) 307 chainMeta := &iotextypes.ChainMeta{ 308 Height: 1000, 309 ChainID: 1, 310 Epoch: &iotextypes.EpochData{Num: 7000}, 311 TpsFloat: 11.22, 312 } 313 syncStatus := "sync ok" 314 core.EXPECT().ChainMeta().Return(chainMeta, syncStatus, nil) 315 request := &iotexapi.GetChainMetaRequest{} 316 res, err := grpcSvr.GetChainMeta(context.Background(), request) 317 require.NoError(err) 318 require.Equal(chainMeta, res.ChainMeta) 319 require.Equal(syncStatus, res.SyncStage) 320 } 321 322 func TestGrpcServer_SendAction(t *testing.T) { 323 require := require.New(t) 324 ctrl := gomock.NewController(t) 325 defer ctrl.Finish() 326 core := mock_apicoreservice.NewMockCoreService(ctrl) 327 grpcSvr := newGRPCHandler(core) 328 329 for _, test := range _sendActionTests { 330 core.EXPECT().SendAction(context.Background(), test.actionPb).Return(test.actionHash, nil) 331 request := &iotexapi.SendActionRequest{Action: test.actionPb} 332 res, err := grpcSvr.SendAction(context.Background(), request) 333 require.NoError(err) 334 require.Equal(test.actionHash, res.ActionHash) 335 } 336 } 337 338 func TestGrpcServer_StreamBlocks(t *testing.T) { 339 require := require.New(t) 340 ctrl := gomock.NewController(t) 341 defer ctrl.Finish() 342 core := mock_apicoreservice.NewMockCoreService(ctrl) 343 grpcSvr := newGRPCHandler(core) 344 345 t.Run("addResponder failed", func(t *testing.T) { 346 listener := mock_apitypes.NewMockListener(ctrl) 347 listener.EXPECT().AddResponder(gomock.Any()).Return("", errors.New("mock test")) 348 core.EXPECT().ChainListener().Return(listener) 349 err := grpcSvr.StreamBlocks(&iotexapi.StreamBlocksRequest{}, nil) 350 require.Contains(err.Error(), "mock test") 351 }) 352 353 t.Run("success", func(t *testing.T) { 354 listener := mock_apitypes.NewMockListener(ctrl) 355 listener.EXPECT().AddResponder(gomock.Any()).DoAndReturn(func(g *gRPCBlockListener) (string, error) { 356 go func() { 357 g.errChan <- nil 358 }() 359 return "", nil 360 }) 361 core.EXPECT().ChainListener().Return(listener) 362 err := grpcSvr.StreamBlocks(&iotexapi.StreamBlocksRequest{}, nil) 363 require.NoError(err) 364 }) 365 } 366 367 func TestGrpcServer_StreamLogs(t *testing.T) { 368 require := require.New(t) 369 ctrl := gomock.NewController(t) 370 defer ctrl.Finish() 371 core := mock_apicoreservice.NewMockCoreService(ctrl) 372 grpcSvr := newGRPCHandler(core) 373 374 t.Run("StreamLogsEmptyFilter", func(t *testing.T) { 375 err := grpcSvr.StreamLogs(&iotexapi.StreamLogsRequest{}, nil) 376 require.Contains(err.Error(), "empty filter") 377 }) 378 t.Run("StreamLogsAddResponderFailed", func(t *testing.T) { 379 listener := mock_apitypes.NewMockListener(ctrl) 380 listener.EXPECT().AddResponder(gomock.Any()).Return("", errors.New("mock test")) 381 core.EXPECT().ChainListener().Return(listener) 382 err := grpcSvr.StreamLogs(&iotexapi.StreamLogsRequest{Filter: &iotexapi.LogsFilter{}}, nil) 383 require.Contains(err.Error(), "mock test") 384 }) 385 t.Run("StreamLogsSuccess", func(t *testing.T) { 386 listener := mock_apitypes.NewMockListener(ctrl) 387 listener.EXPECT().AddResponder(gomock.Any()).DoAndReturn(func(g *gRPCLogListener) (string, error) { 388 go func() { 389 g.errChan <- nil 390 }() 391 return "", nil 392 }) 393 core.EXPECT().ChainListener().Return(listener) 394 err := grpcSvr.StreamLogs(&iotexapi.StreamLogsRequest{Filter: &iotexapi.LogsFilter{}}, nil) 395 require.NoError(err) 396 }) 397 } 398 399 func TestGrpcServer_GetReceiptByAction(t *testing.T) { 400 require := require.New(t) 401 ctrl := gomock.NewController(t) 402 defer ctrl.Finish() 403 core := mock_apicoreservice.NewMockCoreService(ctrl) 404 grpcSvr := newGRPCHandler(core) 405 receipt := &action.Receipt{ 406 Status: 1, 407 BlockHeight: 1, 408 ActionHash: hash.BytesToHash256([]byte("test")), 409 GasConsumed: 1, 410 ContractAddress: "test", 411 TxIndex: 1, 412 } 413 414 t.Run("get receipt by action", func(t *testing.T) { 415 core.EXPECT().ReceiptByActionHash(gomock.Any()).Return(receipt, nil) 416 core.EXPECT().BlockHashByBlockHeight(gomock.Any()).Return(hash.ZeroHash256, nil) 417 418 res, err := grpcSvr.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{}) 419 require.NoError(err) 420 require.Equal(receipt.Status, res.ReceiptInfo.Receipt.Status) 421 require.Equal(receipt.BlockHeight, res.ReceiptInfo.Receipt.BlkHeight) 422 require.Equal(receipt.ActionHash[:], res.ReceiptInfo.Receipt.ActHash) 423 require.Equal(receipt.GasConsumed, res.ReceiptInfo.Receipt.GasConsumed) 424 require.Equal(receipt.ContractAddress, res.ReceiptInfo.Receipt.ContractAddress) 425 require.Equal(receipt.TxIndex, res.ReceiptInfo.Receipt.TxIndex) 426 require.Equal(hex.EncodeToString(hash.ZeroHash256[:]), res.ReceiptInfo.BlkHash) 427 }) 428 429 t.Run("failed to get block hash by block height", func(t *testing.T) { 430 expectedErr := errors.New("failed to get block hash by block height") 431 core.EXPECT().ReceiptByActionHash(gomock.Any()).Return(receipt, nil) 432 core.EXPECT().BlockHashByBlockHeight(gomock.Any()).Return(hash.ZeroHash256, expectedErr) 433 434 _, err := grpcSvr.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{}) 435 require.Contains(err.Error(), expectedErr.Error()) 436 }) 437 438 t.Run("failed to get reciept by action hash", func(t *testing.T) { 439 expectedErr := errors.New("failed to get reciept by action hash") 440 core.EXPECT().ReceiptByActionHash(gomock.Any()).Return(receipt, expectedErr) 441 442 _, err := grpcSvr.GetReceiptByAction(context.Background(), &iotexapi.GetReceiptByActionRequest{}) 443 require.Contains(err.Error(), expectedErr.Error()) 444 }) 445 } 446 447 func TestGrpcServer_GetServerMeta(t *testing.T) { 448 require := require.New(t) 449 ctrl := gomock.NewController(t) 450 defer ctrl.Finish() 451 core := mock_apicoreservice.NewMockCoreService(ctrl) 452 grpcSvr := newGRPCHandler(core) 453 454 core.EXPECT().ServerMeta().Return("packageVersion", "packageCommitID", "gitStatus", "goVersion", "buildTime") 455 res, err := grpcSvr.GetServerMeta(context.Background(), &iotexapi.GetServerMetaRequest{}) 456 require.NoError(err) 457 require.Equal("packageVersion", res.ServerMeta.PackageVersion) 458 require.Equal("packageCommitID", res.ServerMeta.PackageCommitID) 459 require.Equal("gitStatus", res.ServerMeta.GitStatus) 460 require.Equal("goVersion", res.ServerMeta.GoVersion) 461 require.Equal("buildTime", res.ServerMeta.BuildTime) 462 } 463 464 func TestGrpcServer_ReadContract(t *testing.T) { 465 require := require.New(t) 466 ctrl := gomock.NewController(t) 467 defer ctrl.Finish() 468 core := mock_apicoreservice.NewMockCoreService(ctrl) 469 grpcSvr := newGRPCHandler(core) 470 response := &iotextypes.Receipt{ 471 ActHash: []byte("08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4"), 472 GasConsumed: 10100, 473 } 474 475 t.Run("read contract", func(t *testing.T) { 476 request := &iotexapi.ReadContractRequest{ 477 Execution: &iotextypes.Execution{ 478 Data: _executionHash1[:], 479 }, 480 CallerAddress: identityset.Address(0).String(), 481 GasLimit: 10100, 482 } 483 core.EXPECT().ReadContract(gomock.Any(), gomock.Any(), gomock.Any()).Return("", response, nil) 484 485 res, err := grpcSvr.ReadContract(context.Background(), request) 486 require.NoError(err) 487 require.Equal([]byte("08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4"), res.Receipt.ActHash) 488 require.Equal(10100, int(res.Receipt.GasConsumed)) 489 }) 490 491 t.Run("read contract from empty address", func(t *testing.T) { 492 request := &iotexapi.ReadContractRequest{ 493 Execution: &iotextypes.Execution{ 494 Data: _executionHash1[:], 495 }, 496 CallerAddress: "", 497 GasLimit: 10100, 498 } 499 core.EXPECT().ReadContract(gomock.Any(), gomock.Any(), gomock.Any()).Return("", response, nil) 500 501 res, err := grpcSvr.ReadContract(context.Background(), request) 502 require.NoError(err) 503 require.Equal([]byte("08b0066e10b5607e47159c2cf7ba36e36d0c980f5108dfca0ec20547a7adace4"), res.Receipt.ActHash) 504 require.Equal(10100, int(res.Receipt.GasConsumed)) 505 }) 506 507 t.Run("failed to read contract", func(t *testing.T) { 508 expectedErr := errors.New("failed to read contract") 509 request := &iotexapi.ReadContractRequest{ 510 Execution: &iotextypes.Execution{ 511 Data: _executionHash1[:], 512 }, 513 CallerAddress: "", 514 GasLimit: 10100, 515 } 516 core.EXPECT().ReadContract(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil, expectedErr) 517 518 _, err := grpcSvr.ReadContract(context.Background(), request) 519 require.Contains(err.Error(), expectedErr.Error()) 520 }) 521 522 t.Run("failed to load execution", func(t *testing.T) { 523 expectedErr := errors.New("empty action proto to load") 524 request := &iotexapi.ReadContractRequest{ 525 CallerAddress: "", 526 GasLimit: 10100, 527 } 528 529 _, err := grpcSvr.ReadContract(context.Background(), request) 530 require.Contains(err.Error(), expectedErr.Error()) 531 }) 532 533 t.Run("invalid caller address", func(t *testing.T) { 534 expectedErr := errors.New("invalid address") 535 request := &iotexapi.ReadContractRequest{ 536 Execution: &iotextypes.Execution{ 537 Data: _executionHash1[:], 538 }, 539 CallerAddress: "9254d943485d0fb859ff63c5581acc44f00fc2110343ac0445b99dfe39a6f1a5", 540 GasLimit: 10100, 541 } 542 543 _, err := grpcSvr.ReadContract(context.Background(), request) 544 require.Contains(err.Error(), expectedErr.Error()) 545 }) 546 } 547 548 func TestGrpcServer_SuggestGasPrice(t *testing.T) { 549 require := require.New(t) 550 ctrl := gomock.NewController(t) 551 defer ctrl.Finish() 552 core := mock_apicoreservice.NewMockCoreService(ctrl) 553 grpcSvr := newGRPCHandler(core) 554 555 core.EXPECT().SuggestGasPrice().Return(uint64(1), nil) 556 res, err := grpcSvr.SuggestGasPrice(context.Background(), &iotexapi.SuggestGasPriceRequest{}) 557 require.NoError(err) 558 require.Equal(uint64(1), res.GasPrice) 559 560 core.EXPECT().SuggestGasPrice().Return(uint64(0), errors.New("mock gas price error")) 561 _, err = grpcSvr.SuggestGasPrice(context.Background(), &iotexapi.SuggestGasPriceRequest{}) 562 require.Contains(err.Error(), "mock gas price error") 563 } 564 565 func TestGrpcServer_EstimateGasForAction(t *testing.T) { 566 require := require.New(t) 567 ctrl := gomock.NewController(t) 568 defer ctrl.Finish() 569 core := mock_apicoreservice.NewMockCoreService(ctrl) 570 grpcSvr := newGRPCHandler(core) 571 572 core.EXPECT().EstimateGasForAction(gomock.Any(), gomock.Any()).Return(uint64(10000), nil) 573 resp, err := grpcSvr.EstimateGasForAction(context.Background(), &iotexapi.EstimateGasForActionRequest{Action: getAction()}) 574 require.NoError(err) 575 require.Equal(uint64(10000), resp.Gas) 576 577 core.EXPECT().EstimateGasForAction(gomock.Any(), gomock.Any()).Return(uint64(0), action.ErrNilProto) 578 _, err = grpcSvr.EstimateGasForAction(context.Background(), &iotexapi.EstimateGasForActionRequest{Action: nil}) 579 require.Contains(err.Error(), action.ErrNilProto.Error()) 580 } 581 582 func TestGrpcServer_EstimateActionGasConsumption(t *testing.T) { 583 require := require.New(t) 584 ctrl := gomock.NewController(t) 585 defer ctrl.Finish() 586 core := mock_apicoreservice.NewMockCoreService(ctrl) 587 grpcSvr := newGRPCHandler(core) 588 request := &iotexapi.EstimateActionGasConsumptionRequest{ 589 CallerAddress: identityset.Address(0).String(), 590 } 591 592 t.Run("Execution is not nil", func(t *testing.T) { 593 core.EXPECT().EstimateExecutionGasConsumption(gomock.Any(), gomock.Any(), gomock.Any()).Return(uint64(10100), nil) 594 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_Execution{ 595 Execution: &iotextypes.Execution{ 596 Data: _executionHash1[:], 597 }, 598 } 599 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 600 require.NoError(err) 601 require.Equal(uint64(10100), res.Gas) 602 }) 603 604 core.EXPECT().EstimateGasForNonExecution(gomock.Any()).Return(uint64(10100), nil).Times(10) 605 606 t.Run("Transfer is not nil", func(t *testing.T) { 607 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_Transfer{ 608 Transfer: &iotextypes.Transfer{ 609 Amount: "1000", 610 Recipient: identityset.Address(29).String(), 611 Payload: []byte("1234567890"), 612 }, 613 } 614 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 615 require.NoError(err) 616 require.Equal(uint64(10100), res.Gas) 617 }) 618 619 t.Run("StakeCreate is not nil", func(t *testing.T) { 620 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeCreate{ 621 StakeCreate: &iotextypes.StakeCreate{ 622 CandidateName: "Candidate", 623 StakedAmount: "1000", 624 StakedDuration: uint32(111), 625 Payload: []byte("1234567890"), 626 }, 627 } 628 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 629 require.NoError(err) 630 require.Equal(uint64(10100), res.Gas) 631 }) 632 633 t.Run("StakeUnstake is not nil", func(t *testing.T) { 634 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeUnstake{ 635 StakeUnstake: &iotextypes.StakeReclaim{ 636 BucketIndex: uint64(111), 637 Payload: []byte("1234567890"), 638 }, 639 } 640 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 641 require.NoError(err) 642 require.Equal(uint64(10100), res.Gas) 643 }) 644 645 t.Run("StakeWithdraw is not nil", func(t *testing.T) { 646 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeWithdraw{ 647 StakeWithdraw: &iotextypes.StakeReclaim{ 648 BucketIndex: uint64(222), 649 Payload: []byte("abc1234567890"), 650 }, 651 } 652 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 653 require.NoError(err) 654 require.Equal(uint64(10100), res.Gas) 655 }) 656 657 t.Run("StakeAddDeposit is not nil", func(t *testing.T) { 658 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeAddDeposit{ 659 StakeAddDeposit: &iotextypes.StakeAddDeposit{ 660 Amount: "1000", 661 BucketIndex: uint64(333), 662 Payload: []byte("abc1234567890"), 663 }, 664 } 665 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 666 require.NoError(err) 667 require.Equal(uint64(10100), res.Gas) 668 }) 669 670 t.Run("StakeRestake is not nil", func(t *testing.T) { 671 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeRestake{ 672 StakeRestake: &iotextypes.StakeRestake{ 673 BucketIndex: uint64(444), 674 StakedDuration: uint32(111), 675 Payload: []byte("abc1234567890"), 676 }, 677 } 678 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 679 require.NoError(err) 680 require.Equal(uint64(10100), res.Gas) 681 }) 682 683 t.Run("StakeChangeCandidate is not nil", func(t *testing.T) { 684 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeChangeCandidate{ 685 StakeChangeCandidate: &iotextypes.StakeChangeCandidate{ 686 CandidateName: "Candidate", 687 BucketIndex: uint64(555), 688 Payload: []byte("abc1234567890"), 689 }, 690 } 691 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 692 require.NoError(err) 693 require.Equal(uint64(10100), res.Gas) 694 }) 695 696 t.Run("StakeTransferOwnership is not nil", func(t *testing.T) { 697 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_StakeTransferOwnership{ 698 StakeTransferOwnership: &iotextypes.StakeTransferOwnership{ 699 BucketIndex: uint64(666), 700 VoterAddress: identityset.Address(29).String(), 701 Payload: []byte("1234567890"), 702 }, 703 } 704 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 705 require.NoError(err) 706 require.Equal(uint64(10100), res.Gas) 707 }) 708 709 t.Run("CandidateRegister is not nil", func(t *testing.T) { 710 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_CandidateRegister{ 711 CandidateRegister: &iotextypes.CandidateRegister{ 712 Candidate: &iotextypes.CandidateBasicInfo{ 713 Name: "candidate", 714 OperatorAddress: identityset.Address(29).String(), 715 RewardAddress: identityset.Address(28).String(), 716 }, 717 StakedAmount: "1000", 718 StakedDuration: uint32(111), 719 OwnerAddress: identityset.Address(29).String(), 720 Payload: []byte("abc1234567890"), 721 }, 722 } 723 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 724 require.NoError(err) 725 require.Equal(uint64(10100), res.Gas) 726 }) 727 728 t.Run("CandidateUpdate is not nil", func(t *testing.T) { 729 request.Action = &iotexapi.EstimateActionGasConsumptionRequest_CandidateUpdate{ 730 CandidateUpdate: &iotextypes.CandidateBasicInfo{ 731 Name: "candidate", 732 OperatorAddress: identityset.Address(29).String(), 733 RewardAddress: identityset.Address(28).String(), 734 }, 735 } 736 res, err := grpcSvr.EstimateActionGasConsumption(context.Background(), request) 737 require.NoError(err) 738 require.Equal(uint64(10100), res.Gas) 739 }) 740 } 741 742 func TestGrpcServer_ReadState(t *testing.T) { 743 require := require.New(t) 744 ctrl := gomock.NewController(t) 745 defer ctrl.Finish() 746 core := mock_apicoreservice.NewMockCoreService(ctrl) 747 grpcSvr := newGRPCHandler(core) 748 core.EXPECT().ReadState(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&iotexapi.ReadStateResponse{ 749 Data: []byte("10100"), 750 }, nil) 751 resp, err := grpcSvr.ReadState(context.Background(), &iotexapi.ReadStateRequest{ 752 ProtocolID: []byte("rewarding"), 753 MethodName: []byte("UnclaimedBalance"), 754 }) 755 require.NoError(err) 756 require.Equal([]byte("10100"), resp.Data) 757 } 758 759 func TestGrpcServer_GetEpochMeta(t *testing.T) { 760 require := require.New(t) 761 ctrl := gomock.NewController(t) 762 defer ctrl.Finish() 763 core := mock_apicoreservice.NewMockCoreService(ctrl) 764 grpcSvr := newGRPCHandler(core) 765 epochData := &iotextypes.EpochData{Num: 7000} 766 blockProducersInfo := []*iotexapi.BlockProducerInfo{{Production: 8000}} 767 core.EXPECT().EpochMeta(gomock.Any()).Return(epochData, uint64(11), blockProducersInfo, nil) 768 resp, err := grpcSvr.GetEpochMeta(context.Background(), &iotexapi.GetEpochMetaRequest{ 769 EpochNumber: uint64(11), 770 }) 771 require.NoError(err) 772 require.Equal(epochData, resp.EpochData) 773 require.Equal(uint64(11), resp.TotalBlocks) 774 require.Equal(blockProducersInfo, resp.BlockProducersInfo) 775 } 776 777 func TestGrpcServer_GetRawBlocks(t *testing.T) { 778 require := require.New(t) 779 ctrl := gomock.NewController(t) 780 defer ctrl.Finish() 781 core := mock_apicoreservice.NewMockCoreService(ctrl) 782 grpcSvr := newGRPCHandler(core) 783 784 blocks := []*iotexapi.BlockInfo{ 785 { 786 Block: &iotextypes.Block{ 787 Body: &iotextypes.BlockBody{ 788 Actions: []*iotextypes.Action{ 789 { 790 Core: &iotextypes.ActionCore{ 791 Version: 1, 792 Nonce: 2, 793 GasLimit: 3, 794 GasPrice: "4", 795 }, 796 }, 797 }, 798 }, 799 }, 800 Receipts: []*iotextypes.Receipt{ 801 { 802 Status: 1, 803 BlkHeight: 1, 804 ActHash: []byte("02ae2a956d21e8d481c3a69e146633470cf625ec"), 805 GasConsumed: 1, 806 ContractAddress: "test", 807 Logs: []*iotextypes.Log{}, 808 }, 809 }, 810 }, 811 } 812 core.EXPECT().RawBlocks(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(blocks, nil) 813 resp, err := grpcSvr.GetRawBlocks(context.Background(), &iotexapi.GetRawBlocksRequest{ 814 StartHeight: 55, 815 Count: 1000, 816 }) 817 require.NoError(err) 818 require.Equal(blocks, resp.Blocks) 819 } 820 821 func TestGrpcServer_GetLogs(t *testing.T) { 822 require := require.New(t) 823 ctrl := gomock.NewController(t) 824 defer ctrl.Finish() 825 core := mock_apicoreservice.NewMockCoreService(ctrl) 826 grpcSvr := newGRPCHandler(core) 827 request := &iotexapi.GetLogsRequest{ 828 Filter: &iotexapi.LogsFilter{ 829 Address: []string{}, 830 Topics: []*iotexapi.Topics{}, 831 }, 832 } 833 logs := []*action.Log{ 834 { 835 Address: "_topic1", 836 BlockHeight: 1, 837 Topics: []hash.Hash256{ 838 hash.Hash256b([]byte("_topic1")), 839 hash.Hash256b([]byte("_topic11")), 840 }, 841 }, 842 { 843 Address: "_topic2", 844 BlockHeight: 2, 845 Topics: []hash.Hash256{ 846 hash.Hash256b([]byte("_topic2")), 847 hash.Hash256b([]byte("_topic22")), 848 }, 849 }, 850 } 851 852 t.Run("by block", func(t *testing.T) { 853 core.EXPECT().LogsInBlockByHash(gomock.Any(), gomock.Any()).Return(logs, nil) 854 request.Lookup = &iotexapi.GetLogsRequest_ByBlock{ 855 ByBlock: &iotexapi.GetLogsByBlock{ 856 BlockHash: []byte("02ae2a956d21e8d481c3a69e146633470cf625ec"), 857 }, 858 } 859 res, err := grpcSvr.GetLogs(context.Background(), request) 860 require.NoError(err) 861 require.Len(res.Logs, 2) 862 blkHash := hash.BytesToHash256(request.GetByBlock().BlockHash) 863 require.Equal(blkHash[:], res.Logs[0].BlkHash) 864 require.Equal(logs[0].Address, res.Logs[0].ContractAddress) 865 require.Equal(logs[0].BlockHeight, res.Logs[0].BlkHeight) 866 require.Len(res.Logs[0].Topics, 2) 867 require.Equal(logs[0].Topics[0][:], res.Logs[0].Topics[0]) 868 require.Equal(logs[0].Topics[1][:], res.Logs[0].Topics[1]) 869 require.Equal(blkHash[:], res.Logs[1].BlkHash) 870 require.Equal(logs[1].Address, res.Logs[1].ContractAddress) 871 require.Equal(logs[1].BlockHeight, res.Logs[1].BlkHeight) 872 require.Len(res.Logs[1].Topics, 2) 873 require.Equal(logs[1].Topics[0][:], res.Logs[1].Topics[0]) 874 require.Equal(logs[1].Topics[1][:], res.Logs[1].Topics[1]) 875 }) 876 877 t.Run("by range", func(t *testing.T) { 878 hashes := []hash.Hash256{ 879 hash.BytesToHash256([]byte("02ae2a956d21e8d481c3a69e146633470cf625ec")), 880 hash.BytesToHash256([]byte("956d21e8d481c3a6901fc246633470cf62ae2ae1")), 881 } 882 core.EXPECT().LogsInRange(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(logs, hashes, nil) 883 request.Lookup = &iotexapi.GetLogsRequest_ByRange{ 884 ByRange: &iotexapi.GetLogsByRange{ 885 FromBlock: 1, 886 ToBlock: 100, 887 }, 888 } 889 res, err := grpcSvr.GetLogs(context.Background(), request) 890 require.NoError(err) 891 require.Len(res.Logs, 2) 892 require.Equal(hashes[0][:], res.Logs[0].BlkHash) 893 require.Equal(logs[0].Address, res.Logs[0].ContractAddress) 894 require.Equal(logs[0].BlockHeight, res.Logs[0].BlkHeight) 895 require.Len(res.Logs[0].Topics, 2) 896 require.Equal(logs[0].Topics[0][:], res.Logs[0].Topics[0]) 897 require.Equal(logs[0].Topics[1][:], res.Logs[0].Topics[1]) 898 require.Equal(hashes[1][:], res.Logs[1].BlkHash) 899 require.Equal(logs[1].Address, res.Logs[1].ContractAddress) 900 require.Equal(logs[1].BlockHeight, res.Logs[1].BlkHeight) 901 require.Len(res.Logs[1].Topics, 2) 902 require.Equal(logs[1].Topics[0][:], res.Logs[1].Topics[0]) 903 require.Equal(logs[1].Topics[1][:], res.Logs[1].Topics[1]) 904 }) 905 } 906 907 func TestGrpcServer_GetElectionBuckets(t *testing.T) { 908 require := require.New(t) 909 ctrl := gomock.NewController(t) 910 defer ctrl.Finish() 911 core := mock_apicoreservice.NewMockCoreService(ctrl) 912 grpcSvr := newGRPCHandler(core) 913 914 buckets := []*iotextypes.ElectionBucket{ 915 { 916 Voter: []byte("_voter"), 917 Candidate: []byte("_candidate"), 918 }, 919 } 920 core.EXPECT().ElectionBuckets(gomock.Any()).Return(buckets, nil) 921 resp, err := grpcSvr.GetElectionBuckets(context.Background(), &iotexapi.GetElectionBucketsRequest{ 922 EpochNum: 11, 923 }) 924 require.NoError(err) 925 require.Equal(buckets, resp.Buckets) 926 } 927 928 func TestGrpcServer_GetTransactionLogByActionHash(t *testing.T) { 929 require := require.New(t) 930 ctrl := gomock.NewController(t) 931 defer ctrl.Finish() 932 core := mock_apicoreservice.NewMockCoreService(ctrl) 933 grpcSvr := newGRPCHandler(core) 934 935 txLog := &iotextypes.TransactionLog{ 936 ActionHash: []byte("_testAction"), 937 NumTransactions: 100, 938 } 939 core.EXPECT().TransactionLogByActionHash(gomock.Any()).Return(txLog, nil) 940 resp, err := grpcSvr.GetTransactionLogByActionHash(context.Background(), &iotexapi.GetTransactionLogByActionHashRequest{ 941 ActionHash: "_actionHash", 942 }) 943 require.NoError(err) 944 require.Equal(txLog, resp.TransactionLog) 945 } 946 947 func TestGrpcServer_GetTransactionLogByBlockHeight(t *testing.T) { 948 require := require.New(t) 949 ctrl := gomock.NewController(t) 950 defer ctrl.Finish() 951 core := mock_apicoreservice.NewMockCoreService(ctrl) 952 grpcSvr := newGRPCHandler(core) 953 954 blockIdentifier := &iotextypes.BlockIdentifier{ 955 Height: 10100, 956 } 957 txLog := &iotextypes.TransactionLogs{ 958 Logs: []*iotextypes.TransactionLog{ 959 { 960 ActionHash: []byte("_testAction"), 961 NumTransactions: 100, 962 }, 963 }, 964 } 965 core.EXPECT().TransactionLogByBlockHeight(gomock.Any()).Return(blockIdentifier, txLog, nil) 966 resp, err := grpcSvr.GetTransactionLogByBlockHeight(context.Background(), &iotexapi.GetTransactionLogByBlockHeightRequest{ 967 BlockHeight: 10101, 968 }) 969 require.NoError(err) 970 require.Equal(blockIdentifier, resp.BlockIdentifier) 971 require.Equal(txLog, resp.TransactionLogs) 972 } 973 974 func TestGrpcServer_GetActPoolActions(t *testing.T) { 975 require := require.New(t) 976 ctrl := gomock.NewController(t) 977 defer ctrl.Finish() 978 core := mock_apicoreservice.NewMockCoreService(ctrl) 979 grpcSvr := newGRPCHandler(core) 980 981 addr1 := identityset.Address(28).String() 982 priKey1 := identityset.PrivateKey(29) 983 tsf1, err := action.SignedTransfer(addr1, priKey1, uint64(1), big.NewInt(10), []byte{}, uint64(100000), big.NewInt(0)) 984 require.NoError(err) 985 tsf2, err := action.SignedTransfer(addr1, priKey1, uint64(2), big.NewInt(20), []byte{}, uint64(100000), big.NewInt(0)) 986 require.NoError(err) 987 acts := []*action.SealedEnvelope{tsf1, tsf2} 988 core.EXPECT().ActionsInActPool(gomock.Any()).Return(acts, nil) 989 resp, err := grpcSvr.GetActPoolActions(context.Background(), &iotexapi.GetActPoolActionsRequest{ 990 ActionHashes: []string{"_actionHash"}, 991 }) 992 require.NoError(err) 993 require.Equal(len(acts), len(resp.Actions)) 994 require.Equal(acts[0].Signature(), resp.Actions[0].Signature) 995 require.Equal(acts[1].Signature(), resp.Actions[1].Signature) 996 require.Equal(acts[0].SrcPubkey().Bytes(), resp.Actions[0].SenderPubKey) 997 require.Equal(acts[1].SrcPubkey().Bytes(), resp.Actions[1].SenderPubKey) 998 } 999 1000 func TestGrpcServer_ReadContractStorage(t *testing.T) { 1001 require := require.New(t) 1002 ctrl := gomock.NewController(t) 1003 defer ctrl.Finish() 1004 core := mock_apicoreservice.NewMockCoreService(ctrl) 1005 grpcSvr := newGRPCHandler(core) 1006 1007 core.EXPECT().ReadContractStorage(gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte("_data"), nil) 1008 resp, err := grpcSvr.ReadContractStorage(context.Background(), &iotexapi.ReadContractStorageRequest{ 1009 Contract: "io1d4c5lp4ea4754wy439g2t99ue7wryu5r2lslh2", 1010 Key: []byte("_key"), 1011 }) 1012 require.NoError(err) 1013 require.Equal([]byte("_data"), resp.Data) 1014 } 1015 1016 func TestGrpcServer_TraceTransactionStructLogs(t *testing.T) { 1017 require := require.New(t) 1018 ctrl := gomock.NewController(t) 1019 defer ctrl.Finish() 1020 core := mock_apicoreservice.NewMockCoreService(ctrl) 1021 grpcSvr := newGRPCHandler(core) 1022 1023 core.EXPECT().TraceTransaction(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil, logger.NewStructLogger(nil), nil) 1024 resp, err := grpcSvr.TraceTransactionStructLogs(context.Background(), &iotexapi.TraceTransactionStructLogsRequest{ 1025 ActionHash: "_actionHash", 1026 }) 1027 require.NoError(err) 1028 require.Equal(0, len(resp.StructLogs)) 1029 } 1030 1031 func getAction() (act *iotextypes.Action) { 1032 pubKey1 := identityset.PrivateKey(28).PublicKey() 1033 addr2 := identityset.Address(29).String() 1034 1035 act = &iotextypes.Action{ 1036 Core: &iotextypes.ActionCore{ 1037 Action: &iotextypes.ActionCore_Transfer{ 1038 Transfer: &iotextypes.Transfer{Recipient: addr2}, 1039 }, 1040 Version: version.ProtocolVersion, 1041 Nonce: 101, 1042 }, 1043 SenderPubKey: pubKey1.Bytes(), 1044 Signature: action.ValidSig, 1045 } 1046 return 1047 } 1048 1049 func getActionWithPayload() (act *iotextypes.Action) { 1050 pubKey1 := identityset.PrivateKey(28).PublicKey() 1051 addr2 := identityset.Address(29).String() 1052 1053 act = &iotextypes.Action{ 1054 Core: &iotextypes.ActionCore{ 1055 Action: &iotextypes.ActionCore_Transfer{ 1056 Transfer: &iotextypes.Transfer{Recipient: addr2, Payload: []byte("1234567890")}, 1057 }, 1058 Version: version.ProtocolVersion, 1059 Nonce: 101, 1060 }, 1061 SenderPubKey: pubKey1.Bytes(), 1062 Signature: action.ValidSig, 1063 } 1064 return 1065 }