30
30
transaction_result_formatter ,
31
31
)
32
32
from web3 ._utils .normalizers import BASE_RETURN_NORMALIZERS
33
- from web3 .contract import ContractFunction
33
+ from web3 .contract . contract import ContractFunction
34
34
from web3 .datastructures import AttributeDict
35
35
from web3 .exceptions import (
36
- BadFunctionCallOutput ,
37
36
BlockNotFound ,
38
37
TimeExhausted ,
39
38
TransactionNotFound ,
39
+ Web3Exception ,
40
40
)
41
41
from web3 .middleware import geth_poa_middleware , simple_cache_middleware
42
42
from web3 .types import (
43
43
BlockData ,
44
44
BlockIdentifier ,
45
+ BlockTrace ,
45
46
FilterParams ,
47
+ FilterTrace ,
46
48
LogReceipt ,
47
49
Nonce ,
48
- ParityBlockTrace ,
49
- ParityFilterParams ,
50
- ParityFilterTrace ,
51
50
TxData ,
52
51
TxParams ,
53
52
TxReceipt ,
80
79
InvalidNonce ,
81
80
NonceTooHigh ,
82
81
NonceTooLow ,
83
- ParityTraceDecodeException ,
84
82
ReplacementTransactionUnderpriced ,
85
83
SenderAccountNotFoundInNode ,
84
+ TraceDecodeException ,
86
85
TransactionAlreadyImported ,
87
86
TransactionGasPriceTooLow ,
88
87
TransactionQueueLimitReached ,
96
95
97
96
def tx_with_exception_handling (func ):
98
97
"""
99
- Parity
98
+ Parity / OpenEthereum
100
99
- https://github.com/openethereum/openethereum/blob/main/rpc/src/v1/helpers/errors.rs
101
100
Geth
102
101
- https://github.com/ethereum/go-ethereum/blob/master/core/error.go
@@ -133,7 +132,7 @@ def tx_with_exception_handling(func):
133
132
def with_exception_handling (* args , ** kwargs ):
134
133
try :
135
134
return func (* args , ** kwargs )
136
- except ValueError as exc :
135
+ except ( Web3Exception , ValueError ) as exc :
137
136
str_exc = str (exc ).lower ()
138
137
for reason , custom_exception in error_with_exception .items ():
139
138
if reason .lower () in str_exc :
@@ -290,7 +289,7 @@ def batch_call_custom(
290
289
else :
291
290
output_type = payload ["output_type" ]
292
291
try :
293
- decoded_values = self . w3 . codec . decode_abi (
292
+ decoded_values = eth_abi . decode (
294
293
output_type , HexBytes (result ["result" ])
295
294
)
296
295
normalized_data = map_abi_data (
@@ -430,7 +429,7 @@ def _decode_transfer_log(
430
429
if topics_len == 1 :
431
430
# Not standard Transfer(address from, address to, uint256 unknown)
432
431
# 1 topic (transfer topic)
433
- _from , to , unknown = eth_abi .decode_abi (
432
+ _from , to , unknown = eth_abi .decode (
434
433
["address" , "address" , "uint256" ], HexBytes (data )
435
434
)
436
435
return {"from" : _from , "to" : to , "unknown" : unknown }
@@ -439,7 +438,7 @@ def _decode_transfer_log(
439
438
# 3 topics (transfer topic + from + to)
440
439
try :
441
440
value_data = HexBytes (data )
442
- value = eth_abi .decode_single ( "uint256" , value_data )
441
+ value = eth_abi .decode ([ "uint256" ] , value_data )[ 0 ]
443
442
except DecodingError :
444
443
logger .warning (
445
444
"Cannot decode Transfer event `uint256 value` from data=%s" ,
@@ -450,7 +449,7 @@ def _decode_transfer_log(
450
449
from_to_data = b"" .join (topics [1 :])
451
450
_from , to = (
452
451
fast_to_checksum_address (address )
453
- for address in eth_abi .decode_abi (
452
+ for address in eth_abi .decode (
454
453
["address" , "address" ], from_to_data
455
454
)
456
455
)
@@ -464,7 +463,7 @@ def _decode_transfer_log(
464
463
elif topics_len == 4 :
465
464
# ERC712 Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
466
465
# 4 topics (transfer topic + from + to + tokenId)
467
- _from , to , token_id = eth_abi .decode_abi (
466
+ _from , to , token_id = eth_abi .decode (
468
467
["address" , "address" , "uint256" ], b"" .join (topics [1 :])
469
468
)
470
469
_from , to = [
@@ -585,9 +584,9 @@ def get_info(self, erc20_address: str) -> Erc20Info:
585
584
results = [HexBytes (r ["result" ]) for r in response_json ]
586
585
name = decode_string_or_bytes32 (results [0 ])
587
586
symbol = decode_string_or_bytes32 (results [1 ])
588
- decimals = self . ethereum_client . w3 . codec . decode_single ( "uint8" , results [2 ])
587
+ decimals = eth_abi . decode ([ "uint8" ] , results [2 ])[ 0 ]
589
588
return Erc20Info (name , symbol , decimals )
590
- except (ValueError , BadFunctionCallOutput , DecodingError ) as e :
589
+ except (Web3Exception , DecodingError , ValueError ) as e :
591
590
raise InvalidERC20Info from e
592
591
593
592
def get_total_transfer_history (
@@ -670,7 +669,7 @@ def get_total_transfer_history(
670
669
topic_0 = self .TRANSFER_TOPIC .hex ()
671
670
if addresses :
672
671
addresses_encoded = [
673
- HexBytes (eth_abi .encode_single ( "address" , address )).hex ()
672
+ HexBytes (eth_abi .encode ([ "address" ], [ address ] )).hex ()
674
673
for address in addresses
675
674
]
676
675
# Topics for transfer `to` and `from` an address
@@ -752,7 +751,7 @@ def get_transfer_history(
752
751
if to_address :
753
752
argument_filters ["to" ] = to_address
754
753
755
- return erc20 .events .Transfer .createFilter (
754
+ return erc20 .events .Transfer .create_filter (
756
755
fromBlock = from_block ,
757
756
toBlock = to_block ,
758
757
address = token_address ,
@@ -902,8 +901,7 @@ def get_token_uris(
902
901
]
903
902
904
903
905
- class ParityManager (EthereumClientManager ):
906
- # TODO Test with mock
904
+ class TracingManager (EthereumClientManager ):
907
905
def _decode_trace_action (self , action : Dict [str , Any ]) -> Dict [str , Any ]:
908
906
decoded = {}
909
907
@@ -935,6 +933,15 @@ def _decode_trace_action(self, action: Dict[str, Any]) -> Dict[str, Any]:
935
933
if "refundAddress" in action :
936
934
decoded ["refundAddress" ] = fast_to_checksum_address (action ["refundAddress" ])
937
935
936
+ # REWARD
937
+ if "author" in action :
938
+ decoded ["author" ] = action [
939
+ "author"
940
+ ] # TODO Web3 is not performing checksum decoding
941
+
942
+ if "rewardType" in action :
943
+ decoded ["rewardType" ] = action ["rewardType" ]
944
+
938
945
return decoded
939
946
940
947
def _decode_trace_result (self , result : Dict [str , Any ]) -> Dict [str , Any ]:
@@ -955,7 +962,7 @@ def _decode_trace_result(self, result: Dict[str, Any]) -> Dict[str, Any]:
955
962
return decoded
956
963
957
964
def _decode_traces (
958
- self , traces : Sequence [Union [ParityBlockTrace , ParityFilterTrace ]]
965
+ self , traces : Sequence [Union [BlockTrace , FilterTrace ]]
959
966
) -> List [Dict [str , Any ]]:
960
967
new_traces : List [Dict [str , Any ]] = []
961
968
for trace in traces :
@@ -964,7 +971,7 @@ def _decode_traces(
964
971
elif isinstance (trace , AttributeDict ):
965
972
trace_copy = trace .__dict__ .copy ()
966
973
else :
967
- raise ParityTraceDecodeException (
974
+ raise TraceDecodeException (
968
975
"Expected dictionary, but found unexpected trace %s" % trace
969
976
)
970
977
new_traces .append (trace_copy )
@@ -973,6 +980,9 @@ def _decode_traces(
973
980
if "result" in trace and trace ["result" ]:
974
981
trace_copy ["result" ] = self ._decode_trace_result (trace ["result" ])
975
982
trace_copy ["action" ] = self ._decode_trace_action (trace ["action" ])
983
+ trace_copy ["blockHash" ] = HexBytes (trace_copy ["blockHash" ])
984
+ if "transactionHash" in trace_copy : # Reward traces don't have txHash
985
+ trace_copy ["transactionHash" ] = HexBytes (trace_copy ["transactionHash" ])
976
986
return new_traces
977
987
978
988
def filter_out_errored_traces (
@@ -1064,16 +1074,8 @@ def get_next_traces(
1064
1074
traces .append (trace )
1065
1075
return traces
1066
1076
1067
- def trace_block (self , block_identifier : BlockIdentifier ) -> List [Dict [str , Any ]]:
1068
- try :
1069
- return self ._decode_traces (
1070
- self .slow_w3 .parity .trace_block (block_identifier )
1071
- )
1072
- except ParityTraceDecodeException as exc :
1073
- logger .warning ("Problem decoding trace: %s - Retrying" , exc )
1074
- return self ._decode_traces (
1075
- self .slow_w3 .parity .trace_block (block_identifier )
1076
- )
1077
+ def trace_block (self , block_identifier : BlockIdentifier ) -> List [BlockTrace ]:
1078
+ return self .slow_w3 .tracing .trace_block (block_identifier )
1077
1079
1078
1080
def trace_blocks (
1079
1081
self , block_identifiers : List [BlockIdentifier ]
@@ -1100,28 +1102,24 @@ def trace_blocks(
1100
1102
if raw_tx :
1101
1103
try :
1102
1104
decoded_traces = self ._decode_traces (raw_tx )
1103
- except ParityTraceDecodeException as exc :
1105
+ except TraceDecodeException as exc :
1104
1106
logger .warning ("Problem decoding trace: %s - Retrying" , exc )
1105
1107
decoded_traces = self ._decode_traces (raw_tx )
1106
1108
traces .append (decoded_traces )
1107
1109
else :
1108
1110
traces .append ([])
1109
1111
return traces
1110
1112
1111
- def trace_transaction (self , tx_hash : EthereumHash ) -> List [Dict [ str , Any ] ]:
1113
+ def trace_transaction (self , tx_hash : EthereumHash ) -> List [FilterTrace ]:
1112
1114
"""
1113
1115
:param tx_hash:
1114
1116
:return: List of internal txs for `tx_hash`
1115
1117
"""
1116
- try :
1117
- return self ._decode_traces (self .slow_w3 .parity .trace_transaction (tx_hash ))
1118
- except ParityTraceDecodeException as exc :
1119
- logger .warning ("Problem decoding trace: %s - Retrying" , exc )
1120
- return self ._decode_traces (self .slow_w3 .parity .trace_transaction (tx_hash ))
1118
+ return self .slow_w3 .tracing .trace_transaction (tx_hash )
1121
1119
1122
1120
def trace_transactions (
1123
1121
self , tx_hashes : Sequence [EthereumHash ]
1124
- ) -> List [List [Dict [ str , Any ] ]]:
1122
+ ) -> List [List [FilterTrace ]]:
1125
1123
"""
1126
1124
:param tx_hashes:
1127
1125
:return: For every `tx_hash` a list of internal txs (in the same order as the `tx_hashes` were provided)
@@ -1143,7 +1141,7 @@ def trace_transactions(
1143
1141
if raw_tx :
1144
1142
try :
1145
1143
decoded_traces = self ._decode_traces (raw_tx )
1146
- except ParityTraceDecodeException as exc :
1144
+ except TraceDecodeException as exc :
1147
1145
logger .warning ("Problem decoding trace: %s - Retrying" , exc )
1148
1146
decoded_traces = self ._decode_traces (raw_tx )
1149
1147
traces .append (decoded_traces )
@@ -1159,7 +1157,7 @@ def trace_filter(
1159
1157
to_address : Optional [Sequence [ChecksumAddress ]] = None ,
1160
1158
after : Optional [int ] = None ,
1161
1159
count : Optional [int ] = None ,
1162
- ) -> List [Dict [ str , Any ] ]:
1160
+ ) -> List [FilterTrace ]:
1163
1161
"""
1164
1162
Get events using ``trace_filter`` method
1165
1163
@@ -1236,7 +1234,7 @@ def trace_filter(
1236
1234
assert (
1237
1235
from_address or to_address
1238
1236
), "You must provide at least `from_address` or `to_address`"
1239
- parameters : ParityFilterParams = {}
1237
+ parameters : FilterParams = {}
1240
1238
if after :
1241
1239
parameters ["after" ] = after
1242
1240
if count :
@@ -1250,11 +1248,7 @@ def trace_filter(
1250
1248
if to_address :
1251
1249
parameters ["toAddress" ] = to_address
1252
1250
1253
- try :
1254
- return self ._decode_traces (self .slow_w3 .parity .trace_filter (parameters ))
1255
- except ParityTraceDecodeException as exc :
1256
- logger .warning ("Problem decoding trace: %s - Retrying" , exc )
1257
- return self ._decode_traces (self .slow_w3 .parity .trace_filter (parameters ))
1251
+ return self .slow_w3 .tracing .trace_filter (parameters )
1258
1252
1259
1253
1260
1254
class EthereumClient :
@@ -1300,7 +1294,7 @@ def __init__(
1300
1294
self .slow_w3 : Web3 = Web3 (self .w3_slow_provider )
1301
1295
self .erc20 : Erc20Manager = Erc20Manager (self )
1302
1296
self .erc721 : Erc721Manager = Erc721Manager (self )
1303
- self .parity : ParityManager = ParityManager (self )
1297
+ self .tracing : TracingManager = TracingManager (self )
1304
1298
self .batch_call_manager : BatchCallManager = BatchCallManager (self )
1305
1299
try :
1306
1300
if self .get_network () != EthereumNetwork .MAINNET :
@@ -1423,7 +1417,7 @@ def is_eip1559_supported(self) -> EthereumNetwork:
1423
1417
try :
1424
1418
self .w3 .eth .fee_history (1 , "latest" , reward_percentiles = [50 ])
1425
1419
return True
1426
- except ValueError :
1420
+ except ( Web3Exception , ValueError ) :
1427
1421
return False
1428
1422
1429
1423
@cached_property
@@ -1607,7 +1601,7 @@ def estimate_gas(
1607
1601
tx ["gasPrice" ] = gas_price
1608
1602
try :
1609
1603
return self .w3 .eth .estimate_gas (tx , block_identifier = block_identifier )
1610
- except ValueError :
1604
+ except ( Web3Exception , ValueError ) :
1611
1605
if (
1612
1606
block_identifier is not None
1613
1607
): # Geth does not support setting `block_identifier`
0 commit comments