diff --git a/src/ape_test/provider.py b/src/ape_test/provider.py index 72f3459c87..63d7737671 100644 --- a/src/ape_test/provider.py +++ b/src/ape_test/provider.py @@ -9,8 +9,9 @@ from eth_pydantic_types import HexBytes from eth_tester.backends import PyEVMBackend # type: ignore from eth_tester.exceptions import TransactionFailed # type: ignore +from eth_tester.exceptions import ValidationError as EthTesterValidationError from eth_utils import is_0x_prefixed -from eth_utils.exceptions import ValidationError +from eth_utils.exceptions import ValidationError as EthUtilsValidationError from eth_utils.toolz import merge from web3 import EthereumTesterProvider, Web3 from web3.exceptions import ContractLogicError as Web3ContractLogicError @@ -129,7 +130,7 @@ def estimate_gas_cost( try: return estimate_gas(txn_data, block_identifier=block_id) - except (ValidationError, TransactionFailed, Web3ContractLogicError) as err: + except (EthUtilsValidationError, TransactionFailed, Web3ContractLogicError) as err: ape_err = self.get_virtual_machine_error(err, txn=txn) gas_match = self._INVALID_NONCE_PATTERN.match(str(ape_err)) if gas_match: @@ -215,7 +216,7 @@ def send_call( vm_err = None try: result = self.web3.eth.call(tx_params, **call_kwargs) - except ValidationError as err: + except EthUtilsValidationError as err: vm_err = VirtualMachineError(base_err=err) if raise_on_revert: raise vm_err from err @@ -242,7 +243,7 @@ def send_transaction(self, txn: TransactionAPI) -> ReceiptAPI: txn_hash = self.tester.ethereum_tester.send_raw_transaction( txn.serialize_transaction().hex() ) - except (ValidationError, TransactionFailed, Web3ContractLogicError) as err: + except (EthUtilsValidationError, TransactionFailed, Web3ContractLogicError) as err: vm_err = self.get_virtual_machine_error(err, txn=txn) if txn.raise_on_revert: raise vm_err from err @@ -279,7 +280,7 @@ def send_transaction(self, txn: TransactionAPI) -> ReceiptAPI: # Replay txn to get revert reason try: self.web3.eth.call(txn_params) - except (ValidationError, TransactionFailed, Web3ContractLogicError) as err: + except (EthUtilsValidationError, TransactionFailed, Web3ContractLogicError) as err: vm_err = self.get_virtual_machine_error(err, txn=receipt) receipt.error = vm_err if txn.raise_on_revert: @@ -310,19 +311,14 @@ def restore(self, snapshot_id: SnapshotID): def set_timestamp(self, new_timestamp: int): try: self.tester.ethereum_tester.time_travel(new_timestamp) - except ValidationError as err: - pattern = re.compile( - r"timestamp must be strictly later than parent, " - r"but is 0 seconds before\.\n- child\s{2}: (\d*)\n- parent : (\d*)\.\s*" - ) - if match := re.match(pattern, str(err)): - if groups := match.groups(): - if groups[0].strip() == groups[1].strip(): - # Handle race condition when block headers are the same. - # Treat as noop, same as pre-check. - return + except EthTesterValidationError as err: + err_str = str(err) + if "Space time continuum distortion detected" in err_str: + # Handle race condition when block headers are the same. + # Treat as noop, same as pre-check. + return - raise ProviderError(f"Failed to time travel: {err}") from err + raise ProviderError(f"Failed to time travel: {err_str}") from err def mine(self, num_blocks: int = 1): self.evm_backend.mine_blocks(num_blocks) @@ -384,7 +380,7 @@ def _get_last_base_fee(self) -> int: raise APINotImplementedError("No base fee found in block.") def get_virtual_machine_error(self, exception: Exception, **kwargs) -> VirtualMachineError: - if isinstance(exception, ValidationError): + if isinstance(exception, EthUtilsValidationError): match = self._CANNOT_AFFORD_GAS_PATTERN.match(str(exception)) if match: txn_gas, bal = match.groups()