web3 7.0.0b1__py3-none-any.whl → 7.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ens/__init__.py +13 -2
- ens/_normalization.py +4 -4
- ens/async_ens.py +31 -21
- ens/base_ens.py +3 -1
- ens/contract_data.py +2 -2
- ens/ens.py +14 -11
- ens/exceptions.py +16 -29
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +33 -41
- web3/__init__.py +23 -12
- web3/_utils/abi.py +162 -274
- web3/_utils/async_transactions.py +34 -20
- web3/_utils/batching.py +217 -0
- web3/_utils/blocks.py +6 -2
- web3/_utils/caching/__init__.py +12 -0
- web3/_utils/caching/caching_utils.py +433 -0
- web3/_utils/caching/request_caching_validation.py +287 -0
- web3/_utils/compat/__init__.py +2 -3
- web3/_utils/contract_sources/compile_contracts.py +1 -1
- web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +42 -0
- web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
- web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/event_contracts.py +50 -5
- web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
- web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
- web3/_utils/contracts.py +172 -220
- web3/_utils/datatypes.py +5 -1
- web3/_utils/decorators.py +6 -1
- web3/_utils/empty.py +1 -1
- web3/_utils/encoding.py +16 -12
- web3/_utils/error_formatters_utils.py +5 -3
- web3/_utils/events.py +78 -72
- web3/_utils/fee_utils.py +1 -3
- web3/_utils/filters.py +24 -22
- web3/_utils/formatters.py +2 -2
- web3/_utils/http.py +8 -2
- web3/_utils/http_session_manager.py +314 -0
- web3/_utils/math.py +14 -15
- web3/_utils/method_formatters.py +161 -34
- web3/_utils/module.py +2 -1
- web3/_utils/module_testing/__init__.py +3 -2
- web3/_utils/module_testing/eth_module.py +736 -583
- web3/_utils/module_testing/go_ethereum_debug_module.py +128 -0
- web3/_utils/module_testing/module_testing_utils.py +81 -24
- web3/_utils/module_testing/persistent_connection_provider.py +702 -220
- web3/_utils/module_testing/utils.py +114 -33
- web3/_utils/module_testing/web3_module.py +438 -17
- web3/_utils/normalizers.py +13 -11
- web3/_utils/rpc_abi.py +10 -22
- web3/_utils/threads.py +8 -7
- web3/_utils/transactions.py +32 -25
- web3/_utils/type_conversion.py +5 -1
- web3/_utils/validation.py +20 -17
- web3/beacon/__init__.py +5 -0
- web3/beacon/api_endpoints.py +3 -0
- web3/beacon/async_beacon.py +29 -6
- web3/beacon/beacon.py +24 -6
- web3/contract/__init__.py +7 -0
- web3/contract/async_contract.py +285 -82
- web3/contract/base_contract.py +556 -258
- web3/contract/contract.py +295 -84
- web3/contract/utils.py +251 -55
- web3/datastructures.py +56 -41
- web3/eth/__init__.py +7 -0
- web3/eth/async_eth.py +89 -69
- web3/eth/base_eth.py +7 -3
- web3/eth/eth.py +43 -66
- web3/exceptions.py +158 -83
- web3/gas_strategies/time_based.py +8 -6
- web3/geth.py +53 -184
- web3/main.py +77 -43
- web3/manager.py +368 -101
- web3/method.py +43 -15
- web3/middleware/__init__.py +26 -8
- web3/middleware/attrdict.py +12 -22
- web3/middleware/base.py +55 -2
- web3/middleware/filter.py +45 -23
- web3/middleware/formatting.py +6 -3
- web3/middleware/names.py +4 -1
- web3/middleware/signing.py +15 -6
- web3/middleware/stalecheck.py +2 -1
- web3/module.py +62 -26
- web3/providers/__init__.py +21 -0
- web3/providers/async_base.py +93 -38
- web3/providers/base.py +85 -40
- web3/providers/eth_tester/__init__.py +5 -0
- web3/providers/eth_tester/defaults.py +2 -55
- web3/providers/eth_tester/main.py +57 -35
- web3/providers/eth_tester/middleware.py +16 -17
- web3/providers/ipc.py +42 -18
- web3/providers/legacy_websocket.py +27 -2
- web3/providers/persistent/__init__.py +7 -0
- web3/providers/persistent/async_ipc.py +61 -121
- web3/providers/persistent/persistent.py +324 -17
- web3/providers/persistent/persistent_connection.py +54 -5
- web3/providers/persistent/request_processor.py +136 -56
- web3/providers/persistent/subscription_container.py +56 -0
- web3/providers/persistent/subscription_manager.py +233 -0
- web3/providers/persistent/websocket.py +29 -92
- web3/providers/rpc/__init__.py +5 -0
- web3/providers/rpc/async_rpc.py +73 -18
- web3/providers/rpc/rpc.py +73 -30
- web3/providers/rpc/utils.py +1 -13
- web3/scripts/install_pre_releases.py +33 -0
- web3/scripts/parse_pygeth_version.py +16 -0
- web3/testing.py +4 -4
- web3/tracing.py +9 -5
- web3/types.py +141 -74
- web3/utils/__init__.py +64 -5
- web3/utils/abi.py +790 -10
- web3/utils/address.py +8 -0
- web3/utils/async_exception_handling.py +20 -11
- web3/utils/caching.py +34 -4
- web3/utils/exception_handling.py +9 -12
- web3/utils/subscriptions.py +285 -0
- {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/LICENSE +1 -1
- web3-7.7.0.dist-info/METADATA +130 -0
- web3-7.7.0.dist-info/RECORD +171 -0
- {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
- {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/top_level.txt +0 -1
- ethpm/__init__.py +0 -20
- ethpm/_utils/__init__.py +0 -0
- ethpm/_utils/backend.py +0 -93
- ethpm/_utils/cache.py +0 -44
- ethpm/_utils/chains.py +0 -119
- ethpm/_utils/contract.py +0 -35
- ethpm/_utils/deployments.py +0 -145
- ethpm/_utils/ipfs.py +0 -116
- ethpm/_utils/protobuf/__init__.py +0 -0
- ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
- ethpm/_utils/registry.py +0 -29
- ethpm/assets/__init__.py +0 -0
- ethpm/assets/ens/v3.json +0 -1
- ethpm/assets/escrow/with_bytecode_v3.json +0 -1
- ethpm/assets/ipfs_file.proto +0 -32
- ethpm/assets/owned/output_v3.json +0 -1
- ethpm/assets/owned/with_contract_type_v3.json +0 -1
- ethpm/assets/registry/contracts/Authority.sol +0 -156
- ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
- ethpm/assets/registry/contracts/PackageDB.sol +0 -225
- ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
- ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
- ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
- ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
- ethpm/assets/registry/solc_input.json +0 -1
- ethpm/assets/registry/solc_output.json +0 -1
- ethpm/assets/registry/v3.json +0 -1
- ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
- ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
- ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
- ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
- ethpm/assets/simple-registry/solc_input.json +0 -33
- ethpm/assets/simple-registry/solc_output.json +0 -1
- ethpm/assets/simple-registry/v3.json +0 -1
- ethpm/assets/standard-token/output_v3.json +0 -1
- ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
- ethpm/assets/vyper_registry/0.1.0.json +0 -1
- ethpm/assets/vyper_registry/registry.vy +0 -216
- ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
- ethpm/backends/__init__.py +0 -0
- ethpm/backends/base.py +0 -43
- ethpm/backends/http.py +0 -108
- ethpm/backends/ipfs.py +0 -219
- ethpm/backends/registry.py +0 -154
- ethpm/constants.py +0 -17
- ethpm/contract.py +0 -187
- ethpm/dependencies.py +0 -58
- ethpm/deployments.py +0 -80
- ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
- ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
- ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
- ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
- ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
- ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
- ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
- ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
- ethpm/ethpm-spec/examples/owned/v3.json +0 -1
- ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
- ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
- ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
- ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
- ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
- ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
- ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
- ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
- ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
- ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
- ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
- ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
- ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
- ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
- ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
- ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
- ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
- ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
- ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
- ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
- ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
- ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
- ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
- ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
- ethpm/ethpm-spec/spec/package.spec.json +0 -379
- ethpm/ethpm-spec/spec/v3.spec.json +0 -483
- ethpm/exceptions.py +0 -68
- ethpm/package.py +0 -438
- ethpm/tools/__init__.py +0 -4
- ethpm/tools/builder.py +0 -930
- ethpm/tools/checker.py +0 -312
- ethpm/tools/get_manifest.py +0 -19
- ethpm/uri.py +0 -141
- ethpm/validation/__init__.py +0 -0
- ethpm/validation/manifest.py +0 -146
- ethpm/validation/misc.py +0 -39
- ethpm/validation/package.py +0 -80
- ethpm/validation/uri.py +0 -163
- web3/_utils/caching.py +0 -155
- web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
- web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
- web3/_utils/request.py +0 -265
- web3/pm.py +0 -602
- web3/tools/__init__.py +0 -4
- web3/tools/benchmark/__init__.py +0 -0
- web3/tools/benchmark/main.py +0 -185
- web3/tools/benchmark/node.py +0 -126
- web3/tools/benchmark/reporting.py +0 -39
- web3/tools/benchmark/utils.py +0 -69
- web3/tools/pytest_ethereum/__init__.py +0 -0
- web3/tools/pytest_ethereum/_utils.py +0 -145
- web3/tools/pytest_ethereum/deployer.py +0 -48
- web3/tools/pytest_ethereum/exceptions.py +0 -22
- web3/tools/pytest_ethereum/linker.py +0 -128
- web3/tools/pytest_ethereum/plugins.py +0 -33
- web3-7.0.0b1.dist-info/METADATA +0 -114
- web3-7.0.0b1.dist-info/RECORD +0 -280
- web3-7.0.0b1.dist-info/entry_points.txt +0 -2
- /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import pytest
|
|
3
|
-
from typing import (
|
|
4
|
-
TYPE_CHECKING,
|
|
5
|
-
cast,
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
from eth_typing import (
|
|
9
|
-
ChecksumAddress,
|
|
10
|
-
)
|
|
11
|
-
from eth_utils import (
|
|
12
|
-
is_checksum_address,
|
|
13
|
-
is_list_like,
|
|
14
|
-
is_same_address,
|
|
15
|
-
is_string,
|
|
16
|
-
)
|
|
17
|
-
from hexbytes import (
|
|
18
|
-
HexBytes,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
from web3 import (
|
|
22
|
-
constants,
|
|
23
|
-
)
|
|
24
|
-
from web3.datastructures import (
|
|
25
|
-
AttributeDict,
|
|
26
|
-
)
|
|
27
|
-
from web3.types import (
|
|
28
|
-
TxParams,
|
|
29
|
-
Wei,
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
if TYPE_CHECKING:
|
|
33
|
-
from web3 import ( # noqa: F401
|
|
34
|
-
AsyncWeb3,
|
|
35
|
-
Web3,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
PRIVATE_KEY_HEX = "0x56ebb41875ceedd42e395f730e03b5c44989393c9f0484ee6bc05f933673458f"
|
|
39
|
-
SECOND_PRIVATE_KEY_HEX = (
|
|
40
|
-
"0x56ebb41875ceedd42e395f730e03b5c44989393c9f0484ee6bc05f9336712345"
|
|
41
|
-
)
|
|
42
|
-
THIRD_PRIVATE_KEY_HEX = (
|
|
43
|
-
"0x56ebb41875ceedd42e395f730e03b5c44989393c9f0484ee6bc05f9336754321"
|
|
44
|
-
)
|
|
45
|
-
PASSWORD = "web3-testing"
|
|
46
|
-
ADDRESS = "0x844B417c0C58B02c2224306047B9fb0D3264fE8c"
|
|
47
|
-
SECOND_ADDRESS = "0xB96b6B21053e67BA59907E252D990C71742c41B8"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
PRIVATE_KEY_FOR_UNLOCK = (
|
|
51
|
-
"0x392f63a79b1ff8774845f3fa69de4a13800a59e7083f5187f1558f0797ad0f01"
|
|
52
|
-
)
|
|
53
|
-
ACCOUNT_FOR_UNLOCK = "0x12efDc31B1a8FA1A1e756DFD8A1601055C971E13"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class GoEthereumPersonalModuleTest:
|
|
57
|
-
def test_personal_import_raw_key(self, w3: "Web3") -> None:
|
|
58
|
-
actual = w3.geth.personal.import_raw_key(PRIVATE_KEY_HEX, PASSWORD)
|
|
59
|
-
assert actual == ADDRESS
|
|
60
|
-
|
|
61
|
-
def test_personal_list_accounts(self, w3: "Web3") -> None:
|
|
62
|
-
accounts = w3.geth.personal.list_accounts()
|
|
63
|
-
assert is_list_like(accounts)
|
|
64
|
-
assert len(accounts) > 0
|
|
65
|
-
assert all((is_checksum_address(item) for item in accounts))
|
|
66
|
-
|
|
67
|
-
def test_personal_list_wallets(self, w3: "Web3") -> None:
|
|
68
|
-
wallets = w3.geth.personal.list_wallets()
|
|
69
|
-
assert is_list_like(wallets)
|
|
70
|
-
assert len(wallets) > 0
|
|
71
|
-
assert is_checksum_address(wallets[0]["accounts"][0]["address"])
|
|
72
|
-
assert is_string(wallets[0]["accounts"][0]["url"])
|
|
73
|
-
assert is_string(wallets[0]["status"])
|
|
74
|
-
assert is_string(wallets[0]["url"])
|
|
75
|
-
|
|
76
|
-
def test_personal_lock_account(
|
|
77
|
-
self, w3: "Web3", unlockable_account_dual_type: ChecksumAddress
|
|
78
|
-
) -> None:
|
|
79
|
-
# TODO: how do we test this better?
|
|
80
|
-
w3.geth.personal.lock_account(unlockable_account_dual_type)
|
|
81
|
-
|
|
82
|
-
def test_personal_unlock_account_success(
|
|
83
|
-
self,
|
|
84
|
-
w3: "Web3",
|
|
85
|
-
unlockable_account_dual_type: ChecksumAddress,
|
|
86
|
-
unlockable_account_pw: str,
|
|
87
|
-
) -> None:
|
|
88
|
-
result = w3.geth.personal.unlock_account(
|
|
89
|
-
unlockable_account_dual_type, unlockable_account_pw
|
|
90
|
-
)
|
|
91
|
-
assert result is True
|
|
92
|
-
|
|
93
|
-
def test_personal_unlock_account_failure(
|
|
94
|
-
self, w3: "Web3", unlockable_account_dual_type: ChecksumAddress
|
|
95
|
-
) -> None:
|
|
96
|
-
with pytest.raises(ValueError):
|
|
97
|
-
w3.geth.personal.unlock_account(
|
|
98
|
-
unlockable_account_dual_type, "bad-password"
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
def test_personal_new_account(self, w3: "Web3") -> None:
|
|
102
|
-
new_account = w3.geth.personal.new_account(PASSWORD)
|
|
103
|
-
assert is_checksum_address(new_account)
|
|
104
|
-
|
|
105
|
-
def test_personal_send_transaction(
|
|
106
|
-
self,
|
|
107
|
-
w3: "Web3",
|
|
108
|
-
unlockable_account_dual_type: ChecksumAddress,
|
|
109
|
-
unlockable_account_pw: str,
|
|
110
|
-
) -> None:
|
|
111
|
-
assert (
|
|
112
|
-
w3.eth.get_balance(unlockable_account_dual_type) > constants.WEI_PER_ETHER
|
|
113
|
-
)
|
|
114
|
-
txn_params: TxParams = {
|
|
115
|
-
"from": unlockable_account_dual_type,
|
|
116
|
-
"to": unlockable_account_dual_type,
|
|
117
|
-
"gas": 21000,
|
|
118
|
-
"value": Wei(1),
|
|
119
|
-
"gasPrice": w3.to_wei(1, "gwei"),
|
|
120
|
-
}
|
|
121
|
-
txn_hash = w3.geth.personal.send_transaction(txn_params, unlockable_account_pw)
|
|
122
|
-
assert txn_hash
|
|
123
|
-
transaction = w3.eth.get_transaction(txn_hash)
|
|
124
|
-
|
|
125
|
-
assert is_same_address(
|
|
126
|
-
transaction["from"], cast(ChecksumAddress, txn_params["from"])
|
|
127
|
-
)
|
|
128
|
-
assert is_same_address(
|
|
129
|
-
transaction["to"], cast(ChecksumAddress, txn_params["to"])
|
|
130
|
-
)
|
|
131
|
-
assert transaction["gas"] == txn_params["gas"]
|
|
132
|
-
assert transaction["value"] == txn_params["value"]
|
|
133
|
-
assert transaction["gasPrice"] == txn_params["gasPrice"]
|
|
134
|
-
|
|
135
|
-
def test_personal_sign_and_ecrecover(
|
|
136
|
-
self,
|
|
137
|
-
w3: "Web3",
|
|
138
|
-
unlockable_account_dual_type: ChecksumAddress,
|
|
139
|
-
unlockable_account_pw: str,
|
|
140
|
-
) -> None:
|
|
141
|
-
message = "test-web3-geth-personal-sign"
|
|
142
|
-
signature = w3.geth.personal.sign(
|
|
143
|
-
message, unlockable_account_dual_type, unlockable_account_pw
|
|
144
|
-
)
|
|
145
|
-
signer = w3.geth.personal.ec_recover(message, signature)
|
|
146
|
-
assert is_same_address(signer, unlockable_account_dual_type)
|
|
147
|
-
|
|
148
|
-
@pytest.mark.xfail(
|
|
149
|
-
reason="personal_sign_typed_data JSON RPC call has not been released in geth"
|
|
150
|
-
)
|
|
151
|
-
def test_personal_sign_typed_data(
|
|
152
|
-
self,
|
|
153
|
-
w3: "Web3",
|
|
154
|
-
unlockable_account_dual_type: ChecksumAddress,
|
|
155
|
-
unlockable_account_pw: str,
|
|
156
|
-
) -> None:
|
|
157
|
-
typed_message = """
|
|
158
|
-
{
|
|
159
|
-
"types": {
|
|
160
|
-
"EIP712Domain": [
|
|
161
|
-
{"name": "name", "type": "string"},
|
|
162
|
-
{"name": "version", "type": "string"},
|
|
163
|
-
{"name": "chainId", "type": "uint256"},
|
|
164
|
-
{"name": "verifyingContract", "type": "address"}
|
|
165
|
-
],
|
|
166
|
-
"Person": [
|
|
167
|
-
{"name": "name", "type": "string"},
|
|
168
|
-
{"name": "wallet", "type": "address"}
|
|
169
|
-
],
|
|
170
|
-
"Mail": [
|
|
171
|
-
{"name": "from", "type": "Person"},
|
|
172
|
-
{"name": "to", "type": "Person"},
|
|
173
|
-
{"name": "contents", "type": "string"}
|
|
174
|
-
]
|
|
175
|
-
},
|
|
176
|
-
"primaryType": "Mail",
|
|
177
|
-
"domain": {
|
|
178
|
-
"name": "Ether Mail",
|
|
179
|
-
"version": "1",
|
|
180
|
-
"chainId": "0x01",
|
|
181
|
-
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
|
|
182
|
-
},
|
|
183
|
-
"message": {
|
|
184
|
-
"from": {
|
|
185
|
-
"name": "Cow",
|
|
186
|
-
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
|
|
187
|
-
},
|
|
188
|
-
"to": {
|
|
189
|
-
"name": "Bob",
|
|
190
|
-
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
|
|
191
|
-
},
|
|
192
|
-
"contents": "Hello, Bob!"
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
"""
|
|
196
|
-
signature = HexBytes(
|
|
197
|
-
w3.geth.personal.sign_typed_data(
|
|
198
|
-
json.loads(typed_message),
|
|
199
|
-
unlockable_account_dual_type,
|
|
200
|
-
unlockable_account_pw,
|
|
201
|
-
)
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
expected_signature = HexBytes(
|
|
205
|
-
"0xc8b56aaeefd10ab4005c2455daf28d9082af661ac347cd"
|
|
206
|
-
"b612d5b5e11f339f2055be831bf57a6e6cb5f6d93448fa35"
|
|
207
|
-
"c1bd56fe1d745ffa101e74697108668c401c"
|
|
208
|
-
)
|
|
209
|
-
assert signature == expected_signature
|
|
210
|
-
assert len(signature) == 32 + 32 + 1
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
class GoEthereumAsyncPersonalModuleTest:
|
|
214
|
-
@pytest.mark.asyncio
|
|
215
|
-
async def test_async_sign_and_ec_recover(
|
|
216
|
-
self,
|
|
217
|
-
async_w3: "AsyncWeb3",
|
|
218
|
-
async_unlockable_account_dual_type: ChecksumAddress,
|
|
219
|
-
unlockable_account_pw: str,
|
|
220
|
-
) -> None:
|
|
221
|
-
message = "This is a test"
|
|
222
|
-
signature = await async_w3.geth.personal.sign(
|
|
223
|
-
message, async_unlockable_account_dual_type, unlockable_account_pw
|
|
224
|
-
)
|
|
225
|
-
address = await async_w3.geth.personal.ec_recover(message, signature)
|
|
226
|
-
assert is_same_address(async_unlockable_account_dual_type, address)
|
|
227
|
-
|
|
228
|
-
@pytest.mark.asyncio
|
|
229
|
-
async def test_async_import_key(self, async_w3: "AsyncWeb3") -> None:
|
|
230
|
-
address = await async_w3.geth.personal.import_raw_key(
|
|
231
|
-
THIRD_PRIVATE_KEY_HEX, "Testing"
|
|
232
|
-
)
|
|
233
|
-
assert address is not None
|
|
234
|
-
|
|
235
|
-
@pytest.mark.asyncio
|
|
236
|
-
async def test_async_list_accounts(self, async_w3: "AsyncWeb3") -> None:
|
|
237
|
-
accounts = await async_w3.geth.personal.list_accounts()
|
|
238
|
-
assert len(accounts) > 0
|
|
239
|
-
|
|
240
|
-
@pytest.mark.asyncio
|
|
241
|
-
async def test_async_list_wallets(self, async_w3: "AsyncWeb3") -> None:
|
|
242
|
-
wallets = await async_w3.geth.personal.list_wallets()
|
|
243
|
-
assert isinstance(wallets[0], AttributeDict)
|
|
244
|
-
|
|
245
|
-
@pytest.mark.asyncio
|
|
246
|
-
async def test_async_new_account(self, async_w3: "AsyncWeb3") -> None:
|
|
247
|
-
passphrase = "Create New Account"
|
|
248
|
-
account = await async_w3.geth.personal.new_account(passphrase)
|
|
249
|
-
assert is_checksum_address(account)
|
|
250
|
-
|
|
251
|
-
@pytest.mark.asyncio
|
|
252
|
-
async def test_async_unlock_lock_account(
|
|
253
|
-
self,
|
|
254
|
-
async_w3: "AsyncWeb3",
|
|
255
|
-
async_unlockable_account_dual_type: ChecksumAddress,
|
|
256
|
-
unlockable_account_pw: str,
|
|
257
|
-
) -> None:
|
|
258
|
-
unlocked = await async_w3.geth.personal.unlock_account(
|
|
259
|
-
async_unlockable_account_dual_type, unlockable_account_pw
|
|
260
|
-
)
|
|
261
|
-
assert unlocked is True
|
|
262
|
-
locked = await async_w3.geth.personal.lock_account(
|
|
263
|
-
async_unlockable_account_dual_type
|
|
264
|
-
)
|
|
265
|
-
assert locked is True
|
|
266
|
-
|
|
267
|
-
@pytest.mark.asyncio
|
|
268
|
-
async def test_async_send_transaction(
|
|
269
|
-
self,
|
|
270
|
-
async_w3: "AsyncWeb3",
|
|
271
|
-
async_unlockable_account_dual_type: ChecksumAddress,
|
|
272
|
-
unlockable_account_pw: str,
|
|
273
|
-
) -> None:
|
|
274
|
-
tx_params = TxParams()
|
|
275
|
-
tx_params["to"] = async_unlockable_account_dual_type
|
|
276
|
-
tx_params["from"] = async_unlockable_account_dual_type
|
|
277
|
-
tx_params["value"] = Wei(123)
|
|
278
|
-
response = await async_w3.geth.personal.send_transaction(
|
|
279
|
-
tx_params, unlockable_account_pw
|
|
280
|
-
)
|
|
281
|
-
assert response is not None
|
|
282
|
-
|
|
283
|
-
@pytest.mark.xfail(
|
|
284
|
-
reason="personal_signTypedData JSON RPC call has not been released in geth"
|
|
285
|
-
)
|
|
286
|
-
@pytest.mark.asyncio
|
|
287
|
-
async def test_async_sign_typed_data(
|
|
288
|
-
self,
|
|
289
|
-
async_w3: "AsyncWeb3",
|
|
290
|
-
async_unlockable_account_dual_type: ChecksumAddress,
|
|
291
|
-
unlockable_account_pw: str,
|
|
292
|
-
) -> None:
|
|
293
|
-
message = {"message": "This is a test"}
|
|
294
|
-
signature = await async_w3.geth.personal.sign_typed_data(
|
|
295
|
-
message, async_unlockable_account_dual_type, unlockable_account_pw
|
|
296
|
-
)
|
|
297
|
-
address = await async_w3.geth.personal.ec_recover(
|
|
298
|
-
json.dumps(message), signature
|
|
299
|
-
)
|
|
300
|
-
assert is_same_address(async_unlockable_account_dual_type, address)
|
web3/_utils/request.py
DELETED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from concurrent.futures import (
|
|
3
|
-
ThreadPoolExecutor,
|
|
4
|
-
)
|
|
5
|
-
import logging
|
|
6
|
-
import os
|
|
7
|
-
import threading
|
|
8
|
-
from typing import (
|
|
9
|
-
Any,
|
|
10
|
-
Dict,
|
|
11
|
-
List,
|
|
12
|
-
Optional,
|
|
13
|
-
Union,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
from aiohttp import (
|
|
17
|
-
ClientResponse,
|
|
18
|
-
ClientSession,
|
|
19
|
-
ClientTimeout,
|
|
20
|
-
)
|
|
21
|
-
from eth_typing import (
|
|
22
|
-
URI,
|
|
23
|
-
)
|
|
24
|
-
import requests
|
|
25
|
-
|
|
26
|
-
from web3._utils.async_caching import (
|
|
27
|
-
async_lock,
|
|
28
|
-
)
|
|
29
|
-
from web3._utils.caching import (
|
|
30
|
-
generate_cache_key,
|
|
31
|
-
)
|
|
32
|
-
from web3.utils.caching import (
|
|
33
|
-
SimpleCache,
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
logger = logging.getLogger(__name__)
|
|
37
|
-
|
|
38
|
-
DEFAULT_TIMEOUT = 10
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def get_default_http_endpoint() -> URI:
|
|
42
|
-
return URI(os.environ.get("WEB3_HTTP_PROVIDER_URI", "http://localhost:8545"))
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
_session_cache = SimpleCache()
|
|
46
|
-
_session_cache_lock = threading.Lock()
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def cache_and_return_session(
|
|
50
|
-
endpoint_uri: URI, session: requests.Session = None
|
|
51
|
-
) -> requests.Session:
|
|
52
|
-
# cache key should have a unique thread identifier
|
|
53
|
-
cache_key = generate_cache_key(f"{threading.get_ident()}:{endpoint_uri}")
|
|
54
|
-
|
|
55
|
-
cached_session = _session_cache.get_cache_entry(cache_key)
|
|
56
|
-
if cached_session is not None:
|
|
57
|
-
# If read from cache yields a session, no need to lock; return the session.
|
|
58
|
-
# Sync is a bit simpler in this way since a `requests.Session` doesn't really
|
|
59
|
-
# "close" in the same way that an async `ClientSession` does. When "closed", it
|
|
60
|
-
# still uses http / https adapters successfully if a request is made.
|
|
61
|
-
return cached_session
|
|
62
|
-
|
|
63
|
-
if session is None:
|
|
64
|
-
session = requests.Session()
|
|
65
|
-
|
|
66
|
-
with _session_cache_lock:
|
|
67
|
-
cached_session, evicted_items = _session_cache.cache(cache_key, session)
|
|
68
|
-
logger.debug(f"Session cached: {endpoint_uri}, {cached_session}")
|
|
69
|
-
|
|
70
|
-
if evicted_items is not None:
|
|
71
|
-
evicted_sessions = evicted_items.values()
|
|
72
|
-
for evicted_session in evicted_sessions:
|
|
73
|
-
logger.debug(
|
|
74
|
-
f"Session cache full. Session evicted from cache: {evicted_session}",
|
|
75
|
-
)
|
|
76
|
-
threading.Timer(
|
|
77
|
-
DEFAULT_TIMEOUT + 0.1,
|
|
78
|
-
_close_evicted_sessions,
|
|
79
|
-
args=[evicted_sessions],
|
|
80
|
-
).start()
|
|
81
|
-
|
|
82
|
-
return cached_session
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def get_response_from_get_request(
|
|
86
|
-
endpoint_uri: URI, *args: Any, **kwargs: Any
|
|
87
|
-
) -> requests.Response:
|
|
88
|
-
kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
|
|
89
|
-
session = cache_and_return_session(endpoint_uri)
|
|
90
|
-
response = session.get(endpoint_uri, *args, **kwargs)
|
|
91
|
-
return response
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def json_make_get_request(
|
|
95
|
-
endpoint_uri: URI, *args: Any, **kwargs: Any
|
|
96
|
-
) -> Dict[str, Any]:
|
|
97
|
-
response = get_response_from_get_request(endpoint_uri, *args, **kwargs)
|
|
98
|
-
response.raise_for_status()
|
|
99
|
-
return response.json()
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def get_response_from_post_request(
|
|
103
|
-
endpoint_uri: URI, *args: Any, **kwargs: Any
|
|
104
|
-
) -> requests.Response:
|
|
105
|
-
kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
|
|
106
|
-
session = cache_and_return_session(endpoint_uri)
|
|
107
|
-
response = session.post(endpoint_uri, *args, **kwargs)
|
|
108
|
-
return response
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def make_post_request(
|
|
112
|
-
endpoint_uri: URI, data: Union[bytes, Dict[str, Any]], *args: Any, **kwargs: Any
|
|
113
|
-
) -> bytes:
|
|
114
|
-
response = get_response_from_post_request(endpoint_uri, data=data, *args, **kwargs)
|
|
115
|
-
response.raise_for_status()
|
|
116
|
-
return response.content
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def _close_evicted_sessions(evicted_sessions: List[requests.Session]) -> None:
|
|
120
|
-
for evicted_session in evicted_sessions:
|
|
121
|
-
evicted_session.close()
|
|
122
|
-
logger.debug(f"Closed evicted session: {evicted_session}")
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
# --- async --- #
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
_async_session_cache = SimpleCache()
|
|
129
|
-
_async_session_cache_lock = threading.Lock()
|
|
130
|
-
_async_session_pool = ThreadPoolExecutor(max_workers=1)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
async def async_cache_and_return_session(
|
|
134
|
-
endpoint_uri: URI,
|
|
135
|
-
session: Optional[ClientSession] = None,
|
|
136
|
-
) -> ClientSession:
|
|
137
|
-
# cache key should have a unique thread identifier
|
|
138
|
-
cache_key = generate_cache_key(f"{threading.get_ident()}:{endpoint_uri}")
|
|
139
|
-
|
|
140
|
-
evicted_items = None
|
|
141
|
-
async with async_lock(_async_session_pool, _async_session_cache_lock):
|
|
142
|
-
if cache_key not in _async_session_cache:
|
|
143
|
-
if session is None:
|
|
144
|
-
session = ClientSession(raise_for_status=True)
|
|
145
|
-
|
|
146
|
-
cached_session, evicted_items = _async_session_cache.cache(
|
|
147
|
-
cache_key, session
|
|
148
|
-
)
|
|
149
|
-
logger.debug(f"Async session cached: {endpoint_uri}, {cached_session}")
|
|
150
|
-
|
|
151
|
-
else:
|
|
152
|
-
# get the cached session
|
|
153
|
-
cached_session = _async_session_cache.get_cache_entry(cache_key)
|
|
154
|
-
session_is_closed = cached_session.closed
|
|
155
|
-
session_loop_is_closed = cached_session._loop.is_closed()
|
|
156
|
-
|
|
157
|
-
warning = (
|
|
158
|
-
"Async session was closed"
|
|
159
|
-
if session_is_closed
|
|
160
|
-
else (
|
|
161
|
-
"Loop was closed for async session"
|
|
162
|
-
if session_loop_is_closed
|
|
163
|
-
else None
|
|
164
|
-
)
|
|
165
|
-
)
|
|
166
|
-
if warning:
|
|
167
|
-
logger.debug(
|
|
168
|
-
f"{warning}: {endpoint_uri}, {cached_session}. "
|
|
169
|
-
f"Creating and caching a new async session for uri."
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
_async_session_cache._data.pop(cache_key)
|
|
173
|
-
if not session_is_closed:
|
|
174
|
-
# if loop was closed but not the session, close the session
|
|
175
|
-
await cached_session.close()
|
|
176
|
-
logger.debug(
|
|
177
|
-
f"Async session closed and evicted from cache: {cached_session}"
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
# replace stale session with a new session at the cache key
|
|
181
|
-
_session = ClientSession(raise_for_status=True)
|
|
182
|
-
cached_session, evicted_items = _async_session_cache.cache(
|
|
183
|
-
cache_key, _session
|
|
184
|
-
)
|
|
185
|
-
logger.debug(f"Async session cached: {endpoint_uri}, {cached_session}")
|
|
186
|
-
|
|
187
|
-
if evicted_items is not None:
|
|
188
|
-
# At this point the evicted sessions are already popped out of the cache and
|
|
189
|
-
# just stored in the `evicted_sessions` dict. So we can kick off a future task
|
|
190
|
-
# to close them and it should be safe to pop out of the lock here.
|
|
191
|
-
evicted_sessions = evicted_items.values()
|
|
192
|
-
for evicted_session in evicted_sessions:
|
|
193
|
-
logger.debug(
|
|
194
|
-
"Async session cache full. Session evicted from cache: "
|
|
195
|
-
f"{evicted_session}",
|
|
196
|
-
)
|
|
197
|
-
# Kick off a future task, in a separate thread, to close the evicted
|
|
198
|
-
# sessions. In the case that the cache filled very quickly and some
|
|
199
|
-
# sessions have been evicted before their original request has been made,
|
|
200
|
-
# we set the timer to a bit more than the `DEFAULT_TIMEOUT` for a call. This
|
|
201
|
-
# should make it so that any call from an evicted session can still be made
|
|
202
|
-
# before the session is closed.
|
|
203
|
-
threading.Timer(
|
|
204
|
-
DEFAULT_TIMEOUT + 0.1,
|
|
205
|
-
_async_close_evicted_sessions,
|
|
206
|
-
args=[evicted_sessions],
|
|
207
|
-
).start()
|
|
208
|
-
|
|
209
|
-
return cached_session
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
async def async_get_response_from_get_request(
|
|
213
|
-
endpoint_uri: URI, *args: Any, **kwargs: Any
|
|
214
|
-
) -> ClientResponse:
|
|
215
|
-
kwargs.setdefault("timeout", ClientTimeout(DEFAULT_TIMEOUT))
|
|
216
|
-
session = await async_cache_and_return_session(endpoint_uri)
|
|
217
|
-
response = await session.get(endpoint_uri, *args, **kwargs)
|
|
218
|
-
return response
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
async def async_json_make_get_request(
|
|
222
|
-
endpoint_uri: URI, *args: Any, **kwargs: Any
|
|
223
|
-
) -> Dict[str, Any]:
|
|
224
|
-
response = await async_get_response_from_get_request(endpoint_uri, *args, **kwargs)
|
|
225
|
-
response.raise_for_status()
|
|
226
|
-
return await response.json()
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
async def async_get_response_from_post_request(
|
|
230
|
-
endpoint_uri: URI, *args: Any, **kwargs: Any
|
|
231
|
-
) -> ClientResponse:
|
|
232
|
-
kwargs.setdefault("timeout", ClientTimeout(DEFAULT_TIMEOUT))
|
|
233
|
-
session = await async_cache_and_return_session(endpoint_uri)
|
|
234
|
-
response = await session.post(endpoint_uri, *args, **kwargs)
|
|
235
|
-
return response
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
async def async_make_post_request(
|
|
239
|
-
endpoint_uri: URI, data: Union[bytes, Dict[str, Any]], *args: Any, **kwargs: Any
|
|
240
|
-
) -> bytes:
|
|
241
|
-
response = await async_get_response_from_post_request(
|
|
242
|
-
endpoint_uri, data=data, *args, **kwargs
|
|
243
|
-
)
|
|
244
|
-
response.raise_for_status()
|
|
245
|
-
return await response.read()
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
async def async_get_json_from_client_response(
|
|
249
|
-
response: ClientResponse,
|
|
250
|
-
) -> Dict[str, Any]:
|
|
251
|
-
return await response.json()
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
def _async_close_evicted_sessions(evicted_sessions: List[ClientSession]) -> None:
|
|
255
|
-
loop = asyncio.new_event_loop()
|
|
256
|
-
|
|
257
|
-
for evicted_session in evicted_sessions:
|
|
258
|
-
loop.run_until_complete(evicted_session.close())
|
|
259
|
-
logger.debug(f"Closed evicted async session: {evicted_session}")
|
|
260
|
-
|
|
261
|
-
if any(not evicted_session.closed for evicted_session in evicted_sessions):
|
|
262
|
-
logger.warning(
|
|
263
|
-
f"Some evicted async sessions were not properly closed: {evicted_sessions}"
|
|
264
|
-
)
|
|
265
|
-
loop.close()
|