Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ethtx/providers/node/connection_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ class NodeConnection:
chain: str
url: str
poa: bool
timeout: int

def __repr__(self) -> str:
return f"<Chain: {self.chain}, Node: {self.url}, Poa: {self.poa}>"
return f"<Chain: {self.chain}, Node: {self.url}, Poa: {self.poa}, Timeout: {self.timeout}>"

def __iter__(self):
return iter(self.__dict__.items())
3 changes: 2 additions & 1 deletion ethtx/providers/node/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def _set_connections(self, nodes) -> None:
for chain, node_params in nodes.items():
nodes: List[str] = list(node_params.values())[0].split(",")
poa: bool = list(node_params.values())[1]
timeout: int = list(node_params.values())[2]
for url in nodes:
self.add_connection(
NodeConnection(chain=chain, url=url.strip(), poa=poa)
NodeConnection(chain=chain, url=url.strip(), poa=poa, timeout=timeout)
)
25 changes: 17 additions & 8 deletions ethtx/providers/semantic_providers/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from functools import lru_cache
from typing import Optional, List, Dict, Tuple

from web3.exceptions import BadFunctionCallOutput

from ethtx.decoders.decoders.semantics import decode_events_and_functions
from ethtx.models.semantics_model import (
AddressSemantics,
Expand Down Expand Up @@ -159,10 +161,13 @@ def decode_parameter(_parameter):

name = raw_address_semantics.get("name", address)
if name == address and not raw_address_semantics["is_contract"]:
name = self._ens_provider.name(
provider=self._web3provider._get_node_connection(chain_id),
address=address,
)
try:
name = self._ens_provider.name(
provider=self._web3provider._get_node_connection(chain_id),
address=address,
)
except BadFunctionCallOutput as e:
pass # expected for sidechains like polygon

address_semantics = AddressSemantics(
chain_id=chain_id,
Expand Down Expand Up @@ -263,10 +268,14 @@ def get_semantics(self, chain_id: str, address: str) -> Optional[AddressSemantic
else:
# externally owned address
contract_semantics = ContractSemantics(code_hash=ZERO_HASH, name="EOA")
name = self._ens_provider.name(
provider=self._web3provider._get_node_connection(chain_id),
address=address,
)
name = ''
try:
name = self._ens_provider.name(
provider=self._web3provider._get_node_connection(chain_id),
address=address,
)
except BadFunctionCallOutput as e:
pass # expected for sidechains like polygon
address_semantics = AddressSemantics(
chain_id=chain_id,
address=address,
Expand Down
31 changes: 24 additions & 7 deletions ethtx/providers/web3_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import os
from functools import lru_cache
from typing import List, Dict, Optional
from time import sleep

from requests.exceptions import HTTPError
from web3 import Web3
from web3.datastructures import AttributeDict
from web3.middleware import geth_poa_middleware
Expand All @@ -30,7 +32,7 @@


def connect_chain(
http_hook: str = None, ipc_hook: str = None, ws_hook: str = None, poa: bool = False
http_hook: str = None, ipc_hook: str = None, ws_hook: str = None, poa: bool = False, timeout: int = 600
) -> Web3 or None:
if http_hook:
provider = Web3.HTTPProvider
Expand All @@ -45,7 +47,7 @@ def connect_chain(
provider = Web3.IPCProvider
hook = "\\\\.\\pipe\\geth.ipc"

w3 = Web3(provider(hook, request_kwargs={"timeout": 600}))
w3 = Web3(provider(hook, request_kwargs={"timeout": timeout}))

# middleware injection for POA chains
if poa:
Expand Down Expand Up @@ -125,7 +127,7 @@ def _get_node_connection(self, chain_id: Optional[str] = None) -> Web3:
for connection in NodeConnectionPool(nodes=self.nodes).get_connection(
chain=chain_id
):
w3 = connect_chain(http_hook=connection.url, poa=connection.poa)
w3 = connect_chain(http_hook=connection.url, poa=connection.poa, timeout=connection.timeout)

if w3.isConnected():
log.info(
Expand Down Expand Up @@ -172,7 +174,7 @@ def get_block(self, block_number: int, chain_id: Optional[str] = None) -> W3Bloc
# get the raw transaction data from the node
@lru_cache(maxsize=512)
def get_transaction(
self, tx_hash: str, chain_id: Optional[str] = None
self, tx_hash: str, chain_id: Optional[str] = None, timeout: Optional[int] = None
) -> W3Transaction:
chain = self._get_node_connection(chain_id)
raw_tx: TxData = chain.eth.get_transaction(HexStr(tx_hash))
Expand Down Expand Up @@ -248,9 +250,24 @@ def get_calls(self, tx_hash: str, chain_id: Optional[str] = None) -> W3CallTree:
# tracer is a temporary fixed implementation of geth tracer
chain = self._get_node_connection(chain_id)
tracer = self._get_custom_calls_tracer()
response = chain.manager.request_blocking(
"debug_traceTransaction", [tx_hash, {"tracer": tracer, "timeout": "60s"}]
)
retry_count = 10
while True:
try:
response = chain.manager.request_blocking(
"debug_traceTransaction", [tx_hash, {"tracer": tracer, "timeout": "60s"}]
)
break
except HTTPError as e:
if retry_count < 0:
raise e
retry_count = retry_count - 1
log.debug(
"Retrying remote request - %s of 10.",
10 - retry_count,
)
sleep(1.25) # recommended retry sleep time for alchemy.
except Exception as e:
raise e

return self._create_call_from_debug_trace_tx(
tx_hash, chain_id or self.default_chain, response
Expand Down