Skip to content

Commit

Permalink
fix: dont assume has client version
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Jan 6, 2025
1 parent 617885a commit 027bcfd
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/ape_ethereum/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ def get_calltree(self) -> CallTreeNode:
elif self.call_trace_approach is TraceApproach.GETH_STRUCT_LOG_PARSE:
return self._debug_trace_transaction_struct_logs_to_call()

elif "erigon" in self.provider.client_version.lower():
elif "erigon" in getattr(self.provider, "client_version", "").lower():
# Based on the client version, we know parity works.
call = self._trace_transaction()
self._set_approach(TraceApproach.PARITY)
Expand Down
79 changes: 69 additions & 10 deletions tests/functional/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from evm_trace import CallTreeNode, CallType
from hexbytes import HexBytes

from ape.exceptions import ContractLogicError
from ape_ethereum.trace import CallTrace, Trace, TraceApproach, TransactionTrace, parse_rich_tree
from tests.functional.data.python import (
TRACE_MISSING_GAS,
Expand Down Expand Up @@ -177,15 +176,7 @@ def test_transaction_trace_basic_approach_on_failed_call(chain, vyper_contract_i
"""
Show we can use the basic approach for failed calls.
"""
# Get a failed tx
tx = None
try:
vyper_contract_instance.setNumber(0, sender=not_owner)
except ContractLogicError as err:
tx = err.txn

assert tx is not None, "Setup failed - could not get a failed txn."

tx = vyper_contract_instance.setNumber(0, sender=not_owner, raise_on_revert=False)
trace = TransactionTrace.model_validate(
{
"call_trace_approach": None,
Expand All @@ -201,6 +192,74 @@ def test_transaction_trace_basic_approach_on_failed_call(chain, vyper_contract_i
assert isinstance(actual, CallTreeNode)


def test_transaction_trace_when_client_version_erigon(
mocker, vyper_contract_instance, not_owner, networks
):
tx = vyper_contract_instance.setNumber(0, sender=not_owner, raise_on_revert=False)

mock_erigon = mocker.MagicMock()
mock_erigon.client_version = "erigon"

def side_effect(rpc, arguments):
if rpc == "trace_transaction":
return [
{
"action": {
"callType": "CALL",
"from": not_owner.address,
"gas": "0x00",
"input": "0x00",
"to": not_owner.address,
"value": "0x00",
},
"blockHash": "0x123",
"callType": "CALL",
"subtraces": 0,
"traceAddress": [int(vyper_contract_instance.address, 16)],
"transactionHash": tx.txn_hash,
"type": "",
}
]

mock_erigon.make_request.side_effect = side_effect
trace = TransactionTrace.model_validate(
{
"call_trace_approach": None,
"debug_trace_transaction_parameters": {"enableMemory": True},
"transaction_hash": tx.txn_hash,
"transaction": tx,
}
)
provider = networks.provider
networks.active_provider = mock_erigon
actual = trace.get_calltree()
networks.provider = provider
assert isinstance(actual, CallTreeNode)
assert trace.call_trace_approach is TraceApproach.PARITY


def test_transaction_trace_provider_does_not_implement_client_version(
mocker, vyper_contract_instance, not_owner, networks
):
tx = vyper_contract_instance.setNumber(0, sender=not_owner, raise_on_revert=False)
mock_weird_node = mocker.MagicMock()
mock_weird_node.client_version.side_effect = AttributeError
provider = networks.provider
networks.active_provider = mock_weird_node
trace = TransactionTrace.model_validate(
{
"call_trace_approach": None,
"debug_trace_transaction_parameters": {"enableMemory": True},
"transaction_hash": tx.txn_hash,
"transaction": tx,
}
)
actual = trace.get_calltree()
networks.provider = provider
assert isinstance(actual, CallTreeNode)
assert trace.call_trace_approach is not TraceApproach.PARITY


def test_call_trace_debug_trace_call_not_supported(owner, vyper_contract_instance):
"""
When using EthTester, we can still see the top-level trace of a call.
Expand Down

0 comments on commit 027bcfd

Please sign in to comment.