def test_get_header_by_number(): """ Note that v1 & v2 have the same responses. """ reference_response = { "blockHash": "0xb718a66ef2b7764fa75b40bfe7047d015197a65ae4a9c4f2007501825025564c", "blockNumber": 1, "shardID": 0, "leader": "one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy", "viewID": 1, "epoch": 0, "timestamp": "2020-07-12 14:14:17 +0000 UTC", "unixtime": 1594563257, "lastCommitSig": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "lastCommitBitmap": "", "crossLinks": [] } # Check v1 raw_response = base_request("hmy_getHeaderByNumber", params=["0x0"], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["shardID"] == 0 # Check v2 raw_response = base_request("hmyv2_getHeaderByNumber", params=[0], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["shardID"] == 0
def test_get_leader_address(): """ Note that v1 & v2 have the same responses. """ reference_response = "0x6911b75b2560be9a8f71164a33086be4511fc99a" # Check v1 raw_response = base_request("hmy_getLeader", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert type(reference_response) == type(response) if response.startswith("one1"): assert account.is_valid_address( response), f"Leader address is not a valid ONE address" else: ref_len = len(reference_response.replace("0x", "")) assert ref_len == len(response.replace( "0x", "")), f"Leader address hash is not of length {ref_len}" # Check v2 raw_response = base_request("hmyv2_getLeader", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) if response.startswith("one1"): assert account.is_valid_address( response), f"Leader address is not a valid ONE address" else: ref_len = len(reference_response.replace("0x", "")) assert ref_len == len(response.replace( "0x", "")), f"Leader address hash is not of length {ref_len}"
def test_get_current_transaction_error_sink(): """ Note that v1 & v2 have the same responses. """ error_tx = { "from": "one1ujsjs4mhds75xnws0yx0v8l2rvyp67arwzqrvz", "to": "one1wfn43ynxhhdrrjnddqcr74u38frqc7hqjhhdkx", # odor middle lake course smooth drive tone oven stone canyon chapter special recall page tomorrow north moon impose original under shaft guess popular debate "amount": "1000000", "from-shard": 0, "to-shard": 0, "hash": "0xa07018dace53fca04a1fe6bd70e6ef7d95520d8da5758f85ab70125faa2dabfd", "nonce": "0x0", "signed-raw-tx": "0xf86f80843b9aca008252088080947267589266bdda31ca6d68303f57913a460c7ae08ad3c21bcecceda10000008027a0376ba8084723c3a98a11c3b950ad55d3ba26bddac1def84abd0b6fab2299ea73a06db20ea7930d0a3beeb342973406fd8e11a59e500a70f26bf2e43f11579c36ab", } reference_response = [ { "tx-hash-id": "0x371a399f7f62a5f372d3388a07250e16ee56ac763bd3a0c8c5f628f1e1975679", "time-at-rejection": 1594797464, "error-message": "transaction gas-price is 0.000000000000000000 ONE: transaction underpriced" } ] response = base_request('hmy_sendRawTransaction', params=[error_tx["signed-raw-tx"]], endpoint=endpoints[error_tx["from-shard"]]) check_and_unpack_rpc_response(response, expect_error=True) # Send invalid transaction directly... # Check v1 raw_response = base_request("hmy_getCurrentTransactionErrorSink", params=[], endpoint=endpoints[error_tx["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) found_errored_tx = False for err in response: if err["tx-hash-id"] == error_tx["hash"]: found_errored_tx = True break assert found_errored_tx, f"Could not find errored transaction (hash {error_tx['hash']}) in {json.dumps(response, indent=2)}" # Check v2 raw_response = base_request("hmyv2_getCurrentTransactionErrorSink", params=[], endpoint=endpoints[error_tx["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) found_errored_tx = False for err in response: if err["tx-hash-id"] == error_tx["hash"]: found_errored_tx = True break assert found_errored_tx, f"Could not find errored transaction (hash {error_tx['hash']}) in {json.dumps(response, indent=2)}"
def test_get_latest_header(): """ Note that v1 & v2 have the same responses. """ reference_response = { "blockHash": "0x4e9faaf05bd7ed0ed392b3b5b19f2d2df993e60436c94b61b8afae6998b854b5", "blockNumber": 83, "shardID": 0, "leader": "one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy", "viewID": 83, "epoch": 15, "timestamp": "2020-07-12 14:25:05 +0000 UTC", "unixtime": 1594563905, "lastCommitSig": "76e8365fdbd947f74d86f15072546f594f8aaf3f6bf0b085df1d81079b760e17da1666d8d07f5c744e200f81a5fa750901d0dc871a4dbe5461efa779553db3f95785d168701c774b23d2326f0d906e47d534a34c87f4ace5e4ed2242860bfc0e", "lastCommitBitmap": "3f", "crossLinks": [{ "hash": "0x9dda6ad7fdec1e0f76b87bbea432e12c8668dbb2de9100e87442adfb1c7d1f70", "block-number": 80, "view-id": 80, "signature": "73f8e045c0cee4accfd259a78ea440ef2cf8c95d1c2e0e069725b35034c63e27f4db8ec5e1983d1c21831561967d0101ba556977e047a032e2c0f70bc3dc658ae245cb3392c837aed46119fa95ab39aad4ac926a206ab174304be15bb17df68a", "signature-bitmap": "3f", "shard-id": 1, "epoch-number": 14 }] } # Check v1 raw_response = base_request("hmy_latestHeader", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["shardID"] == 0 # Check v2 raw_response = base_request("hmyv2_latestHeader", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["shardID"] == 0
def test_get_transaction_receipt_v2(): reference_response = { "blockHash": "0x08ef4c7b1d24f27be157bdf9f053d3fd2fabc81037cf87f83b000804bc2e1c9f", "blockNumber": 4, "contractAddress": None, "cumulativeGasUsed": 21000, "from": "one1zksj3evekayy90xt4psrz8h6j2v3hla4qwz4ur", "gasUsed": 21000, "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "shardID": 0, "status": 1, "to": "one1v92y4v2x4q27vzydf8zq62zu9g0jl6z0lx2c8q", "transactionHash": "0x5718a2fda967f051611ccfaf2230dc544c9bdd388f5759a42b2fb0847fc8d759", "transactionIndex": 0 } init_tx_record = initial_funding[0] raw_response = base_request("hmyv2_getTransactionReceipt", params=[init_tx_record["hash"]], endpoint=endpoints[init_tx_record["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["transactionHash"] == init_tx_record["hash"], f"Expected transaction {init_tx_record['hash']}, " \ f"got {response['transactionHash']}"
def test_get_transaction_by_hash_v1(): reference_response = { "blockHash": "0x08ef4c7b1d24f27be157bdf9f053d3fd2fabc81037cf87f83b000804bc2e1c9f", "blockNumber": "0x4", "from": "one1zksj3evekayy90xt4psrz8h6j2v3hla4qwz4ur", "timestamp": "0x5f0ec12e", "gas": "0x5208", "gasPrice": "0x3b9aca00", "hash": "0x5718a2fda967f051611ccfaf2230dc544c9bdd388f5759a42b2fb0847fc8d759", "input": "0x", "nonce": "0x0", "to": "one1v92y4v2x4q27vzydf8zq62zu9g0jl6z0lx2c8q", "transactionIndex": "0x0", "value": "0x152d02c7e14af6800000", "shardID": 0, "toShardID": 0, "v": "0x28", "r": "0x76b6130bc018cedb9f8891343fd8982e0d7f923d57ea5250b8bfec9129d4ae22", "s": "0xfbc01c988d72235b4c71b21ce033d4fc5f82c96710b84685de0578cff075a0a" } init_tx_record = initial_funding[0] raw_response = base_request("hmy_getTransactionByHash", params=[init_tx_record["hash"]], endpoint=endpoints[init_tx_record["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["hash"] == init_tx_record["hash"], f"Expected transaction {init_tx_record['hash']}, " \ f"got {response['hash']}"
def test_net_peer_count_v2(): """ Note that this is NOT a `hmy` RPC, however, there are 2 versions of it. """ raw_response = base_request("netv2_peerCount", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance(response, int) # Must be an integer in base 10
def send_staking_transaction(tx_data, confirm_submission=False): """ Send the given staking transaction (`tx_data`), and check that it got submitted to tx pool if `confirm_submission` is enabled. Node that tx_data follow the format of one of the entries in `initial_funding` """ assert isinstance( tx_data, dict ), f"Sanity check: expected tx_data to be of type dict not {type(tx_data)}" for el in ["signed-raw-tx", "hash"]: assert el in tx_data.keys( ), f"Expected {el} as a key in {json.dumps(tx_data, indent=2)}" # Send tx response = base_request('hmy_sendRawStakingTransaction', params=[tx_data["signed-raw-tx"]], endpoint=endpoints[0]) if confirm_submission: tx_hash = check_and_unpack_rpc_response(response, expect_error=False) assert tx_hash == tx_data["hash"], f"Expected submitted staking transaction to get tx hash " \ f"of {tx_data['hash']}, got {tx_hash}" else: assert is_valid_json_rpc( response), f"Invalid JSON response: {response}"
def test_resend_cx(cross_shard_txs): """ Note that v1 & v2 have the same responses. """ reference_response = True for tx in cross_shard_txs: raw_response = base_request("hmy_resendCx", params=[tx["hash"]], endpoint=endpoints[tx["shardID"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) raw_response = base_request("hmyv2_resendCx", params=[tx["hash"]], endpoint=endpoints[tx["shardID"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response)
def test_get_transaction_by_block_number_and_index_v2(): reference_response = { "blockHash": "0x08ef4c7b1d24f27be157bdf9f053d3fd2fabc81037cf87f83b000804bc2e1c9f", "blockNumber": 4, "from": "one1zksj3evekayy90xt4psrz8h6j2v3hla4qwz4ur", "timestamp": 1594802478, "gas": 21000, "gasPrice": 1000000000, "hash": "0x5718a2fda967f051611ccfaf2230dc544c9bdd388f5759a42b2fb0847fc8d759", "input": "0x", "nonce": 0, "to": "one1v92y4v2x4q27vzydf8zq62zu9g0jl6z0lx2c8q", "transactionIndex": 0, "value": 100000000000000000000000, "shardID": 0, "toShardID": 0, "v": "0x28", "r": "0x76b6130bc018cedb9f8891343fd8982e0d7f923d57ea5250b8bfec9129d4ae22", "s": "0xfbc01c988d72235b4c71b21ce033d4fc5f82c96710b84685de0578cff075a0a" } init_tx_record = initial_funding[0] tx = get_transaction(init_tx_record["hash"], init_tx_record["from-shard"]) blk = blockchain.get_block_by_hash(tx["blockHash"], endpoint=endpoints[tx["shardID"]], include_full_tx=False) index, blk_num = blk["transactions"].index(init_tx_record["hash"]), tx["blockNumber"] raw_response = base_request("hmyv2_getTransactionByBlockNumberAndIndex", params=[int(blk_num, 16), index], endpoint=endpoints[init_tx_record["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["hash"] == init_tx_record["hash"], f"Expected transaction {init_tx_record['hash']}, " \ f"got {response['hash']}"
def test_get_storage_at_v2(deployed_contract): address = _get_contract_address(deployed_contract["hash"], deployed_contract["from-shard"]) block_number = blockchain.get_block_number(endpoint=endpoints[deployed_contract["from-shard"]]) raw_response = base_request("hmyv2_getStorageAt", params=[address, "0x0", block_number], endpoint=endpoints[deployed_contract["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance(response, str) and response.startswith("0x") # Must be a hex string
def test_get_pool_stats(): """ Note that v1 & v2 have the same responses. """ reference_response = { "executable-count": 0, "non-executable-count": 0 } raw_response = base_request("hmy_getPoolStats", params=[], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) raw_response = base_request("hmyv2_getPoolStats", params=[], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response)
def test_get_code_v2(deployed_contract): address = _get_contract_address(deployed_contract["hash"], deployed_contract["from-shard"]) block_number = blockchain.get_block_number(endpoint=endpoints[deployed_contract["from-shard"]]) raw_response = base_request("hmyv2_getCode", params=[address, block_number], endpoint=endpoints[deployed_contract["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert response == deployed_contract["code"], f"Expected {deployed_contract['code']}, got {response}"
def test_net_peer_count_v1(): """ Note that this is NOT a `hmy` RPC, however, there are 2 versions of it. """ raw_response = base_request("net_peerCount", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance(response, str) and response.startswith( "0x") # Must be a hex string
def test_invalid_method(): reference_response = { "code": -32601, "message": "The method test_ does not exist/is not available" } raw_response = base_request(f"invalid_{hash('method')}", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=True) assert_valid_json_structure(reference_response, response) assert response["code"] == reference_response["code"]
def test_get_block_transaction_count_by_hash_v2(): init_tx_record = initial_funding[0] init_tx = transaction.get_transaction_by_hash( init_tx_record["hash"], endpoints[init_tx_record["from-shard"]]) raw_response = base_request("hmyv2_getBlockTransactionCountByHash", params=[init_tx["blockHash"]], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance(response, int) assert response > 0, "Expected transaction count > 0 due to initial transactions"
def test_estimate_gas_v1(deployed_contract): """ RPC currently returns a constant, subject to change in the future, so skip for any error. """ try: raw_response = base_request("hmy_estimateGas", params=[{}], endpoint=endpoints[deployed_contract["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert response == "0xcf08", f"Expected constant reply for estimate gas to be 0xcf08, got {response}" except Exception as e: pytest.skip(traceback.format_exc()) pytest.skip(f"Exception: {e}")
def test_pending_transactions_v2(): tx = { "from": "one1u57rlv5q82deja6ew2l9hdy7ag3dwnw57x8s9t", "to": "one1zchjhmsxksamlxuv7h3k9h5aeury670n2jck2u", # kit attack eternal net bronze grace apple evil market spin evil tragic kid capital noble future shrimp gossip flee wonder album ahead catalog crawl "amount": "1000", "from-shard": 0, "to-shard": 0, "hash": "0x78324d91e69bdb14f4d0948bbad4ffc8bf309d4cf3e49c4c9a6871d02910c234", "nonce": "0x0", "signed-raw-tx": "0xf86e80843b9aca00825208808094162f2bee06b43bbf9b8cf5e362de9dcf064d79f3893635c9adc5dea000008028a0c6f2f65ce9dca19c50a81c3ccde8a466d3b1646d22a17184050f88bc28ea935fa0746c8b2c911bea6dce4505f2965b9ed0a4a1d04dc362395bc2ea41bd7b88fab5", } reference_response = [ { "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": None, "from": "one1twhzfc2wr4j5ka7gs9pmllpnrdyaskcl5lq8ye", "timestamp": 0, "gas": 21000, "gasPrice": 1000000000, "hash": "0xef8091e621745bd17133664c96842ef9d730a842f69bce6402b49490af0a17ef", "input": "0x", "nonce": 0, "to": "one13awvzpjt7n3hcrmxax3elps7a6vw46u63kc28p", "transactionIndex": 0, "value": 1000000000000000000000, "shardID": 0, "toShardID": 0, "v": "0x28", "r": "0xe876d901525a8799a8eb3ea03e2c1a43129c2ff3136ec10f6345f2899bab5026", "s": "0x5c4f1e659b9d371c2e9994aee240b966e36b6dd609747d42c9d9c9f23371d808" } ] if get_transaction(tx["hash"], tx["from-shard"]) is not None: pytest.skip(f"Test transaction (hash {tx['hash']}) already present on chain...") send_transaction(tx, confirm_submission=True) start_time = time.time() while time.time() - start_time <= tx_timeout: raw_response = base_request("hmyv2_pendingTransactions", endpoint=endpoints[tx["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) for pending_tx in response: if pending_tx["hash"] == tx["hash"]: assert pending_tx["shardID"] == tx["from-shard"], f"Pending tx has from shard {pending_tx['shardID']}, " \ f"expected shard {tx['from-shard']}" assert pending_tx["toShardID"] == tx["to-shard"], f"Pending tx has to shard {pending_tx['toShardID']}, " \ f"expected shard {tx['to-shard']}" return raise AssertionError(f"Timeout! Pending transaction not found for {json.dumps(tx, indent=2)}")
def test_get_block_signer_keys(): """ Note that v1 & v2 have the same responses. """ reference_response = [ "65f55eb3052f9e9f632b2923be594ba77c55543f5c58ee1454b9cfd658d25e06373b0f7d42a19c84768139ea294f6204", ] # Check v1 raw_response = base_request("hmy_getBlockSignerKeys", params=["0x2"], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) # Check v2 raw_response = base_request("hmyv2_getBlockSignerKeys", params=[2], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response)
def get_staking_transaction(tx_hash): """ Fetch the staking transaction for the given hash on the given shard. It also checks that the RPC response is valid. """ assert isinstance( tx_hash, str ), f"Sanity check: expect tx hash to be of type str not {type(tx_hash)}" raw_response = base_request('hmy_getStakingTransactionByHash', params=[tx_hash], endpoint=endpoints[0]) return check_and_unpack_rpc_response(raw_response, expect_error=False)
def test_get_block_signers(): """ Note that v1 & v2 have the same responses. """ reference_response = ["one1gh043zc95e6mtutwy5a2zhvsxv7lnlklkj42ux"] # Check v1 raw_response = base_request("hmy_getBlockSigners", params=["0x2"], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert len(response) > 0, "expect at least 1 signer" # Check v2 raw_response = base_request("hmyv2_getBlockSigners", params=[2], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert len(response) > 0, "expect at least 1 signer"
def test_send_raw_transaction_v1(): tx = { "from": "one1p5x4t7mvd94jn5awxmhlvgqmlazx5egzz7rveg", "to": "one1mjunf85vnhc4drv57ugsyg2fxjnsq920qzkpwq", # identify energy glimpse train script text town amused major slot armed fiction park alter dance live snow path picture desk metal voice distance good "amount": "1000", "from-shard": 0, "to-shard": 0, "hash": "0x5c5029de0c45a692265ec55d5218834c837c4c8d7cd2ed9598a858ed8ee8c811", "nonce": "0x0", "signed-raw-tx": "0xf86e80843b9aca00825208808094dcb9349e8c9df1568d94f71102214934a700154f893635c9adc5dea000008028a0e727143889e1ac8fbcaed655e186407b6b6978cbff63f79c0a6bd57bfb75ef06a07409113d6df43969d20552c9ea239e930a1ae736a6f3d2b3d4b8a3392217f99d", } reference_response = { "code": -32000, "message": "transaction already finalized" } if get_transaction(tx["hash"], tx["from-shard"]) is not None: pytest.skip(f"Test transaction (hash {tx['hash']}) already present on chain...") # Submit new transaction... response = base_request('hmy_sendRawTransaction', params=[tx["signed-raw-tx"]], endpoint=endpoints[tx["from-shard"]]) tx_hash = check_and_unpack_rpc_response(response, expect_error=False) assert tx_hash == tx["hash"], f"Expect submitted transaction to get tx hash of {tx['hash']}, got {tx_hash}" # Test finalized transaction error... start_time = time.time() while time.time() - start_time <= tx_timeout: if get_transaction(tx["hash"], tx["from-shard"]) is not None: raw_response = base_request('hmy_sendRawTransaction', params=[tx["signed-raw-tx"]], endpoint=endpoints[tx["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=True) assert_valid_json_structure(reference_response, response) assert reference_response["code"] == response["code"], f"Expected error code {reference_response['code']}, " \ f"got {response['code']}" return time.sleep(0.25) raise AssertionError(f"Timeout! Finalized transaction not found for {json.dumps(tx, indent=2)}")
def test_send_raw_transaction_v2(): tx = { "from": "one13lu674f3jkfk2qhsngfc2vhcf372wprctdjvgu", "to": "one14jeshxg75gdr5dz8sg7fm2sjvw7snnsdw98f0y", # humor brain crouch walk focus slush material sort used refuse exist prefer obscure above grow maze scheme myself liquid lab fresh awful easily debris "amount": "1000", "from-shard": 0, "to-shard": 0, "hash": "0x99919613fce4bbc9f4a068373bbb67b3f7e5ce34a7a1eef866a32284ec70261a", "nonce": "0x0", "signed-raw-tx": "0xf86e80843b9aca00825208808094acb30b991ea21a3a3447823c9daa1263bd09ce0d893635c9adc5dea000008028a03ab9d7562ca97f7a57ccca3b691f5b7b8e75a2f0f4d38109bb818da5199d62cda02cb8180d0fed4cfe03d25f3458c7d11c91185273b6ae5e902d1debe998326997", } reference_response = { "code": -32000, "message": "transaction already finalized" } if get_transaction(tx["hash"], tx["from-shard"]) is not None: pytest.skip(f"Test transaction (hash {tx['hash']}) already present on chain...") # Submit new transaction... response = base_request('hmyv2_sendRawTransaction', params=[tx["signed-raw-tx"]], endpoint=endpoints[tx["from-shard"]]) tx_hash = check_and_unpack_rpc_response(response, expect_error=False) assert tx_hash == tx["hash"], f"Expect submitted transaction to get tx hash of {tx['hash']}, got {tx_hash}" # Test finalized transaction error... start_time = time.time() while time.time() - start_time <= tx_timeout: if get_transaction(tx["hash"], tx["from-shard"]) is not None: raw_response = base_request('hmyv2_sendRawTransaction', params=[tx["signed-raw-tx"]], endpoint=endpoints[tx["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=True) assert_valid_json_structure(reference_response, response) assert reference_response["code"] == response["code"], f"Expected error code {reference_response['code']}, " \ f"got {response['code']}" return time.sleep(0.25) raise AssertionError(f"Timeout! Finalized transaction not found for {json.dumps(tx, indent=2)}")
def test_call_v1(deployed_contract): """ TODO: Real smart contract call, currently, it is an error case test. """ address = _get_contract_address(deployed_contract["hash"], deployed_contract["from-shard"]) raw_response = base_request("hmy_call", params=[{"to": address}, "latest"], endpoint=endpoints[deployed_contract["from-shard"]]) assert is_valid_json_rpc(raw_response), f"Invalid JSON response: {raw_response}" try: response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance(response, str) and response.startswith("0x") # Must be a hex string except Exception as e: pytest.skip("RPC format being reworked, fix when finished")
def test_get_latest_chain_headers(): """ Note that v1 & v2 have the same responses. """ reference_response = { "beacon-chain-header": { "shard-id": 0, "block-header-hash": "0x127437058641851cdfe10e9509aa060b169acbce79eb63d04e3be2cfbe596695", "block-number": 171, "view-id": 171, "epoch": 33 }, "shard-chain-header": { "shard-id": 1, "block-header-hash": "0x0ca6c681e128f47e35e4c578b6381f3f8dda8ec9fcb0a8935a0bf12a2e7a19a3", "block-number": 171, "view-id": 171, "epoch": 33 } } # Check v1 raw_response = base_request("hmy_getLatestChainHeaders", endpoint=endpoints[1]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["beacon-chain-header"]["shard-id"] == 0 assert response["shard-chain-header"]["shard-id"] == 1 # Check v2 raw_response = base_request("hmyv2_getLatestChainHeaders", endpoint=endpoints[1]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert response["beacon-chain-header"]["shard-id"] == 0 assert response["shard-chain-header"]["shard-id"] == 1
def test_get_block_transaction_count_by_hash_v1(): init_tx_record = initial_funding[0] init_tx = transaction.get_transaction_by_hash( init_tx_record["hash"], endpoints[init_tx_record["from-shard"]]) raw_response = base_request("hmy_getBlockTransactionCountByHash", params=[init_tx["blockHash"]], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance(response, str) and response.startswith( "0x") # Must be a hex string assert int( response, 16) > 0, "Expected transaction count > 0 due to initial transactions"
def test_get_sharding_structure(): """ Note that v1 & v2 have the same responses. """ reference_response = { "current": True, "http": "http://127.0.0.1:9500", "shardID": 0, "ws": "ws://127.0.0.1:9800" } # Check v1 raw_response = base_request("hmy_getShardingStructure", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance( response, list), f"Expected response to be of type list, not {type(response)}" for d in response: assert isinstance( d, dict), f"Expected type dict in response elements, not {type(d)}" assert_valid_json_structure(reference_response, d) assert response[0]["current"] # Check v2 raw_response = base_request("hmyv2_getShardingStructure", endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert isinstance( response, list), f"Expected response to be of type list, not {type(response)}" for d in response: assert isinstance( d, dict), f"Expected type dict in response elements, not {type(d)}" assert_valid_json_structure(reference_response, d) assert response[0]["current"]
def test_get_cx_receipt_by_hash_v2(cross_shard_txs): reference_response = { "blockHash": "0xf12f3aefd7f189286b6da30871a47946c11f9c1673b3b693f9d37d659f69e018", "blockNumber": 33, "hash": "0xc0a84ec15fc3391089f20fa6b9cc90c654eb8dd2f6815297de89eef38ce4fe2b", "from": "one1ue25q6jk0xk3dth4pxur9e742vcqfwulhwqh45", "to": "one1t40su52axu207vgc6ymcmwe0xmml4njrskk2vf", "shardID": 0, "toShardID": 1, "value": 1000000000000000000000 } raw_response = base_request("hmyv2_getCXReceiptByHash", params=[cross_shard_txs[0]["hash"]], endpoint=endpoints[cross_shard_txs[0]["toShardID"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response)
def test_get_block_by_number_v2(): """ Note the use of a JSON object in the param. This is different from v1. """ reference_response = { "difficulty": 0, "epoch": 0, "extraData": "0x", "gasLimit": 80000000, "gasUsed": 0, "hash": "0x0994da932016ba93937ad46b9a1207ecd6d4fbd689d7f8ddf1f926cd3ebc6016", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "one1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqquzw7vz", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": 0, "number": 1, "parentHash": "0x61610810993c42bacd55a124e3b9009b9ae225a2f727750db4d2171504be59fb", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "size": 798, "stakingTransactions": [], "stateRoot": "0x9e470e803db498e6ba3c9108d3f951060e7121289c2354b8b185349ddef4fc0a", "timestamp": 1594469781, "transactions": [], "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncles": [], "viewID": 1 } raw_response = base_request("hmyv2_getBlockByNumber", params=[0, { "InclStaking": True }], endpoint=endpoints[0]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response)
def test_get_block_by_hash_v2(): """ Note the use of a JSON object in the param. This is different from v1. Note: param options for 'withSigners' will NOT return any sensical data in staking epoch (since it returns ONE addresses) and is subject to removal, thus is not tested here. """ reference_response = { "difficulty": 0, "epoch": 0, "extraData": "0x", "gasLimit": 80000000, "gasUsed": 105000, "hash": "0x8e0ca00640ea70afe078d02fd571085f14d5953dca7be8ef4efc6a02db090156", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "one1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqquzw7vz", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": 0, "number": 9, "parentHash": "0xd5d0e786f1a0c6d8d2ea038ef5f8272bb4e4def1838d61b7e1c395f4b763c09d", "receiptsRoot": "0x100f3336862d22706bbe26d67e5abf90f8f25ec5a22c4446835b6beaa6b59536", "size": 2410, "stateRoot": "0x8a39cac10f8d917564a4e6033dc303d6a47d9fc8768c220640de5bb89765e0cf", "timestamp": 1594660718, "transactions": [ { "blockHash": "0x8e0ca00640ea70afe078d02fd571085f14d5953dca7be8ef4efc6a02db090156", "blockNumber": 9, "from": "one1zksj3evekayy90xt4psrz8h6j2v3hla4qwz4ur", "timestamp": 1594660718, "gas": 21000, "gasPrice": 1000000000, "hash": "0x5718a2fda967f051611ccfaf2230dc544c9bdd388f5759a42b2fb0847fc8d759", "input": "0x", "nonce": 0, "to": "one1v92y4v2x4q27vzydf8zq62zu9g0jl6z0lx2c8q", "transactionIndex": 0, "value": 100000000000000000000000, "shardID": 0, "toShardID": 0, "v": "0x28", "r": "0x76b6130bc018cedb9f8891343fd8982e0d7f923d57ea5250b8bfec9129d4ae22", "s": "0xfbc01c988d72235b4c71b21ce033d4fc5f82c96710b84685de0578cff075a0a" }, ], "transactionsRoot": "0x8954e7b3ec6ef4b04dcaf2829d9ce8ed764f636445fe77d2f4e5ef157e69dbbd", "uncles": [], "viewID": 9 } init_tx_record = initial_funding[0] init_tx = transaction.get_transaction_by_hash( init_tx_record["hash"], endpoints[init_tx_record["from-shard"]]) raw_response = base_request( "hmyv2_getBlockByHash", params=[init_tx["blockHash"], { "fullTx": True, "inclTx": True }], endpoint=endpoints[init_tx_record["from-shard"]]) response = check_and_unpack_rpc_response(raw_response, expect_error=False) assert_valid_json_structure(reference_response, response) assert len( response["transactions"] ) > 0, "Expected transaction on block due to initial transactions" for tx in response["transactions"]: assert tx["blockHash"] == init_tx[ "blockHash"], f"Transaction in block {init_tx['blockHash']} does not have same block hash" assert tx["shardID"] == init_tx_record[ "from-shard"], f"Transaction in block from shard {init_tx_record['from-shard']} does not have same from shard ({tx['shardID']})"