Speed up test runs

This commit is contained in:
Piper Merriam 2016-12-27 17:10:41 -07:00
parent f0deb65ff1
commit 29c3b58c4d
43 changed files with 379 additions and 472 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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",

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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])

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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])

View File

@ -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'

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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):

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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(

View File

@ -2,7 +2,6 @@ from __future__ import absolute_import
import pkg_resources
from web3.main import Web3
from web3.providers.rpc import (
RPCProvider,

View File

@ -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)],

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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",

View File

@ -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)

View File

@ -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"])

View File

@ -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

49
web3/providers/tester.py Normal file
View File

@ -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

View File

@ -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

View File

@ -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