Skip to content

Commit acc6de2

Browse files
committed
coerce accessList storageKeys to HexStr, not HexBytes, fix no_default_exceptions test
1 parent e9ecd9d commit acc6de2

File tree

8 files changed

+78
-18
lines changed

8 files changed

+78
-18
lines changed

docs/web3.eth.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -960,17 +960,17 @@ The following methods are available on the ``web3.eth`` namespace.
960960
... "pending",
961961
... )
962962
AttributeDict({
963-
'accessList': [
963+
"accessList": [
964964
AttributeDict({
965-
'address': '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
966-
'storageKeys': [
967-
HexBytes('0x0000000000000000000000000000000000000000000000000000000000000003'),
968-
HexBytes('0x0000000000000000000000000000000000000000000000000000000000000007'),
965+
"address": "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe",
966+
"storageKeys": [
967+
"0x0000000000000000000000000000000000000000000000000000000000000003",
968+
"0x0000000000000000000000000000000000000000000000000000000000000007",
969969
]
970970
}),
971971
AttributeDict({
972-
'address': '0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413',
973-
'storageKeys': []
972+
"address": "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413",
973+
"storageKeys": []
974974
}),
975975
],
976976
"gasUsed": 21000

newsfragments/3434.breaking.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Format entries in ``accessList`` ``storageKeys`` to be ``HexStr`` instead of ``HexBytes``

tests/core/eth-module/test_transactions.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,8 @@ def test_get_transaction_formatters(w3, request_mocker):
318318
{
319319
"address": checksummed_addr,
320320
"storageKeys": [
321-
HexBytes(
322-
"0x0000000000000000000000000000000000000000000000000000000000000032" # noqa: E501
323-
),
324-
HexBytes(
325-
"0x0000000000000000000000000000000000000000000000000000000000000036" # noqa: E501
326-
),
321+
"0x0000000000000000000000000000000000000000000000000000000000000032", # noqa: E501
322+
"0x0000000000000000000000000000000000000000000000000000000000000036", # noqa: E501
327323
],
328324
}
329325
),

tests/core/test_library_files.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22

3-
WEB3_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "web3")
3+
WEB3_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../..", "web3")
44
DEFAULT_EXCEPTIONS = (
55
AssertionError,
66
ValueError,

tests/core/utilities/test_method_formatters.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import pytest
22

3+
from eth_typing import (
4+
HexStr,
5+
)
6+
37
from web3._utils.method_formatters import (
48
get_error_formatters,
59
raise_contract_logic_error_on_revert,
10+
storage_key_to_hexstr,
611
)
712
from web3._utils.rpc_abi import (
813
RPC,
914
)
1015
from web3.exceptions import (
1116
ContractLogicError,
17+
Web3ValueError,
1218
)
1319
from web3.types import (
1420
RPCResponse,
@@ -192,3 +198,41 @@ def test_get_error_formatters() -> None:
192198
with pytest.raises(ContractLogicError):
193199
formatters(REVERT_WITHOUT_MSG)
194200
assert formatters(OTHER_ERROR) == OTHER_ERROR
201+
202+
203+
@pytest.mark.parametrize(
204+
"input_value,expected_output",
205+
[
206+
("0x" + "a" * 64, HexStr("0x" + "a" * 64)),
207+
("a" * 64, HexStr("0x" + "a" * 64)),
208+
("0x" + "a" * 63, Web3ValueError),
209+
("a" * 63, Web3ValueError),
210+
(b"a" * 32, HexStr("0x" + "61" * 32)),
211+
(b"a" * 31, Web3ValueError),
212+
(b"a" * 33, Web3ValueError),
213+
(
214+
7719472615821079694904732333912527190217998977709370935963838933860875309329, # noqa: E501
215+
HexStr("0x" + "1" * 64),
216+
),
217+
(3567, Web3ValueError),
218+
(3.14, Web3ValueError),
219+
],
220+
ids=[
221+
"valid-0x-hex-string",
222+
"valid-no-0x-hex-string",
223+
"invalid-0x-hex-string",
224+
"invalid-no-0x-hex-string",
225+
"valid-32-byte-value",
226+
"invalid-31-byte-value",
227+
"invalid-33-byte-value",
228+
"valid-integer",
229+
"invalid-integer",
230+
"invalid-float",
231+
],
232+
)
233+
def test_storage_key_to_hexstr(input_value, expected_output):
234+
if isinstance(expected_output, type) and issubclass(expected_output, Exception):
235+
with pytest.raises(expected_output):
236+
storage_key_to_hexstr(input_value)
237+
else:
238+
assert storage_key_to_hexstr(input_value) == expected_output

web3/_utils/method_formatters.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,28 @@ def apply_list_to_array_formatter(formatter: Any) -> Callable[..., Any]:
187187
return to_list(apply_formatter_to_array(formatter))
188188

189189

190+
def storage_key_to_hexstr(value: Union[bytes, int, str]) -> HexStr:
191+
if not isinstance(value, (bytes, int, str)):
192+
raise Web3ValueError(
193+
f"Storage key must be one of bytes, int, str, got {type(value)}"
194+
)
195+
if isinstance(value, str):
196+
if value.startswith("0x") and len(value) == 66:
197+
return HexStr(value)
198+
elif len(value) == 64:
199+
return HexStr(f"0x{value}")
200+
elif isinstance(value, bytes):
201+
if len(value) == 32:
202+
return HexBytes(value).to_0x_hex()
203+
elif isinstance(value, int):
204+
return storage_key_to_hexstr(hex(value))
205+
raise Web3ValueError(f"Storage key must be a 32-byte value, got {value!r}")
206+
207+
190208
ACCESS_LIST_FORMATTER = type_aware_apply_formatters_to_dict(
191209
{
192210
"address": to_checksum_address,
193-
"storageKeys": apply_list_to_array_formatter(to_hexbytes(64)),
211+
"storageKeys": apply_list_to_array_formatter(storage_key_to_hexstr),
194212
}
195213
)
196214

web3/_utils/module_testing/eth_module.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ async def test_eth_create_access_list(
12101210
assert len(access_list) > 0
12111211
assert access_list[0]["address"] is not None
12121212
assert is_checksum_address(access_list[0]["address"])
1213-
assert len(access_list[0]["storageKeys"][0]) == 32
1213+
assert len(access_list[0]["storageKeys"][0]) == 66
12141214
assert int(response["gasUsed"]) >= 0
12151215

12161216
# assert the result can be used directly in a transaction dict
@@ -2786,7 +2786,7 @@ def test_eth_create_access_list(
27862786
assert len(access_list) > 0
27872787
assert access_list[0]["address"] is not None
27882788
assert is_checksum_address(access_list[0]["address"])
2789-
assert len(access_list[0]["storageKeys"][0]) == 32
2789+
assert len(access_list[0]["storageKeys"][0]) == 66
27902790
assert int(response["gasUsed"]) >= 0
27912791

27922792
# assert the result can be used directly in a transaction dict

web3/providers/persistent/persistent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
ProviderConnectionError,
2424
TaskNotRunning,
2525
TimeExhausted,
26+
Web3AttributeError,
2627
)
2728
from web3.providers.async_base import (
2829
AsyncJSONBaseProvider,
@@ -71,7 +72,7 @@ def get_endpoint_uri_or_ipc_path(self) -> str:
7172
elif hasattr(self, "ipc_path"):
7273
return str(self.ipc_path)
7374
else:
74-
raise AttributeError(
75+
raise Web3AttributeError(
7576
"`PersistentConnectionProvider` must have either `endpoint_uri` or "
7677
"`ipc_path` attribute."
7778
)

0 commit comments

Comments
 (0)