github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/rpc/tests/rpc_test.go (about) 1 // This is a test utility for Ethermint's Web3 JSON-RPC services. 2 // 3 // To run these tests please first ensure you have the ethermintd running 4 // and have started the RPC service with `ethermintcli rest-server`. 5 // 6 // You can configure the desired HOST and MODE as well 7 package tests 8 9 import ( 10 "bytes" 11 "encoding/json" 12 "fmt" 13 "io/ioutil" 14 "math/big" 15 "math/rand" 16 "net" 17 "net/http" 18 "os" 19 "strings" 20 "sync" 21 "testing" 22 "time" 23 24 ethcmn "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/common/hexutil" 26 ethtypes "github.com/ethereum/go-ethereum/core/types" 27 gorpc "github.com/ethereum/go-ethereum/rpc" 28 "github.com/spf13/viper" 29 "github.com/stretchr/testify/require" 30 "github.com/stretchr/testify/suite" 31 32 "github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1" 33 "github.com/fibonacci-chain/fbc/app/rpc/backend" 34 cosmos_context "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context" 35 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags" 36 cmserver "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server" 37 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt" 38 cosmost "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/types" 39 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 40 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 41 "github.com/fibonacci-chain/fbc/x/evm/watcher" 42 43 "github.com/fibonacci-chain/fbc/app/rpc" 44 "github.com/fibonacci-chain/fbc/app/rpc/types" 45 apptesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing" 46 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 47 tmamino "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/encoding/amino" 48 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/multisig" 49 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/log" 50 ) 51 52 const ( 53 addrAStoreKey = 0 54 defaultProtocolVersion = 65 55 defaultChainID = 65 56 defaultMinGasPrice = "0.0000000001fibo" 57 safeLowGP = "0.0000000001fibo" 58 avgGP = "0.0000000001fibo" 59 fastestGP = "0.00000000015fibo" 60 latestBlockNumber = "latest" 61 pendingBlockNumber = "pending" 62 ) 63 64 var ( 65 receiverAddr = ethcmn.BytesToAddress([]byte("receiver")) 66 inexistentAddr = ethcmn.BytesToAddress([]byte{0}) 67 inexistentHash = ethcmn.BytesToHash([]byte("inexistent hash")) 68 MODE = os.Getenv("MODE") 69 from = []byte{1} 70 ) 71 72 func init() { 73 tmamino.RegisterKeyType(ethsecp256k1.PubKey{}, ethsecp256k1.PubKeyName) 74 multisig.RegisterKeyType(ethsecp256k1.PubKey{}, ethsecp256k1.PubKeyName) 75 } 76 77 type RPCTestSuite struct { 78 suite.Suite 79 80 coordinator *apptesting.Coordinator 81 82 // testing chains used for convenience and readability 83 chain apptesting.TestChainI 84 85 apiServer *gorpc.Server 86 Mux *http.ServeMux 87 cliCtx *cosmos_context.CLIContext 88 rpcListener net.Listener 89 addr string 90 tmRpcListener net.Listener 91 tmAddr string 92 } 93 94 func (suite *RPCTestSuite) SetupTest() { 95 96 viper.Set(rpc.FlagDebugAPI, true) 97 viper.Set(cmserver.FlagPruning, cosmost.PruningOptionNothing) 98 // set fbchaincli path 99 cliDir, err := ioutil.TempDir("", ".fbchaincli") 100 if err != nil { 101 panic(err) 102 } 103 defer os.RemoveAll(cliDir) 104 viper.Set(cmserver.FlagUlockKeyHome, cliDir) 105 106 // set fbchaind path 107 serverDir, err := ioutil.TempDir("", ".fbchaind") 108 if err != nil { 109 panic(err) 110 } 111 defer os.RemoveAll(serverDir) 112 viper.Set(flags.FlagHome, serverDir) 113 114 chainId := apptesting.GetOKChainID(1) 115 suite.coordinator = apptesting.NewEthCoordinator(suite.T(), 1) 116 suite.chain = suite.coordinator.GetChain(chainId) 117 suite.chain.App().SetOption(abci.RequestSetOption{ 118 Key: "CheckChainID", 119 Value: chainId, 120 }) 121 122 //Kb = keys.NewInMemory(hd.EthSecp256k1Options()...) 123 //info, err := Kb.CreateAccount("captain", "puzzle glide follow cruel say burst deliver wild tragic galaxy lumber offer", "", "12345678", "m/44'/60'/0'/0/1", "eth_secp256k1") 124 125 mck := NewMockClient(chainId, suite.chain, suite.chain.App()) 126 suite.tmRpcListener, suite.tmAddr, err = mck.StartTmRPC() 127 if err != nil { 128 panic(err) 129 } 130 viper.Set("rpc.laddr", suite.tmAddr) 131 132 cliCtx := cosmos_context.NewCLIContext(). 133 WithProxy(suite.chain.Codec()). 134 WithTrustNode(true). 135 WithChainID(chainId). 136 WithClient(mck). 137 WithBroadcastMode(flags.BroadcastSync) 138 139 suite.cliCtx = &cliCtx 140 commitBlock(suite) 141 142 suite.apiServer = gorpc.NewServer() 143 144 viper.Set(rpc.FlagDisableAPI, "") 145 146 viper.Set(backend.FlagApiBackendBlockLruCache, 100) 147 viper.Set(backend.FlagApiBackendTxLruCache, 100) 148 viper.Set(watcher.FlagFastQueryLru, 100) 149 viper.Set(flags.FlagKeyringBackend, "test") 150 151 viper.Set(rpc.FlagPersonalAPI, true) 152 153 senderPv := suite.chain.SenderAccountPVBZ() 154 genesisAcc = suite.chain.SenderAccount().GetAddress() 155 senderAddr = ethcmn.BytesToAddress(genesisAcc.Bytes()) 156 apis := rpc.GetAPIs(cliCtx, log.NewNopLogger(), []ethsecp256k1.PrivKey{ethsecp256k1.PrivKey(senderPv)}...) 157 for _, api := range apis { 158 if err := suite.apiServer.RegisterName(api.Namespace, api.Service); err != nil { 159 panic(err) 160 } 161 } 162 StartRpc(suite) 163 } 164 165 func (suite *RPCTestSuite) TearDownTest() { 166 if suite.rpcListener != nil { 167 suite.rpcListener.Close() 168 } 169 if suite.tmRpcListener != nil { 170 suite.rpcListener.Close() 171 } 172 } 173 func StartRpc(suite *RPCTestSuite) { 174 suite.Mux = http.NewServeMux() 175 suite.Mux.HandleFunc("/", suite.apiServer.ServeHTTP) 176 listener, err := net.Listen("tcp", ":0") 177 if err != nil { 178 panic(err) 179 } 180 suite.rpcListener = listener 181 suite.addr = fmt.Sprintf("http://localhost:%d", listener.Addr().(*net.TCPAddr).Port) 182 go func() { 183 http.Serve(listener, suite.Mux) 184 }() 185 } 186 func TestRPCTestSuite(t *testing.T) { 187 suite.Run(t, new(RPCTestSuite)) 188 } 189 190 func TestRPCTestSuiteWithMarsHeight2(t *testing.T) { 191 mpt.TrieWriteAhead = true 192 tmtypes.UnittestOnlySetMilestoneMarsHeight(2) 193 suite.Run(t, new(RPCTestSuite)) 194 } 195 196 func TestRPCTestSuiteWithMarsHeight1(t *testing.T) { 197 mpt.TrieWriteAhead = true 198 tmtypes.UnittestOnlySetMilestoneMarsHeight(1) 199 suite.Run(t, new(RPCTestSuite)) 200 } 201 202 func commitBlock(suite *RPCTestSuite) { 203 mck, ok := suite.cliCtx.Client.(*MockClient) 204 suite.Require().True(ok) 205 mck.CommitBlock() 206 } 207 func (suite *RPCTestSuite) TestEth_GetBalance() { 208 // initial balance of hexAddr2 is 1000000000fibo in test.sh 209 initialBalance := suite.chain.SenderAccount().GetCoins()[0] 210 genesisAcc := ethcmn.BytesToAddress(suite.chain.SenderAccount().GetAddress().Bytes()).String() 211 212 rpcRes, err := CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, latestBlockNumber}) 213 suite.Require().NoError(err) 214 215 rpcRes2, err := CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, latestBlockNumber}) 216 suite.Require().NoError(err) 217 suite.Require().NotNil(rpcRes2) 218 219 var balance hexutil.Big 220 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance)) 221 suite.Require().Equal(initialBalance.Amount.Int, balance.ToInt()) 222 223 //suite.coordinator.CommitBlock(suite.chain) 224 // query on certain block height (2) 225 rpcRes, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, hexutil.EncodeUint64(1)}) 226 suite.Require().NoError(err) 227 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance)) 228 suite.Require().Equal(initialBalance.Amount.Int, balance.ToInt()) 229 230 // query with pending -> no tx in mempool 231 rpcRes, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, pendingBlockNumber}) 232 suite.Require().NoError(err) 233 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance)) 234 suite.Require().Equal(initialBalance.Amount.Int, balance.ToInt()) 235 236 // inexistent addr -> zero balance 237 rpcRes, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{inexistentAddr, latestBlockNumber}) 238 suite.Require().NoError(err) 239 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance)) 240 suite.Require().Equal(big.NewInt(0).Int64(), balance.ToInt().Int64()) 241 242 // error check 243 // empty hex string 244 _, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{hexAddr2, ""}) 245 suite.Require().Error(err) 246 247 // missing argument 248 _, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{hexAddr2}) 249 suite.Require().Error(err) 250 } 251 func (suite *RPCTestSuite) TestEth_Accounts() { 252 // all unlocked addresses 253 rpcRes, err := CallWithError(suite.addr, "eth_accounts", nil) 254 suite.Require().NoError(err) 255 suite.Require().Equal(1, rpcRes.ID) 256 257 var addrsUnlocked []ethcmn.Address 258 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &addrsUnlocked)) 259 //suite.Require().Equal(addrCounter, len(addrsUnlocked)) 260 //suite.Require().True(addrsUnlocked[0] == hexAddr1) 261 //suite.Require().True(addrsUnlocked[1] == hexAddr2) 262 } 263 264 func (suite *RPCTestSuite) TestEth_ProtocolVersion() { 265 rpcRes, err := CallWithError(suite.addr, "eth_protocolVersion", nil) 266 suite.Require().NoError(err) 267 268 var version hexutil.Uint 269 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &version)) 270 suite.Require().Equal(version, hexutil.Uint(defaultProtocolVersion)) 271 } 272 273 func (suite *RPCTestSuite) TestEth_ChainId() { 274 rpcRes, err := CallWithError(suite.addr, "eth_chainId", nil) 275 suite.Require().NoError(err) 276 277 var chainID hexutil.Uint 278 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &chainID)) 279 suite.Require().Equal(hexutil.Uint(1), chainID) 280 } 281 282 func (suite *RPCTestSuite) TestEth_Syncing() { 283 rpcRes, err := CallWithError(suite.addr, "eth_syncing", nil) 284 suite.Require().NoError(err) 285 286 // single node for test.sh -> always leading without syncing 287 var catchingUp bool 288 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &catchingUp)) 289 suite.Require().False(catchingUp) 290 291 // TODO: set an evn in multi-nodes testnet to test the sycing status of a lagging node 292 } 293 294 func (suite *RPCTestSuite) TestEth_Coinbase() { 295 // single node -> always the same addr for coinbase 296 rpcRes, err := CallWithError(suite.addr, "eth_coinbase", nil) 297 suite.Require().NoError(err) 298 299 var coinbaseAddr1 ethcmn.Address 300 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &coinbaseAddr1)) 301 302 // wait for 5s as an block interval 303 time.Sleep(5 * time.Second) 304 305 // query again 306 rpcRes, err = CallWithError(suite.addr, "eth_coinbase", nil) 307 suite.Require().NoError(err) 308 309 var coinbaseAddr2 ethcmn.Address 310 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &coinbaseAddr2)) 311 312 suite.Require().Equal(coinbaseAddr1, coinbaseAddr2) 313 } 314 315 func (suite *RPCTestSuite) TestEth_PowAttribute() { 316 // eth_mining -> always false 317 rpcRes, err := CallWithError(suite.addr, "eth_mining", nil) 318 suite.Require().NoError(err) 319 320 var mining bool 321 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &mining)) 322 suite.Require().False(mining) 323 324 // eth_hashrate -> always 0 325 rpcRes, err = CallWithError(suite.addr, "eth_hashrate", nil) 326 suite.Require().NoError(err) 327 328 var hashrate hexutil.Uint64 329 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hashrate)) 330 suite.Require().True(hashrate == 0) 331 332 // eth_getUncleCountByBlockHash -> 0 for any hash 333 rpcRes, err = CallWithError(suite.addr, "eth_getUncleCountByBlockHash", []interface{}{inexistentHash}) 334 suite.Require().NoError(err) 335 336 var uncleCount hexutil.Uint 337 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &uncleCount)) 338 suite.Require().True(uncleCount == 0) 339 340 // eth_getUncleCountByBlockNumber -> 0 for any block number 341 rpcRes, err = CallWithError(suite.addr, "eth_getUncleCountByBlockNumber", []interface{}{latestBlockNumber}) 342 suite.Require().NoError(err) 343 344 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &uncleCount)) 345 suite.Require().True(uncleCount == 0) 346 347 // eth_getUncleByBlockHashAndIndex -> always "null" 348 rand.Seed(time.Now().UnixNano()) 349 luckyNum := int64(rand.Int()) 350 randomBlockHash := ethcmn.BigToHash(big.NewInt(luckyNum)) 351 randomIndex := hexutil.Uint(luckyNum) 352 rpcRes, err = CallWithError(suite.addr, "eth_getUncleByBlockHashAndIndex", []interface{}{randomBlockHash, randomIndex}) 353 suite.Require().NoError(err) 354 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 355 356 // error check 357 // miss argument 358 _, err = CallWithError(suite.addr, "eth_getUncleByBlockHashAndIndex", []interface{}{randomBlockHash}) 359 suite.Require().Error(err) 360 361 _, err = CallWithError(suite.addr, "eth_getUncleByBlockHashAndIndex", nil) 362 suite.Require().Error(err) 363 364 // eth_getUncleByBlockNumberAndIndex -> always "null" 365 luckyNum = int64(rand.Int()) 366 randomBlockHeight := hexutil.Uint(luckyNum) 367 randomIndex = hexutil.Uint(luckyNum) 368 rpcRes, err = CallWithError(suite.addr, "eth_getUncleByBlockNumberAndIndex", []interface{}{randomBlockHeight, randomIndex}) 369 suite.Require().NoError(err) 370 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 371 372 // error check 373 // miss argument 374 _, err = CallWithError(suite.addr, "eth_getUncleByBlockNumberAndIndex", []interface{}{randomBlockHeight}) 375 suite.Require().Error(err) 376 377 _, err = CallWithError(suite.addr, "eth_getUncleByBlockNumberAndIndex", nil) 378 suite.Require().Error(err) 379 } 380 381 func (suite *RPCTestSuite) TestEth_GasPrice() { 382 rpcRes, err := CallWithError(suite.addr, "eth_gasPrice", nil) 383 suite.Require().NoError(err) 384 385 var gasPrice hexutil.Big 386 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &gasPrice)) 387 388 // min gas price in test.sh is "0.000000001fibo" 389 mgp, err := sdk.ParseDecCoin(defaultMinGasPrice) 390 suite.Require().NoError(err) 391 392 suite.Require().Equal(mgp.Amount.BigInt(), gasPrice.ToInt()) 393 } 394 395 func (suite *RPCTestSuite) TestEth_GasPriceIn3Gears() { 396 rpcRes, err := CallWithError(suite.addr, "eth_gasPriceIn3Gears", nil) 397 suite.Require().NoError(err) 398 399 var gpIn3Gears types.GPIn3Gears 400 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &gpIn3Gears)) 401 402 mgp, err := sdk.ParseDecCoin(safeLowGP) 403 suite.Require().NoError(err) 404 agp, err := sdk.ParseDecCoin(avgGP) 405 suite.Require().NoError(err) 406 fgp, err := sdk.ParseDecCoin(fastestGP) 407 suite.Require().NoError(err) 408 409 suite.Require().Equal(mgp.Amount.BigInt(), gpIn3Gears.SafeLow.ToInt()) 410 suite.Require().Equal(agp.Amount.BigInt(), gpIn3Gears.Average.ToInt()) 411 suite.Require().Equal(fgp.Amount.BigInt(), gpIn3Gears.Fastest.ToInt()) 412 } 413 414 func (suite *RPCTestSuite) TestEth_BlockNumber() { 415 rpcRes := Call(suite.T(), suite.addr, "eth_blockNumber", nil) 416 var blockNumber1 hexutil.Uint64 417 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &blockNumber1)) 418 419 commitBlock(suite) 420 commitBlock(suite) 421 422 rpcRes = Call(suite.T(), suite.addr, "eth_blockNumber", nil) 423 var blockNumber2 hexutil.Uint64 424 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &blockNumber2)) 425 426 suite.Require().True(blockNumber2 > blockNumber1) 427 } 428 func (suite *RPCTestSuite) TestDebug_traceTransaction_Transfer() { 429 430 value := sdk.NewDec(1) 431 param := make([]map[string]string, 1) 432 param[0] = make(map[string]string) 433 param[0]["from"] = senderAddr.Hex() 434 param[0]["to"] = receiverAddr.Hex() 435 param[0]["value"] = (*hexutil.Big)(value.BigInt()).String() 436 param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String() 437 438 rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param) 439 440 var hash ethcmn.Hash 441 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 442 443 commitBlock(suite) 444 commitBlock(suite) 445 receipt := WaitForReceipt(suite.T(), suite.addr, hash) 446 suite.Require().NotNil(receipt) 447 suite.Require().Equal("0x1", receipt["status"].(string)) 448 449 debugParam := make([]interface{}, 2) 450 debugParam[0] = hash.Hex() 451 debugParam[1] = map[string]string{} 452 453 rpcRes = Call(suite.T(), suite.addr, "debug_traceTransaction", debugParam) 454 suite.Require().NotNil(rpcRes.Result) 455 } 456 457 func (suite *RPCTestSuite) TestEth_SendTransaction_Transfer() { 458 459 value := sdk.NewDec(1) 460 param := make([]map[string]string, 1) 461 param[0] = make(map[string]string) 462 param[0]["from"] = senderAddr.Hex() 463 param[0]["to"] = receiverAddr.Hex() 464 param[0]["value"] = (*hexutil.Big)(value.BigInt()).String() 465 param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String() 466 467 rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param) 468 469 var hash ethcmn.Hash 470 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 471 472 commitBlock(suite) 473 commitBlock(suite) 474 receipt := WaitForReceipt(suite.T(), suite.addr, hash) 475 suite.Require().NotNil(receipt) 476 suite.Require().Equal("0x1", receipt["status"].(string)) 477 //suite.T().Logf("%s transfers %sfibo to %s successfully\n", hexAddr1.Hex(), value.String(), receiverAddr.Hex()) 478 479 // TODO: logic bug, fix it later 480 // ignore gas price -> default 'ethermint.DefaultGasPrice' on node -> successfully 481 //delete(param[0], "gasPrice") 482 //rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param) 483 // 484 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 485 //receipt = WaitForReceipt(suite.T(), hash) 486 //suite.Require().NotNil(receipt) 487 //suite.Require().Equal("0x1", receipt["status"].(string)) 488 //suite.T().Logf("%s transfers %sfibo to %s successfully with nil gas price \n", hexAddr1.Hex(), value.String(), receiverAddr.Hex()) 489 490 // error check 491 // sender is not unlocked on the node 492 param[0]["from"] = receiverAddr.Hex() 493 param[0]["to"] = hexAddr1.Hex() 494 _, err := CallWithError(suite.addr, "eth_sendTransaction", param) 495 suite.Require().Error(err) 496 497 // data.Data and data.Input are not same 498 param[0]["from"], param[0]["to"] = param[0]["to"], param[0]["from"] 499 param[0]["data"] = "0x1234567890abcdef" 500 param[0]["input"] = param[0]["data"][:len(param[0]["data"])-2] 501 _, err = CallWithError(suite.addr, "eth_sendTransaction", param) 502 suite.Require().Error(err) 503 504 // input and toAddr are all empty 505 delete(param[0], "to") 506 delete(param[0], "input") 507 delete(param[0], "data") 508 509 _, err = CallWithError(suite.addr, "eth_sendTransaction", param) 510 suite.Require().Error(err) 511 512 // 0 gas price 513 param[0]["to"] = receiverAddr.Hex() 514 param[0]["gasPrice"] = (*hexutil.Big)(sdk.ZeroDec().BigInt()).String() 515 _, err = CallWithError(suite.addr, "eth_sendTransaction", param) 516 suite.Require().Error(err) 517 } 518 519 /*func (suite *RPCTestSuite) TestEth_SendTransaction_ContractDeploy() { 520 521 param := make([]map[string]string, 1) 522 param[0] = make(map[string]string) 523 param[0]["from"] = senderAddr.Hex() 524 param[0]["data"] = "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029" 525 param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String() 526 rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param) 527 528 var hash ethcmn.Hash 529 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 530 531 commitBlock(suite) 532 commitBlock(suite) 533 534 receipt := WaitForReceipt(suite.T(), suite.addr, hash) 535 suite.Require().NotNil(receipt) 536 suite.Require().Equal("0x1", receipt["status"].(string)) 537 //suite.T().Logf("%s deploys contract (filled \"data\") successfully with tx hash %s\n", hexAddr1.Hex(), hash.String()) 538 539 // TODO: logic bug, fix it later 540 // ignore gas price -> default 'ethermint.DefaultGasPrice' on node -> successfully 541 //delete(param[0], "gasPrice") 542 //rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param) 543 // 544 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 545 //receipt = WaitForReceipt(suite.T(), hash) 546 //suite.Require().NotNil(receipt) 547 //suite.Require().Equal("0x1", receipt["status"].(string)) 548 //suite.T().Logf("%s deploys contract successfully with tx hash %s and nil gas price\n", hexAddr1.Hex(), hash.String()) 549 550 // same payload filled in both 'input' and 'data' -> ok 551 param[0]["input"] = param[0]["data"] 552 553 rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param) 554 555 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 556 557 commitBlock(suite) 558 commitBlock(suite) 559 receipt = WaitForReceipt(suite.T(), suite.addr, hash) 560 suite.Require().NotNil(receipt) 561 suite.Require().Equal("0x1", receipt["status"].(string)) 562 //suite.T().Logf("%s deploys contract (filled \"input\" and \"data\") successfully with tx hash %s\n", hexAddr1.Hex(), hash.String()) 563 564 // TODO: logic bug, fix it later 565 // filled in 'input' -> ok 566 //delete(param[0], "data") 567 //rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param) 568 // 569 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 570 //receipt = WaitForReceipt(suite.T(), hash) 571 //suite.Require().NotNil(receipt) 572 //suite.Require().Equal("0x1", receipt["status"].(string)) 573 //suite.T().Logf("%s deploys contract (filled \"input\") successfully with tx hash %s\n", hexAddr1.Hex(), hash.String()) 574 575 // error check 576 // sender is not unlocked on the node 577 param[0]["from"] = receiverAddr.Hex() 578 //suite.chain.GetContextPointer().SetAccountNonce(0) 579 _, err := CallWithError(suite.addr, "eth_sendTransaction", param) 580 suite.Require().Error(err) 581 582 // data.Data and data.Input are not same 583 param[0]["from"] = hexAddr1.Hex() 584 //suite.chain.GetContextPointer().SetAccountNonce(0) 585 param[0]["input"] = param[0]["data"][:len(param[0]["data"])-2] 586 _, err = CallWithError(suite.addr, "eth_sendTransaction", param) 587 suite.Require().Error(err) 588 589 // 0 gas price 590 delete(param[0], "input") 591 param[0]["gasPrice"] = (*hexutil.Big)(sdk.ZeroDec().BigInt()).String() 592 _, err = CallWithError(suite.addr, "eth_sendTransaction", param) 593 suite.Require().Error(err) 594 595 // no payload of contract deployment 596 delete(param[0], "data") 597 598 _, err = CallWithError(suite.addr, "eth_sendTransaction", param) 599 suite.Require().Error(err) 600 }*/ 601 602 func (suite *RPCTestSuite) TestEth_GetStorageAt() { 603 expectedRes := hexutil.Bytes{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 604 rpcRes := Call(suite.T(), suite.addr, "eth_getStorageAt", []string{hexAddr1.Hex(), fmt.Sprint(addrAStoreKey), latestBlockNumber}) 605 606 var storage hexutil.Bytes 607 suite.Require().NoError(storage.UnmarshalJSON(rpcRes.Result)) 608 609 suite.T().Logf("Got value [%X] for %s with key %X\n", storage, hexAddr1.Hex(), addrAStoreKey) 610 611 suite.Require().True(bytes.Equal(storage, expectedRes), "expected: %d (%d bytes) got: %d (%d bytes)", expectedRes, len(expectedRes), storage, len(storage)) 612 613 // error check 614 // miss argument 615 _, err := CallWithError(suite.addr, "eth_getStorageAt", []string{hexAddr1.Hex(), fmt.Sprint(addrAStoreKey)}) 616 suite.Require().Error(err) 617 618 _, err = CallWithError(suite.addr, "eth_getStorageAt", []string{hexAddr1.Hex()}) 619 suite.Require().Error(err) 620 } 621 622 func (suite *RPCTestSuite) TestEth_GetTransactionByHash() { 623 624 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 625 626 commitBlock(suite) 627 commitBlock(suite) 628 629 rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionByHash", []interface{}{hash}) 630 631 var transaction watcher.Transaction 632 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transaction)) 633 suite.Require().True(senderAddr.Hex() == transaction.From.Hex()) 634 suite.Require().True(receiverAddr == *transaction.To) 635 suite.Require().True(hash == transaction.Hash) 636 suite.Require().True(transaction.Value.ToInt().Cmp(big.NewInt(1024)) == 0) 637 suite.Require().True(transaction.GasPrice.ToInt().Cmp(defaultGasPrice.Amount.BigInt()) == 0) 638 // no input for a transfer tx 639 suite.Require().Equal(0, len(transaction.Input)) 640 641 // hash not found -> rpcRes.Result -> "null" 642 rpcRes, err := CallWithError(suite.addr, "eth_getTransactionByHash", []interface{}{inexistentHash}) 643 suite.Require().NoError(err) 644 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 645 suite.Require().Nil(rpcRes.Error) 646 } 647 648 func (suite *RPCTestSuite) TestEth_GetTransactionCount() { 649 650 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 651 652 commitBlock(suite) 653 commitBlock(suite) 654 655 height := getBlockHeightFromTxHash(suite.T(), suite.addr, hash) 656 657 rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), height.String()}) 658 659 var nonce, preNonce hexutil.Uint64 660 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &nonce)) 661 662 // query height - 1 663 /*rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), (height - 1).String()}) 664 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &preNonce)) 665 666 suite.Require().True(nonce-preNonce == 1) 667 */ 668 // latestBlock query 669 rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), latestBlockNumber}) 670 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &preNonce)) 671 suite.Require().Equal(nonce, preNonce) 672 673 // pendingBlock query 674 rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), pendingBlockNumber}) 675 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &nonce)) 676 suite.Require().Equal(preNonce, nonce) 677 678 // error check 679 // miss argument 680 _, err := CallWithError(suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex()}) 681 suite.Require().Error(err) 682 683 _, err = CallWithError(suite.addr, "eth_getTransactionCount", nil) 684 suite.Require().Error(err) 685 } 686 687 func (suite *RPCTestSuite) TestEth_GetBlockTransactionCountByHash() { 688 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 689 690 commitBlock(suite) 691 commitBlock(suite) 692 693 blockhash := getBlockHashFromTxHash(suite.T(), suite.addr, hash) 694 //suite.Require().NotNil(blockHash) 695 696 rpcRes := Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByHash", []interface{}{blockhash.Hex()}) 697 698 var txCount hexutil.Uint 699 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount)) 700 // only 1 tx on that height in this single node testnet 701 suite.Require().True(txCount == 1) 702 703 // inexistent hash -> return nil 704 rpcRes = Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByHash", []interface{}{inexistentHash}) 705 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 706 707 // error check 708 // miss argument 709 _, err := CallWithError(suite.addr, "eth_getBlockTransactionCountByHash", nil) 710 suite.Require().Error(err) 711 } 712 713 func (suite *RPCTestSuite) TestEth_GetBlockTransactionCountByNumber() { 714 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 715 716 commitBlock(suite) 717 commitBlock(suite) 718 719 // sleep for a while 720 height := getBlockHeightFromTxHash(suite.T(), suite.addr, hash) 721 suite.Require().True(height != 0) 722 723 rpcRes := Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByNumber", []interface{}{height.String()}) 724 725 var txCount hexutil.Uint 726 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount)) 727 // only 1 tx on that height in this single node testnet 728 suite.Require().True(txCount == 1) 729 730 // latestBlock query 731 rpcRes = Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByNumber", []interface{}{latestBlockNumber}) 732 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount)) 733 // there is no tx on latest block 734 suite.Require().True(txCount == 0) 735 736 // pendingBlock query 737 rpcRes = Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByNumber", []interface{}{pendingBlockNumber}) 738 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount)) 739 // there is no tx on latest block and mempool 740 suite.Require().Equal(hexutil.Uint(0), txCount) 741 742 // error check 743 // miss argument 744 _, err := CallWithError(suite.addr, "eth_getBlockTransactionCountByNumber", nil) 745 suite.Require().Error(err) 746 fmt.Println(err) 747 } 748 749 func (suite *RPCTestSuite) TestEth_GetCode() { 750 // TODO: logic bug, fix it later 751 // erc20 contract 752 //hash, receipet := deployTestContract(hexAddr1, erc20ContractKind) 753 //height := getBlockHeightFromTxHash(hash) 754 //suite.Require().True(height != 0) 755 // 756 //rpcRes := Call(suite.T(), suite.addr, "eth_getCode", []interface{}{receipet["contractAddress"], height.String()}) 757 //var code hexutil.Bytes 758 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &code)) 759 //suite.Require().True(strings.EqualFold(erc20ContractByteCode, code.String())) 760 761 // test contract 762 // TODO: logic bug, fix it later 763 //hash, receipet := deployTestContract(hexAddr1, testContractKind) 764 //height := getBlockHeightFromTxHash(hash) 765 //suite.Require().True(height != 0) 766 // 767 //rpcRes := Call(suite.T(), suite.addr, "eth_getCode", []interface{}{receipet["contractAddress"], height.String()}) 768 //var code hexutil.Bytes 769 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &code)) 770 //fmt.Println(testContractByteCode) 771 //fmt.Println(code.String()) 772 //suite.Require().True(strings.EqualFold(testContractByteCode, code.String())) 773 774 // error check 775 // miss argument 776 // TODO: use a valid contract address as the first argument in params 777 _, err := CallWithError(suite.addr, "eth_getCode", []interface{}{hexAddr1}) 778 suite.Require().Error(err) 779 780 _, err = CallWithError(suite.addr, "eth_getCode", nil) 781 suite.Require().Error(err) 782 } 783 784 func (suite *RPCTestSuite) TestEth_GetTransactionLogs() { 785 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 786 787 commitBlock(suite) 788 commitBlock(suite) 789 790 rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionLogs", []interface{}{hash}) 791 var transactionLogs []ethtypes.Log 792 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactionLogs)) 793 // no transaction log for an evm transfer 794 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 795 796 // test contract that emits an event in its constructor 797 /*hash, receipt := deployTestContract(suite, suite.addr, senderAddr, testContractKind) 798 799 rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionLogs", []interface{}{hash}) 800 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactionLogs)) 801 suite.Require().Equal(1, len(transactionLogs)) 802 suite.Require().True(ethcmn.HexToAddress(receipt["contractAddress"].(string)) == transactionLogs[0].Address) 803 suite.Require().True(hash == transactionLogs[0].TxHash) 804 // event in test contract constructor keeps the value: 1024 805 suite.Require().True(transactionLogs[0].Topics[1].Big().Cmp(big.NewInt(1024)) == 0) 806 807 // inexistent tx hash 808 _, err := CallWithError(suite.addr, "eth_getTransactionLogs", []interface{}{inexistentHash}) 809 suite.Require().Error(err) 810 811 // error check 812 // miss argument 813 _, err = CallWithError(suite.addr, "eth_getTransactionLogs", nil) 814 suite.Require().Error(err)*/ 815 } 816 817 func (suite *RPCTestSuite) TestEth_Sign() { 818 data := []byte("context to sign") 819 //expectedSignature, err := signWithAccNameAndPasswd("alice", defaultPassWd, data) 820 //suite.Require().NoError(err) 821 822 rpcRes := Call(suite.T(), suite.addr, "eth_sign", []interface{}{senderAddr.Hex(), hexutil.Bytes(data)}) 823 var sig hexutil.Bytes 824 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &sig)) 825 826 //suite.Require().True(bytes.Equal(expectedSignature, sig)) 827 828 // error check 829 // inexistent signer 830 _, err := CallWithError(suite.addr, "eth_sign", []interface{}{receiverAddr, hexutil.Bytes(data)}) 831 suite.Require().Error(err) 832 833 // miss argument 834 _, err = CallWithError(suite.addr, "eth_sign", []interface{}{receiverAddr}) 835 suite.Require().Error(err) 836 837 _, err = CallWithError(suite.addr, "eth_sign", nil) 838 suite.Require().Error(err) 839 } 840 841 func (suite *RPCTestSuite) TestEth_Call() { 842 // simulate evm transfer 843 callArgs := make(map[string]string) 844 callArgs["from"] = senderAddr.Hex() 845 callArgs["to"] = receiverAddr.Hex() 846 callArgs["value"] = hexutil.Uint(1024).String() 847 callArgs["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String() 848 _, err := CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber}) 849 suite.Require().NoError(err) 850 851 // simulate contract deployment 852 delete(callArgs, "to") 853 delete(callArgs, "value") 854 callArgs["data"] = erc20ContractDeployedByteCode 855 _, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber}) 856 suite.Require().NoError(err) 857 858 // error check 859 // miss argument 860 _, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs}) 861 suite.Require().Error(err) 862 863 _, err = CallWithError(suite.addr, "eth_call", nil) 864 suite.Require().Error(err) 865 } 866 func (suite *RPCTestSuite) TestEth_Call_Overrides() { 867 // simulate evm transfer 868 callArgs := make(map[string]string) 869 callArgs["from"] = senderAddr.Hex() 870 callArgs["to"] = "0x45dD91b0289E60D89Cec94dF0Aac3a2f539c514a" 871 callArgs["data"] = "0x2e64cec1" 872 expected := "0x0000000000000000000000000000000000000000000000000000000000000007" 873 overridesArgs := map[string]interface{}{} 874 overrideAccount := map[string]interface{}{} 875 code := "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632e64cec1146100515780634cd8de131461006f5780636057361d1461009f578063f8b2cb4f146100bb575b600080fd5b6100596100eb565b604051610066919061025a565b60405180910390f35b61008960048036038101906100849190610196565b6100f4565b6040516100969190610238565b60405180910390f35b6100b960048036038101906100b491906101c3565b610130565b005b6100d560048036038101906100d09190610196565b61014b565b6040516100e2919061025a565b60405180910390f35b60008054905090565b60608173ffffffffffffffffffffffffffffffffffffffff16803b806020016040519081016040528181526000908060200190933c9050919050565b806000808282546101419190610291565b9250508190555050565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b60008135905061017b8161039b565b92915050565b600081359050610190816103b2565b92915050565b6000602082840312156101ac576101ab610385565b5b60006101ba8482850161016c565b91505092915050565b6000602082840312156101d9576101d8610385565b5b60006101e784828501610181565b91505092915050565b60006101fb82610275565b6102058185610280565b9350610215818560208601610323565b61021e8161038a565b840191505092915050565b61023281610319565b82525050565b6000602082019050818103600083015261025281846101f0565b905092915050565b600060208201905061026f6000830184610229565b92915050565b600081519050919050565b600082825260208201905092915050565b600061029c82610319565b91506102a783610319565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156102dc576102db610356565b5b828201905092915050565b60006102f2826102f9565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b83811015610341578082015181840152602081019050610326565b83811115610350576000848401525b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b6000601f19601f8301169050919050565b6103a4816102e7565b81146103af57600080fd5b50565b6103bb81610319565b81146103c657600080fd5b5056fea26469706673582212202f99901e5c26c9c389fef67564f7c7b71316025fe9346120d3b01d4b7066034364736f6c63430008070033" 876 overrideAccount["code"] = code 877 overrideAccount["state"] = map[string]string{ 878 "0x0000000000000000000000000000000000000000000000000000000000000000": expected, 879 } 880 overridesArgs["0x45dD91b0289E60D89Cec94dF0Aac3a2f539c514a"] = overrideAccount 881 882 resp, err := CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber, overridesArgs}) 883 suite.Require().NoError(err) 884 885 var res string 886 _ = json.Unmarshal(resp.Result, &res) 887 suite.Require().EqualValues(expected, res) 888 889 callArgs["data"] = "0xf8b2cb4f000000000000000000000000bbe4733d85bc2b90682147779da49cab38c0aa1f" // get balance of bbe4733d85bc2b90682147779da49cab38c0aa1f 890 expectedBal := "0x10000000000000000000000000000000000000000000000000000000003e8000" 891 overridesArgs["0xbbE4733d85bc2b90682147779DA49caB38C0aA1F"] = map[string]string{"balance": expectedBal} 892 resp, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber, overridesArgs}) 893 suite.Require().NoError(err) 894 895 _ = json.Unmarshal(resp.Result, &res) 896 suite.Require().EqualValues(expectedBal, res) 897 898 callArgs["data"] = "0x4cd8de1300000000000000000000000045dd91b0289e60d89cec94df0aac3a2f539c514a" // get code of 0x45dD91b0289E60D89Cec94dF0Aac3a2f539c514a 899 resp, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber, overridesArgs}) 900 suite.Require().NoError(err) 901 902 _ = json.Unmarshal(resp.Result, &res) 903 suite.Require().EqualValues(code+"00", strings.Replace(res, "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000003ff", "0x", -1)) 904 } 905 func (suite *RPCTestSuite) TestEth_EstimateGas_WithoutArgs() { 906 // error check 907 // miss argument 908 res, err := CallWithError(suite.addr, "eth_estimateGas", nil) 909 suite.Require().Error(err) 910 suite.Require().Nil(res) 911 } 912 913 func (suite *RPCTestSuite) TestEth_EstimateGas_Transfer() { 914 param := make([]map[string]string, 1) 915 param[0] = make(map[string]string) 916 param[0]["from"] = senderAddr.Hex() 917 param[0]["to"] = "0x1122334455667788990011223344556677889900" 918 param[0]["value"] = "0x1" 919 param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String() 920 rpcRes := Call(suite.T(), suite.addr, "eth_estimateGas", param) 921 suite.Require().NotNil(rpcRes) 922 suite.Require().NotEmpty(rpcRes.Result) 923 924 var gas string 925 err := json.Unmarshal(rpcRes.Result, &gas) 926 suite.Require().NoError(err, string(rpcRes.Result)) 927 928 suite.Require().Equal("0x5208", gas) 929 } 930 931 func (suite *RPCTestSuite) TestEth_EstimateGas_ContractDeployment() { 932 bytecode := "0x608060405234801561001057600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a260d08061004d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063eb8ac92114602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506062565b005b8160008190555080827ff3ca124a697ba07e8c5e80bebcfcc48991fc16a63170e8a9206e30508960d00360405160405180910390a3505056fea265627a7a723158201d94d2187aaf3a6790527b615fcc40970febf0385fa6d72a2344848ebd0df3e964736f6c63430005110032" 933 934 param := make([]map[string]string, 1) 935 param[0] = make(map[string]string) 936 param[0]["from"] = senderAddr.Hex() 937 param[0]["data"] = bytecode 938 939 rpcRes := Call(suite.T(), suite.addr, "eth_estimateGas", param) 940 suite.Require().NotNil(rpcRes) 941 suite.Require().NotEmpty(rpcRes.Result) 942 943 var gas hexutil.Uint64 944 err := json.Unmarshal(rpcRes.Result, &gas) 945 suite.Require().NoError(err, string(rpcRes.Result)) 946 947 suite.Require().Equal("0x271fc", gas.String()) 948 } 949 950 func (suite *RPCTestSuite) TestEth_GetBlockByHash() { 951 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 952 expectedBlockHash := getBlockHashFromTxHash(suite.T(), suite.addr, hash) 953 954 // TODO: fbchainonly supports the block query with txs' hash inside no matter what the second bool argument is. 955 // eth rpc: false -> txs' hash inside 956 // true -> txs full content 957 958 // TODO: block hash bug , wait for pr merge 959 //rpcRes := Call(suite.T(), suite.addr, "eth_getBlockByHash", []interface{}{expectedBlockHash, false}) 960 //var res map[string]interface{} 961 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res)) 962 //suite.Require().True(strings.EqualFold(expectedBlockHash, res["hash"].(string))) 963 // 964 //rpcRes = Call(suite.T(), suite.addr, "eth_getBlockByHash", []interface{}{expectedBlockHash, true}) 965 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res)) 966 //suite.Require().True(strings.EqualFold(expectedBlockHash, res["hash"].(string))) 967 968 // inexistent hash 969 //rpcRes, err :=CallWithError(suite.addr, "eth_getBlockByHash", []interface{}{inexistentHash, false}) 970 971 // error check 972 // miss argument 973 _, err := CallWithError(suite.addr, "eth_getBlockByHash", []interface{}{expectedBlockHash}) 974 suite.Require().Error(err) 975 976 _, err = CallWithError(suite.addr, "eth_getBlockByHash", nil) 977 suite.Require().Error(err) 978 } 979 980 func (suite *RPCTestSuite) TestEth_GetBlockByNumber() { 981 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 982 983 // sleep for a while 984 //time.Sleep(3 * time.Second) 985 commitBlock(suite) 986 commitBlock(suite) 987 988 expectedHeight := getBlockHeightFromTxHash(suite.T(), suite.addr, hash) 989 990 // TODO: fbchainonly supports the block query with txs' hash inside no matter what the second bool argument is. 991 // eth rpc: false -> txs' hash inside 992 rpcRes := Call(suite.T(), suite.addr, "eth_getBlockByNumber", []interface{}{expectedHeight, false}) 993 var res map[string]interface{} 994 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res)) 995 //suite.Require().True(strings.EqualFold(expectedHeight.String(), res["number"].(string))) 996 997 rpcRes = Call(suite.T(), suite.addr, "eth_getBlockByNumber", []interface{}{expectedHeight, true}) 998 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res)) 999 //suite.Require().True(strings.EqualFold(expectedHeight.String(), res["number"].(string))) 1000 1001 // error check 1002 // future block height -> return nil without error 1003 rpcRes = Call(suite.T(), suite.addr, "eth_blockNumber", nil) 1004 var currentBlockHeight hexutil.Uint64 1005 suite.Require().NoError(json.Unmarshal(rpcRes.Result, ¤tBlockHeight)) 1006 1007 rpcRes, err := CallWithError(suite.addr, "eth_getBlockByNumber", []interface{}{currentBlockHeight + 100, false}) 1008 suite.Require().NoError(err) 1009 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 1010 1011 // miss argument 1012 _, err = CallWithError(suite.addr, "eth_getBlockByNumber", []interface{}{currentBlockHeight}) 1013 suite.Require().Error(err) 1014 1015 _, err = CallWithError(suite.addr, "eth_getBlockByNumber", nil) 1016 suite.Require().Error(err) 1017 } 1018 1019 func (suite *RPCTestSuite) TestEth_GetTransactionByBlockHashAndIndex() { 1020 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 1021 1022 // sleep for a while 1023 //time.Sleep(5 * time.Second) 1024 commitBlock(suite) 1025 commitBlock(suite) 1026 blockHash, index := getBlockHashFromTxHash(suite.T(), suite.addr, hash), hexutil.Uint(0) 1027 rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{blockHash, index}) 1028 var transaction watcher.Transaction 1029 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transaction)) 1030 suite.Require().Equal(hash, transaction.Hash) 1031 suite.Require().True(*blockHash == *transaction.BlockHash) 1032 suite.Require().True(hexutil.Uint64(index) == *transaction.TransactionIndex) 1033 1034 // inexistent block hash 1035 // TODO: error:{"code":1,"log":"internal","height":1497,"codespace":"undefined"}, fix it later 1036 //rpcRes, err :=CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{inexistentHash, index}) 1037 //fmt.Println(err) 1038 1039 // inexistent transaction index -> nil 1040 rpcRes, err := CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{blockHash, index + 100}) 1041 suite.Require().NoError(err) 1042 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 1043 1044 // error check 1045 // miss argument 1046 _, err = CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{blockHash}) 1047 suite.Require().Error(err) 1048 1049 _, err = CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", nil) 1050 suite.Require().Error(err) 1051 } 1052 1053 func (suite *RPCTestSuite) TestEth_GetTransactionReceipt() { 1054 hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024) 1055 1056 // sleep for a while 1057 commitBlock(suite) 1058 commitBlock(suite) 1059 rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionReceipt", []interface{}{hash}) 1060 1061 var receipt map[string]interface{} 1062 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &receipt)) 1063 suite.Require().True(strings.EqualFold(senderAddr.Hex(), receipt["from"].(string))) 1064 suite.Require().True(strings.EqualFold(receiverAddr.Hex(), receipt["to"].(string))) 1065 suite.Require().True(strings.EqualFold(hexutil.Uint(1).String(), receipt["status"].(string))) 1066 suite.Require().True(strings.EqualFold(hash.Hex(), receipt["transactionHash"].(string))) 1067 1068 // contract deployment 1069 /*hash, receipt = deployTestContract(suite, suite.addr, senderAddr, erc20ContractKind) 1070 1071 suite.Require().True(strings.EqualFold(senderAddr.Hex(), receipt["from"].(string))) 1072 suite.Require().True(strings.EqualFold(hexutil.Uint(1).String(), receipt["status"].(string))) 1073 suite.Require().True(strings.EqualFold(hash.Hex(), receipt["transactionHash"].(string))) 1074 1075 // inexistent hash -> nil without error 1076 rpcRes, err := CallWithError(suite.addr, "eth_getTransactionReceipt", []interface{}{inexistentHash}) 1077 suite.Require().NoError(err) 1078 assertNullFromJSONResponse(suite.T(), rpcRes.Result) 1079 1080 // error check 1081 // miss argument 1082 _, err = CallWithError(suite.addr, "eth_getTransactionReceipt", nil) 1083 suite.Require().Error(err)*/ 1084 } 1085 1086 func (suite *RPCTestSuite) TestEth_PendingTransactions() { 1087 // there will be no pending tx in mempool because of the quick grab of block building 1088 rpcRes := Call(suite.T(), suite.addr, "eth_pendingTransactions", nil) 1089 var transactions []watcher.Transaction 1090 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactions)) 1091 suite.Require().Zero(len(transactions)) 1092 } 1093 1094 func (suite *RPCTestSuite) TestBlockBloom() { 1095 hash, receipt := deployTestContract(suite, suite.addr, senderAddr, testContractKind) 1096 1097 rpcRes := Call(suite.T(), suite.addr, "eth_getBlockByNumber", []interface{}{receipt["blockNumber"].(string), false}) 1098 var blockInfo map[string]interface{} 1099 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &blockInfo)) 1100 logsBloom := hexToBloom(suite.T(), blockInfo["logsBloom"].(string)) 1101 1102 // get the transaction log with tx hash 1103 rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionLogs", []interface{}{hash}) 1104 var transactionLogs []ethtypes.Log 1105 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactionLogs)) 1106 suite.Require().Equal(1, len(transactionLogs)) 1107 1108 // all the topics in the transactionLogs should be included in the logs bloom of the block 1109 suite.Require().True(logsBloom.Test(transactionLogs[0].Topics[0].Bytes())) 1110 suite.Require().True(logsBloom.Test(transactionLogs[0].Topics[1].Bytes())) 1111 // check the consistency of tx hash 1112 suite.Require().True(strings.EqualFold(hash.Hex(), blockInfo["transactions"].([]interface{})[0].(string))) 1113 } 1114 1115 /* 1116 func (suite *RPCTestSuite) TestEth_GetLogs_NoLogs() { 1117 param := make([]map[string][]string, 1) 1118 param[0] = make(map[string][]string) 1119 // inexistent topics 1120 inexistentTopicsHash := ethcmn.BytesToHash([]byte("inexistent topics")).Hex() 1121 param[0]["topics"] = []string{inexistentTopicsHash} 1122 rpcRes, err := CallWithError(suite.addr, "eth_getLogs", param) 1123 suite.Require().NoError(err) 1124 1125 var logs []ethtypes.Log 1126 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &logs)) 1127 suite.Require().Zero(len(logs)) 1128 1129 // error check 1130 _, err = CallWithError(suite.addr, "eth_getLogs", nil) 1131 suite.Require().Error(err) 1132 } 1133 1134 func (suite *RPCTestSuite) TestEth_GetLogs_GetTopicsFromHistory() { 1135 _, receipt := deployTestContract(suite, suite.addr, senderAddr, testContractKind) 1136 param := make([]map[string]interface{}, 1) 1137 param[0] = make(map[string]interface{}) 1138 param[0]["topics"] = []string{helloTopic, worldTopic} 1139 param[0]["fromBlock"] = receipt["blockNumber"].(string) 1140 1141 time.Sleep(time.Second * 5) 1142 rpcRes := Call(suite.T(), suite.addr, "eth_getLogs", param) 1143 1144 var logs []ethtypes.Log 1145 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &logs)) 1146 suite.Require().Equal(1, len(logs)) 1147 suite.Require().Equal(2, len(logs[0].Topics)) 1148 suite.Require().True(logs[0].Topics[0].Hex() == helloTopic) 1149 suite.Require().True(logs[0].Topics[1].Hex() == worldTopic) 1150 1151 // get block number from receipt 1152 blockNumber, err := hexutil.DecodeUint64(receipt["blockNumber"].(string)) 1153 suite.Require().NoError(err) 1154 1155 // get current block height -> there is no logs from that height 1156 param[0]["fromBlock"] = hexutil.Uint64(blockNumber + 1).String() 1157 1158 rpcRes, err = CallWithError(suite.addr, "eth_getLogs", param) 1159 suite.Require().NoError(err) 1160 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &logs)) 1161 suite.Require().Zero(len(logs)) 1162 }*/ 1163 1164 func (suite *RPCTestSuite) TestEth_GetProof() { 1165 1166 initialBalance := suite.chain.SenderAccount().GetCoins()[0] 1167 commitBlock(suite) 1168 commitBlock(suite) 1169 rpcRes := Call(suite.T(), suite.addr, "eth_getProof", []interface{}{senderAddr.Hex(), []string{fmt.Sprint(addrAStoreKey)}, "latest"}) 1170 suite.Require().NotNil(rpcRes) 1171 1172 var accRes types.AccountResult 1173 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &accRes)) 1174 suite.Require().Equal(senderAddr, accRes.Address) 1175 suite.Require().Equal(initialBalance.Amount.Int, accRes.Balance.ToInt()) 1176 suite.Require().NotEmpty(accRes.AccountProof) 1177 suite.Require().NotEmpty(accRes.StorageProof) 1178 1179 // inexistentAddr -> zero value account result 1180 rpcRes, err := CallWithError(suite.addr, "eth_getProof", []interface{}{inexistentAddr.Hex(), []string{fmt.Sprint(addrAStoreKey)}, "latest"}) 1181 suite.Require().NoError(err) 1182 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &accRes)) 1183 suite.Require().Equal(inexistentAddr, accRes.Address) 1184 suite.Require().True(sdk.ZeroDec().Int.Cmp(accRes.Balance.ToInt()) == 0) 1185 1186 // error check 1187 // miss argument 1188 _, err = CallWithError(suite.addr, "eth_getProof", []interface{}{hexAddr2.Hex(), []string{fmt.Sprint(addrAStoreKey)}}) 1189 suite.Require().Error(err) 1190 1191 _, err = CallWithError(suite.addr, "eth_getProof", []interface{}{hexAddr2.Hex()}) 1192 suite.Require().Error(err) 1193 1194 _, err = CallWithError(suite.addr, "eth_getProof", nil) 1195 suite.Require().Error(err) 1196 } 1197 1198 /* 1199 func (suite *RPCTestSuite) TestEth_NewFilter() { 1200 param := make([]map[string]interface{}, 1) 1201 param[0] = make(map[string]interface{}) 1202 // random topics 1203 param[0]["topics"] = []ethcmn.Hash{ethcmn.BytesToHash([]byte("random topics"))} 1204 rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param) 1205 1206 var ID string 1207 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1208 suite.Require().NotZero(ID) 1209 1210 // fromBlock: latest, toBlock: latest -> no error 1211 delete(param[0], "topics") 1212 param[0]["fromBlock"] = latestBlockNumber 1213 param[0]["toBlock"] = latestBlockNumber 1214 rpcRes, err := CallWithError(suite.addr, "eth_newFilter", param) 1215 suite.Require().NoError(err) 1216 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1217 suite.Require().NotZero(ID) 1218 1219 // fromBlock: nil, toBlock: latest -> no error 1220 delete(param[0], "fromBlock") 1221 rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param) 1222 suite.Require().NoError(err) 1223 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1224 suite.Require().NotZero(ID) 1225 1226 // fromBlock: latest, toBlock: nil -> no error 1227 delete(param[0], "toBlock") 1228 param[0]["fromBlock"] = latestBlockNumber 1229 rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param) 1230 suite.Require().NoError(err) 1231 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1232 suite.Require().NotZero(ID) 1233 1234 // fromBlock: pending, toBlock: pending -> no error 1235 param[0]["fromBlock"] = pendingBlockNumber 1236 param[0]["toBlock"] = pendingBlockNumber 1237 rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param) 1238 suite.Require().NoError(err) 1239 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1240 suite.Require().NotZero(ID) 1241 1242 // fromBlock: latest, toBlock: pending -> no error 1243 param[0]["fromBlock"] = latestBlockNumber 1244 rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param) 1245 suite.Require().NoError(err) 1246 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1247 suite.Require().NotZero(ID) 1248 1249 // toBlock > fromBlock -> no error 1250 param[0]["fromBlock"] = (*hexutil.Big)(big.NewInt(2)).String() 1251 param[0]["toBlock"] = (*hexutil.Big)(big.NewInt(3)).String() 1252 rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param) 1253 suite.Require().NoError(err) 1254 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1255 suite.Require().NotZero(ID) 1256 1257 // error check 1258 // miss argument 1259 _, err = CallWithError(suite.addr, "eth_newFilter", nil) 1260 suite.Require().Error(err) 1261 1262 // fromBlock > toBlock -> error: invalid from and to block combination: from > to 1263 param[0]["fromBlock"] = (*hexutil.Big)(big.NewInt(3)).String() 1264 param[0]["toBlock"] = (*hexutil.Big)(big.NewInt(2)).String() 1265 rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param) 1266 suite.Require().Error(err) 1267 1268 // fromBlock: pending, toBlock: latest 1269 param[0]["fromBlock"] = pendingBlockNumber 1270 param[0]["toBlock"] = latestBlockNumber 1271 rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param) 1272 suite.Require().Error(err) 1273 } 1274 1275 func (suite *RPCTestSuite) TestEth_NewBlockFilter() { 1276 rpcRes := Call(suite.T(), suite.addr, "eth_newBlockFilter", nil) 1277 1278 var ID string 1279 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1280 suite.Require().NotZero(ID) 1281 } 1282 1283 func (suite *RPCTestSuite) TestEth_GetFilterChanges_BlockFilter() { 1284 rpcRes := Call(suite.T(), suite.addr, "eth_newBlockFilter", nil) 1285 1286 var ID string 1287 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1288 1289 // wait for block generation 1290 time.Sleep(5 * time.Second) 1291 1292 changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []interface{}{ID}) 1293 var hashes []ethcmn.Hash 1294 suite.Require().NoError(json.Unmarshal(changesRes.Result, &hashes)) 1295 suite.Require().GreaterOrEqual(len(hashes), 1) 1296 1297 // error check 1298 // miss argument 1299 _, err := CallWithError(suite.addr, "eth_getFilterChanges", nil) 1300 suite.Require().Error(err) 1301 } 1302 1303 func (suite *RPCTestSuite) TestEth_GetFilterChanges_NoLogs() { 1304 param := make([]map[string]interface{}, 1) 1305 param[0] = make(map[string]interface{}) 1306 param[0]["topics"] = []ethcmn.Hash{ethcmn.BytesToHash([]byte("random topics"))} 1307 1308 rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param) 1309 1310 var ID string 1311 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1312 1313 changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []interface{}{ID}) 1314 1315 var logs []ethtypes.Log 1316 suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs)) 1317 // no logs 1318 suite.Require().Empty(logs) 1319 } 1320 1321 func (suite *RPCTestSuite) TestEth_GetFilterChanges_WrongID() { 1322 // ID's length is 16 1323 inexistentID := "0x1234567890abcdef" 1324 _, err := CallWithError(suite.addr, "eth_getFilterChanges", []interface{}{inexistentID}) 1325 suite.Require().Error(err) 1326 } 1327 1328 func (suite *RPCTestSuite) TestEth_GetFilterChanges_NoTopics() { 1329 // create a new filter with no topics and latest block height for "fromBlock" 1330 param := make([]map[string]interface{}, 1) 1331 param[0] = make(map[string]interface{}) 1332 param[0]["fromBlock"] = latestBlockNumber 1333 1334 rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param) 1335 suite.Require().Nil(rpcRes.Error) 1336 var ID string 1337 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1338 suite.T().Logf("create filter successfully with ID %s\n", ID) 1339 1340 // deploy contract with emitting events 1341 _, _ = deployTestContract(suite, suite.addr, senderAddr, testContractKind) 1342 1343 // get filter changes 1344 changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID}) 1345 1346 var logs []ethtypes.Log 1347 suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs)) 1348 suite.Require().Equal(1, len(logs)) 1349 } 1350 1351 func (suite *RPCTestSuite) TestEth_GetFilterChanges_Addresses() { 1352 // TODO: logic bug, fix it later 1353 //// deploy contract with emitting events 1354 //_, receipt := deployTestContract(hexAddr1, testContractKind) 1355 //contractAddrHex := receipt["contractAddress"].(string) 1356 //blockHeight := receipt["blockNumber"].(string) 1357 //// create a filter 1358 //param := make([]map[string]interface{}, 1) 1359 //param[0] = make(map[string]interface{}) 1360 //// focus on the contract by its address 1361 //param[0]["addresses"] = []string{contractAddrHex} 1362 //param[0]["topics"] = []string{helloTopic, worldTopic} 1363 //param[0]["fromBlock"] = blockHeight 1364 //rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param) 1365 // 1366 //var ID string 1367 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1368 //suite.T().Logf("create filter focusing on contract %s successfully with ID %s\n", contractAddrHex, ID) 1369 // 1370 //// get filter changes 1371 //changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID}) 1372 // 1373 //var logs []ethtypes.Log 1374 //suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs)) 1375 //suite.Require().Equal(1, len(logs)) 1376 } 1377 1378 func (suite *RPCTestSuite) TestEth_GetFilterChanges_BlockHash() { 1379 // TODO: logic bug, fix it later 1380 //// deploy contract with emitting events 1381 //_, receipt := deployTestContract(hexAddr1, testContractKind) 1382 //blockHash := receipt["blockHash"].(string) 1383 //contractAddrHex := receipt["contractAddress"].(string) 1384 //// create a filter 1385 //param := make([]map[string]interface{}, 1) 1386 //param[0] = make(map[string]interface{}) 1387 //// focus on the contract by its address 1388 //param[0]["blockHash"] = blockHash 1389 //param[0]["addresses"] = []string{contractAddrHex} 1390 //param[0]["topics"] = []string{helloTopic, worldTopic} 1391 //rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param) 1392 // 1393 //var ID string 1394 //suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1395 //suite.T().Logf("create filter focusing on contract %s in the block with block hash %s successfully with ID %s\n", contractAddrHex, blockHash, ID) 1396 // 1397 //// get filter changes 1398 //changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID}) 1399 // 1400 //var logs []ethtypes.Log 1401 //suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs)) 1402 //suite.Require().Equal(1, len(logs)) 1403 } 1404 1405 // Tests topics case where there are topics in first two positions 1406 func (suite *RPCTestSuite) TestEth_GetFilterChanges_Topics_AB() { 1407 param := make([]map[string]interface{}, 1) 1408 param[0] = make(map[string]interface{}) 1409 // set topics in filter with A && B 1410 param[0]["topics"] = []string{helloTopic, worldTopic} 1411 param[0]["fromBlock"] = latestBlockNumber 1412 1413 // create new filter 1414 rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param) 1415 1416 var ID string 1417 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1418 suite.T().Logf("create filter successfully with ID %s\n", ID) 1419 1420 // deploy contract with emitting events 1421 _, _ = deployTestContract(suite, suite.addr, senderAddr, testContractKind) 1422 1423 // get filter changes 1424 changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID}) 1425 1426 var logs []ethtypes.Log 1427 suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs)) 1428 suite.Require().Equal(1, len(logs)) 1429 } 1430 1431 func (suite *RPCTestSuite) TestEth_GetFilterChanges_Topics_XB() { 1432 param := make([]map[string]interface{}, 1) 1433 param[0] = make(map[string]interface{}) 1434 // set topics in filter with X && B 1435 param[0]["topics"] = []interface{}{nil, worldTopic} 1436 param[0]["fromBlock"] = latestBlockNumber 1437 1438 // create new filter 1439 rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param) 1440 1441 var ID string 1442 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1443 suite.T().Logf("create filter successfully with ID %s\n", ID) 1444 1445 // deploy contract with emitting events 1446 _, _ = deployTestContract(suite, suite.addr, senderAddr, testContractKind) 1447 1448 // get filter changes 1449 changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID}) 1450 1451 var logs []ethtypes.Log 1452 suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs)) 1453 suite.Require().Equal(1, len(logs)) 1454 } 1455 1456 //func (suite *RPCTestSuite)TestEth_GetFilterChanges_Topics_XXC() { 1457 // t.Skip() 1458 // // TODO: call test function, need tx receipts to determine contract address 1459 //} 1460 1461 func (suite *RPCTestSuite) TestEth_PendingTransactionFilter() { 1462 rpcRes := Call(suite.T(), suite.addr, "eth_newPendingTransactionFilter", nil) 1463 1464 var ID string 1465 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1466 1467 for i := 0; i < 5; i++ { 1468 _, _ = deployTestContract(suite, suite.addr, senderAddr, erc20ContractKind) 1469 } 1470 1471 time.Sleep(10 * time.Second) 1472 1473 // get filter changes 1474 changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID}) 1475 suite.Require().NotNil(changesRes) 1476 1477 var txs []hexutil.Bytes 1478 suite.Require().NoError(json.Unmarshal(changesRes.Result, &txs)) 1479 1480 suite.Require().True(len(txs) >= 2, "could not get any txs", "changesRes.Result", string(changesRes.Result)) 1481 } 1482 1483 func (suite *RPCTestSuite) TestEth_UninstallFilter() { 1484 // create a new filter, get id 1485 rpcRes := Call(suite.T(), suite.addr, "eth_newBlockFilter", nil) 1486 var ID string 1487 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID)) 1488 suite.Require().NotZero(ID) 1489 1490 // based on id, uninstall filter 1491 rpcRes = Call(suite.T(), suite.addr, "eth_uninstallFilter", []string{ID}) 1492 suite.Require().NotNil(rpcRes) 1493 var status bool 1494 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &status)) 1495 suite.Require().Equal(true, status) 1496 1497 // uninstall a non-existent filter 1498 rpcRes = Call(suite.T(), suite.addr, "eth_uninstallFilter", []string{ID}) 1499 suite.Require().NotNil(rpcRes) 1500 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &status)) 1501 suite.Require().Equal(false, status) 1502 1503 } 1504 1505 func (suite *RPCTestSuite) TestEth_Subscribe_And_UnSubscribe() { 1506 // create websocket 1507 origin, url := "http://127.0.0.1:8546/", "ws://127.0.0.1:8546" 1508 ws, err := websocket.Dial(url, "", origin) 1509 suite.Require().NoError(err) 1510 defer func() { 1511 // close websocket 1512 err = ws.Close() 1513 suite.Require().NoError(err) 1514 }() 1515 1516 // send valid message 1517 validMessage := []byte(`{"id": 2, "method": "eth_subscribe", "params": ["newHeads"]}`) 1518 excuteValidMessage(suite.T(), ws, validMessage) 1519 1520 // send invalid message 1521 invalidMessage := []byte(`{"id": 2, "method": "eth_subscribe", "params": ["non-existent method"]}`) 1522 excuteInvalidMessage(suite.T(), ws, invalidMessage) 1523 1524 invalidMessage = []byte(`{"id": 2, "method": "eth_subscribe", "params": [""]}`) 1525 excuteInvalidMessage(suite.T(), ws, invalidMessage) 1526 } 1527 1528 func excuteValidMessage(t *testing.T, ws *websocket.Conn, message []byte) { 1529 fmt.Println("Send:", string(message)) 1530 _, err := ws.Write(message) 1531 require.NoError(t, err) 1532 1533 msg := make([]byte, 10240) 1534 // receive subscription id 1535 n, err := ws.Read(msg) 1536 require.NoError(t, err) 1537 var res Response 1538 require.NoError(t, json.Unmarshal(msg[:n], &res)) 1539 subscriptionId := string(res.Result) 1540 1541 // receive message three times 1542 for i := 0; i < 3; i++ { 1543 n, err = ws.Read(msg) 1544 require.NoError(t, err) 1545 fmt.Println("Receive:", string(msg[:n])) 1546 } 1547 1548 // cancel the subscription 1549 cancelMsg := fmt.Sprintf(`{"id": 2, "method": "eth_unsubscribe", "params": [%s]}`, subscriptionId) 1550 fmt.Println("Send:", cancelMsg) 1551 _, err = ws.Write([]byte(cancelMsg)) 1552 require.NoError(t, err) 1553 1554 // receive the result of eth_unsubscribe 1555 n, err = ws.Read(msg) 1556 require.NoError(t, err) 1557 require.NoError(t, json.Unmarshal(msg[:n], &res)) 1558 require.Equal(t, "true", string(res.Result)) 1559 } 1560 1561 func excuteInvalidMessage(t *testing.T, ws *websocket.Conn, message []byte) { 1562 fmt.Println("Send:", string(message)) 1563 _, err := ws.Write(message) 1564 require.NoError(t, err) 1565 1566 msg := make([]byte, 10240) 1567 // receive error msg 1568 n, err := ws.Read(msg) 1569 require.NoError(t, err) 1570 1571 var res Response 1572 require.NoError(t, json.Unmarshal(msg[:n], &res)) 1573 require.Equal(t, -32600, res.Error.Code) 1574 require.Equal(t, 1, res.ID) 1575 } 1576 1577 func (suite *RPCTestSuite) TestWebsocket_PendingTransaction() { 1578 // create websocket 1579 origin, url := "http://127.0.0.1:8546/", "ws://127.0.0.1:8546" 1580 ws, err := websocket.Dial(url, "", origin) 1581 suite.Require().NoError(err) 1582 defer func() { 1583 // close websocket 1584 err = ws.Close() 1585 suite.Require().NoError(err) 1586 }() 1587 1588 // send message to call newPendingTransactions ws api 1589 _, err = ws.Write([]byte(`{"id": 2, "method": "eth_subscribe", "params": ["newPendingTransactions"]}`)) 1590 suite.Require().NoError(err) 1591 1592 msg := make([]byte, 10240) 1593 // receive subscription id 1594 n, err := ws.Read(msg) 1595 suite.Require().NoError(err) 1596 var res Response 1597 suite.Require().NoError(json.Unmarshal(msg[:n], &res)) 1598 subscriptionId := string(res.Result) 1599 1600 // send transactions 1601 var expectedHashList [3]ethcmn.Hash 1602 var wg sync.WaitGroup 1603 wg.Add(1) 1604 go func() { 1605 defer wg.Done() 1606 for i := 0; i < 3; i++ { 1607 param := make([]map[string]string, 1) 1608 param[0] = make(map[string]string) 1609 param[0]["from"] = hexAddr1.Hex() 1610 param[0]["data"] = "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029" 1611 param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String() 1612 rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param) 1613 1614 var hash ethcmn.Hash 1615 suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash)) 1616 expectedHashList[i] = hash 1617 } 1618 }() 1619 var actualHashList [3]ethcmn.Hash 1620 // receive message three times 1621 for i := 0; i < 3; i++ { 1622 n, err = ws.Read(msg) 1623 suite.Require().NoError(err) 1624 var notification websockets.SubscriptionNotification 1625 suite.Require().NoError(json.Unmarshal(msg[:n], ¬ification)) 1626 actualHashList[i] = ethcmn.HexToHash(notification.Params.Result.(string)) 1627 } 1628 wg.Wait() 1629 suite.Require().EqualValues(expectedHashList, actualHashList) 1630 1631 // cancel the subscription 1632 cancelMsg := fmt.Sprintf(`{"id": 2, "method": "eth_unsubscribe", "params": [%s]}`, subscriptionId) 1633 _, err = ws.Write([]byte(cancelMsg)) 1634 suite.Require().NoError(err) 1635 } 1636 1637 //{} or nil matches any topic list 1638 //{A} matches topic A in first position 1639 //{{}, {B}} matches any topic in first position AND B in second position 1640 //{{A}, {B}} matches topic A in first position AND B in second position 1641 //{{A, B}, {C, D}} matches topic (A OR B) in first position AND (C OR D) in second position 1642 func (suite *RPCTestSuite) TestWebsocket_Logs(netAddr string) { 1643 t := suite.T() 1644 contractAddr1, contractAddr2, contractAddr3 := deployTestTokenContract(t, netAddr), deployTestTokenContract(t, netAddr), deployTestTokenContract(t, netAddr) 1645 1646 // init test cases 1647 tests := []struct { 1648 addressList string // input 1649 topicsList string // input 1650 expected int // expected result 1651 }{ 1652 // case 0: matches any contract address & any topics 1653 {"", "", 21}, 1654 // case 1: matches one contract address & any topics 1655 {fmt.Sprintf(`"address":"%s"`, contractAddr1), "", 7}, 1656 // case 2: matches two contract addressses & any topics 1657 {fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), "", 14}, 1658 // case 3: matches two contract addressses & one topic in first position 1659 {fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":["%s"]`, approveFuncHash), 6}, 1660 // case 4: matches two contract addressses & one topic in third position 1661 {fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":[null, null, ["%s"]]`, recvAddr1Hash), 4}, 1662 // case 5: matches two contract addressses & two topics in first、third position 1663 {fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":[["%s"], null, ["%s"]]`, approveFuncHash, recvAddr1Hash), 2}, 1664 // case 6: matches two contract addressses & two topic lists in first、third position 1665 {fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":[["%s","%s"], null, ["%s","%s"]]`, approveFuncHash, transferFuncHash, recvAddr1Hash, recvAddr2Hash), 8}, 1666 } 1667 1668 go func() { 1669 time.Sleep(time.Minute * 2) 1670 panic("the tasks have been running for too long time, over 2 minutes") 1671 }() 1672 // the approximate running time is one minute 1673 var wg sync.WaitGroup 1674 wg.Add(len(tests) + 1) 1675 for i, test := range tests { 1676 go verifyWebSocketRecvNum(suite.T(), &wg, i, test.addressList, test.topicsList, test.expected) 1677 } 1678 go sendTxs(suite.T(), netAddr, &wg, contractAddr1, contractAddr2, contractAddr3) 1679 wg.Wait() 1680 } 1681 1682 func deployTestTokenContract(t *testing.T, netAddr string) string { 1683 param := make([]map[string]string, 1) 1684 param[0] = map[string]string{ 1685 "from": hexAddr1.Hex(), 1686 "data": ttokenContractByteCode, 1687 "gasPrice": (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String(), 1688 } 1689 rpcRes := Call(t, netAddr, "eth_sendTransaction", param) 1690 var hash ethcmn.Hash 1691 require.NoError(t, json.Unmarshal(rpcRes.Result, &hash)) 1692 receipt := WaitForReceipt(t, netAddr, hash) 1693 require.NotNil(t, receipt) 1694 contractAddr, ok := receipt["contractAddress"].(string) 1695 require.True(t, ok) 1696 return contractAddr 1697 } 1698 1699 func verifyWebSocketRecvNum(t *testing.T, wg *sync.WaitGroup, index int, addressList, topicsList string, expected int) { 1700 defer wg.Done() 1701 1702 // create websocket 1703 origin, url := "http://127.0.0.1:8546/", "ws://127.0.0.1:8546" 1704 ws, err := websocket.Dial(url, "", origin) 1705 require.NoError(t, err) 1706 defer func() { 1707 // close websocket 1708 err := ws.Close() 1709 require.NoError(t, err) 1710 }() 1711 1712 // fulfill parameters 1713 param := assembleParameters(addressList, topicsList) 1714 _, err = ws.Write([]byte(param)) 1715 require.NoError(t, err) 1716 1717 msg := make([]byte, 10240) 1718 // receive subscription id 1719 n, err := ws.Read(msg) 1720 var res Response 1721 require.NoError(t, err) 1722 require.NoError(t, json.Unmarshal(msg[:n], &res)) 1723 require.Nil(t, res.Error) 1724 subscriptionId := string(res.Result) 1725 //log.Printf("test case %d: websocket %s is created successfully, expect receive %d logs \n", index, subscriptionId, expected) 1726 1727 for i := 0; i < expected; i++ { 1728 n, err = ws.Read(msg) 1729 require.NoError(t, err) 1730 var notification websockets.SubscriptionNotification 1731 require.NoError(t, json.Unmarshal(msg[:n], ¬ification)) 1732 } 1733 1734 // cancel the subscription 1735 cancelMsg := fmt.Sprintf(`{"id": 2, "method": "eth_unsubscribe", "params": [%s]}`, subscriptionId) 1736 _, err = ws.Write([]byte(cancelMsg)) 1737 require.NoError(t, err) 1738 //log.Printf("test case %d: webdocket %s receive %d logs, then close successfully", index, subscriptionId, expected) 1739 } 1740 */ 1741 1742 func assembleParameters(addressList string, topicsList string) string { 1743 var param string 1744 if addressList == "" { 1745 param = topicsList 1746 } 1747 if topicsList == "" { 1748 param = addressList 1749 } 1750 if addressList != "" && topicsList != "" { 1751 param = addressList + "," + topicsList 1752 } 1753 return fmt.Sprintf(`{"id": 2, "method": "eth_subscribe", "params": ["logs",{%s}]}`, param) 1754 } 1755 1756 func sendTxs(t *testing.T, netAddr string, wg *sync.WaitGroup, contractAddrs ...string) { 1757 dataList := []string{ 1758 // 0. mint 4294967295coin -> 0x2cf4ea7df75b513509d95946b43062e26bd88035 1759 "0x40c10f190000000000000000000000002cf4ea7df75b513509d95946b43062e26bd8803500000000000000000000000000000000000000000000000000000000ffffffff", 1760 // 1. approve 12345678coin -> 0x9ad84c8630e0282f78e5479b46e64e17779e3cfb 1761 "0x095ea7b30000000000000000000000009ad84c8630e0282f78e5479b46e64e17779e3cfb0000000000000000000000000000000000000000000000000000000000bc614e", 1762 // 2. approve 12345678coin -> 0xc9c9b43322f5e1dc401252076fa4e699c9122cd6 1763 "0x095ea7b3000000000000000000000000c9c9b43322f5e1dc401252076fa4e699c9122cd60000000000000000000000000000000000000000000000000000000000bc614e", 1764 // 3. approve 12345678coin -> 0x2B5Cf24AeBcE90f0B8f80Bc42603157b27cFbf47 1765 "0x095ea7b30000000000000000000000002b5cf24aebce90f0b8f80bc42603157b27cfbf470000000000000000000000000000000000000000000000000000000000bc614e", 1766 // 4. transfer 1234coin -> 0x9ad84c8630e0282f78e5479b46e64e17779e3cfb 1767 "0xa9059cbb0000000000000000000000009ad84c8630e0282f78e5479b46e64e17779e3cfb00000000000000000000000000000000000000000000000000000000000004d2", 1768 // 5. transfer 1234coin -> 0xc9c9b43322f5e1dc401252076fa4e699c9122cd6 1769 "0xa9059cbb000000000000000000000000c9c9b43322f5e1dc401252076fa4e699c9122cd600000000000000000000000000000000000000000000000000000000000004d2", 1770 // 6. transfer 1234coin -> 0x2B5Cf24AeBcE90f0B8f80Bc42603157b27cFbf47 1771 "0xa9059cbb0000000000000000000000002b5cf24aebce90f0b8f80bc42603157b27cfbf4700000000000000000000000000000000000000000000000000000000000004d2", 1772 } 1773 defer wg.Done() 1774 for _, contractAddr := range contractAddrs { 1775 for i := 0; i < 7; i++ { 1776 param := make([]map[string]string, 1) 1777 param[0] = make(map[string]string) 1778 param[0]["from"] = hexAddr1.Hex() 1779 param[0]["to"] = contractAddr 1780 param[0]["data"] = dataList[i] 1781 param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String() 1782 rpcRes := Call(t, netAddr, "eth_sendTransaction", param) 1783 var hash ethcmn.Hash 1784 require.NoError(t, json.Unmarshal(rpcRes.Result, &hash)) 1785 1786 time.Sleep(time.Second * 1) 1787 } 1788 } 1789 }