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
ethpm/tools/checker.py
DELETED
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
from typing import (
|
|
3
|
-
Any,
|
|
4
|
-
Dict,
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
from eth_typing import (
|
|
8
|
-
Manifest,
|
|
9
|
-
)
|
|
10
|
-
from eth_utils.toolz import (
|
|
11
|
-
assoc,
|
|
12
|
-
assoc_in,
|
|
13
|
-
curry,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
from ethpm.constants import (
|
|
17
|
-
PACKAGE_NAME_REGEX,
|
|
18
|
-
)
|
|
19
|
-
from ethpm.tools.builder import (
|
|
20
|
-
build,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
# todo: validate no duplicate blockchain uris in deployments, if web3 is available
|
|
24
|
-
|
|
25
|
-
WARNINGS = {
|
|
26
|
-
"manifest_missing": "Manifest missing a required 'manifest' field.",
|
|
27
|
-
"manifest_invalid": """'manifest' is invalid. The only supported"""
|
|
28
|
-
""" version is 'ethpm/3'.""",
|
|
29
|
-
"name_missing": "Manifest missing a suggested 'name' field",
|
|
30
|
-
"name_invalid": "'name' is invalid. "
|
|
31
|
-
f"Doesn't match the regex: {PACKAGE_NAME_REGEX}",
|
|
32
|
-
"version_missing": "Manifest missing a suggested 'version' field.",
|
|
33
|
-
"meta_missing": "Manifest missing a suggested 'meta' field.",
|
|
34
|
-
"authors_missing": "'meta' field missing suggested 'authors' field.",
|
|
35
|
-
"description_missing": "'meta' field missing suggested 'description' field.",
|
|
36
|
-
"links_missing": "'meta' field missing suggested 'links' field.",
|
|
37
|
-
"license_missing": "'meta' field missing suggested 'license' field.",
|
|
38
|
-
"keywords_missing": "'meta' field missing suggested 'keywords' field.",
|
|
39
|
-
"sources_missing": """Manifest is missing a sources field, """
|
|
40
|
-
"""which defines a source tree that should comprise the full source tree """
|
|
41
|
-
"""necessary to recompile the contracts contained in this release.""",
|
|
42
|
-
"contract_type_missing": """Manifest does not contain any 'contractTypes'. """
|
|
43
|
-
"""Packages should only include contract types that can be found in the """
|
|
44
|
-
"""source files for this package. Packages should not include contract types """
|
|
45
|
-
"""from dependencies. Packages should not include abstract contracts in the """
|
|
46
|
-
"""contract types section of a release.""",
|
|
47
|
-
"abi_missing": """Contract type: {0} is missing an abi field, which is """
|
|
48
|
-
"""essential for using this package.""",
|
|
49
|
-
"deployment_bytecode_missing": """Contract type: {0} is missing a """
|
|
50
|
-
"""`deploymentBytecode` field, which is essential for using this package.""",
|
|
51
|
-
"contract_type_subfield_missing": """Contract type: {0} is missing a"""
|
|
52
|
-
""" `contractType` field, which is essential if an alias is being used """
|
|
53
|
-
"""to namespace this contract type.""",
|
|
54
|
-
"runtime_bytecode_missing": """Contract type: {0} is missing a """
|
|
55
|
-
"""`runtimeBytecode` field.""",
|
|
56
|
-
"bytecode_subfield_missing": """Contract type: {0} is missing a required """
|
|
57
|
-
"""bytecode subfield in its {1} bytecode object.""",
|
|
58
|
-
"devdoc_missing": "Contract type: {0} is missing a devdoc field.",
|
|
59
|
-
"userdoc_missing": "Contract type: {0} is missing a userdoc field.",
|
|
60
|
-
"compilers_missing": "Manifest is missing a suggested `compilers` field.",
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
#
|
|
65
|
-
# Validation
|
|
66
|
-
#
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def check_manifest(manifest: Manifest) -> Dict[str, str]:
|
|
70
|
-
generate_warnings = (
|
|
71
|
-
check_manifest_version(manifest),
|
|
72
|
-
check_package_name(manifest),
|
|
73
|
-
check_version(manifest),
|
|
74
|
-
check_meta(manifest),
|
|
75
|
-
check_sources(manifest),
|
|
76
|
-
check_contract_types(manifest),
|
|
77
|
-
check_compilers(manifest),
|
|
78
|
-
)
|
|
79
|
-
return build({}, *generate_warnings)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
#
|
|
83
|
-
# Required fields
|
|
84
|
-
#
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@curry
|
|
88
|
-
def check_manifest_version(
|
|
89
|
-
manifest: Manifest, warnings: Dict[str, str]
|
|
90
|
-
) -> Dict[str, str]:
|
|
91
|
-
if "manifest" not in manifest or not manifest["manifest"]:
|
|
92
|
-
return assoc(warnings, "manifest", WARNINGS["manifest_missing"])
|
|
93
|
-
if manifest["manifest"] != "ethpm/3":
|
|
94
|
-
return assoc(warnings, "manifest", WARNINGS["manifest_invalid"])
|
|
95
|
-
return warnings
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
@curry
|
|
99
|
-
def check_package_name(manifest: Manifest, warnings: Dict[str, str]) -> Dict[str, str]:
|
|
100
|
-
if "name" not in manifest or not manifest["name"]:
|
|
101
|
-
return assoc(warnings, "name", WARNINGS["name_missing"])
|
|
102
|
-
if not bool(re.match(PACKAGE_NAME_REGEX, manifest["name"])):
|
|
103
|
-
return assoc(warnings, "name", WARNINGS["name_invalid"])
|
|
104
|
-
return warnings
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@curry
|
|
108
|
-
def check_version(manifest: Manifest, warnings: Dict[str, str]) -> Dict[str, str]:
|
|
109
|
-
if "version" not in manifest or not manifest["version"]:
|
|
110
|
-
return assoc(warnings, "version", WARNINGS["version_missing"])
|
|
111
|
-
return warnings
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
# Meta fields
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
@curry
|
|
120
|
-
def check_meta(manifest: Manifest, warnings: Dict[str, str]) -> Dict[str, str]:
|
|
121
|
-
if "meta" not in manifest or not manifest["meta"]:
|
|
122
|
-
return assoc(warnings, "meta", WARNINGS["meta_missing"])
|
|
123
|
-
meta_validation = (
|
|
124
|
-
check_authors(manifest["meta"]),
|
|
125
|
-
check_license(manifest["meta"]),
|
|
126
|
-
check_description(manifest["meta"]),
|
|
127
|
-
check_keywords(manifest["meta"]),
|
|
128
|
-
check_links(manifest["meta"]),
|
|
129
|
-
)
|
|
130
|
-
return build(warnings, *meta_validation)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
@curry
|
|
134
|
-
def check_authors(meta: Dict[str, Any], warnings: Dict[str, str]) -> Dict[str, str]:
|
|
135
|
-
if "authors" not in meta:
|
|
136
|
-
return assoc(warnings, "meta.authors", WARNINGS["authors_missing"])
|
|
137
|
-
return warnings
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
@curry
|
|
141
|
-
def check_license(meta: Dict[str, Any], warnings: Dict[str, str]) -> Dict[str, str]:
|
|
142
|
-
if "license" not in meta or not meta["license"]:
|
|
143
|
-
return assoc(warnings, "meta.license", WARNINGS["license_missing"])
|
|
144
|
-
return warnings
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@curry
|
|
148
|
-
def check_description(meta: Dict[str, Any], warnings: Dict[str, str]) -> Dict[str, str]:
|
|
149
|
-
if "description" not in meta or not meta["description"]:
|
|
150
|
-
return assoc(warnings, "meta.description", WARNINGS["description_missing"])
|
|
151
|
-
return warnings
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
@curry
|
|
155
|
-
def check_keywords(meta: Dict[str, Any], warnings: Dict[str, str]) -> Dict[str, str]:
|
|
156
|
-
if "keywords" not in meta or not meta["keywords"]:
|
|
157
|
-
return assoc(warnings, "meta.keywords", WARNINGS["keywords_missing"])
|
|
158
|
-
return warnings
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@curry
|
|
162
|
-
def check_links(meta: Dict[str, Any], warnings: Dict[str, str]) -> Dict[str, str]:
|
|
163
|
-
if "links" not in meta or not meta["links"]:
|
|
164
|
-
return assoc(warnings, "meta.links", WARNINGS["links_missing"])
|
|
165
|
-
return warnings
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
#
|
|
169
|
-
# Sources
|
|
170
|
-
#
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
@curry
|
|
174
|
-
def check_sources(manifest: Manifest, warnings: Dict[str, str]) -> Dict[str, str]:
|
|
175
|
-
if "sources" not in manifest or not manifest["sources"]:
|
|
176
|
-
return assoc(warnings, "sources", WARNINGS["sources_missing"])
|
|
177
|
-
return warnings
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
#
|
|
181
|
-
# Contract Types
|
|
182
|
-
#
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
# todo: validate a contract type matches source
|
|
186
|
-
@curry
|
|
187
|
-
def check_contract_types(
|
|
188
|
-
manifest: Manifest, warnings: Dict[str, str]
|
|
189
|
-
) -> Dict[str, str]:
|
|
190
|
-
if "contractTypes" not in manifest or not manifest["contractTypes"]:
|
|
191
|
-
return assoc(warnings, "contractTypes", WARNINGS["contract_type_missing"])
|
|
192
|
-
|
|
193
|
-
all_contract_type_validations = (
|
|
194
|
-
(
|
|
195
|
-
check_abi(contract_name, data),
|
|
196
|
-
check_contract_type(contract_name, data),
|
|
197
|
-
check_deployment_bytecode(contract_name, data),
|
|
198
|
-
check_runtime_bytecode(contract_name, data),
|
|
199
|
-
check_devdoc(contract_name, data),
|
|
200
|
-
check_userdoc(contract_name, data),
|
|
201
|
-
)
|
|
202
|
-
for contract_name, data in manifest["contractTypes"].items()
|
|
203
|
-
)
|
|
204
|
-
return build(warnings, *sum(all_contract_type_validations, ()))
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
@curry
|
|
208
|
-
def check_abi(
|
|
209
|
-
contract_name: str, data: Dict[str, Any], warnings: Dict[str, str]
|
|
210
|
-
) -> Dict[str, str]:
|
|
211
|
-
if "abi" not in data or not data["abi"]:
|
|
212
|
-
return assoc_in(
|
|
213
|
-
warnings,
|
|
214
|
-
["contractTypes", contract_name, "abi"],
|
|
215
|
-
WARNINGS["abi_missing"].format(contract_name),
|
|
216
|
-
)
|
|
217
|
-
return warnings
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
@curry
|
|
221
|
-
def check_contract_type(
|
|
222
|
-
contract_name: str, data: Dict[str, Any], warnings: Dict[str, str]
|
|
223
|
-
) -> Dict[str, str]:
|
|
224
|
-
if "contractType" not in data or not data["contractType"]:
|
|
225
|
-
return assoc_in(
|
|
226
|
-
warnings,
|
|
227
|
-
["contractTypes", contract_name, "contractType"],
|
|
228
|
-
WARNINGS["contract_type_subfield_missing"].format(contract_name),
|
|
229
|
-
)
|
|
230
|
-
return warnings
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
@curry
|
|
234
|
-
def check_deployment_bytecode(
|
|
235
|
-
contract_name: str, data: Dict[str, Any], warnings: Dict[str, str]
|
|
236
|
-
) -> Dict[str, str]:
|
|
237
|
-
if "deploymentBytecode" not in data or not data["deploymentBytecode"]:
|
|
238
|
-
return assoc_in(
|
|
239
|
-
warnings,
|
|
240
|
-
["contractTypes", contract_name, "deploymentBytecode"],
|
|
241
|
-
WARNINGS["deployment_bytecode_missing"].format(contract_name),
|
|
242
|
-
)
|
|
243
|
-
return build(
|
|
244
|
-
warnings,
|
|
245
|
-
check_bytecode_object(contract_name, "deployment", data["deploymentBytecode"]),
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
@curry
|
|
250
|
-
def check_runtime_bytecode(
|
|
251
|
-
contract_name: str, data: Dict[str, Any], warnings: Dict[str, str]
|
|
252
|
-
) -> Dict[str, str]:
|
|
253
|
-
if "runtimeBytecode" not in data or not data["runtimeBytecode"]:
|
|
254
|
-
return assoc_in(
|
|
255
|
-
warnings,
|
|
256
|
-
["contractTypes", contract_name, "runtimeBytecode"],
|
|
257
|
-
WARNINGS["runtime_bytecode_missing"].format(contract_name),
|
|
258
|
-
)
|
|
259
|
-
return build(
|
|
260
|
-
warnings,
|
|
261
|
-
check_bytecode_object(contract_name, "runtime", data["runtimeBytecode"]),
|
|
262
|
-
)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
@curry
|
|
266
|
-
def check_bytecode_object(
|
|
267
|
-
contract_name: str,
|
|
268
|
-
bytecode_type: str,
|
|
269
|
-
bytecode_data: Dict[str, Any],
|
|
270
|
-
warnings: Dict[str, str],
|
|
271
|
-
) -> Dict[str, str]:
|
|
272
|
-
# todo: check if bytecode has link_refs & validate link_refs present in object
|
|
273
|
-
if "bytecode" not in bytecode_data or not bytecode_data["bytecode"]:
|
|
274
|
-
return assoc_in(
|
|
275
|
-
warnings,
|
|
276
|
-
["contractTypes", contract_name, f"{bytecode_type}Bytecode"],
|
|
277
|
-
WARNINGS["bytecode_subfield_missing"].format(contract_name, bytecode_type),
|
|
278
|
-
)
|
|
279
|
-
return warnings
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
@curry
|
|
283
|
-
def check_devdoc(
|
|
284
|
-
contract_name: str, data: Dict[str, Any], warnings: Dict[str, str]
|
|
285
|
-
) -> Dict[str, str]:
|
|
286
|
-
if "devdoc" not in data or not data["devdoc"]:
|
|
287
|
-
return assoc_in(
|
|
288
|
-
warnings,
|
|
289
|
-
["contractTypes", contract_name, "devdoc"],
|
|
290
|
-
WARNINGS["devdoc_missing"].format(contract_name),
|
|
291
|
-
)
|
|
292
|
-
return warnings
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
@curry
|
|
296
|
-
def check_userdoc(
|
|
297
|
-
contract_name: str, data: Dict[str, Any], warnings: Dict[str, str]
|
|
298
|
-
) -> Dict[str, str]:
|
|
299
|
-
if "userdoc" not in data or not data["userdoc"]:
|
|
300
|
-
return assoc_in(
|
|
301
|
-
warnings,
|
|
302
|
-
["contractTypes", contract_name, "userdoc"],
|
|
303
|
-
WARNINGS["userdoc_missing"].format(contract_name),
|
|
304
|
-
)
|
|
305
|
-
return warnings
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
@curry
|
|
309
|
-
def check_compilers(manifest: Manifest, warnings: Dict[str, str]) -> Dict[str, str]:
|
|
310
|
-
if "compilers" not in manifest or not manifest["compilers"]:
|
|
311
|
-
return assoc(warnings, "compilers", WARNINGS["compilers_missing"])
|
|
312
|
-
return warnings
|
ethpm/tools/get_manifest.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import (
|
|
3
|
-
Any,
|
|
4
|
-
Dict,
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
from ethpm import (
|
|
8
|
-
ASSETS_DIR,
|
|
9
|
-
get_ethpm_spec_dir,
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def get_ethpm_spec_manifest(use_case: str, filename: str) -> Dict[str, Any]:
|
|
14
|
-
ethpm_spec_dir = get_ethpm_spec_dir()
|
|
15
|
-
return json.loads((ethpm_spec_dir / "examples" / use_case / filename).read_text())
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def get_ethpm_local_manifest(use_case: str, filename: str) -> Dict[str, Any]:
|
|
19
|
-
return json.loads((ASSETS_DIR / use_case / filename).read_text())
|
ethpm/uri.py
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import (
|
|
3
|
-
TYPE_CHECKING,
|
|
4
|
-
)
|
|
5
|
-
|
|
6
|
-
from eth_typing import (
|
|
7
|
-
URI,
|
|
8
|
-
)
|
|
9
|
-
from eth_utils import (
|
|
10
|
-
encode_hex,
|
|
11
|
-
to_hex,
|
|
12
|
-
)
|
|
13
|
-
from eth_utils.toolz import (
|
|
14
|
-
curry,
|
|
15
|
-
)
|
|
16
|
-
import requests
|
|
17
|
-
|
|
18
|
-
from ethpm._utils.backend import (
|
|
19
|
-
get_resolvable_backends_for_uri,
|
|
20
|
-
get_translatable_backends_for_uri,
|
|
21
|
-
)
|
|
22
|
-
from ethpm._utils.chains import (
|
|
23
|
-
BLOCK,
|
|
24
|
-
create_block_uri,
|
|
25
|
-
get_genesis_block_hash,
|
|
26
|
-
parse_BIP122_uri,
|
|
27
|
-
)
|
|
28
|
-
from ethpm._utils.ipfs import (
|
|
29
|
-
is_ipfs_uri,
|
|
30
|
-
)
|
|
31
|
-
from ethpm.backends.http import (
|
|
32
|
-
is_valid_api_github_uri,
|
|
33
|
-
is_valid_content_addressed_github_uri,
|
|
34
|
-
)
|
|
35
|
-
from ethpm.backends.registry import (
|
|
36
|
-
RegistryURIBackend,
|
|
37
|
-
)
|
|
38
|
-
from ethpm.exceptions import (
|
|
39
|
-
CannotHandleURI,
|
|
40
|
-
)
|
|
41
|
-
from web3.types import (
|
|
42
|
-
BlockNumber,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
if TYPE_CHECKING:
|
|
46
|
-
from web3 import Web3 # noqa F401
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def resolve_uri_contents(uri: URI, fingerprint: bool = None) -> bytes:
|
|
50
|
-
resolvable_backends = get_resolvable_backends_for_uri(uri)
|
|
51
|
-
if resolvable_backends:
|
|
52
|
-
for backend in resolvable_backends:
|
|
53
|
-
try:
|
|
54
|
-
# type ignored to handle case if URI is returned
|
|
55
|
-
contents: bytes = backend().fetch_uri_contents(uri) # type: ignore
|
|
56
|
-
except CannotHandleURI:
|
|
57
|
-
continue
|
|
58
|
-
return contents
|
|
59
|
-
|
|
60
|
-
translatable_backends = get_translatable_backends_for_uri(uri)
|
|
61
|
-
if translatable_backends:
|
|
62
|
-
if fingerprint:
|
|
63
|
-
raise CannotHandleURI(
|
|
64
|
-
"Registry URIs must point to a resolvable content-addressed URI."
|
|
65
|
-
)
|
|
66
|
-
package_id = RegistryURIBackend().fetch_uri_contents(uri)
|
|
67
|
-
return resolve_uri_contents(package_id, True)
|
|
68
|
-
|
|
69
|
-
raise CannotHandleURI(
|
|
70
|
-
f"URI: {uri} cannot be resolved by any of the available backends."
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def create_content_addressed_github_uri(uri: URI) -> URI:
|
|
75
|
-
"""
|
|
76
|
-
Returns a content-addressed Github "git_url" that conforms to this scheme.
|
|
77
|
-
https://api.github.com/repos/:owner/:repo/git/blobs/:file_sha
|
|
78
|
-
|
|
79
|
-
Accepts Github-defined "url" that conforms to this scheme
|
|
80
|
-
https://api.github.com/repos/:owner/:repo/contents/:path/:to/manifest.json
|
|
81
|
-
"""
|
|
82
|
-
if not is_valid_api_github_uri(uri):
|
|
83
|
-
raise CannotHandleURI(f"{uri} does not conform to Github's API 'url' scheme.")
|
|
84
|
-
response = requests.get(uri)
|
|
85
|
-
response.raise_for_status()
|
|
86
|
-
contents = json.loads(response.content)
|
|
87
|
-
if contents["type"] != "file":
|
|
88
|
-
raise CannotHandleURI(
|
|
89
|
-
"Expected url to point to a 'file' type, "
|
|
90
|
-
f"instead received {contents['type']}."
|
|
91
|
-
)
|
|
92
|
-
return contents["git_url"]
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def is_supported_content_addressed_uri(uri: URI) -> bool:
|
|
96
|
-
"""
|
|
97
|
-
Returns a bool indicating whether provided uri is currently supported.
|
|
98
|
-
Currently Py-EthPM only supports IPFS and Github blob content-addressed uris.
|
|
99
|
-
"""
|
|
100
|
-
if not is_ipfs_uri(uri) and not is_valid_content_addressed_github_uri(uri):
|
|
101
|
-
return False
|
|
102
|
-
return True
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def create_latest_block_uri(w3: "Web3", from_blocks_ago: int = 3) -> URI:
|
|
106
|
-
"""
|
|
107
|
-
Creates a block uri for the given w3 instance.
|
|
108
|
-
Defaults to 3 blocks prior to the "latest" block to accommodate for block reorgs.
|
|
109
|
-
If using a testnet with less than 3 mined blocks, adjust :from_blocks_ago:.
|
|
110
|
-
"""
|
|
111
|
-
chain_id = to_hex(get_genesis_block_hash(w3))
|
|
112
|
-
latest_block_tx_receipt = w3.eth.get_block("latest")
|
|
113
|
-
target_block_number = BlockNumber(
|
|
114
|
-
latest_block_tx_receipt["number"] - from_blocks_ago
|
|
115
|
-
)
|
|
116
|
-
if target_block_number < 0:
|
|
117
|
-
raise Exception(
|
|
118
|
-
f"Only {latest_block_tx_receipt['number']} blocks avaible on provided w3, "
|
|
119
|
-
f"cannot create latest block uri for {from_blocks_ago} blocks ago."
|
|
120
|
-
)
|
|
121
|
-
recent_block = to_hex(w3.eth.get_block(target_block_number)["hash"])
|
|
122
|
-
return create_block_uri(chain_id, recent_block)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
@curry
|
|
126
|
-
def check_if_chain_matches_chain_uri(w3: "Web3", blockchain_uri: URI) -> bool:
|
|
127
|
-
chain_id, resource_type, resource_hash = parse_BIP122_uri(blockchain_uri)
|
|
128
|
-
genesis_block = w3.eth.get_block("earliest")
|
|
129
|
-
|
|
130
|
-
if encode_hex(genesis_block["hash"]) != chain_id:
|
|
131
|
-
return False
|
|
132
|
-
|
|
133
|
-
if resource_type == BLOCK:
|
|
134
|
-
resource = w3.eth.get_block(resource_hash)
|
|
135
|
-
else:
|
|
136
|
-
raise ValueError(f"Unsupported resource type: {resource_type}")
|
|
137
|
-
|
|
138
|
-
if encode_hex(resource["hash"]) == resource_hash:
|
|
139
|
-
return True
|
|
140
|
-
else:
|
|
141
|
-
return False
|
ethpm/validation/__init__.py
DELETED
|
File without changes
|
ethpm/validation/manifest.py
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
from abc import (
|
|
2
|
-
ABCMeta,
|
|
3
|
-
)
|
|
4
|
-
import json
|
|
5
|
-
from typing import (
|
|
6
|
-
Any,
|
|
7
|
-
Dict,
|
|
8
|
-
List,
|
|
9
|
-
Set,
|
|
10
|
-
cast,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
from jsonschema import (
|
|
14
|
-
ValidationError as jsonValidationError,
|
|
15
|
-
validate,
|
|
16
|
-
)
|
|
17
|
-
from jsonschema.validators import (
|
|
18
|
-
Draft7Validator,
|
|
19
|
-
validator_for,
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
from ethpm import (
|
|
23
|
-
get_ethpm_spec_dir,
|
|
24
|
-
)
|
|
25
|
-
from ethpm.exceptions import (
|
|
26
|
-
EthPMValidationError,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
META_FIELDS = {
|
|
30
|
-
"license": str,
|
|
31
|
-
"authors": list,
|
|
32
|
-
"description": str,
|
|
33
|
-
"keywords": list,
|
|
34
|
-
"links": dict,
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def validate_meta_object(meta: Dict[str, Any], allow_extra_meta_fields: bool) -> None:
|
|
39
|
-
"""
|
|
40
|
-
Validates that every key is one of `META_FIELDS`
|
|
41
|
-
and has a value of the expected type.
|
|
42
|
-
"""
|
|
43
|
-
for key, value in meta.items():
|
|
44
|
-
if key in META_FIELDS:
|
|
45
|
-
if cast(ABCMeta, type(value)) is not META_FIELDS[key]:
|
|
46
|
-
raise EthPMValidationError(
|
|
47
|
-
f"Values for {key} are expected to have the type "
|
|
48
|
-
f"{META_FIELDS[key]}, instead got {type(value)}."
|
|
49
|
-
)
|
|
50
|
-
elif allow_extra_meta_fields:
|
|
51
|
-
if key[:2] != "x-":
|
|
52
|
-
raise EthPMValidationError(
|
|
53
|
-
"Undefined meta fields need to begin with 'x-', "
|
|
54
|
-
f"{key} is not a valid undefined meta field."
|
|
55
|
-
)
|
|
56
|
-
else:
|
|
57
|
-
raise EthPMValidationError(
|
|
58
|
-
f"{key} is not a permitted meta field. To allow undefined fields, "
|
|
59
|
-
"set `allow_extra_meta_fields` to True."
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def _load_schema_data() -> Dict[str, Any]:
|
|
64
|
-
ethpm_spec_dir = get_ethpm_spec_dir()
|
|
65
|
-
v3_schema_path = ethpm_spec_dir / "spec" / "v3.spec.json"
|
|
66
|
-
return json.loads(v3_schema_path.read_text())
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def extract_contract_types_from_deployments(deployment_data: List[Any]) -> Set[str]:
|
|
70
|
-
contract_types = {
|
|
71
|
-
deployment["contractType"]
|
|
72
|
-
for chain_deployments in deployment_data
|
|
73
|
-
for deployment in chain_deployments.values()
|
|
74
|
-
}
|
|
75
|
-
return contract_types
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def validate_manifest_against_schema(manifest: Dict[str, Any]) -> None:
|
|
79
|
-
"""
|
|
80
|
-
Load and validate manifest against schema
|
|
81
|
-
located at v3_schema_path.
|
|
82
|
-
"""
|
|
83
|
-
schema_data = _load_schema_data()
|
|
84
|
-
try:
|
|
85
|
-
validate(manifest, schema_data, cls=validator_for(schema_data, Draft7Validator))
|
|
86
|
-
except jsonValidationError as e:
|
|
87
|
-
raise EthPMValidationError(
|
|
88
|
-
f"Manifest invalid for schema version {schema_data['version']}. "
|
|
89
|
-
f"Reason: {e.message}"
|
|
90
|
-
f"{e}"
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def check_for_deployments(manifest: Dict[str, Any]) -> bool:
|
|
95
|
-
if "deployments" not in manifest or not manifest["deployments"]:
|
|
96
|
-
return False
|
|
97
|
-
return True
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def validate_build_dependencies_are_present(manifest: Dict[str, Any]) -> None:
|
|
101
|
-
if "buildDependencies" not in manifest:
|
|
102
|
-
raise EthPMValidationError("Manifest doesn't have any build dependencies.")
|
|
103
|
-
|
|
104
|
-
if not manifest["buildDependencies"]:
|
|
105
|
-
raise EthPMValidationError("Manifest's build dependencies key is empty.")
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def validate_manifest_deployments(manifest: Dict[str, Any]) -> None:
|
|
109
|
-
"""
|
|
110
|
-
Validate that a manifest's deployments contracts reference existing contractTypes.
|
|
111
|
-
"""
|
|
112
|
-
if {"contractTypes", "deployments"}.issubset(manifest):
|
|
113
|
-
all_contract_types = manifest["contractTypes"].keys()
|
|
114
|
-
all_deployments = manifest["deployments"].values()
|
|
115
|
-
all_deployment_names = extract_contract_types_from_deployments(all_deployments)
|
|
116
|
-
missing_contract_types = all_deployment_names.difference(all_contract_types)
|
|
117
|
-
if missing_contract_types:
|
|
118
|
-
raise EthPMValidationError(
|
|
119
|
-
f"Manifest missing references to contracts: {missing_contract_types}."
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def validate_raw_manifest_format(raw_manifest: str) -> None:
|
|
124
|
-
"""
|
|
125
|
-
Raise a EthPMValidationError if a manifest ...
|
|
126
|
-
- is not tightly packed (i.e. no linebreaks or extra whitespace)
|
|
127
|
-
- does not have alphabetically sorted keys
|
|
128
|
-
- has duplicate keys
|
|
129
|
-
- is not UTF-8 encoded
|
|
130
|
-
- has a trailing newline
|
|
131
|
-
"""
|
|
132
|
-
try:
|
|
133
|
-
manifest_dict = json.loads(raw_manifest)
|
|
134
|
-
except json.JSONDecodeError as err:
|
|
135
|
-
raise json.JSONDecodeError(
|
|
136
|
-
"Failed to load package data. File is not a valid JSON document.",
|
|
137
|
-
err.doc,
|
|
138
|
-
err.pos,
|
|
139
|
-
)
|
|
140
|
-
compact_manifest = json.dumps(manifest_dict, sort_keys=True, separators=(",", ":"))
|
|
141
|
-
if raw_manifest != compact_manifest:
|
|
142
|
-
raise EthPMValidationError(
|
|
143
|
-
"The manifest appears to be malformed. Please ensure that it conforms to "
|
|
144
|
-
"the EthPM-Spec for document format. "
|
|
145
|
-
"http://ethpm.github.io/ethpm-spec/package-spec.html#document-format "
|
|
146
|
-
)
|
ethpm/validation/misc.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
from urllib import (
|
|
2
|
-
parse,
|
|
3
|
-
)
|
|
4
|
-
|
|
5
|
-
from ethpm.exceptions import (
|
|
6
|
-
EthPMValidationError,
|
|
7
|
-
)
|
|
8
|
-
from web3 import (
|
|
9
|
-
Web3,
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def validate_w3_instance(w3: "Web3") -> None:
|
|
14
|
-
if w3 is None or not isinstance(w3, Web3):
|
|
15
|
-
raise ValueError("Package does not have valid web3 instance.")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def validate_empty_bytes(offset: int, length: int, bytecode: bytes) -> None:
|
|
19
|
-
"""
|
|
20
|
-
Validates that segment [`offset`:`offset`+`length`] of
|
|
21
|
-
`bytecode` is comprised of empty bytes (b'\00').
|
|
22
|
-
"""
|
|
23
|
-
slot_length = offset + length
|
|
24
|
-
slot = bytecode[offset:slot_length]
|
|
25
|
-
if slot != bytearray(length):
|
|
26
|
-
raise EthPMValidationError(
|
|
27
|
-
f"Bytecode segment: [{offset}:{slot_length}] "
|
|
28
|
-
f"is not comprised of empty bytes, rather: {slot!r}."
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def validate_escaped_string(string: str) -> None:
|
|
33
|
-
unsafe = parse.unquote(string)
|
|
34
|
-
safe = parse.quote(unsafe)
|
|
35
|
-
if string != safe:
|
|
36
|
-
raise EthPMValidationError(
|
|
37
|
-
f"String: {string} is not properly escaped, and contains url "
|
|
38
|
-
"unsafe characters."
|
|
39
|
-
)
|