Skip to content

Commit

Permalink
feat: trace api
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Jan 12, 2024
1 parent dca5aa9 commit 50ce12d
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 48 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ repos:
- id: isort

- repo: https://github.com/psf/black
rev: 23.12.0
rev: 23.12.1
hooks:
- id: black
name: black

- repo: https://github.com/pycqa/flake8
rev: 6.1.0
rev: 7.0.0
hooks:
- id: flake8

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.7.1
rev: v1.8.0
hooks:
- id: mypy
additional_dependencies: [types-PyYAML, types-requests, pydantic, types-setuptools]
Expand Down
55 changes: 13 additions & 42 deletions ape_alchemy/provider.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
import os
from typing import Any, Dict, List, Optional

from ape.api import ReceiptAPI, TransactionAPI, UpstreamProvider
from ape.exceptions import (
APINotImplementedError,
ContractLogicError,
ProviderError,
VirtualMachineError,
)
from ape.api import ReceiptAPI, TraceAPI, TransactionAPI, UpstreamProvider
from ape.exceptions import ContractLogicError, ProviderError, VirtualMachineError
from ape.logging import logger
from ape.types import CallTreeNode
from ape_ethereum.provider import Web3Provider
from eth_pydantic_types import HexBytes
from eth_typing import HexStr
from evm_trace import (
ParityTraceList,
get_calltree_from_geth_call_trace,
get_calltree_from_parity_trace,
)
from requests import HTTPError
from web3 import HTTPProvider, Web3
from web3.exceptions import ContractLogicError as Web3ContractLogicError
Expand Down Expand Up @@ -117,34 +106,16 @@ def connect(self):
def disconnect(self):
self._web3 = None

def _get_prestate_trace(self, txn_hash: str) -> Dict:
return self._debug_trace_transaction(txn_hash, "prestateTracer")

def get_call_tree(self, txn_hash: str) -> CallTreeNode:
try:
return self._get_calltree_using_parity_style(txn_hash)
except Exception as err:
try:
return self._get_calltree_using_call_tracer(txn_hash)
except Exception:
pass

raise APINotImplementedError() from err

def _get_calltree_using_parity_style(self, txn_hash: str) -> CallTreeNode:
raw_trace_list = self._make_request("trace_transaction", [txn_hash])
trace_list = ParityTraceList.model_validate(raw_trace_list)
evm_call = get_calltree_from_parity_trace(trace_list)
return self._create_call_tree_node(evm_call)
def _get_prestate_trace(self, transaction_hash: str) -> Dict:
return self.make_request(
"debug_traceTransaction", [transaction_hash, {"tracer": "prestateTracer"}]
)

def _get_calltree_using_call_tracer(self, txn_hash: str) -> CallTreeNode:
# Create trace frames using geth-style call tracer
calls = self._debug_trace_transaction(txn_hash, "callTracer")
evm_call = get_calltree_from_geth_call_trace(calls)
return self._create_call_tree_node(evm_call, txn_hash=txn_hash)
def get_transaction_trace(self, transaction_hash: str, **kwargs) -> TraceAPI:
if "debug_trace_transaction_parameters" not in kwargs:
kwargs["debug_trace_transaction_parameters"] = {}

def _debug_trace_transaction(self, txn_hash: str, tracer: str) -> Dict:
return self._make_request("debug_traceTransaction", [txn_hash, {"tracer": tracer}])
return self._get_transaction_trace(transaction_hash, **kwargs)

def get_virtual_machine_error(self, exception: Exception, **kwargs) -> VirtualMachineError:
txn = kwargs.get("txn")
Expand Down Expand Up @@ -179,9 +150,9 @@ def get_virtual_machine_error(self, exception: Exception, **kwargs) -> VirtualMa

return VirtualMachineError(message=message, txn=txn)

def _make_request(self, endpoint: str, parameters: Optional[List] = None) -> Any:
def make_request(self, endpoint: str, parameters: Optional[List] = None) -> Any:
try:
return super()._make_request(endpoint, parameters)
return super().make_request(endpoint, parameters)
except HTTPError as err:
response_data = err.response.json() if err.response else {}
if "error" not in response_data:
Expand Down Expand Up @@ -226,7 +197,7 @@ def send_private_transaction(self, txn: TransactionAPI, **kwargs) -> ReceiptAPI:
params["preferences"] = kwargs

try:
txn_hash = self._make_request("eth_sendPrivateTransaction", [params])
txn_hash = self.make_request("eth_sendPrivateTransaction", [params])
except (ValueError, Web3ContractLogicError) as err:
vm_err = self.get_virtual_machine_error(err, txn=txn)
raise vm_err from err
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
"websocket-client", # Used for web socket integration testing
],
"lint": [
"black>=23.12.0,<24", # Auto-formatter and linter
"mypy>=1.7.1,<2", # Static type analyzer
"black>=23.12.1,<24", # Auto-formatter and linter
"mypy>=1.8.0,<2", # Static type analyzer
"types-setuptools", # Needed for mypy type shed
"types-requests", # Needed for mypy type shed
"flake8>=6.1.0,<7", # Style linter
"flake8>=7.0.0,<8", # Style linter
"flake8-breakpoint>=1.1.0,<2", # Detect breakpoints left in code
"flake8-print>=5.0.0,<6", # Detect print statements left in code
"isort>=5.10.1,<6", # Import sorting linter
Expand Down

0 comments on commit 50ce12d

Please sign in to comment.