code.vegaprotocol.io/vega@v0.79.0/datanode/api/trading_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package api_test 17 18 import ( 19 "context" 20 "fmt" 21 "net" 22 "testing" 23 "time" 24 25 "code.vegaprotocol.io/vega/datanode/api" 26 "code.vegaprotocol.io/vega/datanode/api/mocks" 27 "code.vegaprotocol.io/vega/datanode/broker" 28 "code.vegaprotocol.io/vega/datanode/candlesv2" 29 "code.vegaprotocol.io/vega/datanode/config" 30 vgtesting "code.vegaprotocol.io/vega/datanode/libs/testing" 31 "code.vegaprotocol.io/vega/datanode/service" 32 "code.vegaprotocol.io/vega/datanode/sqlstore" 33 "code.vegaprotocol.io/vega/datanode/sqlsubscribers" 34 "code.vegaprotocol.io/vega/libs/subscribers" 35 "code.vegaprotocol.io/vega/logging" 36 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 37 vegaprotoapi "code.vegaprotocol.io/vega/protos/vega/api/v1" 38 commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1" 39 40 "github.com/golang/mock/gomock" 41 "github.com/golang/protobuf/proto" 42 "github.com/pkg/errors" 43 "github.com/stretchr/testify/assert" 44 "google.golang.org/grpc" 45 "google.golang.org/grpc/test/bufconn" 46 ) 47 48 const connBufSize = 1024 * 1024 49 50 func waitForNode(ctx context.Context, t *testing.T, conn *grpc.ClientConn) { 51 t.Helper() 52 const maxSleep = 2000 // milliseconds 53 54 c := v2.NewTradingDataServiceClient(conn) 55 56 sleepTime := 10 // milliseconds 57 for sleepTime < maxSleep { 58 _, err := c.Ping(ctx, &v2.PingRequest{}) 59 if err == nil { 60 return 61 } 62 63 time.Sleep(time.Duration(sleepTime) * time.Millisecond) 64 sleepTime *= 2 65 } 66 if sleepTime >= maxSleep { 67 t.Fatalf("Gave up waiting for gRPC server to respond properly.") 68 } 69 } 70 71 func getTestGRPCServer(t *testing.T, ctx context.Context) (tidy func(), conn *grpc.ClientConn, mockCoreServiceClient *mocks.MockCoreServiceClient, err error) { 72 t.Helper() 73 _, cleanupFn := vgtesting.NewVegaPaths() 74 75 conf := config.NewDefaultConfig() 76 conf.API.IP = "127.0.0.1" 77 conf.API.Port = 64201 78 79 // Mock BlockchainClient 80 mockCtrl := gomock.NewController(t) 81 82 mockCoreServiceClient = mocks.NewMockCoreServiceClient(mockCtrl) 83 84 mockNetworkHistoryService := mocks.NewMockNetworkHistoryService(mockCtrl) 85 86 rawEventSource, err := broker.NewEventReceiverSender(conf.Broker, logging.NewTestLogger(), "") 87 if err != nil { 88 t.Fatalf("failed to create raw event source: %v", err) 89 } 90 91 eventSource := broker.NewDeserializer(rawEventSource) 92 if err != nil { 93 t.Fatalf("failed to create event source: %v", err) 94 } 95 96 conf.CandlesV2.CandleStore.DefaultCandleIntervals = "" 97 98 sqlConn := &sqlstore.ConnectionSource{} 99 sqlConn.ToggleTest() // ensure calls to query and copyTo do not fail 100 101 bro, err := broker.New(ctx, logging.NewTestLogger(), conf.Broker, "", eventSource) 102 if err != nil { 103 err = errors.Wrap(err, "failed to create broker") 104 return 105 } 106 107 logger := logging.NewTestLogger() 108 eventService := subscribers.NewService(logger, bro, conf.Broker.EventBusClientBufferSize) 109 sqlOrderStore := sqlstore.NewOrders(sqlConn) 110 sqlOrderService := service.NewOrder(sqlOrderStore, logger) 111 sqlNetworkLimitsService := service.NewNetworkLimits(sqlstore.NewNetworkLimits(sqlConn)) 112 sqlMarketDataService := service.NewMarketData(sqlstore.NewMarketData(sqlConn), logger) 113 sqlCandleStore := sqlstore.NewCandles(ctx, sqlConn, conf.CandlesV2.CandleStore) 114 sqlCandlesService := candlesv2.NewService(ctx, logger, conf.CandlesV2, sqlCandleStore) 115 sqlTradeService := service.NewTrade(sqlstore.NewTrades(sqlConn), logger) 116 sqlPositionService := service.NewPosition(sqlstore.NewPositions(sqlConn), logger) 117 sqlAssetService := service.NewAsset(sqlstore.NewAssets(sqlConn)) 118 sqlAccountService := service.NewAccount(sqlstore.NewAccounts(sqlConn), sqlstore.NewBalances(sqlConn), logger) 119 sqlRewardsService := service.NewReward(sqlstore.NewRewards(ctx, sqlConn), logger) 120 sqlMarketsService := service.NewMarkets(sqlstore.NewMarkets(sqlConn)) 121 sqlDelegationService := service.NewDelegation(sqlstore.NewDelegations(sqlConn), logger) 122 sqlEpochService := service.NewEpoch(sqlstore.NewEpochs(sqlConn)) 123 sqlDepositService := service.NewDeposit(sqlstore.NewDeposits(sqlConn)) 124 sqlWithdrawalService := service.NewWithdrawal(sqlstore.NewWithdrawals(sqlConn)) 125 sqlGovernanceService := service.NewGovernance(sqlstore.NewProposals(sqlConn), sqlstore.NewVotes(sqlConn), logger) 126 sqlRiskFactorsService := service.NewRiskFactor(sqlstore.NewRiskFactors(sqlConn)) 127 sqlMarginLevelsService := service.NewRisk(sqlstore.NewMarginLevels(sqlConn), sqlAccountService, logger) 128 sqlNetParamService := service.NewNetworkParameter(sqlstore.NewNetworkParameters(sqlConn)) 129 sqlBlockService := service.NewBlock(sqlstore.NewBlocks(sqlConn)) 130 sqlCheckpointService := service.NewCheckpoint(sqlstore.NewCheckpoints(sqlConn)) 131 sqlPartyService := service.NewParty(sqlstore.NewParties(sqlConn)) 132 sqlOracleSpecService := service.NewOracleSpec(sqlstore.NewOracleSpec(sqlConn)) 133 sqlOracleDataService := service.NewOracleData(sqlstore.NewOracleData(sqlConn)) 134 sqlLPDataService := service.NewLiquidityProvision(sqlstore.NewLiquidityProvision(sqlConn, logger)) 135 sqlTransferService := service.NewTransfer(sqlstore.NewTransfers(sqlConn)) 136 sqlStakeLinkingService := service.NewStakeLinking(sqlstore.NewStakeLinking(sqlConn)) 137 sqlNotaryService := service.NewNotary(sqlstore.NewNotary(sqlConn)) 138 sqlMultiSigService := service.NewMultiSig(sqlstore.NewERC20MultiSigSignerEvent(sqlConn)) 139 sqlKeyRotationsService := service.NewKeyRotations(sqlstore.NewKeyRotations(sqlConn)) 140 sqlEthereumKeyRotationService := service.NewEthereumKeyRotation(sqlstore.NewEthereumKeyRotations(sqlConn), logger) 141 sqlNodeService := service.NewNode(sqlstore.NewNode(sqlConn)) 142 sqlLedgerService := service.NewLedger(sqlstore.NewLedger(sqlConn), logger) 143 sqlProtocolUpgradeService := service.NewProtocolUpgrade(sqlstore.NewProtocolUpgradeProposals(sqlConn), logger) 144 sqlCoreSnapshotService := service.NewSnapshotData(sqlstore.NewCoreSnapshotData(sqlConn)) 145 stopOrderService := service.NewStopOrders(sqlstore.NewStopOrders(sqlConn)) 146 fundingPeriodService := service.NewFundingPeriods(sqlstore.NewFundingPeriods(sqlConn)) 147 partyActivityStreak := service.NewPartyActivityStreak(sqlstore.NewPartyActivityStreaks(sqlConn)) 148 referralProgramService := service.NewReferralPrograms(sqlstore.NewReferralPrograms(sqlConn)) 149 referralSetsService := service.NewReferralSets(sqlstore.NewReferralSets(sqlConn)) 150 teamsService := service.NewTeams(sqlstore.NewTeams(sqlConn)) 151 vestingStatsService := service.NewVestingStats(sqlstore.NewVestingStats(sqlConn)) 152 FeesStatsService := service.NewFeesStats(sqlstore.NewFeesStats(sqlConn)) 153 fundingPaymentService := service.NewFundingPayment(sqlstore.NewFundingPayments(sqlConn)) 154 volumeDiscountStatsService := service.NewVolumeDiscountStats(sqlstore.NewVolumeDiscountStats(sqlConn)) 155 volumeDiscountProgramService := service.NewVolumeDiscountPrograms(sqlstore.NewVolumeDiscountPrograms(sqlConn)) 156 paidLiquidityFeesStatsService := service.NewPaidLiquidityFeesStats(sqlstore.NewPaidLiquidityFeesStats(sqlConn)) 157 partyLockedBalances := service.NewPartyLockedBalances(sqlstore.NewPartyLockedBalances(sqlConn)) 158 partyVestingBalances := service.NewPartyVestingBalances(sqlstore.NewPartyVestingBalances(sqlConn)) 159 transactionResults := service.NewTransactionResults(sqlsubscribers.NewTransactionResults(logger)) 160 gameService := service.NewGames(sqlstore.NewGames(sqlConn)) 161 marginModesService := service.NewMarginModes(sqlstore.NewMarginModes(sqlConn)) 162 timeWeightedNotionPositionService := service.NewTimeWeightedNotionalPosition(sqlstore.NewTimeWeightedNotionalPosition(sqlConn)) 163 gameScoreService := service.NewGameScore(sqlstore.NewGameScores(sqlConn), logger) 164 ammPoolsService := service.NewAMMPools(sqlstore.NewAMMPools(sqlConn)) 165 sqlMarketDepthService := service.NewMarketDepth(service.NewDefaultConfig().MarketDepth, sqlOrderService, ammPoolsService, nil, nil, nil, nil, logger) 166 volumeRebateStatsService := service.NewVolumeRebateStats(sqlstore.NewVolumeRebateStats(sqlConn)) 167 volumeRebateProgramssService := service.NewVolumeRebatePrograms(sqlstore.NewVolumeRebatePrograms(sqlConn)) 168 169 g := api.NewGRPCServer( 170 logger, 171 conf.API, 172 mockCoreServiceClient, 173 eventService, 174 sqlOrderService, 175 sqlNetworkLimitsService, 176 sqlMarketDataService, 177 sqlTradeService, 178 sqlAssetService, 179 sqlAccountService, 180 sqlRewardsService, 181 sqlMarketsService, 182 sqlDelegationService, 183 sqlEpochService, 184 sqlDepositService, 185 sqlWithdrawalService, 186 sqlGovernanceService, 187 sqlRiskFactorsService, 188 sqlMarginLevelsService, 189 sqlNetParamService, 190 sqlBlockService, 191 sqlCheckpointService, 192 sqlPartyService, 193 sqlCandlesService, 194 sqlOracleSpecService, 195 sqlOracleDataService, 196 sqlLPDataService, 197 sqlPositionService, 198 sqlTransferService, 199 sqlStakeLinkingService, 200 sqlNotaryService, 201 sqlMultiSigService, 202 sqlKeyRotationsService, 203 sqlEthereumKeyRotationService, 204 sqlNodeService, 205 sqlMarketDepthService, 206 sqlLedgerService, 207 sqlProtocolUpgradeService, 208 mockNetworkHistoryService, 209 sqlCoreSnapshotService, 210 stopOrderService, 211 fundingPeriodService, 212 partyActivityStreak, 213 referralProgramService, 214 referralSetsService, 215 teamsService, 216 vestingStatsService, 217 FeesStatsService, 218 fundingPaymentService, 219 volumeDiscountStatsService, 220 volumeDiscountProgramService, 221 paidLiquidityFeesStatsService, 222 partyLockedBalances, 223 partyVestingBalances, 224 transactionResults, 225 gameService, 226 marginModesService, 227 timeWeightedNotionPositionService, 228 gameScoreService, 229 ammPoolsService, 230 volumeRebateStatsService, 231 volumeRebateProgramssService, 232 ) 233 if g == nil { 234 err = fmt.Errorf("failed to create gRPC server") 235 return 236 } 237 238 tidy = func() { 239 cleanupFn() 240 } 241 242 lis := bufconn.Listen(connBufSize) 243 ctxDialer := func(context.Context, string) (net.Conn, error) { return lis.Dial() } 244 245 // Start the gRPC server, then wait for it to be ready. 246 go func() { 247 _ = g.Start(ctx, lis) 248 }() 249 250 conn, err = grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(ctxDialer), grpc.WithInsecure()) 251 if err != nil { 252 t.Fatalf("Failed to create connection to gRPC server") 253 } 254 255 waitForNode(ctx, t, conn) 256 257 return tidy, conn, mockCoreServiceClient, err 258 } 259 260 func TestSubmitTransaction(t *testing.T) { 261 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 262 defer cancel() 263 264 t.Run("proxy call is successful", func(t *testing.T) { 265 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 266 if err != nil { 267 t.Fatalf("Failed to get test gRPC server: %s", err.Error()) 268 } 269 defer tidy() 270 271 req := &vegaprotoapi.SubmitTransactionRequest{ 272 Type: vegaprotoapi.SubmitTransactionRequest_TYPE_UNSPECIFIED, 273 Tx: &commandspb.Transaction{ 274 InputData: []byte("input data"), 275 Signature: &commandspb.Signature{ 276 Value: "value", 277 Algo: "algo", 278 Version: 1, 279 }, 280 }, 281 } 282 283 expectedRes := &vegaprotoapi.SubmitTransactionResponse{Success: true} 284 285 vegaReq := &vegaprotoapi.SubmitTransactionRequest{ 286 Type: vegaprotoapi.SubmitTransactionRequest_TYPE_UNSPECIFIED, 287 Tx: &commandspb.Transaction{ 288 InputData: []byte("input data"), 289 Signature: &commandspb.Signature{ 290 Value: "value", 291 Algo: "algo", 292 Version: 1, 293 }, 294 }, 295 } 296 297 mockTradingServiceClient.EXPECT(). 298 SubmitTransaction(gomock.Any(), vgtesting.ProtosEq(vegaReq)). 299 Return(&vegaprotoapi.SubmitTransactionResponse{Success: true}, nil).Times(1) 300 301 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 302 assert.NotNil(t, proxyClient) 303 304 actualResp, err := proxyClient.SubmitTransaction(ctx, req) 305 assert.NoError(t, err) 306 vgtesting.AssertProtoEqual(t, expectedRes, actualResp) 307 }) 308 309 t.Run("proxy propagates an error", func(t *testing.T) { 310 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 311 defer cancel() 312 313 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 314 if err != nil { 315 t.Fatalf("Failed to get test gRPC server: %s", err.Error()) 316 } 317 defer tidy() 318 319 req := &vegaprotoapi.SubmitTransactionRequest{ 320 Type: vegaprotoapi.SubmitTransactionRequest_TYPE_COMMIT, 321 Tx: &commandspb.Transaction{ 322 InputData: []byte("input data"), 323 Signature: &commandspb.Signature{ 324 Value: "value", 325 Algo: "algo", 326 Version: 1, 327 }, 328 }, 329 } 330 331 vegaReq := &vegaprotoapi.SubmitTransactionRequest{ 332 Type: vegaprotoapi.SubmitTransactionRequest_TYPE_COMMIT, 333 Tx: &commandspb.Transaction{ 334 InputData: []byte("input data"), 335 Signature: &commandspb.Signature{ 336 Value: "value", 337 Algo: "algo", 338 Version: 1, 339 }, 340 }, 341 } 342 343 mockTradingServiceClient.EXPECT(). 344 SubmitTransaction(gomock.Any(), vgtesting.ProtosEq(vegaReq)). 345 Return(nil, errors.New("Critical error")) 346 347 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 348 assert.NotNil(t, proxyClient) 349 350 actualResp, err := proxyClient.SubmitTransaction(ctx, req) 351 assert.Error(t, err) 352 assert.Nil(t, actualResp) 353 assert.Contains(t, err.Error(), "Critical error") 354 }) 355 } 356 357 func TestSubmitRawTransaction(t *testing.T) { 358 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 359 defer cancel() 360 361 t.Run("proxy call is successful", func(t *testing.T) { 362 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 363 if err != nil { 364 t.Fatalf("Failed to get test gRPC server: %s", err.Error()) 365 } 366 defer tidy() 367 368 tx := &commandspb.Transaction{ 369 InputData: []byte("input data"), 370 Signature: &commandspb.Signature{ 371 Value: "value", 372 Algo: "algo", 373 Version: 1, 374 }, 375 } 376 377 bs, err := proto.Marshal(tx) 378 assert.NoError(t, err) 379 380 req := &vegaprotoapi.SubmitRawTransactionRequest{ 381 Type: vegaprotoapi.SubmitRawTransactionRequest_TYPE_UNSPECIFIED, 382 Tx: bs, 383 } 384 385 expectedRes := &vegaprotoapi.SubmitRawTransactionResponse{Success: true} 386 387 vegaReq := &vegaprotoapi.SubmitRawTransactionRequest{ 388 Type: vegaprotoapi.SubmitRawTransactionRequest_TYPE_UNSPECIFIED, 389 Tx: bs, 390 } 391 392 mockTradingServiceClient.EXPECT(). 393 SubmitRawTransaction(gomock.Any(), vgtesting.ProtosEq(vegaReq)). 394 Return(&vegaprotoapi.SubmitRawTransactionResponse{Success: true}, nil).Times(1) 395 396 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 397 assert.NotNil(t, proxyClient) 398 399 actualResp, err := proxyClient.SubmitRawTransaction(ctx, req) 400 assert.NoError(t, err) 401 vgtesting.AssertProtoEqual(t, expectedRes, actualResp) 402 }) 403 404 t.Run("proxy propagates an error", func(t *testing.T) { 405 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 406 defer cancel() 407 408 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 409 if err != nil { 410 t.Fatalf("Failed to get test gRPC server: %s", err.Error()) 411 } 412 defer tidy() 413 tx := &commandspb.Transaction{ 414 InputData: []byte("input data"), 415 Signature: &commandspb.Signature{ 416 Value: "value", 417 Algo: "algo", 418 Version: 1, 419 }, 420 } 421 422 bs, err := proto.Marshal(tx) 423 assert.NoError(t, err) 424 425 req := &vegaprotoapi.SubmitRawTransactionRequest{ 426 Type: vegaprotoapi.SubmitRawTransactionRequest_TYPE_COMMIT, 427 Tx: bs, 428 } 429 430 vegaReq := &vegaprotoapi.SubmitRawTransactionRequest{ 431 Type: vegaprotoapi.SubmitRawTransactionRequest_TYPE_COMMIT, 432 Tx: bs, 433 } 434 435 mockTradingServiceClient.EXPECT(). 436 SubmitRawTransaction(gomock.Any(), vgtesting.ProtosEq(vegaReq)). 437 Return(nil, errors.New("Critical error")) 438 439 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 440 assert.NotNil(t, proxyClient) 441 442 actualResp, err := proxyClient.SubmitRawTransaction(ctx, req) 443 assert.Error(t, err) 444 assert.Nil(t, actualResp) 445 assert.Contains(t, err.Error(), "Critical error") 446 }) 447 } 448 449 func TestLastBlockHeight(t *testing.T) { 450 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 451 defer cancel() 452 453 t.Run("proxy call is successful", func(t *testing.T) { 454 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 455 if err != nil { 456 t.Fatalf("Failed to get test gRPC server: %s", err.Error()) 457 } 458 defer tidy() 459 460 req := &vegaprotoapi.LastBlockHeightRequest{} 461 expectedRes := &vegaprotoapi.LastBlockHeightResponse{Height: 20} 462 463 vegaReq := &vegaprotoapi.LastBlockHeightRequest{} 464 465 mockTradingServiceClient.EXPECT(). 466 LastBlockHeight(gomock.Any(), vgtesting.ProtosEq(vegaReq)). 467 Return(&vegaprotoapi.LastBlockHeightResponse{Height: 20}, nil).Times(1) 468 469 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 470 assert.NotNil(t, proxyClient) 471 472 actualResp, err := proxyClient.LastBlockHeight(ctx, req) 473 assert.NoError(t, err) 474 vgtesting.AssertProtoEqual(t, expectedRes, actualResp) 475 }) 476 477 t.Run("proxy propagates an error", func(t *testing.T) { 478 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 479 if err != nil { 480 t.Fatalf("Failed to get test gRPC server: %s", err.Error()) 481 } 482 defer tidy() 483 484 req := &vegaprotoapi.LastBlockHeightRequest{} 485 vegaReq := &vegaprotoapi.LastBlockHeightRequest{} 486 487 mockTradingServiceClient.EXPECT(). 488 LastBlockHeight(gomock.Any(), vgtesting.ProtosEq(vegaReq)). 489 Return(nil, fmt.Errorf("Critical error")).Times(1) 490 491 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 492 assert.NotNil(t, proxyClient) 493 494 actualResp, err := proxyClient.LastBlockHeight(ctx, req) 495 assert.Error(t, err) 496 assert.Nil(t, actualResp) 497 assert.Contains(t, err.Error(), "Critical error") 498 }) 499 } 500 501 func TestGetSpamStatistics(t *testing.T) { 502 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 503 defer cancel() 504 505 t.Run("proxy call is successful", func(t *testing.T) { 506 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 507 if err != nil { 508 t.Fatalf("failed to get test gRPC server: %v", err) 509 } 510 defer tidy() 511 512 req := &vegaprotoapi.GetSpamStatisticsRequest{ 513 PartyId: "DEADBEEF", 514 } 515 516 wantReq := &vegaprotoapi.GetSpamStatisticsRequest{ 517 PartyId: "DEADBEEF", 518 } 519 520 wantResp := &vegaprotoapi.GetSpamStatisticsResponse{ 521 Statistics: &vegaprotoapi.SpamStatistics{ 522 Proposals: nil, 523 Delegations: nil, 524 Transfers: nil, 525 NodeAnnouncements: nil, 526 Votes: nil, 527 }, 528 } 529 530 mockTradingServiceClient.EXPECT(). 531 GetSpamStatistics(gomock.Any(), vgtesting.ProtosEq(wantReq)). 532 Return(&vegaprotoapi.GetSpamStatisticsResponse{ 533 Statistics: &vegaprotoapi.SpamStatistics{ 534 Proposals: nil, 535 Delegations: nil, 536 Transfers: nil, 537 NodeAnnouncements: nil, 538 Votes: nil, 539 }, 540 }, nil).Times(1) 541 542 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 543 assert.NotNil(t, proxyClient) 544 545 resp, err := proxyClient.GetSpamStatistics(ctx, req) 546 assert.NoError(t, err) 547 vgtesting.AssertProtoEqual(t, wantResp, resp) 548 }) 549 550 t.Run("proxy propagates an error", func(t *testing.T) { 551 tidy, conn, mockTradingServiceClient, err := getTestGRPCServer(t, ctx) 552 if err != nil { 553 t.Fatalf("failed to get test gRPC server: %v", err) 554 } 555 defer tidy() 556 557 req := &vegaprotoapi.GetSpamStatisticsRequest{ 558 PartyId: "DEADBEEF", 559 } 560 561 wantReq := &vegaprotoapi.GetSpamStatisticsRequest{ 562 PartyId: "DEADBEEF", 563 } 564 565 mockTradingServiceClient.EXPECT(). 566 GetSpamStatistics(gomock.Any(), vgtesting.ProtosEq(wantReq)). 567 Return(nil, fmt.Errorf("Critical error")).Times(1) 568 569 proxyClient := vegaprotoapi.NewCoreServiceClient(conn) 570 assert.NotNil(t, proxyClient) 571 572 resp, err := proxyClient.GetSpamStatistics(ctx, req) 573 assert.Error(t, err) 574 assert.Nil(t, resp) 575 assert.Contains(t, err.Error(), "Critical error") 576 }) 577 }