github.com/fiagdao/tendermint@v0.32.11-0.20220824195748-2087fcc480c1/rpc/client/rpc_test.go (about) 1 package client_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 "math/rand" 8 "net/http" 9 "strings" 10 "sync" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 17 abci "github.com/tendermint/tendermint/abci/types" 18 19 "github.com/tendermint/tendermint/crypto/ed25519" 20 "github.com/tendermint/tendermint/crypto/tmhash" 21 "github.com/tendermint/tendermint/libs/log" 22 tmmath "github.com/tendermint/tendermint/libs/math" 23 mempl "github.com/tendermint/tendermint/mempool" 24 "github.com/tendermint/tendermint/privval" 25 "github.com/tendermint/tendermint/rpc/client" 26 rpchttp "github.com/tendermint/tendermint/rpc/client/http" 27 rpclocal "github.com/tendermint/tendermint/rpc/client/local" 28 ctypes "github.com/tendermint/tendermint/rpc/core/types" 29 rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" 30 rpctest "github.com/tendermint/tendermint/rpc/test" 31 "github.com/tendermint/tendermint/types" 32 ) 33 34 func getHTTPClient() *rpchttp.HTTP { 35 rpcAddr := rpctest.GetConfig().RPC.ListenAddress 36 c, err := rpchttp.New(rpcAddr, "/websocket") 37 if err != nil { 38 panic(err) 39 } 40 c.SetLogger(log.TestingLogger()) 41 return c 42 } 43 44 func getHTTPClientWithTimeout(timeout uint) *rpchttp.HTTP { 45 rpcAddr := rpctest.GetConfig().RPC.ListenAddress 46 c, err := rpchttp.NewWithTimeout(rpcAddr, "/websocket", timeout) 47 if err != nil { 48 panic(err) 49 } 50 c.SetLogger(log.TestingLogger()) 51 return c 52 } 53 54 func getLocalClient() *rpclocal.Local { 55 return rpclocal.New(node) 56 } 57 58 // GetClients returns a slice of clients for table-driven tests 59 func GetClients() []client.Client { 60 return []client.Client{ 61 getHTTPClient(), 62 getLocalClient(), 63 } 64 } 65 66 func TestNilCustomHTTPClient(t *testing.T) { 67 require.Panics(t, func() { 68 _, _ = rpchttp.NewWithClient("http://example.com", "/websocket", nil) 69 }) 70 require.Panics(t, func() { 71 _, _ = rpcclient.NewWithHTTPClient("http://example.com", nil) 72 }) 73 } 74 75 func TestCustomHTTPClient(t *testing.T) { 76 remote := rpctest.GetConfig().RPC.ListenAddress 77 c, err := rpchttp.NewWithClient(remote, "/websocket", http.DefaultClient) 78 require.Nil(t, err) 79 status, err := c.Status() 80 require.NoError(t, err) 81 require.NotNil(t, status) 82 } 83 84 func TestCorsEnabled(t *testing.T) { 85 origin := rpctest.GetConfig().RPC.CORSAllowedOrigins[0] 86 remote := strings.Replace(rpctest.GetConfig().RPC.ListenAddress, "tcp", "http", -1) 87 88 req, err := http.NewRequest("GET", remote, nil) 89 require.Nil(t, err, "%+v", err) 90 req.Header.Set("Origin", origin) 91 c := &http.Client{} 92 resp, err := c.Do(req) 93 require.Nil(t, err, "%+v", err) 94 defer resp.Body.Close() 95 96 assert.Equal(t, resp.Header.Get("Access-Control-Allow-Origin"), origin) 97 } 98 99 // Make sure status is correct (we connect properly) 100 func TestStatus(t *testing.T) { 101 for i, c := range GetClients() { 102 moniker := rpctest.GetConfig().Moniker 103 status, err := c.Status() 104 require.Nil(t, err, "%d: %+v", i, err) 105 assert.Equal(t, moniker, status.NodeInfo.Moniker) 106 } 107 } 108 109 // Make sure status is correct (we connect properly) 110 func TestConsensusReactorStatus(t *testing.T) { 111 for i, c := range GetClients() { 112 status, err := c.ConsensusReactorStatus() 113 require.Nil(t, err, "%d: %+v", i, err) 114 require.NotNil(t, status) 115 require.NotEmpty(t, status) 116 } 117 } 118 119 // Make sure info is correct (we connect properly) 120 func TestInfo(t *testing.T) { 121 for i, c := range GetClients() { 122 // status, err := c.Status() 123 // require.Nil(t, err, "%+v", err) 124 info, err := c.ABCIInfo() 125 require.Nil(t, err, "%d: %+v", i, err) 126 // TODO: this is not correct - fix merkleeyes! 127 // assert.EqualValues(t, status.SyncInfo.LatestBlockHeight, info.Response.LastBlockHeight) 128 assert.True(t, strings.Contains(info.Response.Data, "size")) 129 } 130 } 131 132 func TestNetInfo(t *testing.T) { 133 for i, c := range GetClients() { 134 nc, ok := c.(client.NetworkClient) 135 require.True(t, ok, "%d", i) 136 netinfo, err := nc.NetInfo() 137 require.Nil(t, err, "%d: %+v", i, err) 138 assert.True(t, netinfo.Listening) 139 assert.Equal(t, 0, len(netinfo.Peers)) 140 } 141 } 142 143 func TestDumpConsensusState(t *testing.T) { 144 for i, c := range GetClients() { 145 // FIXME: fix server so it doesn't panic on invalid input 146 nc, ok := c.(client.NetworkClient) 147 require.True(t, ok, "%d", i) 148 cons, err := nc.DumpConsensusState() 149 require.Nil(t, err, "%d: %+v", i, err) 150 assert.NotEmpty(t, cons.RoundState) 151 assert.Empty(t, cons.Peers) 152 } 153 } 154 155 func TestConsensusState(t *testing.T) { 156 for i, c := range GetClients() { 157 // FIXME: fix server so it doesn't panic on invalid input 158 nc, ok := c.(client.NetworkClient) 159 require.True(t, ok, "%d", i) 160 cons, err := nc.ConsensusState() 161 require.Nil(t, err, "%d: %+v", i, err) 162 assert.NotEmpty(t, cons.RoundState) 163 } 164 } 165 166 func TestHealth(t *testing.T) { 167 for i, c := range GetClients() { 168 nc, ok := c.(client.NetworkClient) 169 require.True(t, ok, "%d", i) 170 _, err := nc.Health() 171 require.Nil(t, err, "%d: %+v", i, err) 172 } 173 } 174 175 func TestGenesisAndValidators(t *testing.T) { 176 for i, c := range GetClients() { 177 178 // make sure this is the right genesis file 179 gen, err := c.Genesis() 180 require.Nil(t, err, "%d: %+v", i, err) 181 // get the genesis validator 182 require.Equal(t, 1, len(gen.Genesis.Validators)) 183 gval := gen.Genesis.Validators[0] 184 185 // get the current validators 186 vals, err := c.Validators(nil, 0, 0) 187 require.Nil(t, err, "%d: %+v", i, err) 188 require.Equal(t, 1, len(vals.Validators)) 189 require.Equal(t, 1, vals.Count) 190 require.Equal(t, 1, vals.Total) 191 val := vals.Validators[0] 192 193 // make sure the current set is also the genesis set 194 assert.Equal(t, gval.Power, val.VotingPower) 195 assert.Equal(t, gval.PubKey, val.PubKey) 196 } 197 } 198 199 func TestABCIQuery(t *testing.T) { 200 for i, c := range GetClients() { 201 // write something 202 k, v, tx := MakeTxKV() 203 bres, err := c.BroadcastTxCommit(tx) 204 require.Nil(t, err, "%d: %+v", i, err) 205 apph := bres.Height + 1 // this is where the tx will be applied to the state 206 207 // wait before querying 208 client.WaitForHeight(c, apph, nil) 209 res, err := c.ABCIQuery("/key", k) 210 qres := res.Response 211 if assert.Nil(t, err) && assert.True(t, qres.IsOK()) { 212 assert.EqualValues(t, v, qres.Value) 213 } 214 } 215 } 216 217 // Make some app checks 218 func TestAppCalls(t *testing.T) { 219 assert, require := assert.New(t), require.New(t) 220 for i, c := range GetClients() { 221 222 // get an offset of height to avoid racing and guessing 223 s, err := c.Status() 224 require.Nil(err, "%d: %+v", i, err) 225 // sh is start height or status height 226 sh := s.SyncInfo.LatestBlockHeight 227 228 // look for the future 229 h := sh + 2 230 _, err = c.Block(&h) 231 assert.NotNil(err) // no block yet 232 233 // write something 234 k, v, tx := MakeTxKV() 235 bres, err := c.BroadcastTxCommit(tx) 236 require.Nil(err, "%d: %+v", i, err) 237 require.True(bres.DeliverTx.IsOK()) 238 txh := bres.Height 239 apph := txh + 1 // this is where the tx will be applied to the state 240 241 // wait before querying 242 if err := client.WaitForHeight(c, apph, nil); err != nil { 243 t.Error(err) 244 } 245 _qres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: false}) 246 qres := _qres.Response 247 if assert.Nil(err) && assert.True(qres.IsOK()) { 248 assert.Equal(k, qres.Key) 249 assert.EqualValues(v, qres.Value) 250 } 251 252 // make sure we can lookup the tx with proof 253 ptx, err := c.Tx(bres.Hash, true) 254 require.Nil(err, "%d: %+v", i, err) 255 assert.EqualValues(txh, ptx.Height) 256 assert.EqualValues(tx, ptx.Tx) 257 258 // and we can even check the block is added 259 block, err := c.Block(&apph) 260 require.Nil(err, "%d: %+v", i, err) 261 appHash := block.Block.Header.AppHash 262 assert.True(len(appHash) > 0) 263 assert.EqualValues(apph, block.Block.Header.Height) 264 265 // now check the results 266 blockResults, err := c.BlockResults(&txh) 267 require.Nil(err, "%d: %+v", i, err) 268 assert.Equal(txh, blockResults.Height) 269 if assert.Equal(1, len(blockResults.TxsResults)) { 270 // check success code 271 assert.EqualValues(0, blockResults.TxsResults[0].Code) 272 } 273 274 // check blockchain info, now that we know there is info 275 info, err := c.BlockchainInfo(apph, apph) 276 require.Nil(err, "%d: %+v", i, err) 277 assert.True(info.LastHeight >= apph) 278 if assert.Equal(1, len(info.BlockMetas)) { 279 lastMeta := info.BlockMetas[0] 280 assert.EqualValues(apph, lastMeta.Header.Height) 281 blockData := block.Block 282 assert.Equal(blockData.Header.AppHash, lastMeta.Header.AppHash) 283 assert.Equal(block.BlockID, lastMeta.BlockID) 284 } 285 286 // and get the corresponding commit with the same apphash 287 commit, err := c.Commit(&apph) 288 require.Nil(err, "%d: %+v", i, err) 289 cappHash := commit.Header.AppHash 290 assert.Equal(appHash, cappHash) 291 assert.NotNil(commit.Commit) 292 293 // compare the commits (note Commit(2) has commit from Block(3)) 294 h = apph - 1 295 commit2, err := c.Commit(&h) 296 require.Nil(err, "%d: %+v", i, err) 297 assert.Equal(block.Block.LastCommit, commit2.Commit) 298 299 // and we got a proof that works! 300 _pres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: true}) 301 pres := _pres.Response 302 assert.Nil(err) 303 assert.True(pres.IsOK()) 304 305 // XXX Test proof 306 } 307 } 308 309 func TestBroadcastTxSync(t *testing.T) { 310 require := require.New(t) 311 312 // TODO (melekes): use mempool which is set on RPC rather than getting it from node 313 mempool := node.Mempool() 314 initMempoolSize := mempool.Size() 315 316 for i, c := range GetClients() { 317 _, _, tx := MakeTxKV() 318 bres, err := c.BroadcastTxSync(tx) 319 require.Nil(err, "%d: %+v", i, err) 320 require.Equal(bres.Code, abci.CodeTypeOK) // FIXME 321 322 require.Equal(initMempoolSize+1, mempool.Size()) 323 324 txs := mempool.ReapMaxTxs(len(tx)) 325 require.EqualValues(tx, txs[0]) 326 mempool.Flush() 327 } 328 } 329 330 func TestBroadcastTxCommit(t *testing.T) { 331 require := require.New(t) 332 333 mempool := node.Mempool() 334 for i, c := range GetClients() { 335 _, _, tx := MakeTxKV() 336 bres, err := c.BroadcastTxCommit(tx) 337 require.Nil(err, "%d: %+v", i, err) 338 require.True(bres.CheckTx.IsOK()) 339 require.True(bres.DeliverTx.IsOK()) 340 341 require.Equal(0, mempool.Size()) 342 } 343 } 344 345 func TestUnconfirmedTxs(t *testing.T) { 346 _, _, tx := MakeTxKV() 347 348 mempool := node.Mempool() 349 _ = mempool.CheckTx(tx, nil, mempl.TxInfo{}) 350 351 for i, c := range GetClients() { 352 mc, ok := c.(client.MempoolClient) 353 require.True(t, ok, "%d", i) 354 res, err := mc.UnconfirmedTxs(1) 355 require.Nil(t, err, "%d: %+v", i, err) 356 357 assert.Equal(t, 1, res.Count) 358 assert.Equal(t, 1, res.Total) 359 assert.Equal(t, mempool.TxsBytes(), res.TotalBytes) 360 assert.Exactly(t, types.Txs{tx}, types.Txs(res.Txs)) 361 } 362 363 mempool.Flush() 364 } 365 366 func TestNumUnconfirmedTxs(t *testing.T) { 367 _, _, tx := MakeTxKV() 368 369 mempool := node.Mempool() 370 _ = mempool.CheckTx(tx, nil, mempl.TxInfo{}) 371 mempoolSize := mempool.Size() 372 373 for i, c := range GetClients() { 374 mc, ok := c.(client.MempoolClient) 375 require.True(t, ok, "%d", i) 376 res, err := mc.NumUnconfirmedTxs() 377 require.Nil(t, err, "%d: %+v", i, err) 378 379 assert.Equal(t, mempoolSize, res.Count) 380 assert.Equal(t, mempoolSize, res.Total) 381 assert.Equal(t, mempool.TxsBytes(), res.TotalBytes) 382 } 383 384 mempool.Flush() 385 } 386 387 func TestTx(t *testing.T) { 388 // first we broadcast a tx 389 c := getHTTPClient() 390 _, _, tx := MakeTxKV() 391 bres, err := c.BroadcastTxCommit(tx) 392 require.Nil(t, err, "%+v", err) 393 394 txHeight := bres.Height 395 txHash := bres.Hash 396 397 anotherTxHash := types.Tx("a different tx").Hash() 398 399 cases := []struct { 400 valid bool 401 prove bool 402 hash []byte 403 }{ 404 // only valid if correct hash provided 405 {true, false, txHash}, 406 {true, true, txHash}, 407 {false, false, anotherTxHash}, 408 {false, true, anotherTxHash}, 409 {false, false, nil}, 410 {false, true, nil}, 411 } 412 413 for i, c := range GetClients() { 414 for j, tc := range cases { 415 t.Logf("client %d, case %d", i, j) 416 417 // now we query for the tx. 418 // since there's only one tx, we know index=0. 419 ptx, err := c.Tx(tc.hash, tc.prove) 420 421 if !tc.valid { 422 require.NotNil(t, err) 423 } else { 424 require.Nil(t, err, "%+v", err) 425 assert.EqualValues(t, txHeight, ptx.Height) 426 assert.EqualValues(t, tx, ptx.Tx) 427 assert.Zero(t, ptx.Index) 428 assert.True(t, ptx.TxResult.IsOK()) 429 assert.EqualValues(t, txHash, ptx.Hash) 430 431 // time to verify the proof 432 proof := ptx.Proof 433 if tc.prove && assert.EqualValues(t, tx, proof.Data) { 434 assert.NoError(t, proof.Proof.Verify(proof.RootHash, txHash)) 435 } 436 } 437 } 438 } 439 } 440 441 func TestTxSearchWithTimeout(t *testing.T) { 442 // Get a client with a time-out of 10 secs. 443 timeoutClient := getHTTPClientWithTimeout(10) 444 445 // query using a compositeKey (see kvstore application) 446 result, err := timeoutClient.TxSearch("app.creator='Cosmoshi Netowoko'", false, 1, 30, "asc") 447 require.Nil(t, err) 448 if len(result.Txs) == 0 { 449 t.Fatal("expected a lot of transactions") 450 } 451 } 452 453 func TestTxSearch(t *testing.T) { 454 c := getHTTPClient() 455 456 // first we broadcast a few txs 457 for i := 0; i < 10; i++ { 458 _, _, tx := MakeTxKV() 459 _, err := c.BroadcastTxCommit(tx) 460 require.NoError(t, err) 461 } 462 463 // since we're not using an isolated test server, we'll have lingering transactions 464 // from other tests as well 465 result, err := c.TxSearch("tx.height >= 0", true, 1, 100, "asc") 466 require.NoError(t, err) 467 txCount := len(result.Txs) 468 469 // pick out the last tx to have something to search for in tests 470 find := result.Txs[len(result.Txs)-1] 471 anotherTxHash := types.Tx("a different tx").Hash() 472 473 for i, c := range GetClients() { 474 t.Logf("client %d", i) 475 476 // now we query for the tx. 477 result, err := c.TxSearch(fmt.Sprintf("tx.hash='%v'", find.Hash), true, 1, 30, "asc") 478 require.Nil(t, err) 479 require.Len(t, result.Txs, 1) 480 require.Equal(t, find.Hash, result.Txs[0].Hash) 481 482 ptx := result.Txs[0] 483 assert.EqualValues(t, find.Height, ptx.Height) 484 assert.EqualValues(t, find.Tx, ptx.Tx) 485 assert.Zero(t, ptx.Index) 486 assert.True(t, ptx.TxResult.IsOK()) 487 assert.EqualValues(t, find.Hash, ptx.Hash) 488 489 // time to verify the proof 490 if assert.EqualValues(t, find.Tx, ptx.Proof.Data) { 491 assert.NoError(t, ptx.Proof.Proof.Verify(ptx.Proof.RootHash, find.Hash)) 492 } 493 494 // query by height 495 result, err = c.TxSearch(fmt.Sprintf("tx.height=%d", find.Height), true, 1, 30, "asc") 496 require.Nil(t, err) 497 require.Len(t, result.Txs, 1) 498 499 // query for non existing tx 500 result, err = c.TxSearch(fmt.Sprintf("tx.hash='%X'", anotherTxHash), false, 1, 30, "asc") 501 require.Nil(t, err) 502 require.Len(t, result.Txs, 0) 503 504 // query using a compositeKey (see kvstore application) 505 result, err = c.TxSearch("app.creator='Cosmoshi Netowoko'", false, 1, 30, "asc") 506 require.Nil(t, err) 507 if len(result.Txs) == 0 { 508 t.Fatal("expected a lot of transactions") 509 } 510 511 // query using a compositeKey (see kvstore application) and height 512 result, err = c.TxSearch("app.creator='Cosmoshi Netowoko' AND tx.height<10000", true, 1, 30, "asc") 513 require.Nil(t, err) 514 if len(result.Txs) == 0 { 515 t.Fatal("expected a lot of transactions") 516 } 517 518 // query a non existing tx with page 1 and txsPerPage 1 519 result, err = c.TxSearch("app.creator='Cosmoshi Neetowoko'", true, 1, 1, "asc") 520 require.Nil(t, err) 521 require.Len(t, result.Txs, 0) 522 523 // check sorting 524 result, err = c.TxSearch(fmt.Sprintf("tx.height >= 1"), false, 1, 30, "asc") 525 require.Nil(t, err) 526 for k := 0; k < len(result.Txs)-1; k++ { 527 require.LessOrEqual(t, result.Txs[k].Height, result.Txs[k+1].Height) 528 require.LessOrEqual(t, result.Txs[k].Index, result.Txs[k+1].Index) 529 } 530 531 result, err = c.TxSearch(fmt.Sprintf("tx.height >= 1"), false, 1, 30, "desc") 532 require.Nil(t, err) 533 for k := 0; k < len(result.Txs)-1; k++ { 534 require.GreaterOrEqual(t, result.Txs[k].Height, result.Txs[k+1].Height) 535 require.GreaterOrEqual(t, result.Txs[k].Index, result.Txs[k+1].Index) 536 } 537 538 // check pagination 539 var ( 540 seen = map[int64]bool{} 541 maxHeight int64 542 perPage = 3 543 pages = int(math.Ceil(float64(txCount) / float64(perPage))) 544 ) 545 for page := 1; page <= pages; page++ { 546 result, err = c.TxSearch("tx.height >= 1", false, page, perPage, "asc") 547 require.NoError(t, err) 548 if page < pages { 549 require.Len(t, result.Txs, perPage) 550 } else { 551 require.LessOrEqual(t, len(result.Txs), perPage) 552 } 553 require.Equal(t, txCount, result.TotalCount) 554 for _, tx := range result.Txs { 555 require.False(t, seen[tx.Height], 556 "Found duplicate height %v in page %v", tx.Height, page) 557 require.Greater(t, tx.Height, maxHeight, 558 "Found decreasing height %v (max seen %v) in page %v", tx.Height, maxHeight, page) 559 seen[tx.Height] = true 560 maxHeight = tx.Height 561 } 562 } 563 require.Len(t, seen, txCount) 564 } 565 } 566 567 func deepcpVote(vote *types.Vote) (res *types.Vote) { 568 res = &types.Vote{ 569 ValidatorAddress: make([]byte, len(vote.ValidatorAddress)), 570 ValidatorIndex: vote.ValidatorIndex, 571 Height: vote.Height, 572 Round: vote.Round, 573 Type: vote.Type, 574 Timestamp: vote.Timestamp, 575 BlockID: types.BlockID{ 576 Hash: make([]byte, len(vote.BlockID.Hash)), 577 PartsHeader: vote.BlockID.PartsHeader, 578 }, 579 Signature: make([]byte, len(vote.Signature)), 580 } 581 copy(res.ValidatorAddress, vote.ValidatorAddress) 582 copy(res.BlockID.Hash, vote.BlockID.Hash) 583 copy(res.Signature, vote.Signature) 584 return 585 } 586 587 func newEvidence( 588 t *testing.T, 589 val *privval.FilePV, 590 vote *types.Vote, 591 vote2 *types.Vote, 592 chainID string, 593 ) types.DuplicateVoteEvidence { 594 var err error 595 deepcpVote2 := deepcpVote(vote2) 596 deepcpVote2.Signature, err = val.Key.PrivKey.Sign(deepcpVote2.SignBytes(chainID)) 597 require.NoError(t, err) 598 599 return *types.NewDuplicateVoteEvidence(val.Key.PubKey, vote, deepcpVote2) 600 } 601 602 func makeEvidences( 603 t *testing.T, 604 val *privval.FilePV, 605 chainID string, 606 ) (ev types.DuplicateVoteEvidence, fakes []types.DuplicateVoteEvidence) { 607 vote := &types.Vote{ 608 ValidatorAddress: val.Key.Address, 609 ValidatorIndex: 0, 610 Height: 1, 611 Round: 0, 612 Type: types.PrevoteType, 613 Timestamp: time.Now().UTC(), 614 BlockID: types.BlockID{ 615 Hash: tmhash.Sum([]byte("blockhash")), 616 PartsHeader: types.PartSetHeader{ 617 Total: 1000, 618 Hash: tmhash.Sum([]byte("partset")), 619 }, 620 }, 621 } 622 623 var err error 624 vote.Signature, err = val.Key.PrivKey.Sign(vote.SignBytes(chainID)) 625 require.NoError(t, err) 626 627 vote2 := deepcpVote(vote) 628 vote2.BlockID.Hash = tmhash.Sum([]byte("blockhash2")) 629 630 ev = newEvidence(t, val, vote, vote2, chainID) 631 632 fakes = make([]types.DuplicateVoteEvidence, 42) 633 634 // different address 635 vote2 = deepcpVote(vote) 636 for i := 0; i < 10; i++ { 637 rand.Read(vote2.ValidatorAddress) // nolint: gosec 638 fakes[i] = newEvidence(t, val, vote, vote2, chainID) 639 } 640 // different index 641 vote2 = deepcpVote(vote) 642 for i := 10; i < 20; i++ { 643 vote2.ValidatorIndex = rand.Int()%100 + 1 // nolint: gosec 644 fakes[i] = newEvidence(t, val, vote, vote2, chainID) 645 } 646 // different height 647 vote2 = deepcpVote(vote) 648 for i := 20; i < 30; i++ { 649 vote2.Height = rand.Int63()%1000 + 100 // nolint: gosec 650 fakes[i] = newEvidence(t, val, vote, vote2, chainID) 651 } 652 // different round 653 vote2 = deepcpVote(vote) 654 for i := 30; i < 40; i++ { 655 vote2.Round = rand.Int()%10 + 1 // nolint: gosec 656 fakes[i] = newEvidence(t, val, vote, vote2, chainID) 657 } 658 // different type 659 vote2 = deepcpVote(vote) 660 vote2.Type = types.PrecommitType 661 fakes[40] = newEvidence(t, val, vote, vote2, chainID) 662 // exactly same vote 663 vote2 = deepcpVote(vote) 664 fakes[41] = newEvidence(t, val, vote, vote2, chainID) 665 return ev, fakes 666 } 667 668 func TestBroadcastEvidenceDuplicateVote(t *testing.T) { 669 config := rpctest.GetConfig() 670 chainID := config.ChainID() 671 pvKeyFile := config.PrivValidatorKeyFile() 672 pvKeyStateFile := config.PrivValidatorStateFile() 673 pv := privval.LoadOrGenFilePV(pvKeyFile, pvKeyStateFile) 674 675 ev, fakes := makeEvidences(t, pv, chainID) 676 t.Logf("evidence %v", ev) 677 678 for i, c := range GetClients() { 679 t.Logf("client %d", i) 680 681 result, err := c.BroadcastEvidence(&ev) 682 require.Nil(t, err) 683 require.Equal(t, ev.Hash(), result.Hash, "Invalid response, result %+v", result) 684 685 status, err := c.Status() 686 require.NoError(t, err) 687 client.WaitForHeight(c, status.SyncInfo.LatestBlockHeight+2, nil) 688 689 ed25519pub := ev.PubKey.(ed25519.PubKeyEd25519) 690 rawpub := ed25519pub[:] 691 result2, err := c.ABCIQuery("/val", rawpub) 692 require.Nil(t, err, "Error querying evidence, err %v", err) 693 qres := result2.Response 694 require.True(t, qres.IsOK(), "Response not OK") 695 696 var v abci.ValidatorUpdate 697 err = abci.ReadMessage(bytes.NewReader(qres.Value), &v) 698 require.NoError(t, err, "Error reading query result, value %v", qres.Value) 699 700 require.EqualValues(t, rawpub, v.PubKey.Data, "Stored PubKey not equal with expected, value %v", string(qres.Value)) 701 require.Equal(t, int64(9), v.Power, "Stored Power not equal with expected, value %v", string(qres.Value)) 702 703 for _, fake := range fakes { 704 _, err := c.BroadcastEvidence(&types.DuplicateVoteEvidence{ 705 PubKey: fake.PubKey, 706 VoteA: fake.VoteA, 707 VoteB: fake.VoteB}) 708 require.Error(t, err, "Broadcasting fake evidence succeed: %s", fake.String()) 709 } 710 } 711 } 712 713 func TestBatchedJSONRPCCalls(t *testing.T) { 714 c := getHTTPClient() 715 testBatchedJSONRPCCalls(t, c) 716 } 717 718 func testBatchedJSONRPCCalls(t *testing.T, c *rpchttp.HTTP) { 719 k1, v1, tx1 := MakeTxKV() 720 k2, v2, tx2 := MakeTxKV() 721 722 batch := c.NewBatch() 723 r1, err := batch.BroadcastTxCommit(tx1) 724 require.NoError(t, err) 725 r2, err := batch.BroadcastTxCommit(tx2) 726 require.NoError(t, err) 727 require.Equal(t, 2, batch.Count()) 728 bresults, err := batch.Send() 729 require.NoError(t, err) 730 require.Len(t, bresults, 2) 731 require.Equal(t, 0, batch.Count()) 732 733 bresult1, ok := bresults[0].(*ctypes.ResultBroadcastTxCommit) 734 require.True(t, ok) 735 require.Equal(t, *bresult1, *r1) 736 bresult2, ok := bresults[1].(*ctypes.ResultBroadcastTxCommit) 737 require.True(t, ok) 738 require.Equal(t, *bresult2, *r2) 739 apph := tmmath.MaxInt64(bresult1.Height, bresult2.Height) + 1 740 741 client.WaitForHeight(c, apph, nil) 742 743 q1, err := batch.ABCIQuery("/key", k1) 744 require.NoError(t, err) 745 q2, err := batch.ABCIQuery("/key", k2) 746 require.NoError(t, err) 747 require.Equal(t, 2, batch.Count()) 748 qresults, err := batch.Send() 749 require.NoError(t, err) 750 require.Len(t, qresults, 2) 751 require.Equal(t, 0, batch.Count()) 752 753 qresult1, ok := qresults[0].(*ctypes.ResultABCIQuery) 754 require.True(t, ok) 755 require.Equal(t, *qresult1, *q1) 756 qresult2, ok := qresults[1].(*ctypes.ResultABCIQuery) 757 require.True(t, ok) 758 require.Equal(t, *qresult2, *q2) 759 760 require.Equal(t, qresult1.Response.Key, k1) 761 require.Equal(t, qresult2.Response.Key, k2) 762 require.Equal(t, qresult1.Response.Value, v1) 763 require.Equal(t, qresult2.Response.Value, v2) 764 } 765 766 func TestBatchedJSONRPCCallsCancellation(t *testing.T) { 767 c := getHTTPClient() 768 _, _, tx1 := MakeTxKV() 769 _, _, tx2 := MakeTxKV() 770 771 batch := c.NewBatch() 772 _, err := batch.BroadcastTxCommit(tx1) 773 require.NoError(t, err) 774 _, err = batch.BroadcastTxCommit(tx2) 775 require.NoError(t, err) 776 // we should have 2 requests waiting 777 require.Equal(t, 2, batch.Count()) 778 // we want to make sure we cleared 2 pending requests 779 require.Equal(t, 2, batch.Clear()) 780 // now there should be no batched requests 781 require.Equal(t, 0, batch.Count()) 782 } 783 784 func TestSendingEmptyRequestBatch(t *testing.T) { 785 c := getHTTPClient() 786 batch := c.NewBatch() 787 _, err := batch.Send() 788 require.Error(t, err, "sending an empty batch of JSON RPC requests should result in an error") 789 } 790 791 func TestClearingEmptyRequestBatch(t *testing.T) { 792 c := getHTTPClient() 793 batch := c.NewBatch() 794 require.Zero(t, batch.Clear(), "clearing an empty batch of JSON RPC requests should result in a 0 result") 795 } 796 797 func TestConcurrentJSONRPCBatching(t *testing.T) { 798 var wg sync.WaitGroup 799 c := getHTTPClient() 800 for i := 0; i < 50; i++ { 801 wg.Add(1) 802 go func() { 803 defer wg.Done() 804 testBatchedJSONRPCCalls(t, c) 805 }() 806 } 807 wg.Wait() 808 }