Skip to content

Commit

Permalink
Merge branch 'safe-global:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Agustin Tradito authored Apr 27, 2023
2 parents b67b64d + f6f1dcf commit d93361e
Show file tree
Hide file tree
Showing 35 changed files with 4,369 additions and 1,697 deletions.
4 changes: 2 additions & 2 deletions gnosis/eth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
UnknownAccount,
)
from .ethereum_network import EthereumNetwork, EthereumNetworkNotSupported
from .exceptions import InvalidERC20Info, InvalidERC721Info, ParityTraceDecodeException
from .exceptions import InvalidERC20Info, InvalidERC721Info, TraceDecodeException

__all__ = [
"EthereumClient",
Expand All @@ -39,5 +39,5 @@
"EthereumNetworkNotSupported",
"InvalidERC20Info",
"InvalidERC721Info",
"ParityTraceDecodeException",
"TraceDecodeException",
]
Empty file added gnosis/eth/abis/__init__.py
Empty file.
250 changes: 250 additions & 0 deletions gnosis/eth/abis/multicall.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion gnosis/eth/eip712/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import re
from typing import Any, Dict, List, Union

from eth_abi import encode_abi
from eth_abi import encode as encode_abi
from eth_account import Account
from eth_typing import Hash32, HexStr
from hexbytes import HexBytes
Expand Down
94 changes: 44 additions & 50 deletions gnosis/eth/ethereum_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,23 @@
transaction_result_formatter,
)
from web3._utils.normalizers import BASE_RETURN_NORMALIZERS
from web3.contract import ContractFunction
from web3.contract.contract import ContractFunction
from web3.datastructures import AttributeDict
from web3.exceptions import (
BadFunctionCallOutput,
BlockNotFound,
TimeExhausted,
TransactionNotFound,
Web3Exception,
)
from web3.middleware import geth_poa_middleware, simple_cache_middleware
from web3.types import (
BlockData,
BlockIdentifier,
BlockTrace,
FilterParams,
FilterTrace,
LogReceipt,
Nonce,
ParityBlockTrace,
ParityFilterParams,
ParityFilterTrace,
TxData,
TxParams,
TxReceipt,
Expand Down Expand Up @@ -80,9 +79,9 @@
InvalidNonce,
NonceTooHigh,
NonceTooLow,
ParityTraceDecodeException,
ReplacementTransactionUnderpriced,
SenderAccountNotFoundInNode,
TraceDecodeException,
TransactionAlreadyImported,
TransactionGasPriceTooLow,
TransactionQueueLimitReached,
Expand All @@ -96,7 +95,7 @@

def tx_with_exception_handling(func):
"""
Parity
Parity / OpenEthereum
- https://github.com/openethereum/openethereum/blob/main/rpc/src/v1/helpers/errors.rs
Geth
- https://github.com/ethereum/go-ethereum/blob/master/core/error.go
Expand Down Expand Up @@ -133,7 +132,7 @@ def tx_with_exception_handling(func):
def with_exception_handling(*args, **kwargs):
try:
return func(*args, **kwargs)
except ValueError as exc:
except (Web3Exception, ValueError) as exc:
str_exc = str(exc).lower()
for reason, custom_exception in error_with_exception.items():
if reason.lower() in str_exc:
Expand Down Expand Up @@ -290,7 +289,7 @@ def batch_call_custom(
else:
output_type = payload["output_type"]
try:
decoded_values = self.w3.codec.decode_abi(
decoded_values = eth_abi.decode(
output_type, HexBytes(result["result"])
)
normalized_data = map_abi_data(
Expand Down Expand Up @@ -430,7 +429,7 @@ def _decode_transfer_log(
if topics_len == 1:
# Not standard Transfer(address from, address to, uint256 unknown)
# 1 topic (transfer topic)
_from, to, unknown = eth_abi.decode_abi(
_from, to, unknown = eth_abi.decode(
["address", "address", "uint256"], HexBytes(data)
)
return {"from": _from, "to": to, "unknown": unknown}
Expand All @@ -439,7 +438,7 @@ def _decode_transfer_log(
# 3 topics (transfer topic + from + to)
try:
value_data = HexBytes(data)
value = eth_abi.decode_single("uint256", value_data)
value = eth_abi.decode(["uint256"], value_data)[0]
except DecodingError:
logger.warning(
"Cannot decode Transfer event `uint256 value` from data=%s",
Expand All @@ -450,7 +449,7 @@ def _decode_transfer_log(
from_to_data = b"".join(topics[1:])
_from, to = (
fast_to_checksum_address(address)
for address in eth_abi.decode_abi(
for address in eth_abi.decode(
["address", "address"], from_to_data
)
)
Expand All @@ -464,7 +463,7 @@ def _decode_transfer_log(
elif topics_len == 4:
# ERC712 Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
# 4 topics (transfer topic + from + to + tokenId)
_from, to, token_id = eth_abi.decode_abi(
_from, to, token_id = eth_abi.decode(
["address", "address", "uint256"], b"".join(topics[1:])
)
_from, to = [
Expand Down Expand Up @@ -585,9 +584,9 @@ def get_info(self, erc20_address: str) -> Erc20Info:
results = [HexBytes(r["result"]) for r in response_json]
name = decode_string_or_bytes32(results[0])
symbol = decode_string_or_bytes32(results[1])
decimals = self.ethereum_client.w3.codec.decode_single("uint8", results[2])
decimals = eth_abi.decode(["uint8"], results[2])[0]
return Erc20Info(name, symbol, decimals)
except (ValueError, BadFunctionCallOutput, DecodingError) as e:
except (Web3Exception, DecodingError, ValueError) as e:
raise InvalidERC20Info from e

def get_total_transfer_history(
Expand Down Expand Up @@ -670,7 +669,7 @@ def get_total_transfer_history(
topic_0 = self.TRANSFER_TOPIC.hex()
if addresses:
addresses_encoded = [
HexBytes(eth_abi.encode_single("address", address)).hex()
HexBytes(eth_abi.encode(["address"], [address])).hex()
for address in addresses
]
# Topics for transfer `to` and `from` an address
Expand Down Expand Up @@ -752,7 +751,7 @@ def get_transfer_history(
if to_address:
argument_filters["to"] = to_address

return erc20.events.Transfer.createFilter(
return erc20.events.Transfer.create_filter(
fromBlock=from_block,
toBlock=to_block,
address=token_address,
Expand Down Expand Up @@ -902,8 +901,7 @@ def get_token_uris(
]


class ParityManager(EthereumClientManager):
# TODO Test with mock
class TracingManager(EthereumClientManager):
def _decode_trace_action(self, action: Dict[str, Any]) -> Dict[str, Any]:
decoded = {}

Expand Down Expand Up @@ -935,6 +933,15 @@ def _decode_trace_action(self, action: Dict[str, Any]) -> Dict[str, Any]:
if "refundAddress" in action:
decoded["refundAddress"] = fast_to_checksum_address(action["refundAddress"])

# REWARD
if "author" in action:
decoded["author"] = action[
"author"
] # TODO Web3 is not performing checksum decoding

if "rewardType" in action:
decoded["rewardType"] = action["rewardType"]

return decoded

def _decode_trace_result(self, result: Dict[str, Any]) -> Dict[str, Any]:
Expand All @@ -955,7 +962,7 @@ def _decode_trace_result(self, result: Dict[str, Any]) -> Dict[str, Any]:
return decoded

def _decode_traces(
self, traces: Sequence[Union[ParityBlockTrace, ParityFilterTrace]]
self, traces: Sequence[Union[BlockTrace, FilterTrace]]
) -> List[Dict[str, Any]]:
new_traces: List[Dict[str, Any]] = []
for trace in traces:
Expand All @@ -964,7 +971,7 @@ def _decode_traces(
elif isinstance(trace, AttributeDict):
trace_copy = trace.__dict__.copy()
else:
raise ParityTraceDecodeException(
raise TraceDecodeException(
"Expected dictionary, but found unexpected trace %s" % trace
)
new_traces.append(trace_copy)
Expand All @@ -973,6 +980,9 @@ def _decode_traces(
if "result" in trace and trace["result"]:
trace_copy["result"] = self._decode_trace_result(trace["result"])
trace_copy["action"] = self._decode_trace_action(trace["action"])
trace_copy["blockHash"] = HexBytes(trace_copy["blockHash"])
if "transactionHash" in trace_copy: # Reward traces don't have txHash
trace_copy["transactionHash"] = HexBytes(trace_copy["transactionHash"])
return new_traces

def filter_out_errored_traces(
Expand Down Expand Up @@ -1064,16 +1074,8 @@ def get_next_traces(
traces.append(trace)
return traces

def trace_block(self, block_identifier: BlockIdentifier) -> List[Dict[str, Any]]:
try:
return self._decode_traces(
self.slow_w3.parity.trace_block(block_identifier)
)
except ParityTraceDecodeException as exc:
logger.warning("Problem decoding trace: %s - Retrying", exc)
return self._decode_traces(
self.slow_w3.parity.trace_block(block_identifier)
)
def trace_block(self, block_identifier: BlockIdentifier) -> List[BlockTrace]:
return self.slow_w3.tracing.trace_block(block_identifier)

def trace_blocks(
self, block_identifiers: List[BlockIdentifier]
Expand All @@ -1100,28 +1102,24 @@ def trace_blocks(
if raw_tx:
try:
decoded_traces = self._decode_traces(raw_tx)
except ParityTraceDecodeException as exc:
except TraceDecodeException as exc:
logger.warning("Problem decoding trace: %s - Retrying", exc)
decoded_traces = self._decode_traces(raw_tx)
traces.append(decoded_traces)
else:
traces.append([])
return traces

def trace_transaction(self, tx_hash: EthereumHash) -> List[Dict[str, Any]]:
def trace_transaction(self, tx_hash: EthereumHash) -> List[FilterTrace]:
"""
:param tx_hash:
:return: List of internal txs for `tx_hash`
"""
try:
return self._decode_traces(self.slow_w3.parity.trace_transaction(tx_hash))
except ParityTraceDecodeException as exc:
logger.warning("Problem decoding trace: %s - Retrying", exc)
return self._decode_traces(self.slow_w3.parity.trace_transaction(tx_hash))
return self.slow_w3.tracing.trace_transaction(tx_hash)

def trace_transactions(
self, tx_hashes: Sequence[EthereumHash]
) -> List[List[Dict[str, Any]]]:
) -> List[List[FilterTrace]]:
"""
:param tx_hashes:
:return: For every `tx_hash` a list of internal txs (in the same order as the `tx_hashes` were provided)
Expand All @@ -1143,7 +1141,7 @@ def trace_transactions(
if raw_tx:
try:
decoded_traces = self._decode_traces(raw_tx)
except ParityTraceDecodeException as exc:
except TraceDecodeException as exc:
logger.warning("Problem decoding trace: %s - Retrying", exc)
decoded_traces = self._decode_traces(raw_tx)
traces.append(decoded_traces)
Expand All @@ -1159,7 +1157,7 @@ def trace_filter(
to_address: Optional[Sequence[ChecksumAddress]] = None,
after: Optional[int] = None,
count: Optional[int] = None,
) -> List[Dict[str, Any]]:
) -> List[FilterTrace]:
"""
Get events using ``trace_filter`` method
Expand Down Expand Up @@ -1236,7 +1234,7 @@ def trace_filter(
assert (
from_address or to_address
), "You must provide at least `from_address` or `to_address`"
parameters: ParityFilterParams = {}
parameters: FilterParams = {}
if after:
parameters["after"] = after
if count:
Expand All @@ -1250,11 +1248,7 @@ def trace_filter(
if to_address:
parameters["toAddress"] = to_address

try:
return self._decode_traces(self.slow_w3.parity.trace_filter(parameters))
except ParityTraceDecodeException as exc:
logger.warning("Problem decoding trace: %s - Retrying", exc)
return self._decode_traces(self.slow_w3.parity.trace_filter(parameters))
return self.slow_w3.tracing.trace_filter(parameters)


class EthereumClient:
Expand Down Expand Up @@ -1300,7 +1294,7 @@ def __init__(
self.slow_w3: Web3 = Web3(self.w3_slow_provider)
self.erc20: Erc20Manager = Erc20Manager(self)
self.erc721: Erc721Manager = Erc721Manager(self)
self.parity: ParityManager = ParityManager(self)
self.tracing: TracingManager = TracingManager(self)
self.batch_call_manager: BatchCallManager = BatchCallManager(self)
try:
if self.get_network() != EthereumNetwork.MAINNET:
Expand Down Expand Up @@ -1423,7 +1417,7 @@ def is_eip1559_supported(self) -> EthereumNetwork:
try:
self.w3.eth.fee_history(1, "latest", reward_percentiles=[50])
return True
except ValueError:
except (Web3Exception, ValueError):
return False

@cached_property
Expand Down Expand Up @@ -1607,7 +1601,7 @@ def estimate_gas(
tx["gasPrice"] = gas_price
try:
return self.w3.eth.estimate_gas(tx, block_identifier=block_identifier)
except ValueError:
except (Web3Exception, ValueError):
if (
block_identifier is not None
): # Geth does not support setting `block_identifier`
Expand Down
2 changes: 1 addition & 1 deletion gnosis/eth/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class TransactionGasPriceTooLow(EthereumClientException):
pass


class ParityTraceDecodeException(EthereumClientException):
class TraceDecodeException(EthereumClientException):
pass


Expand Down
Loading

0 comments on commit d93361e

Please sign in to comment.