import pytest from pyhmy import transaction from pyhmy.rpc import exceptions endpoint = "http://localhost:9500" endpoint_shard_one = "http://localhost:9502" fake_shard = "http://example.com" # previously sent txs to get and check tx_hash = "0xc26be5776aa57438bccf196671a2d34f3f22c9c983c0f844c62b2fb90403aa43" tx_block_num = None tx_block_hash = None tx_index = None cx_hash = "0xf73ba634cb96fc0e3e2c9d3b4c91379e223741be4a5aa56e6d6caf49c1ae75cf" stx_hash = "0xc8177ace2049d9f4eb4a45fd6bd6b16f693573d036322c36774cc00d05a3e24f" stx_block_num = None stx_block_hash = None stx_index = None # new txs to send and check raw_tx = "0xf86f0385174876e800825208808094c9c6d47ee5f2e3e08d7367ad1a1373ba9dd172418905b12aefafa80400008027a07a4952b90bf38723a9197179a8e6d2e9b3a86fd6da4e66a9cf09fdc59783f757a053910798b311245525bd77d6119332458c2855102e4fb9e564f6a3b710d18bb0" raw_tx_hash = "0x7ccd80f8513f76ec58b357c7a82a12a95e025d88f1444e953f90e3d86e222571" raw_stx = "0xf88302f494c9c6d47ee5f2e3e08d7367ad1a1373ba9dd1724194a5241513da9f4463f1d4874b548dfbac29d91f3489056bc75e2d631000008085174876e80082c35027a0808ea7d27adf3b1f561e8da4676814084bb75ac541b616bece87c6446e6cc54ea02f19f0b14240354bd42ad60b0c7189873c0be87044e13072b0981a837ca76f64" raw_stx_hash = "0xe7d07ef6d9fca595a14ceb0ca917bece7bedb15efe662300e9334a32ac1da629" def _test_transaction_rpc( fn, *args, **kwargs ): if not callable( fn ): pytest.fail( f"Invalid function: {fn}" ) try: response = fn( *args, **kwargs ) except Exception as e: if isinstance( e, exceptions.RPCError ) and "does not exist/is not available" in str( e ): pytest.skip( f"{str(e)}" ) pytest.fail( f"Unexpected error: {e.__class__} {e}" ) return response def test_get_pending_transactions( setup_blockchain ): pool = _test_transaction_rpc( transaction.get_pending_transactions ) assert isinstance( pool, list ) def test_get_transaction_by_hash( setup_blockchain ): tx = _test_transaction_rpc( transaction.get_transaction_by_hash, tx_hash, endpoint = endpoint ) assert tx assert isinstance( tx, dict ) assert "blockNumber" in tx.keys() assert "blockHash" in tx.keys() global tx_block_num tx_block_num = int( tx[ "blockNumber" ] ) global tx_block_hash tx_block_hash = tx[ "blockHash" ] global tx_index tx_index = int( tx[ "transactionIndex" ] ) def test_get_transaction_by_block_hash_and_index( setup_blockchain ): if not tx_block_hash: pytest.skip( "Failed to get reference block hash" ) tx = _test_transaction_rpc( transaction.get_transaction_by_block_hash_and_index, tx_block_hash, tx_index, endpoint = endpoint, ) assert tx assert isinstance( tx, dict ) def test_get_transaction_by_block_number_and_index( setup_blockchain ): if not tx_block_num: pytest.skip( "Failed to get reference block num" ) tx = _test_transaction_rpc( transaction.get_transaction_by_block_number_and_index, tx_block_num, tx_index, endpoint = endpoint, ) assert tx assert isinstance( tx, dict ) def test_get_transaction_receipt( setup_blockchain ): tx_receipt = _test_transaction_rpc( transaction.get_transaction_receipt, tx_hash, endpoint = endpoint ) assert tx_receipt assert isinstance( tx_receipt, dict ) def test_get_transaction_error_sink( setup_blockchain ): errors = _test_transaction_rpc( transaction.get_transaction_error_sink ) assert isinstance( errors, list ) def test_send_and_confirm_raw_transaction( setup_blockchain ): # Note: this test is not yet idempotent since the localnet will reject transactions which were previously finalized. test_tx = _test_transaction_rpc( transaction.send_and_confirm_raw_transaction, raw_tx ) assert isinstance( test_tx, dict ) assert test_tx[ "hash" ] == raw_tx_hash def test_get_pending_cx_receipts( setup_blockchain ): pending = _test_transaction_rpc( transaction.get_pending_cx_receipts ) assert isinstance( pending, list ) def test_get_cx_receipt_by_hash( setup_blockchain ): cx = _test_transaction_rpc( transaction.get_cx_receipt_by_hash, cx_hash, endpoint_shard_one ) assert cx assert isinstance( cx, dict ) def test_resend_cx_receipt( setup_blockchain ): sent = _test_transaction_rpc( transaction.resend_cx_receipt, cx_hash ) assert isinstance( sent, bool ) assert sent def test_get_staking_transaction_by_hash( setup_blockchain ): staking_tx = _test_transaction_rpc( transaction.get_staking_transaction_by_hash, stx_hash ) assert staking_tx assert isinstance( staking_tx, dict ) assert "blockNumber" in staking_tx.keys() assert "blockHash" in staking_tx.keys() global stx_block_num stx_block_num = int( staking_tx[ "blockNumber" ] ) global stx_block_hash stx_block_hash = staking_tx[ "blockHash" ] global stx_index stx_index = int( staking_tx[ "transactionIndex" ] ) def test_get_transaction_by_block_hash_and_index( setup_blockchain ): if not stx_block_hash: pytest.skip( "Failed to get reference block hash" ) stx = _test_transaction_rpc( transaction.get_staking_transaction_by_block_hash_and_index, stx_block_hash, stx_index, ) assert stx assert isinstance( stx, dict ) def test_get_transaction_by_block_number_and_index( setup_blockchain ): if not stx_block_num: pytest.skip( "Failed to get reference block num" ) stx = _test_transaction_rpc( transaction.get_staking_transaction_by_block_number_and_index, stx_block_num, stx_index, ) assert stx assert isinstance( stx, dict ) def test_get_staking_transaction_error_sink( setup_blockchain ): errors = _test_transaction_rpc( transaction.get_staking_transaction_error_sink ) assert isinstance( errors, list ) def test_send_raw_staking_transaction( setup_blockchain ): test_stx = _test_transaction_rpc( transaction.send_and_confirm_raw_staking_transaction, raw_stx, endpoint = endpoint ) assert isinstance( test_stx, dict ) assert test_stx[ "hash" ] == raw_stx_hash def test_get_pool_stats( setup_blockchain ): test_pool_stats = _test_transaction_rpc( transaction.get_pool_stats, endpoint = endpoint ) assert isinstance( test_pool_stats, dict ) def test_get_pending_staking_transactions( setup_blockchain ): pending_staking_transactions = _test_transaction_rpc( transaction.get_pending_staking_transactions, endpoint = endpoint ) assert isinstance( pending_staking_transactions, list ) def test_errors(): with pytest.raises( exceptions.RPCError ): transaction.get_pending_transactions( fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_transaction_error_sink( fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_pool_stats( fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_transaction_by_hash( "", endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_transaction_by_block_hash_and_index( "", 1, endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_transaction_by_block_number_and_index( 1, 1, endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_transaction_receipt( "", endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.send_raw_transaction( "", endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_pending_cx_receipts( fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_cx_receipt_by_hash( "", endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.resend_cx_receipt( "", endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_staking_transaction_by_hash( "", endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_staking_transaction_by_block_hash_and_index( "", 1, endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_staking_transaction_by_block_number_and_index( 1, 1, endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_staking_transaction_error_sink( endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.send_raw_staking_transaction( "", endpoint = fake_shard ) with pytest.raises( exceptions.RPCError ): transaction.get_pending_staking_transactions( endpoint = fake_shard )