diff --git a/README.md b/README.md index 3375e24..43aa948 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ For testing you can use the `TestRPCProvider`. This depends on following installation command. ```sh -pip install web3[TestRPCProvider] +pip install web3[Tester] ``` Then in your code: diff --git a/conftest.py b/conftest.py index 6c61cec..65ad562 100644 --- a/conftest.py +++ b/conftest.py @@ -1,54 +1,44 @@ -import contextlib -import tempfile -import shutil -import random - import pytest import gevent -from gevent import socket -from geth import ( # noqa: E402 - LoggingMixin, - DevGethProcess, -) +from web3.providers.tester import EthereumTesterProvider +from web3.providers.rpc import TestRPCProvider +from web3.main import Web3 -class GethProcess(LoggingMixin, DevGethProcess): - pass +class PollDelayCounter(object): + def __init__(self, initial_delay=0, max_delay=1, initial_step=0.01): + self.initial_delay = initial_delay + self.initial_step = initial_step + self.max_delay = max_delay + self.current_delay = initial_delay + def __call__(self): + delay = self.current_delay -def get_open_port(): - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.bind(("", 0)) - s.listen(1) - port = s.getsockname()[1] - s.close() - return port - - -def wait_for_http_connection(port, timeout=60): - with gevent.Timeout(timeout): - while True: - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.timeout = 1 - try: - s.connect(('127.0.0.1', port)) - except (socket.timeout, ConnectionRefusedError): - gevent.sleep(random.random()) - continue - else: - break + if self.current_delay == 0: + self.current_delay += self.initial_step else: - raise ValueError("Unable to establish HTTP connection") + self.current_delay *= 2 + self.current_delay = min(self.current_delay, self.max_delay) + + return delay + + def reset(self): + self.current_delay = self.initial_delay + + +@pytest.fixture() +def sleep_interval(): + return PollDelayCounter() @pytest.fixture() def skip_if_testrpc(): - from web3.providers.rpc import TestRPCProvider def _skip_if_testrpc(web3): - if isinstance(web3.currentProvider, TestRPCProvider): + if isinstance(web3.currentProvider, (TestRPCProvider, EthereumTesterProvider)): pytest.skip() return _skip_if_testrpc @@ -56,198 +46,43 @@ def skip_if_testrpc(): @pytest.fixture() def wait_for_miner_start(): def _wait_for_miner_start(web3, timeout=60): + poll_delay_counter = PollDelayCounter() with gevent.Timeout(timeout): while not web3.eth.mining or not web3.eth.hashrate: - gevent.sleep(random.random()) + gevent.sleep(poll_delay_counter()) return _wait_for_miner_start @pytest.fixture() def wait_for_block(): - from web3.providers.rpc import TestRPCProvider - def _wait_for_block(web3, block_number=1, timeout=60 * 10): + poll_delay_counter = PollDelayCounter() with gevent.Timeout(timeout): while True: if web3.eth.blockNumber >= block_number: break - if isinstance(web3.currentProvider, TestRPCProvider): + if isinstance(web3.currentProvider, (TestRPCProvider, EthereumTesterProvider)): web3._requestManager.request_blocking("evm_mine", []) - gevent.sleep(1) + gevent.sleep(poll_delay_counter()) return _wait_for_block @pytest.fixture() def wait_for_transaction(): def _wait_for_transaction(web3, txn_hash, timeout=120): + poll_delay_counter = PollDelayCounter() with gevent.Timeout(timeout): while True: txn_receipt = web3.eth.getTransactionReceipt(txn_hash) if txn_receipt is not None: break - gevent.sleep(1) + gevent.sleep(poll_delay_counter()) return txn_receipt return _wait_for_transaction -@contextlib.contextmanager -def tempdir(): - directory = tempfile.mkdtemp() - - try: - yield directory - finally: - shutil.rmtree(directory) - - -@pytest.yield_fixture(scope="session") -def web3_tester_provider(): - from testrpc import testrpc - - from web3.providers.rpc import TestRPCProvider - port = get_open_port() - provider = TestRPCProvider(port=port) - - testrpc.full_reset() - testrpc.rpc_configure('eth_mining', False) - testrpc.rpc_configure('eth_protocolVersion', '0x3f') - testrpc.rpc_configure('net_version', 1) - testrpc.evm_mine() - - provider.testrpc = testrpc - wait_for_http_connection(port) - - yield provider - - provider.server.stop() - provider.server.close() - provider.thread.kill() - - @pytest.fixture() -def web3_tester_empty(request, web3_tester_provider): - from web3 import Web3 - - if getattr(request, 'reset_chain', True): - web3_tester_provider.testrpc.full_reset() - - web3 = Web3(web3_tester_provider) - return web3 - - -@pytest.fixture() -def web3_tester_persistent(request, web3_tester_provider): - from web3 import Web3 - - web3 = Web3(web3_tester_provider) - return web3 - - -@pytest.fixture() -def web3_tester(web3_tester_persistent): - # alias - return web3_tester_persistent - - -@contextlib.contextmanager -def setup_testing_geth(): - with tempdir() as base_dir: - geth_process = GethProcess( - 'testing', - base_dir=base_dir, - overrides={'verbosity': '3','shh': True}, - ) - with geth_process as running_geth_process: - running_geth_process.wait_for_ipc(60) - running_geth_process.wait_for_rpc(60) - running_geth_process.wait_for_dag(600) - yield running_geth_process - - -@pytest.yield_fixture(scope="session") -def geth_persistent(): - with setup_testing_geth() as geth: - yield geth - - -@pytest.fixture(scope="session") -def web3_rpc_persistent(geth_persistent): - from web3 import ( - Web3, RPCProvider, - ) - - provider = RPCProvider(port=geth_persistent.rpc_port) - provider._geth = geth_persistent - web3 = Web3(provider) - return web3 - - -@pytest.yield_fixture() -def web3_rpc_empty(): - from web3 import ( - Web3, RPCProvider, - ) - - with setup_testing_geth() as geth: - provider = RPCProvider(port=geth.rpc_port) - provider._geth = geth - web3 = Web3(provider) - yield web3 - - -@pytest.fixture(scope="session") -def web3_ipc_persistent(geth_persistent): - from web3 import ( - Web3, IPCProvider, - ) - - provider = IPCProvider(ipc_path=geth_persistent.ipc_path) - provider._geth = geth_persistent - web3 = Web3(provider) - return web3 - - -@pytest.yield_fixture() -def web3_ipc_empty(): - from web3 import ( - Web3, IPCProvider, - ) - - with setup_testing_geth() as geth: - provider = IPCProvider(ipc_path=geth.ipc_path) - provider._geth = geth - web3 = Web3(provider) - yield web3 - - -@pytest.fixture(params=[ - 'tester', - pytest.mark.slow('rpc'), - pytest.mark.slow('ipc'), -]) -def web3(request): - if request.param == "tester": - return request.getfuncargvalue('web3_tester_persistent') - elif request.param == "rpc": - return request.getfuncargvalue('web3_rpc_persistent') - elif request.param == "ipc": - return request.getfuncargvalue('web3_ipc_persistent') - else: - raise ValueError("Unknown param") - - -@pytest.fixture(params=[ - 'tester', - pytest.mark.slow('rpc'), - pytest.mark.slow('ipc'), -]) -def web3_empty(request): - if request.param == "tester": - return request.getfuncargvalue('web3_tester_empty') - elif request.param == "rpc": - return request.getfuncargvalue('web3_rpc_empty') - elif request.param == "ipc": - return request.getfuncargvalue('web3_ipc_empty') - else: - raise ValueError("Unknown param") +def web3(): + provider = EthereumTesterProvider() + return Web3(provider) diff --git a/requirements-dev.txt b/requirements-dev.txt index af9b88a..08fd0ed 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,8 +1,7 @@ pytest>=2.8.2 pytest-pythonpath>=0.3 tox>=1.8.0 -eth-testrpc>=0.8.6 -ethereum-tester-client>=1.2.3 +eth-testrpc>=0.9.0 py-geth>=1.4.0 ethereum>=1.5.2 secp256k1>=0.13.1 diff --git a/setup.py b/setup.py index e377c78..d6f415b 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ setup( "pylru>=1.0.9", ], extras_require={ - 'TestRPCProvider': ["eth-testrpc>=0.9.0"], + 'Tester': ["eth-testrpc>=0.9.0"], }, py_modules=['web3'], license="MIT", diff --git a/tests/contracts/conftest.py b/tests/contracts/conftest.py index ebf4de3..dc5a903 100644 --- a/tests/contracts/conftest.py +++ b/tests/contracts/conftest.py @@ -1,9 +1,10 @@ import pytest import json import textwrap -from sha3 import sha3_256 -assert sha3_256(b'').hexdigest() == 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' +from web3.utils.abi import ( + event_signature_to_log_topic, +) CONTRACT_CODE = "0x606060405261022e806100126000396000f360606040523615610074576000357c01000000000000000000000000000000000000000000000000000000009004806316216f391461007657806361bc221a146100995780637cf5dab0146100bc578063a5f3c23b146100e8578063d09de08a1461011d578063dcf537b11461014057610074565b005b610083600480505061016c565b6040518082815260200191505060405180910390f35b6100a6600480505061017f565b6040518082815260200191505060405180910390f35b6100d26004808035906020019091905050610188565b6040518082815260200191505060405180910390f35b61010760048080359060200190919080359060200190919050506101ea565b6040518082815260200191505060405180910390f35b61012a6004805050610201565b6040518082815260200191505060405180910390f35b6101566004808035906020019091905050610217565b6040518082815260200191505060405180910390f35b6000600d9050805080905061017c565b90565b60006000505481565b6000816000600082828250540192505081905550600060005054905080507f3496c3ede4ec3ab3686712aa1c238593ea6a42df83f98a5ec7df9834cfa577c5816040518082815260200191505060405180910390a18090506101e5565b919050565b6000818301905080508090506101fb565b92915050565b600061020d6001610188565b9050610214565b90565b60006007820290508050809050610229565b91905056" @@ -70,8 +71,8 @@ def MATH_ABI(): @pytest.fixture() -def MathContract(web3_tester, MATH_ABI, MATH_CODE, MATH_RUNTIME, MATH_SOURCE): - return web3_tester.eth.contract( +def MathContract(web3, MATH_ABI, MATH_CODE, MATH_RUNTIME, MATH_SOURCE): + return web3.eth.contract( abi=MATH_ABI, code=MATH_CODE, code_runtime=MATH_RUNTIME, @@ -106,12 +107,12 @@ def SIMPLE_CONSTRUCTOR_ABI(): @pytest.fixture() -def SimpleConstructorContract(web3_tester, +def SimpleConstructorContract(web3, SIMPLE_CONSTRUCTOR_SOURCE, SIMPLE_CONSTRUCTOR_CODE, SIMPLE_CONSTRUCTOR_RUNTIME, SIMPLE_CONSTRUCTOR_ABI): - return web3_tester.eth.contract( + return web3.eth.contract( abi=SIMPLE_CONSTRUCTOR_ABI, code=SIMPLE_CONSTRUCTOR_CODE, code_runtime=SIMPLE_CONSTRUCTOR_RUNTIME, @@ -147,12 +148,12 @@ def WITH_CONSTRUCTOR_ARGUMENTS_ABI(): @pytest.fixture() -def WithConstructorArgumentsContract(web3_tester, +def WithConstructorArgumentsContract(web3, WITH_CONSTRUCTOR_ARGUMENTS_SOURCE, WITH_CONSTRUCTOR_ARGUMENTS_CODE, WITH_CONSTRUCTOR_ARGUMENTS_RUNTIME, WITH_CONSTRUCTOR_ARGUMENTS_ABI): - return web3_tester.eth.contract( + return web3.eth.contract( abi=WITH_CONSTRUCTOR_ARGUMENTS_ABI, code=WITH_CONSTRUCTOR_ARGUMENTS_CODE, code_runtime=WITH_CONSTRUCTOR_ARGUMENTS_RUNTIME, @@ -187,12 +188,12 @@ def WITH_CONSTRUCTOR_ADDRESS_ABI(): @pytest.fixture() -def WithConstructorAddressArgumentsContract(web3_tester, - WITH_CONSTRUCTOR_ADDRESS_SOURCE, - WITH_CONSTRUCTOR_ADDRESS_CODE, - WITH_CONSTRUCTOR_ADDRESS_RUNTIME, - WITH_CONSTRUCTOR_ADDRESS_ABI): - return web3_tester.eth.contract( +def WithConstructorAddressArgumentsContract(web3, + WITH_CONSTRUCTOR_ADDRESS_SOURCE, + WITH_CONSTRUCTOR_ADDRESS_CODE, + WITH_CONSTRUCTOR_ADDRESS_RUNTIME, + WITH_CONSTRUCTOR_ADDRESS_ABI): + return web3.eth.contract( abi=WITH_CONSTRUCTOR_ADDRESS_ABI, code=WITH_CONSTRUCTOR_ADDRESS_CODE, code_runtime=WITH_CONSTRUCTOR_ADDRESS_RUNTIME, @@ -261,8 +262,8 @@ def STRING_CONTRACT(STRING_SOURCE, STRING_CODE, STRING_RUNTIME, STRING_ABI): } @pytest.fixture() -def StringContract(web3_tester, STRING_CONTRACT): - return web3_tester.eth.contract(**STRING_CONTRACT) +def StringContract(web3, STRING_CONTRACT): + return web3.eth.contract(**STRING_CONTRACT) CONTRACT_EMITTER_SOURCE = textwrap.dedent((""" @@ -423,26 +424,21 @@ def emitter_event_ids(): return LogFunctions -def event_topic(event_signature): - from web3.utils.string import force_bytes - return "0x" + sha3_256(force_bytes(event_signature)).hexdigest() - - class LogTopics(object): - LogAnonymous = event_topic("LogAnonymous()") - LogNoArguments = event_topic("LogNoArguments()") - LogSingleArg = event_topic("LogSingleArg(uint256)") - LogSingleAnonymous = event_topic("LogSingleAnonymous(uint256)") - LogSingleWithIndex = event_topic("LogSingleWithIndex(uint256)") - LogDoubleArg = event_topic("LogDoubleArg(uint256,uint256)") - LogDoubleAnonymous = event_topic("LogDoubleAnonymous(uint256,uint256)") - LogDoubleWithIndex = event_topic("LogDoubleWithIndex(uint256,uint256)") - LogTripleArg = event_topic("LogTripleArg(uint256,uint256,uint256)") - LogTripleWithIndex = event_topic("LogTripleWithIndex(uint256,uint256,uint256)") - LogQuadrupleArg = event_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)") - LogQuadrupleWithIndex = event_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)") - LogBytes = event_topic("LogBytes(bytes)") - LogString = event_topic("LogString(string)") + LogAnonymous = event_signature_to_log_topic("LogAnonymous()") + LogNoArguments = event_signature_to_log_topic("LogNoArguments()") + LogSingleArg = event_signature_to_log_topic("LogSingleArg(uint256)") + LogSingleAnonymous = event_signature_to_log_topic("LogSingleAnonymous(uint256)") + LogSingleWithIndex = event_signature_to_log_topic("LogSingleWithIndex(uint256)") + LogDoubleArg = event_signature_to_log_topic("LogDoubleArg(uint256,uint256)") + LogDoubleAnonymous = event_signature_to_log_topic("LogDoubleAnonymous(uint256,uint256)") + LogDoubleWithIndex = event_signature_to_log_topic("LogDoubleWithIndex(uint256,uint256)") + LogTripleArg = event_signature_to_log_topic("LogTripleArg(uint256,uint256,uint256)") + LogTripleWithIndex = event_signature_to_log_topic("LogTripleWithIndex(uint256,uint256,uint256)") + LogQuadrupleArg = event_signature_to_log_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)") + LogQuadrupleWithIndex = event_signature_to_log_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)") + LogBytes = event_signature_to_log_topic("LogBytes(bytes)") + LogString = event_signature_to_log_topic("LogString(string)") @pytest.fixture() diff --git a/tests/contracts/test_contract_call_interface.py b/tests/contracts/test_contract_call_interface.py index 823dd6d..d9029fe 100644 --- a/tests/contracts/test_contract_call_interface.py +++ b/tests/contracts/test_contract_call_interface.py @@ -9,29 +9,29 @@ from web3.utils.string import ( @pytest.fixture() -def math_contract(web3_tester, MathContract): +def math_contract(web3, MathContract): deploy_txn = MathContract.deploy() - deploy_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + deploy_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert deploy_receipt is not None _math_contract = MathContract(address=deploy_receipt['contractAddress']) return _math_contract @pytest.fixture() -def string_contract(web3_tester, StringContract): +def string_contract(web3, StringContract): deploy_txn = StringContract.deploy(args=["Caqalai"]) - deploy_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + deploy_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert deploy_receipt is not None _string_contract = StringContract(address=deploy_receipt['contractAddress']) return _string_contract @pytest.fixture() -def address_contract(web3_tester, WithConstructorAddressArgumentsContract): +def address_contract(web3, WithConstructorAddressArgumentsContract): deploy_txn = WithConstructorAddressArgumentsContract.deploy(args=[ "0xd3cda913deb6f67967b99d67acdfa1712c293601", ]) - deploy_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + deploy_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert deploy_receipt is not None _address_contract = WithConstructorAddressArgumentsContract(address=deploy_receipt['contractAddress']) return _address_contract diff --git a/tests/contracts/test_contract_class_construction.py b/tests/contracts/test_contract_class_construction.py index 85c815d..4559955 100644 --- a/tests/contracts/test_contract_class_construction.py +++ b/tests/contracts/test_contract_class_construction.py @@ -3,16 +3,16 @@ import pytest from web3.contract import Contract -def test_class_construction_sets_class_vars(web3_tester, MATH_ABI, MATH_CODE, +def test_class_construction_sets_class_vars(web3, MATH_ABI, MATH_CODE, MATH_RUNTIME, MATH_SOURCE): - MathContract = web3_tester.eth.contract( + MathContract = web3.eth.contract( abi=MATH_ABI, code=MATH_CODE, code_runtime=MATH_RUNTIME, source=MATH_SOURCE, ) - assert MathContract.web3 == web3_tester + assert MathContract.web3 == web3 assert MathContract.code == MATH_CODE assert MathContract.code_runtime == MATH_RUNTIME assert MathContract.source == MATH_SOURCE @@ -23,7 +23,7 @@ def test_error_to_instantiate_base_class(): Contract() -def test_can_instantiate_without_address(web3_tester, MATH_ABI): - MathContract = web3_tester.eth.contract(MATH_ABI) +def test_can_instantiate_without_address(web3, MATH_ABI): + MathContract = web3.eth.contract(MATH_ABI) math = MathContract() diff --git a/tests/contracts/test_contract_deployment.py b/tests/contracts/test_contract_deployment.py index 04b2108..4444fe0 100644 --- a/tests/contracts/test_contract_deployment.py +++ b/tests/contracts/test_contract_deployment.py @@ -1,60 +1,60 @@ from web3.utils.string import force_bytes -def test_contract_deployment_no_constructor(web3_tester, MathContract, +def test_contract_deployment_no_constructor(web3, MathContract, MATH_RUNTIME): deploy_txn = MathContract.deploy() - txn_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + txn_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert txn_receipt is not None assert txn_receipt['contractAddress'] contract_address = txn_receipt['contractAddress'] - blockchain_code = web3_tester.eth.getCode(contract_address) + blockchain_code = web3.eth.getCode(contract_address) assert force_bytes(blockchain_code) == force_bytes(MATH_RUNTIME) -def test_contract_deployment_with_constructor_without_args(web3_tester, +def test_contract_deployment_with_constructor_without_args(web3, SimpleConstructorContract, SIMPLE_CONSTRUCTOR_RUNTIME): deploy_txn = SimpleConstructorContract.deploy() - txn_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + txn_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert txn_receipt is not None assert txn_receipt['contractAddress'] contract_address = txn_receipt['contractAddress'] - blockchain_code = web3_tester.eth.getCode(contract_address) + blockchain_code = web3.eth.getCode(contract_address) assert force_bytes(blockchain_code) == force_bytes(SIMPLE_CONSTRUCTOR_RUNTIME) -def test_contract_deployment_with_constructor_with_arguments(web3_tester, +def test_contract_deployment_with_constructor_with_arguments(web3, WithConstructorArgumentsContract, WITH_CONSTRUCTOR_ARGUMENTS_RUNTIME): deploy_txn = WithConstructorArgumentsContract.deploy(args=[1234, 'abcd']) - txn_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + txn_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert txn_receipt is not None assert txn_receipt['contractAddress'] contract_address = txn_receipt['contractAddress'] - blockchain_code = web3_tester.eth.getCode(contract_address) + blockchain_code = web3.eth.getCode(contract_address) assert force_bytes(blockchain_code) == force_bytes(WITH_CONSTRUCTOR_ARGUMENTS_RUNTIME) -def test_contract_deployment_with_constructor_with_address_argument(web3_tester, +def test_contract_deployment_with_constructor_with_address_argument(web3, WithConstructorAddressArgumentsContract, WITH_CONSTRUCTOR_ADDRESS_RUNTIME): deploy_txn = WithConstructorAddressArgumentsContract.deploy(args=["0x16d9983245de15e7a9a73bc586e01ff6e08de737"]) - txn_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + txn_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert txn_receipt is not None assert txn_receipt['contractAddress'] contract_address = txn_receipt['contractAddress'] - blockchain_code = web3_tester.eth.getCode(contract_address) + blockchain_code = web3.eth.getCode(contract_address) assert force_bytes(blockchain_code) == force_bytes(WITH_CONSTRUCTOR_ADDRESS_RUNTIME) diff --git a/tests/contracts/test_contract_method_abi_encoding.py b/tests/contracts/test_contract_method_abi_encoding.py index 95049c5..6e933ec 100644 --- a/tests/contracts/test_contract_method_abi_encoding.py +++ b/tests/contracts/test_contract_method_abi_encoding.py @@ -18,7 +18,7 @@ ABI_C = json.loads('[{"constant":false,"inputs":[],"name":"a","outputs":[],"type (ABI_C, 'a', ['a'], None, '0x6100000000000000000000000000000000000000000000000000000000000000'), ), ) -def test_contract_abi_encoding(web3_tester, abi, method, arguments, data, expected): - contract = web3_tester.eth.contract(abi) +def test_contract_abi_encoding(web3, abi, method, arguments, data, expected): + contract = web3.eth.contract(abi) actual = contract.encodeABI(method, arguments, data=data) assert actual == expected diff --git a/tests/contracts/test_contract_method_to_argument_matching.py b/tests/contracts/test_contract_method_to_argument_matching.py index a203288..c5626e7 100644 --- a/tests/contracts/test_contract_method_to_argument_matching.py +++ b/tests/contracts/test_contract_method_to_argument_matching.py @@ -11,16 +11,16 @@ SINGLE_FN_ONE_ARG = json.loads('[{"constant":false,"inputs":[{"name":"","type":" MULTIPLE_FUNCTIONS = json.loads('[{"constant":false,"inputs":[],"name":"a","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"","type":"bytes32"}],"name":"a","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"","type":"uint256"}],"name":"a","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"","type":"uint8"}],"name":"a","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"","type":"int8"}],"name":"a","outputs":[],"type":"function"}]') -def test_finds_single_function_without_args(web3_tester): - Contract = web3_tester.eth.contract(SINGLE_FN_NO_ARGS) +def test_finds_single_function_without_args(web3): + Contract = web3.eth.contract(SINGLE_FN_NO_ARGS) abi = Contract._find_matching_fn_abi('a', []) assert abi['name'] == 'a' assert abi['inputs'] == [] -def test_finds_single_function_with_args(web3_tester): - Contract = web3_tester.eth.contract(SINGLE_FN_ONE_ARG) +def test_finds_single_function_with_args(web3): + Contract = web3.eth.contract(SINGLE_FN_ONE_ARG) abi = Contract._find_matching_fn_abi('a', [1234]) assert abi['name'] == 'a' @@ -28,8 +28,8 @@ def test_finds_single_function_with_args(web3_tester): assert abi['inputs'][0]['type'] == 'uint256' -def test_error_when_no_function_name_match(web3_tester): - Contract = web3_tester.eth.contract(SINGLE_FN_NO_ARGS) +def test_error_when_no_function_name_match(web3): + Contract = web3.eth.contract(SINGLE_FN_NO_ARGS) with pytest.raises(ValueError): Contract._find_matching_fn_abi('no_function_name', [1234]) @@ -45,8 +45,8 @@ def test_error_when_no_function_name_match(web3_tester): #([-1], ['int8']), ) ) -def test_finds_function_with_matching_args(web3_tester, arguments, expected_types): - Contract = web3_tester.eth.contract(MULTIPLE_FUNCTIONS) +def test_finds_function_with_matching_args(web3, arguments, expected_types): + Contract = web3.eth.contract(MULTIPLE_FUNCTIONS) abi = Contract._find_matching_fn_abi('a', arguments) assert abi['name'] == 'a' @@ -54,8 +54,8 @@ def test_finds_function_with_matching_args(web3_tester, arguments, expected_type assert set(get_abi_input_types(abi)) == set(expected_types) -def test_error_when_duplicate_match(web3_tester): - Contract = web3_tester.eth.contract(MULTIPLE_FUNCTIONS) +def test_error_when_duplicate_match(web3): + Contract = web3.eth.contract(MULTIPLE_FUNCTIONS) with pytest.raises(ValueError): abi = Contract._find_matching_fn_abi('a', [100]) diff --git a/tests/contracts/test_contract_transact_interface.py b/tests/contracts/test_contract_transact_interface.py index 5c0d573..83a4081 100644 --- a/tests/contracts/test_contract_transact_interface.py +++ b/tests/contracts/test_contract_transact_interface.py @@ -12,28 +12,28 @@ from web3.utils.string import ( @pytest.fixture() -def math_contract(web3_tester, MathContract): +def math_contract(web3, MathContract): deploy_txn = MathContract.deploy() - deploy_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + deploy_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert deploy_receipt is not None _math_contract = MathContract(address=deploy_receipt['contractAddress']) return _math_contract @pytest.fixture() -def string_contract(web3_tester, StringContract): +def string_contract(web3, StringContract): deploy_txn = StringContract.deploy(args=["Caqalai"]) - deploy_receipt = web3_tester.eth.getTransactionReceipt(deploy_txn) + deploy_receipt = web3.eth.getTransactionReceipt(deploy_txn) assert deploy_receipt is not None _math_contract = StringContract(address=deploy_receipt['contractAddress']) return _math_contract -def test_transacting_with_contract_no_arguments(web3_tester, math_contract): +def test_transacting_with_contract_no_arguments(web3, math_contract): initial_value = math_contract.call().counter() txn_hash = math_contract.transact().increment() - txn_receipt = web3_tester.eth.getTransactionReceipt(txn_hash) + txn_receipt = web3.eth.getTransactionReceipt(txn_hash) assert txn_receipt is not None final_value = math_contract.call().counter() @@ -48,14 +48,14 @@ def test_transacting_with_contract_no_arguments(web3_tester, math_contract): (tuple(), {'amt': 5}), ), ) -def test_transacting_with_contract_with_arguments(web3_tester, +def test_transacting_with_contract_with_arguments(web3, math_contract, transact_args, transact_kwargs): initial_value = math_contract.call().counter() txn_hash = math_contract.transact().increment(*transact_args, **transact_kwargs) - txn_receipt = web3_tester.eth.getTransactionReceipt(txn_hash) + txn_receipt = web3.eth.getTransactionReceipt(txn_hash) assert txn_receipt is not None final_value = math_contract.call().counter() @@ -63,37 +63,37 @@ def test_transacting_with_contract_with_arguments(web3_tester, assert final_value - initial_value == 5 -def test_deploy_when_default_account_is_different_than_coinbase(web3_tester, +def test_deploy_when_default_account_is_different_than_coinbase(web3, wait_for_transaction, STRING_CONTRACT): - web3_tester.eth.defaultAccount = web3_tester.eth.accounts[1] - assert web3_tester.eth.defaultAccount != web3_tester.eth.coinbase + web3.eth.defaultAccount = web3.eth.accounts[1] + assert web3.eth.defaultAccount != web3.eth.coinbase - StringContract = web3_tester.eth.contract(**STRING_CONTRACT) + StringContract = web3.eth.contract(**STRING_CONTRACT) deploy_txn = StringContract.deploy(args=["Caqalai"]) - wait_for_transaction(web3_tester, deploy_txn) - txn_after = web3_tester.eth.getTransaction(deploy_txn) - assert txn_after['from'] == web3_tester.eth.defaultAccount + wait_for_transaction(web3, deploy_txn) + txn_after = web3.eth.getTransaction(deploy_txn) + assert txn_after['from'] == web3.eth.defaultAccount -def test_transact_when_default_account_is_different_than_coinbase(web3_tester, +def test_transact_when_default_account_is_different_than_coinbase(web3, wait_for_transaction, math_contract): - web3_tester.eth.defaultAccount = web3_tester.eth.accounts[1] - assert web3_tester.eth.defaultAccount != web3_tester.eth.coinbase + web3.eth.defaultAccount = web3.eth.accounts[1] + assert web3.eth.defaultAccount != web3.eth.coinbase txn_hash = math_contract.transact().increment() - wait_for_transaction(web3_tester, txn_hash) - txn_after = web3_tester.eth.getTransaction(txn_hash) - assert txn_after['from'] == web3_tester.eth.defaultAccount + wait_for_transaction(web3, txn_hash) + txn_after = web3.eth.getTransaction(txn_hash) + assert txn_after['from'] == web3.eth.defaultAccount -def test_transacting_with_contract_with_string_argument(web3_tester, string_contract): +def test_transacting_with_contract_with_string_argument(web3, string_contract): # eth_abi will pass as raw bytes, no encoding # unless we encode ourselves txn_hash = string_contract.transact().setValue(force_bytes("ÄLÄMÖLÖ")) - txn_receipt = web3_tester.eth.getTransactionReceipt(txn_hash) + txn_receipt = web3.eth.getTransactionReceipt(txn_hash) assert txn_receipt is not None final_value = string_contract.call().getValue() diff --git a/tests/contracts/test_extracting_event_data.py b/tests/contracts/test_extracting_event_data.py index 5737ab6..227f56a 100644 --- a/tests/contracts/test_extracting_event_data.py +++ b/tests/contracts/test_extracting_event_data.py @@ -6,15 +6,12 @@ from web3.utils.events import ( @pytest.fixture() -def Emitter(web3_tester_persistent, EMITTER): - web3 = web3_tester_persistent +def Emitter(web3, EMITTER): return web3.eth.contract(**EMITTER) @pytest.fixture() -def emitter(web3_tester_persistent, Emitter, wait_for_transaction, wait_for_block): - web3 = web3_tester_persistent - +def emitter(web3, Emitter, wait_for_transaction, wait_for_block): wait_for_block(web3) deploy_txn_hash = Emitter.deploy({'from': web3.eth.coinbase, 'gas': 1000000}) deploy_receipt = wait_for_transaction(web3, deploy_txn_hash) @@ -42,7 +39,7 @@ def emitter(web3_tester_persistent, Emitter, wait_for_transaction, wait_for_bloc ('logQuadruple', 'LogQuadrupleWithIndex', [12345, 54321, 98765, 56789], {'arg0': 12345, 'arg1': 54321, 'arg2': 98765, 'arg3': 56789}), ) ) -def test_event_data_extraction(web3_tester_persistent, +def test_event_data_extraction(web3, emitter, wait_for_transaction, emitter_log_topics, @@ -51,8 +48,6 @@ def test_event_data_extraction(web3_tester_persistent, event_name, call_args, expected_args): - web3 = web3_tester_persistent - transact_fn = getattr(emitter.transact(), contract_fn) event_id = getattr(emitter_event_ids, event_name) txn_hash = transact_fn(event_id, *call_args) diff --git a/tests/eth-module/test_eth_mining.py b/tests/eth-module/test_eth_mining.py index 210d33d..cd4f831 100644 --- a/tests/eth-module/test_eth_mining.py +++ b/tests/eth-module/test_eth_mining.py @@ -1,13 +1,8 @@ -def test_mining_property_tester(web3_tester): - web3 = web3_tester - +def test_mining_property_tester(web3): assert web3.eth.mining is False -def test_mining_property_ipc_and_rpc(web3_empty, wait_for_miner_start, - skip_if_testrpc): - web3 = web3_empty - +def test_mining_property_ipc_and_rpc(web3, wait_for_miner_start, skip_if_testrpc): skip_if_testrpc(web3) wait_for_miner_start(web3) diff --git a/tests/eth-module/test_eth_sendRawTransaction.py b/tests/eth-module/test_eth_sendRawTransaction.py index 0d52fd5..6e96551 100644 --- a/tests/eth-module/test_eth_sendRawTransaction.py +++ b/tests/eth-module/test_eth_sendRawTransaction.py @@ -9,8 +9,6 @@ from eth_tester_client.utils import ( encode_data, ) -from web3.providers.rpc import TestRPCProvider - def test_eth_sendRawTransaction(web3, wait_for_transaction, extra_accounts): private_key = mk_random_privkey() @@ -23,12 +21,11 @@ def test_eth_sendRawTransaction(web3, wait_for_transaction, extra_accounts): }) wait_for_transaction(web3, funding_txn_hash) - if isinstance(web3.currentProvider, TestRPCProvider): - # ethereum-tester-client doesn't quite implement the - # `sendRawTransaction` correctly because of how the underlying tester - # evm works. It needs to know about the address for this to work. - web3.personal.importRawKey(private_key, "password") - web3.personal.unlockAccount(address, "password") + # ethereum-tester-client doesn't quite implement the + # `sendRawTransaction` correctly because of how the underlying tester + # evm works. It needs to know about the address for this to work. + web3.personal.importRawKey(private_key, "password") + web3.personal.unlockAccount(address, "password") initial_balance = web3.eth.getBalance(extra_accounts[1]) diff --git a/tests/eth-module/test_eth_sign.py b/tests/eth-module/test_eth_sign.py index 3b26102..af74c0f 100644 --- a/tests/eth-module/test_eth_sign.py +++ b/tests/eth-module/test_eth_sign.py @@ -1,6 +1,5 @@ import pytest -from sha3 import sha3_256 from secp256k1 import PrivateKey, PublicKey, ALL_FLAGS from bitcoin import encode_pubkey @@ -8,6 +7,9 @@ from bitcoin import encode_pubkey from ethereum.utils import privtoaddr from web3.providers.rpc import TestRPCProvider +from web3.utils.crypto import ( + sha3 as _sha3, +) from web3.utils.string import ( force_bytes, force_text, @@ -29,7 +31,7 @@ from web3.utils.encoding import ( @coerce_return_to_bytes def sha3(s): - return add_0x_prefix(sha3_256(s).hexdigest()) + return add_0x_prefix(_sha3(s)) assert sha3(b'') == b'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' @@ -57,9 +59,7 @@ def extract_ecdsa_signer(msg_hash, signature): return address -def test_eth_sign(web3_empty, skip_if_testrpc): - web3 = web3_empty - +def test_eth_sign(web3, skip_if_testrpc): skip_if_testrpc(web3) private_key_hex = '0x5e95384d8050109aab08c1922d3c230739bc16976553c317e5d0b87b59371f2a' diff --git a/tests/eth-module/test_iban.py b/tests/eth-module/test_iban.py index ca8e49f..ca8505b 100644 --- a/tests/eth-module/test_iban.py +++ b/tests/eth-module/test_iban.py @@ -10,8 +10,8 @@ import pytest ), ) ) -def test_createIndirect(value, expected, web3_tester): - actual = web3_tester.eth.iban.createIndirect(value).toString() +def test_createIndirect(value, expected, web3): + actual = web3.eth.iban.createIndirect(value).toString() assert actual == expected @@ -40,8 +40,8 @@ def test_createIndirect(value, expected, web3_tester): ), ), ) -def test_fromAddress(value, expected, web3_tester): - actual = web3_tester.eth.iban.fromAddress(value).toString() +def test_fromAddress(value, expected, web3): + actual = web3.eth.iban.fromAddress(value).toString() assert actual == expected @@ -118,11 +118,11 @@ def test_fromAddress(value, expected, web3_tester): ), ), ) -def test_isValid(value, expected, web3_tester): - actual = web3_tester.eth.iban.isValid(value) +def test_isValid(value, expected, web3): + actual = web3.eth.iban.isValid(value) assert actual is expected - iban = web3_tester.eth.iban(value) + iban = web3.eth.iban(value) assert iban.isValid() is expected @@ -136,6 +136,6 @@ def test_isValid(value, expected, web3_tester): ), ) ) -def test_toAddress(value, expected, web3_tester): - actual = web3_tester.eth.iban(value).address() +def test_toAddress(value, expected, web3): + actual = web3.eth.iban(value).address() assert actual == expected diff --git a/tests/filtering/conftest.py b/tests/filtering/conftest.py index 38aaa06..5b6eab4 100644 --- a/tests/filtering/conftest.py +++ b/tests/filtering/conftest.py @@ -1,14 +1,15 @@ import pytest import json import textwrap -from sha3 import sha3_256 -assert sha3_256(b'').hexdigest() == 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' +from web3.utils.abi import ( + event_signature_to_log_topic, +) @pytest.fixture(autouse=True) -def wait_for_mining_start(web3_empty, wait_for_block): - wait_for_block(web3_empty) +def wait_for_mining_start(web3, wait_for_block): + wait_for_block(web3) CONTRACT_EMITTER_SOURCE = textwrap.dedent((""" @@ -130,15 +131,12 @@ def EMITTER(EMITTER_CODE, @pytest.fixture() -def Emitter(web3_empty, EMITTER): - web3 = web3_empty +def Emitter(web3, EMITTER): return web3.eth.contract(**EMITTER) @pytest.fixture() -def emitter(web3_empty, Emitter, wait_for_transaction, wait_for_block): - web3 = web3_empty - +def emitter(web3, Emitter, wait_for_transaction, wait_for_block): wait_for_block(web3) deploy_txn_hash = Emitter.deploy({'from': web3.eth.coinbase, 'gas': 1000000}) deploy_receipt = wait_for_transaction(web3, deploy_txn_hash) @@ -169,26 +167,21 @@ def emitter_event_ids(): return LogFunctions -def event_topic(event_signature): - from web3.utils.string import force_bytes - return force_bytes("0x" + sha3_256(force_bytes(event_signature)).hexdigest()) - - class LogTopics(object): - LogAnonymous = event_topic("LogAnonymous()") - LogNoArguments = event_topic("LogNoArguments()") - LogSingleArg = event_topic("LogSingleArg(uint256)") - LogSingleAnonymous = event_topic("LogSingleAnonymous(uint256)") - LogSingleWithIndex = event_topic("LogSingleWithIndex(uint256)") - LogDoubleArg = event_topic("LogDoubleArg(uint256,uint256)") - LogDoubleAnonymous = event_topic("LogDoubleAnonymous(uint256,uint256)") - LogDoubleWithIndex = event_topic("LogDoubleWithIndex(uint256,uint256)") - LogTripleArg = event_topic("LogTripleArg(uint256,uint256,uint256)") - LogTripleWithIndex = event_topic("LogTripleWithIndex(uint256,uint256,uint256)") - LogQuadrupleArg = event_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)") - LogQuadrupleWithIndex = event_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)") - LogBytes = event_topic("LogBytes(bytes)") - LogString = event_topic("LogString(string)") + LogAnonymous = event_signature_to_log_topic("LogAnonymous()") + LogNoArguments = event_signature_to_log_topic("LogNoArguments()") + LogSingleArg = event_signature_to_log_topic("LogSingleArg(uint256)") + LogSingleAnonymous = event_signature_to_log_topic("LogSingleAnonymous(uint256)") + LogSingleWithIndex = event_signature_to_log_topic("LogSingleWithIndex(uint256)") + LogDoubleArg = event_signature_to_log_topic("LogDoubleArg(uint256,uint256)") + LogDoubleAnonymous = event_signature_to_log_topic("LogDoubleAnonymous(uint256,uint256)") + LogDoubleWithIndex = event_signature_to_log_topic("LogDoubleWithIndex(uint256,uint256)") + LogTripleArg = event_signature_to_log_topic("LogTripleArg(uint256,uint256,uint256)") + LogTripleWithIndex = event_signature_to_log_topic("LogTripleWithIndex(uint256,uint256,uint256)") + LogQuadrupleArg = event_signature_to_log_topic("LogQuadrupleArg(uint256,uint256,uint256,uint256)") + LogQuadrupleWithIndex = event_signature_to_log_topic("LogQuadrupleWithIndex(uint256,uint256,uint256,uint256)") + LogBytes = event_signature_to_log_topic("LogBytes(bytes)") + LogString = event_signature_to_log_topic("LogString(string)") @pytest.fixture() diff --git a/tests/filtering/test_contract_on_event_filtering.py b/tests/filtering/test_contract_on_event_filtering.py index d5fde8a..8010675 100644 --- a/tests/filtering/test_contract_on_event_filtering.py +++ b/tests/filtering/test_contract_on_event_filtering.py @@ -1,20 +1,18 @@ import pytest -import random import gevent from flaky import flaky @flaky(max_runs=3) @pytest.mark.parametrize('call_as_instance', (True, False)) -def test_on_filter_using_get_interface(web3_empty, +def test_on_filter_using_get_interface(web3, + sleep_interval, emitter, Emitter, wait_for_transaction, emitter_log_topics, emitter_event_ids, call_as_instance): - web3 = web3_empty - if call_as_instance: filter = emitter.on('LogNoArguments', {}) else: @@ -25,7 +23,7 @@ def test_on_filter_using_get_interface(web3_empty, with gevent.Timeout(30): while not filter.get(False): - gevent.sleep(random.random()) + gevent.sleep(sleep_interval()) log_entries = filter.get() @@ -35,15 +33,14 @@ def test_on_filter_using_get_interface(web3_empty, @flaky(max_runs=3) @pytest.mark.parametrize('call_as_instance', (True, False)) -def test_on_filter_with_only_event_name(web3_empty, +def test_on_filter_with_only_event_name(web3, + sleep_interval, emitter, Emitter, wait_for_transaction, emitter_log_topics, emitter_event_ids, call_as_instance): - web3 = web3_empty - seen_logs = [] if call_as_instance: @@ -56,7 +53,7 @@ def test_on_filter_with_only_event_name(web3_empty, with gevent.Timeout(30): while not seen_logs: - gevent.sleep(random.random()) + gevent.sleep(sleep_interval()) filter.stop_watching(30) @@ -66,15 +63,14 @@ def test_on_filter_with_only_event_name(web3_empty, @flaky(max_runs=3) @pytest.mark.parametrize('call_as_instance', (True, False)) -def test_on_filter_with_event_name_and_single_argument(web3_empty, +def test_on_filter_with_event_name_and_single_argument(web3, + sleep_interval, emitter, Emitter, wait_for_transaction, emitter_log_topics, emitter_event_ids, call_as_instance): - web3 = web3_empty - seen_logs = [] if call_as_instance: @@ -101,7 +97,7 @@ def test_on_filter_with_event_name_and_single_argument(web3_empty, with gevent.Timeout(30): while len(seen_logs) < 2: - gevent.sleep(random.random()) + gevent.sleep(sleep_interval()) filter.stop_watching(30) @@ -111,15 +107,14 @@ def test_on_filter_with_event_name_and_single_argument(web3_empty, @flaky(max_runs=3) @pytest.mark.parametrize('call_as_instance', (True, False)) -def test_on_filter_with_event_name_and_non_indexed_argument(web3_empty, +def test_on_filter_with_event_name_and_non_indexed_argument(web3, + sleep_interval, emitter, Emitter, wait_for_transaction, emitter_log_topics, emitter_event_ids, call_as_instance): - web3 = web3_empty - seen_logs = [] if call_as_instance: @@ -146,7 +141,7 @@ def test_on_filter_with_event_name_and_non_indexed_argument(web3_empty, with gevent.Timeout(30): while not seen_logs: - gevent.sleep(random.random()) + gevent.sleep(sleep_interval()) filter.stop_watching(30) diff --git a/tests/filtering/test_contract_past_event_filtering.py b/tests/filtering/test_contract_past_event_filtering.py index fe02bbe..30c9a01 100644 --- a/tests/filtering/test_contract_past_event_filtering.py +++ b/tests/filtering/test_contract_past_event_filtering.py @@ -6,7 +6,8 @@ from flaky import flaky @flaky(max_runs=3) @pytest.mark.parametrize('call_as_instance', (True, False)) -def test_past_events_filter_with_callback(web3_empty, +def test_past_events_filter_with_callback(web3, + sleep_interval, emitter, Emitter, wait_for_transaction, @@ -14,8 +15,6 @@ def test_past_events_filter_with_callback(web3_empty, emitter_event_ids, LogTopics, call_as_instance): - web3 = web3_empty - txn_hash = emitter.transact().logNoArgs(emitter_event_ids.LogNoArguments) txn_receipt = wait_for_transaction(web3, txn_hash) @@ -28,7 +27,7 @@ def test_past_events_filter_with_callback(web3_empty, with gevent.Timeout(30): while not seen_logs: - gevent.sleep(random.random()) + gevent.sleep(sleep_interval()) filter.stop_watching(30) @@ -44,7 +43,8 @@ def test_past_events_filter_with_callback(web3_empty, @flaky(max_runs=3) @pytest.mark.parametrize('call_as_instance', (True, False)) -def test_past_events_filter_using_get_api(web3_empty, +def test_past_events_filter_using_get_api(web3, + sleep_interval, emitter, Emitter, wait_for_transaction, @@ -52,8 +52,6 @@ def test_past_events_filter_using_get_api(web3_empty, emitter_event_ids, LogTopics, call_as_instance): - web3 = web3_empty - txn_hash = emitter.transact().logNoArgs(emitter_event_ids.LogNoArguments) txn_receipt = wait_for_transaction(web3, txn_hash) @@ -64,7 +62,7 @@ def test_past_events_filter_using_get_api(web3_empty, with gevent.Timeout(30): while not filter.get(False): - gevent.sleep(random.random()) + gevent.sleep(sleep_interval()) log_entries = filter.get(False) diff --git a/tests/filtering/test_filter_against_latest_blocks.py b/tests/filtering/test_filter_against_latest_blocks.py index ace08d7..2be110b 100644 --- a/tests/filtering/test_filter_against_latest_blocks.py +++ b/tests/filtering/test_filter_against_latest_blocks.py @@ -4,8 +4,7 @@ from flaky import flaky @flaky(max_runs=3) -def test_filter_against_latest_blocks(web3_empty, wait_for_block, skip_if_testrpc): - web3 = web3_empty +def test_filter_against_latest_blocks(web3, sleep_interval, wait_for_block, skip_if_testrpc): skip_if_testrpc(web3) seen_blocks = [] @@ -18,7 +17,7 @@ def test_filter_against_latest_blocks(web3_empty, wait_for_block, skip_if_testrp with gevent.Timeout(5): while len(seen_blocks) < 2: - gevent.sleep(random.random()) + gevent.sleep(sleep_interval()) txn_filter.stop_watching(3) diff --git a/tests/managers/test_private_key_signing_manager.py b/tests/managers/test_private_key_signing_manager.py index f30cdd8..01d651d 100644 --- a/tests/managers/test_private_key_signing_manager.py +++ b/tests/managers/test_private_key_signing_manager.py @@ -5,6 +5,7 @@ from web3.providers.manager import ( ) from web3.utils.address import to_address from web3.utils.currency import denoms +from web3.utils.encoding import decode_hex @pytest.fixture() @@ -21,43 +22,52 @@ def account_public_key(account_private_key): @pytest.fixture() -def web3_pk_signer(web3_ipc_persistent, +def web3_pk_signer(web3, account_public_key, account_private_key, wait_for_block, wait_for_transaction): - pk_signing_manager = PrivateKeySigningManager(web3_ipc_persistent._requestManager) + pk_signing_manager = PrivateKeySigningManager(web3._requestManager) pk_signing_manager.register_private_key(account_private_key) assert account_public_key in pk_signing_manager.keys - wait_for_block(web3_ipc_persistent) + wait_for_block(web3) - fund_txn_hash = web3_ipc_persistent.eth.sendTransaction({ - 'from': web3_ipc_persistent.eth.coinbase, + fund_txn_hash = web3.eth.sendTransaction({ + 'from': web3.eth.coinbase, 'to': account_public_key, 'value': 10 * denoms.ether, }) - wait_for_transaction(web3_ipc_persistent, fund_txn_hash) + wait_for_transaction(web3, fund_txn_hash) + + web3._requestManager = pk_signing_manager + return web3 + + +def test_private_key_signing_manager(web3_pk_signer, + account_private_key, + account_public_key, + wait_for_transaction): + web3 = web3_pk_signer + assert account_public_key not in web3_pk_signer.eth.accounts with pytest.raises(ValueError): - web3_ipc_persistent.eth.sendTransaction({ + web3.eth.sendTransaction({ 'from': account_public_key, - 'to': web3_ipc_persistent.eth.coinbase, + 'to': web3.eth.coinbase, 'value': 1, }) - web3_ipc_persistent._requestManager = pk_signing_manager - return web3_ipc_persistent + from ethereum import tester + tester.keys.append(account_private_key) + tester.accounts.append(decode_hex(account_public_key)) - -def test_private_key_signing_manager(web3_pk_signer, account_public_key, wait_for_transaction): - assert account_public_key not in web3_pk_signer.eth.accounts - txn_hash = web3_pk_signer.eth.sendTransaction({ + txn_hash = web3.eth.sendTransaction({ 'from': account_public_key, - 'to': web3_pk_signer.eth.coinbase, - 'value': 12345, + 'to': web3.eth.coinbase, + 'value': 1, }) - txn_receipt = wait_for_transaction(web3_pk_signer, txn_hash) - txn = web3_pk_signer.eth.getTransaction(txn_hash) + txn_receipt = wait_for_transaction(web3, txn_hash) + txn = web3.eth.getTransaction(txn_hash) assert txn['from'] == account_public_key diff --git a/tests/mining-module/conftest.py b/tests/mining-module/conftest.py index 870f205..4cb950e 100644 --- a/tests/mining-module/conftest.py +++ b/tests/mining-module/conftest.py @@ -2,10 +2,9 @@ import pytest @pytest.fixture(autouse=True) -def always_wait_for_mining_start(web3_empty, wait_for_miner_start, +def always_wait_for_mining_start(web3, + wait_for_miner_start, skip_if_testrpc): - web3 = web3_empty - skip_if_testrpc(web3) wait_for_miner_start(web3) diff --git a/tests/personal-module/conftest.py b/tests/personal-module/conftest.py index cdc3122..dfba89e 100644 --- a/tests/personal-module/conftest.py +++ b/tests/personal-module/conftest.py @@ -20,15 +20,13 @@ def account_public_key(account_private_key): @pytest.fixture() -def password_account(web3_empty, +def password_account(web3, account_password, account_private_key, account_public_key, wait_for_transaction): from eth_tester_client.utils import normalize_address - web3 = web3_empty - address = web3.personal.importRawKey(account_private_key, account_password) # sanity check @@ -48,9 +46,7 @@ def password_account(web3_empty, @pytest.fixture() -def empty_account(web3_empty): - web3 = web3_empty - +def empty_account(web3): from eth_tester_client.utils import mk_random_privkey address = web3.personal.importRawKey(mk_random_privkey(), "a-password") diff --git a/tests/personal-module/test_personal_importRawKey.py b/tests/personal-module/test_personal_importRawKey.py index 37df8fc..8d35c9b 100644 --- a/tests/personal-module/test_personal_importRawKey.py +++ b/tests/personal-module/test_personal_importRawKey.py @@ -5,10 +5,8 @@ from eth_tester_client.utils import ( ) -def test_personal_importRawKey_as_bytes(web3_empty, account_private_key, +def test_personal_importRawKey_as_bytes(web3, account_private_key, account_password, account_public_key): - web3 = web3_empty - address = web3.personal.importRawKey(account_private_key, account_password) # sanity check @@ -17,11 +15,9 @@ def test_personal_importRawKey_as_bytes(web3_empty, account_private_key, assert web3.personal.unlockAccount(address, account_password) is True -def test_personal_importRawKey_as_hex_with_0x(web3_empty, account_private_key, +def test_personal_importRawKey_as_hex_with_0x(web3, account_private_key, account_password, account_public_key): - web3 = web3_empty - address = web3.personal.importRawKey(encode_32bytes(account_private_key), account_password) # sanity check @@ -30,12 +26,10 @@ def test_personal_importRawKey_as_hex_with_0x(web3_empty, account_private_key, assert web3.personal.unlockAccount(address, account_password) is True -def test_personal_importRawKey_as_hex_without_0x(web3_empty, +def test_personal_importRawKey_as_hex_without_0x(web3, account_private_key, account_password, account_public_key): - web3 = web3_empty - address = web3.personal.importRawKey(strip_0x(encode_32bytes(account_private_key)), account_password) # sanity check diff --git a/tests/personal-module/test_personal_lockAccount.py b/tests/personal-module/test_personal_lockAccount.py index 66be987..3fe9520 100644 --- a/tests/personal-module/test_personal_lockAccount.py +++ b/tests/personal-module/test_personal_lockAccount.py @@ -1,10 +1,8 @@ import pytest -def test_personal_lockAccount(web3_empty, password_account, account_password, +def test_personal_lockAccount(web3, password_account, account_password, wait_for_transaction, empty_account): - web3 = web3_empty - initial_balancee = web3.eth.getBalance(empty_account) assert web3.personal.unlockAccount(password_account, account_password) is True diff --git a/tests/personal-module/test_personal_signAndSendTransaction.py b/tests/personal-module/test_personal_signAndSendTransaction.py index 1db7c91..0a1c101 100644 --- a/tests/personal-module/test_personal_signAndSendTransaction.py +++ b/tests/personal-module/test_personal_signAndSendTransaction.py @@ -1,9 +1,7 @@ -def test_personal_signAndSendTransaction(web3_empty, password_account, +def test_personal_signAndSendTransaction(web3, password_account, account_password, wait_for_transaction, empty_account): - web3 = web3_empty - txn_hash = web3.personal.signAndSendTransaction({ 'from': password_account, 'to': empty_account, diff --git a/tests/personal-module/test_personal_unlockAccount.py b/tests/personal-module/test_personal_unlockAccount.py index 6aace2f..4bbe0d2 100644 --- a/tests/personal-module/test_personal_unlockAccount.py +++ b/tests/personal-module/test_personal_unlockAccount.py @@ -2,14 +2,12 @@ import pytest @pytest.fixture(autouse=True) -def wait_for_first_block(web3_empty, wait_for_block): - wait_for_block(web3_empty) +def wait_for_first_block(web3, wait_for_block): + wait_for_block(web3) -def test_personal_unlockAccount(web3_empty, password_account, account_password, +def test_personal_unlockAccount(web3, password_account, account_password, wait_for_transaction, empty_account): - web3 = web3_empty - initial_balancee = web3.eth.getBalance(empty_account) with pytest.raises(ValueError): diff --git a/tests/providers/test_tester_provider.py b/tests/providers/test_tester_provider.py index 0f74c50..8a4e2b8 100644 --- a/tests/providers/test_tester_provider.py +++ b/tests/providers/test_tester_provider.py @@ -1,28 +1,18 @@ import pytest -from gevent import socket from web3.providers.manager import RequestManager -from web3.providers.rpc import ( - TestRPCProvider, +from web3.providers.tester import ( + EthereumTesterProvider, is_testrpc_available, ) -def get_open_port(): - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.bind(("", 0)) - s.listen(1) - port = s.getsockname()[1] - s.close() - return port - - @pytest.mark.skipif(not is_testrpc_available, reason="`eth-testrpc` is not installed") def test_making_provider_request(): - from testrpc.testrpc import web3_clientVersion - provider = TestRPCProvider(port=get_open_port()) + from testrpc.rpc import RPCMethods + provider = EthereumTesterProvider() rm = RequestManager(provider) response = rm.request_blocking(method="web3_clientVersion", params=[]) - assert response == web3_clientVersion() + assert response == RPCMethods.web3_clientVersion() diff --git a/tests/providers/test_testrpc_provider.py b/tests/providers/test_testrpc_provider.py new file mode 100644 index 0000000..c08b3b2 --- /dev/null +++ b/tests/providers/test_testrpc_provider.py @@ -0,0 +1,28 @@ +import pytest +from gevent import socket + +from web3.providers.manager import RequestManager +from web3.providers.rpc import ( + TestRPCProvider, + is_testrpc_available, +) + + +def get_open_port(): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 0)) + s.listen(1) + port = s.getsockname()[1] + s.close() + return port + + +@pytest.mark.skipif(not is_testrpc_available, reason="`eth-testrpc` is not installed") +def test_making_provider_request(): + from testrpc.rpc import RPCMethods + provider = TestRPCProvider(port=get_open_port()) + rm = RequestManager(provider) + + response = rm.request_blocking(method="web3_clientVersion", params=[]) + + assert response == RPCMethods.web3_clientVersion() diff --git a/tests/txpool-module/conftest.py b/tests/txpool-module/conftest.py index 62a12c6..264d98a 100644 --- a/tests/txpool-module/conftest.py +++ b/tests/txpool-module/conftest.py @@ -2,11 +2,9 @@ import pytest @pytest.fixture(autouse=True) -def skip_testrpc_and_wait_for_mining_start(web3_empty, +def skip_testrpc_and_wait_for_mining_start(web3, wait_for_miner_start, skip_if_testrpc): - web3 = web3_empty - skip_if_testrpc(web3) wait_for_miner_start(web3) diff --git a/tests/utilities/test_formatter.py b/tests/utilities/test_formatter.py index f1edceb..c196540 100644 --- a/tests/utilities/test_formatter.py +++ b/tests/utilities/test_formatter.py @@ -137,8 +137,8 @@ def test_inputPostFormatter(value, expected): } )] ) -def test_input_transaction_formatter(web3_tester, value, expected): - assert formatters.input_transaction_formatter(web3_tester.eth, value) == expected +def test_input_transaction_formatter(web3, value, expected): + assert formatters.input_transaction_formatter(web3.eth, value) == expected @pytest.mark.parametrize( diff --git a/web3/__init__.py b/web3/__init__.py index 622f1b7..a407ca2 100644 --- a/web3/__init__.py +++ b/web3/__init__.py @@ -2,7 +2,6 @@ from __future__ import absolute_import import pkg_resources - from web3.main import Web3 from web3.providers.rpc import ( RPCProvider, diff --git a/web3/eth.py b/web3/eth.py index 2d6b4fa..e905fce 100644 --- a/web3/eth.py +++ b/web3/eth.py @@ -9,6 +9,9 @@ from web3.utils.types import ( is_integer, is_string, ) +from web3.utils.string import ( + coerce_return_to_text, +) from web3.utils.functional import ( apply_formatters_to_return, ) @@ -35,6 +38,7 @@ class Eth(object): _defaultAccount = None @property + @coerce_return_to_text def defaultAccount(self): if self._defaultAccount is not None: return self._defaultAccount @@ -64,9 +68,11 @@ class Eth(object): raise NotImplementedError("Async calling has not been implemented") @property + @coerce_return_to_text def coinbase(self): return self.web3._requestManager.request_blocking("eth_coinbase", []) + @coerce_return_to_text def getCoinbase(self): raise NotImplementedError("Async calling has not been implemented") @@ -94,6 +100,7 @@ class Eth(object): raise NotImplementedError("Async calling has not been implemented") @property + @coerce_return_to_text def accounts(self): return self.web3._requestManager.request_blocking("eth_accounts", []) @@ -132,6 +139,7 @@ class Eth(object): ], ) + @coerce_return_to_text def getCode(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock @@ -228,6 +236,7 @@ class Eth(object): ], ) + @coerce_return_to_text def sendTransaction(self, transaction): formatted_transaction = formatters.input_transaction_formatter(self, transaction) if 'gas' not in formatted_transaction and 'data' in formatted_transaction: @@ -243,12 +252,14 @@ class Eth(object): [formatters.input_transaction_formatter(self, formatted_transaction)], ) + @coerce_return_to_text def sendRawTransaction(self, raw_transaction): return self.web3._requestManager.request_blocking( "eth_sendRawTransaction", [raw_transaction], ) + @coerce_return_to_text def sign(self, account, data): data_hash = self.web3._requestManager.request_blocking( "web3_sha3", [encode_hex(data)], diff --git a/web3/iban.py b/web3/iban.py index 6596b56..e9c478e 100644 --- a/web3/iban.py +++ b/web3/iban.py @@ -5,6 +5,9 @@ import functools from web3.utils.types import ( is_string, ) +from web3.utils.string import ( + coerce_args_to_text, +) from web3.utils.formatting import ( pad_left, add_0x_prefix, @@ -86,6 +89,7 @@ class IsValid(object): return functools.partial(self.validate, instance._iban) @staticmethod + @coerce_args_to_text def validate(iban_address): if not is_string(iban_address): return False diff --git a/web3/main.py b/web3/main.py index ad0d83a..a73b3de 100644 --- a/web3/main.py +++ b/web3/main.py @@ -29,6 +29,7 @@ from web3.utils.functional import ( ) from web3.utils.string import ( force_text, + coerce_return_to_text, ) from web3.utils.encoding import ( to_hex, @@ -104,6 +105,7 @@ class Web3(object): def currentProvider(self): return self._requestManager.provider + @coerce_return_to_text def sha3(self, value, encoding="hex"): if encoding == 'hex': hex_string = value diff --git a/web3/personal.py b/web3/personal.py index eb84873..1abad23 100644 --- a/web3/personal.py +++ b/web3/personal.py @@ -1,6 +1,9 @@ from __future__ import absolute_import import getpass +from web3.utils.string import ( + coerce_return_to_text, +) from web3.utils.encoding import ( remove_0x_prefix, encode_hex, @@ -14,6 +17,7 @@ class Personal(object): def __init__(self, web3): self.web3 = web3 + @coerce_return_to_text def importRawKey(self, private_key, passphrase): if len(private_key) == 66: private_key = remove_0x_prefix(private_key) @@ -28,6 +32,7 @@ class Personal(object): [private_key, passphrase], ) + @coerce_return_to_text def newAccount(self, password=None): if password is None: password1 = getpass.getpass("Passphrase:") @@ -45,14 +50,17 @@ class Personal(object): ) @property + @coerce_return_to_text def listAccounts(self): return self.web3._requestManager.request_blocking( "personal_listAccounts", [], ) + @coerce_return_to_text def getListAccounts(self, *args, **kwargs): raise NotImplementedError("Async calling has not been implemented") + @coerce_return_to_text def signAndSendTransaction(self, transaction, passphrase): return self.web3._requestManager.request_blocking( # "personal_sendTransaction", diff --git a/web3/providers/base.py b/web3/providers/base.py index 4ff3a44..ad72002 100644 --- a/web3/providers/base.py +++ b/web3/providers/base.py @@ -11,12 +11,17 @@ from web3.utils.string import ( class BaseProvider(object): - def __init__(self): - self.request_counter = itertools.count() - def make_request(self, method, params): raise NotImplementedError("Providers must implement this method") + def isConnected(self): + raise NotImplementedError("Providers must implement this method") + + +class JSONBaseProvider(BaseProvider): + def __init__(self): + self.request_counter = itertools.count() + def encode_rpc_request(self, method, params): return force_bytes(json.dumps(force_obj_to_text({ "jsonrpc": "2.0", diff --git a/web3/providers/ipc.py b/web3/providers/ipc.py index 8e3e1a8..b3009a8 100644 --- a/web3/providers/ipc.py +++ b/web3/providers/ipc.py @@ -18,7 +18,7 @@ from web3.utils.string import ( force_text, ) -from .base import BaseProvider +from .base import JSONBaseProvider @contextlib.contextmanager @@ -67,7 +67,7 @@ def get_default_ipc_path(testnet=False): ) -class IPCProvider(BaseProvider): +class IPCProvider(JSONBaseProvider): def __init__(self, ipc_path=None, testnet=False, *args, **kwargs): if ipc_path is None: self.ipc_path = get_default_ipc_path(testnet) diff --git a/web3/providers/manager.py b/web3/providers/manager.py index 01b4ac6..4203c35 100644 --- a/web3/providers/manager.py +++ b/web3/providers/manager.py @@ -9,6 +9,10 @@ import rlp from web3.utils.crypto import sha3 from web3.utils.string import force_text from web3.utils.address import to_address +from web3.utils.types import ( + is_string, + is_object, +) from web3.utils.encoding import ( to_decimal, encode_hex, @@ -36,7 +40,10 @@ class RequestManager(object): """ response_raw = self.provider.make_request(method, params) - response = json.loads(force_text(response_raw)) + if is_string(response_raw): + response = json.loads(force_text(response_raw)) + elif is_object(response_raw): + response = response_raw if "error" in response: raise ValueError(response["error"]) diff --git a/web3/providers/rpc.py b/web3/providers/rpc.py index a339efc..7fd8d4c 100644 --- a/web3/providers/rpc.py +++ b/web3/providers/rpc.py @@ -5,13 +5,13 @@ import logging import pylru -from .base import BaseProvider # noqa: E402 +from .base import JSONBaseProvider # noqa: E402 logger = logging.getLogger(__name__) -class RPCProvider(BaseProvider): +class RPCProvider(JSONBaseProvider): """Create a RPC client. .. note :: @@ -78,7 +78,7 @@ class RPCProvider(BaseProvider): _client_cache = pylru.lrucache(128) -class KeepAliveRPCProvider(BaseProvider): +class KeepAliveRPCProvider(JSONBaseProvider): """RPC-provider that handles HTTP keep-alive connection correctly. HTTP client is recycled across requests. Create only one instance of diff --git a/web3/providers/tester.py b/web3/providers/tester.py new file mode 100644 index 0000000..f0542b0 --- /dev/null +++ b/web3/providers/tester.py @@ -0,0 +1,49 @@ +import logging + +from testrpc.rpc import RPCMethods + +from .base import BaseProvider # noqa: E402 + + +logger = logging.getLogger(__name__) + + +def is_testrpc_available(): + try: + import testrpc # noqa: F401 + return True + except ImportError: + return False + + +class EthereumTesterProvider(BaseProvider): + def __init__(self, + *args, + **kwargs): + """Create a new RPC client. + + :param connection_timeout: See :class:`geventhttpclient.HTTPClient` + + :param network_timeout: See :class:`geventhttpclient.HTTPClient` + """ + if not is_testrpc_available(): + raise Exception("`TestRPCProvider` requires the `eth-testrpc` package to be installed") + self.rpc_methods = RPCMethods() + super(BaseProvider, self).__init__(*args, **kwargs) + + def __str__(self): + return "EthereumTesterProvider" + + def __repr__(self): + return self.__str__() + + def make_request(self, method, params): + rpc_fn = getattr(self.rpc_methods, method) + response = rpc_fn(*params) + + return { + 'result': response, + } + + def isConnected(self): + return True diff --git a/web3/utils/abi.py b/web3/utils/abi.py index 705a1d1..9637112 100644 --- a/web3/utils/abi.py +++ b/web3/utils/abi.py @@ -285,14 +285,22 @@ def abi_to_signature(abi): return function_signature +def function_signature_to_4byte_selector(event_signature): + return add_0x_prefix(sha3(event_signature)[:8]) + + def function_abi_to_4byte_selector(function_abi): function_signature = abi_to_signature(function_abi) - return add_0x_prefix(sha3(function_signature)[:8]) + return function_signature_to_4byte_selector(function_signature) + + +def event_signature_to_log_topic(event_signature): + return add_0x_prefix(sha3(event_signature)) def event_abi_to_log_topic(event_abi): event_signature = abi_to_signature(event_abi) - return add_0x_prefix(sha3(event_signature)) + return event_signature_to_log_topic(event_signature) @coerce_return_to_text diff --git a/web3/utils/crypto.py b/web3/utils/crypto.py index 38b6137..41ca0d9 100644 --- a/web3/utils/crypto.py +++ b/web3/utils/crypto.py @@ -2,7 +2,10 @@ from __future__ import absolute_import import codecs -from sha3 import sha3_256 +try: + from sha3 import keccak_256 +except ImportError: + from sha3 import sha3_256 as keccak_256 def sha3(value, encoding=None): @@ -16,7 +19,7 @@ def sha3(value, encoding=None): if encoding: value = codecs.decode(remove_0x_prefix(value), encoding) - return sha3_256(force_bytes(value)).hexdigest() + return keccak_256(force_bytes(value)).hexdigest() # ensure we have the *right* sha3 installed