From dee60bb228df5c15fe068b1e3a46622c23f187ce Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Fri, 7 Dec 2018 14:06:45 +0200 Subject: [PATCH 1/3] Add better ValidationError for supplying incorrect from on transaction sending. --- eth_tester/backends/pyevm/main.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/eth_tester/backends/pyevm/main.py b/eth_tester/backends/pyevm/main.py index d8306daf..51ccb7c4 100644 --- a/eth_tester/backends/pyevm/main.py +++ b/eth_tester/backends/pyevm/main.py @@ -35,10 +35,12 @@ FORK_BYZANTIUM, ) from eth_tester.exceptions import ( + BackendDistributionNotFound, BlockNotFound, - TransactionNotFound, TransactionFailed, - BackendDistributionNotFound, + TransactionNotFound, + UnknownFork, + ValidationError, ) from eth_tester.utils.formatting import ( @@ -471,6 +473,8 @@ def _get_normalized_and_unsigned_evm_transaction(self, transaction, block_number return evm_transaction def _get_normalized_and_signed_evm_transaction(self, transaction, block_number='latest'): + if transaction['from'] not in self._key_lookup: + raise ValidationError('"from" key not available, does this account exist?') signing_key = self._key_lookup[transaction['from']] normalized_transaction = self._normalize_transaction(transaction, block_number) evm_transaction = self.chain.create_unsigned_transaction(**normalized_transaction) From e89fb45943ebf3f3d837c186d43b31b1de5cca32 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Fri, 7 Dec 2018 14:15:54 +0200 Subject: [PATCH 2/3] Test for invalid from account on transaction sending. --- eth_tester/backends/pyevm/main.py | 1 - tests/backends/test_pyevm.py | 101 ++++++++++++++++++------------ 2 files changed, 60 insertions(+), 42 deletions(-) diff --git a/eth_tester/backends/pyevm/main.py b/eth_tester/backends/pyevm/main.py index 51ccb7c4..827b71f6 100644 --- a/eth_tester/backends/pyevm/main.py +++ b/eth_tester/backends/pyevm/main.py @@ -39,7 +39,6 @@ BlockNotFound, TransactionFailed, TransactionNotFound, - UnknownFork, ValidationError, ) diff --git a/tests/backends/test_pyevm.py b/tests/backends/test_pyevm.py index ab23e22a..18f046b3 100644 --- a/tests/backends/test_pyevm.py +++ b/tests/backends/test_pyevm.py @@ -3,21 +3,18 @@ import pytest from eth_utils import to_wei -from eth_tester import ( - EthereumTester, - PyEVMBackend, -) +from eth_tester import EthereumTester, PyEVMBackend from eth_tester.backends.pyevm.main import ( generate_genesis_state_for_keys, get_default_account_keys, - get_default_genesis_params -) -from eth_tester.backends.pyevm.utils import ( - is_pyevm_available, -) -from eth_tester.utils.backend_testing import ( - BaseTestBackendDirect, + get_default_genesis_params, ) +from eth_tester.backends.pyevm.utils import is_pyevm_available +from eth_tester.exceptions import ValidationError +from eth_tester.utils.backend_testing import BaseTestBackendDirect, SIMPLE_TRANSACTION + + +ZERO_ADDRESS_HEX = "0x0000000000000000000000000000000000000000" @pytest.fixture @@ -29,10 +26,9 @@ def eth_tester(): class TestPyEVMBackendDirect(BaseTestBackendDirect): - def test_generate_custom_genesis_state(self): - state_overrides = {'balance': to_wei(900000, 'ether')} - invalid_overrides = {'gato': 'con botas'} + state_overrides = {"balance": to_wei(900000, "ether")} + invalid_overrides = {"gato": "con botas"} # Test creating a specific number of accounts account_keys = get_default_account_keys(quantity=2) @@ -41,35 +37,43 @@ def test_generate_custom_genesis_state(self): assert len(account_keys) == 10 # Test the underlying state merging functionality - genesis_state = generate_genesis_state_for_keys(account_keys=account_keys, overrides=state_overrides) + genesis_state = generate_genesis_state_for_keys( + account_keys=account_keys, overrides=state_overrides + ) assert len(genesis_state) == len(account_keys) == 10 for _public_address, account_state in genesis_state.items(): - assert account_state['balance'] == state_overrides['balance'] - assert account_state['code'] == b'' + assert account_state["balance"] == state_overrides["balance"] + assert account_state["code"] == b"" # Only existing default genesis state keys can be overridden with pytest.raises(ValueError): - _invalid_genesis_state = generate_genesis_state_for_keys(account_keys=account_keys, - overrides=invalid_overrides) + _invalid_genesis_state = generate_genesis_state_for_keys( + account_keys=account_keys, overrides=invalid_overrides + ) # Use staticmethod state overriding - genesis_state = PyEVMBackend._generate_genesis_state(overrides=state_overrides, num_accounts=3) + genesis_state = PyEVMBackend._generate_genesis_state( + overrides=state_overrides, num_accounts=3 + ) assert len(genesis_state) == 3 for _public_address, account_state in genesis_state.items(): - assert account_state['balance'] == state_overrides['balance'] - assert account_state['code'] == b'' + assert account_state["balance"] == state_overrides["balance"] + assert account_state["code"] == b"" # Only existing default genesis state keys can be overridden with pytest.raises(ValueError): - _invalid_genesis_state = PyEVMBackend._generate_genesis_state(overrides=invalid_overrides) + _invalid_genesis_state = PyEVMBackend._generate_genesis_state( + overrides=invalid_overrides + ) def test_override_genesis_state(self): - state_overrides = {'balance': to_wei(900000, 'ether')} + state_overrides = {"balance": to_wei(900000, "ether")} test_accounts = 3 # Initialize PyEVM backend with custom genesis state - genesis_state = PyEVMBackend._generate_genesis_state(overrides=state_overrides, - num_accounts=test_accounts) + genesis_state = PyEVMBackend._generate_genesis_state( + overrides=state_overrides, num_accounts=test_accounts + ) # Test the correct number of accounts are created with the specified balance override pyevm_backend = PyEVMBackend(genesis_state=genesis_state) @@ -77,52 +81,67 @@ def test_override_genesis_state(self): for private_key in pyevm_backend.account_keys: account = private_key.public_key.to_canonical_address() balance = pyevm_backend.get_balance(account=account) - assert balance == state_overrides['balance'] + assert balance == state_overrides["balance"] # Test integration with EthereumTester tester = EthereumTester(backend=pyevm_backend) for private_key in pyevm_backend.account_keys: account = private_key.public_key.to_checksum_address() balance = tester.get_balance(account=account) - assert balance == state_overrides['balance'] + assert balance == state_overrides["balance"] def test_generate_custom_genesis_parameters(self): # Establish parameter overrides, for example a custom genesis gas limit - param_overrides = {'gas_limit': 4750000} + param_overrides = {"gas_limit": 4750000} # Test the underlying default parameter merging functionality genesis_params = get_default_genesis_params(overrides=param_overrides) - assert genesis_params['block_number'] == 0 - assert genesis_params['gas_limit'] == param_overrides['gas_limit'] + assert genesis_params["block_number"] == 0 + assert genesis_params["gas_limit"] == param_overrides["gas_limit"] # Use the the staticmethod to generate custom genesis parameters genesis_params = PyEVMBackend._generate_genesis_params(param_overrides) - assert genesis_params['block_number'] == 0 - assert genesis_params['gas_limit'] == param_overrides['gas_limit'] + assert genesis_params["block_number"] == 0 + assert genesis_params["gas_limit"] == param_overrides["gas_limit"] # Only existing default genesis parameter keys can be overridden - invalid_overrides = {'gato': 'con botas'} + invalid_overrides = {"gato": "con botas"} with pytest.raises(ValueError): - _invalid_genesis_params = PyEVMBackend._generate_genesis_params(overrides=invalid_overrides) + _invalid_genesis_params = PyEVMBackend._generate_genesis_params( + overrides=invalid_overrides + ) def test_override_genesis_parameters(self): # Establish a custom gas limit - param_overrides = {'gas_limit': 4750000} + param_overrides = {"gas_limit": 4750000} block_one_gas_limit = 4745362 # Initialize PyEVM backend with custom genesis parameters - genesis_params = PyEVMBackend._generate_genesis_params(overrides=param_overrides) + genesis_params = PyEVMBackend._generate_genesis_params( + overrides=param_overrides + ) pyevm_backend = PyEVMBackend(genesis_parameters=genesis_params) genesis_block = pyevm_backend.get_block_by_number(0) - assert genesis_block['gas_limit'] == param_overrides['gas_limit'] + assert genesis_block["gas_limit"] == param_overrides["gas_limit"] genesis_block = pyevm_backend.get_block_by_number(1) - assert genesis_block['gas_limit'] == block_one_gas_limit + assert genesis_block["gas_limit"] == block_one_gas_limit # Integrate with EthereumTester tester = EthereumTester(backend=pyevm_backend) genesis_block = tester.get_block_by_number(0) - assert genesis_block['gas_limit'] == param_overrides['gas_limit'] + assert genesis_block["gas_limit"] == param_overrides["gas_limit"] genesis_block = tester.get_block_by_number(1) - assert genesis_block['gas_limit'] == block_one_gas_limit + assert genesis_block["gas_limit"] == block_one_gas_limit + + def test_send_transaction_invalid_from(self, eth_tester): + accounts = eth_tester.get_accounts() + assert accounts, "No accounts available for transaction sending" + + with pytest.raises(ValidationError) as excinfo: + self._send_and_check_transaction( + eth_tester, SIMPLE_TRANSACTION, ZERO_ADDRESS_HEX + ) + + assert "does this account exist?" in str(excinfo.value) From b9a29063a2a6ca1a13da5f4823ecedeece651949 Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Tue, 11 Dec 2018 01:09:38 +0200 Subject: [PATCH 3/3] Minor cleanup. --- eth_tester/backends/pyevm/main.py | 5 ++++- tests/backends/test_pyevm.py | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/eth_tester/backends/pyevm/main.py b/eth_tester/backends/pyevm/main.py index 827b71f6..dd332285 100644 --- a/eth_tester/backends/pyevm/main.py +++ b/eth_tester/backends/pyevm/main.py @@ -473,7 +473,10 @@ def _get_normalized_and_unsigned_evm_transaction(self, transaction, block_number def _get_normalized_and_signed_evm_transaction(self, transaction, block_number='latest'): if transaction['from'] not in self._key_lookup: - raise ValidationError('"from" key not available, does this account exist?') + raise ValidationError( + 'No valid "from" key was provided in the transaction ' + 'which is required for transaction signing.' + ) signing_key = self._key_lookup[transaction['from']] normalized_transaction = self._normalize_transaction(transaction, block_number) evm_transaction = self.chain.create_unsigned_transaction(**normalized_transaction) diff --git a/tests/backends/test_pyevm.py b/tests/backends/test_pyevm.py index 18f046b3..880b7445 100644 --- a/tests/backends/test_pyevm.py +++ b/tests/backends/test_pyevm.py @@ -139,9 +139,7 @@ def test_send_transaction_invalid_from(self, eth_tester): accounts = eth_tester.get_accounts() assert accounts, "No accounts available for transaction sending" - with pytest.raises(ValidationError) as excinfo: + with pytest.raises(ValidationError, match=r'No valid "from" key was provided'): self._send_and_check_transaction( eth_tester, SIMPLE_TRANSACTION, ZERO_ADDRESS_HEX ) - - assert "does this account exist?" in str(excinfo.value)