Skip to content

Commit

Permalink
perf: minor trace improvements (#2423)
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Dec 18, 2024
1 parent be8f67e commit 376b366
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/ape/api/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def ran_out_of_gas(self) -> bool:
same amount of gas as the given ``gas_limit``.
"""

@property
@cached_property
def trace(self) -> "TraceAPI":
"""
The :class:`~ape.api.trace.TraceAPI` of the transaction.
Expand Down Expand Up @@ -489,7 +489,7 @@ def method_called(self) -> Optional["MethodABI"]:
"""
return None

@property
@cached_property
def return_value(self) -> Any:
"""
Obtain the final return value of the call. Requires tracing to function,
Expand Down
20 changes: 13 additions & 7 deletions src/ape_ethereum/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ def return_value(self) -> Any:

# Barely enrich a calltree for performance reasons
# (likely not a need to enrich the whole thing).
calltree = self.get_raw_calltree()
calltree = self.get_calltree()
return self._get_return_value_from_calltree(calltree)

@cached_property
Expand All @@ -248,16 +248,22 @@ def _return_value_from_enriched_calltree(self) -> Any:

return self._get_return_value_from_calltree(calltree)

def _get_return_value_from_calltree(self, calltree: dict) -> tuple[Optional[Any], ...]:
def _get_return_value_from_calltree(
self, calltree: Union[dict, CallTreeNode]
) -> tuple[Optional[Any], ...]:
num_outputs = 1
if raw_return_data := calltree.get("returndata"):
if raw_return_data := (
calltree.get("returndata") if isinstance(calltree, dict) else calltree.returndata
):
if abi := self._get_abi(calltree):
# Ensure we return a tuple with the correct length, even if fails.
num_outputs = len(abi.outputs)
try:
return self._ecosystem.decode_returndata(abi, HexBytes(raw_return_data))
except Exception as err:
logger.debug(f"Failed decoding raw returndata: {raw_return_data}. Error: {err}")
logger.debug(
f"Failed decoding raw returndata: {to_hex(raw_return_data)}. Error: {err}"
)
return tuple([None for _ in range(num_outputs)])

return tuple([None for _ in range(num_outputs)])
Expand Down Expand Up @@ -440,10 +446,10 @@ def _debug_trace_transaction_struct_logs_to_call(self) -> CallTreeNode:
def _get_tree(self, verbose: bool = False) -> Tree:
return parse_rich_tree(self.enriched_calltree, verbose=verbose)

def _get_abi(self, call: dict) -> Optional["MethodABI"]:
if not (addr := call.get("address")):
def _get_abi(self, call: Union[dict, CallTreeNode]) -> Optional["MethodABI"]:
if not (addr := call.get("address") if isinstance(call, dict) else call.address):
return self.root_method_abi
if not (calldata := call.get("calldata")):
if not (calldata := call.get("calldata") if isinstance(call, dict) else call.calldata):
return self.root_method_abi
if not (contract_type := self.chain_manager.contracts.get(addr)):
return self.root_method_abi
Expand Down
5 changes: 3 additions & 2 deletions tests/functional/geth/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest
from ethpm_types import MethodABI
from ethpm_types.abi import ABIType
from evm_trace import CallTreeNode
from hexbytes import HexBytes

from ape.utils import run_in_tempdir
Expand Down Expand Up @@ -494,8 +495,8 @@ class TraceForTest(TransactionTrace):
def transaction(self) -> dict:
return transaction

def get_raw_calltree(self) -> dict:
return calltree
def get_calltree(self) -> CallTreeNode:
return CallTreeNode.model_validate(calltree)

@property
def root_method_abi(self) -> Optional[MethodABI]:
Expand Down

0 comments on commit 376b366

Please sign in to comment.