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