py-geth 5.2.1__tar.gz → 5.4.0__tar.gz
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.
- {py_geth-5.2.1/py_geth.egg-info → py_geth-5.4.0}/PKG-INFO +9 -6
- {py_geth-5.2.1 → py_geth-5.4.0}/README.md +6 -4
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/chain.py +1 -6
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/genesis.json +14 -1
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/install.py +32 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/process.py +7 -1
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/validation.py +55 -71
- {py_geth-5.2.1 → py_geth-5.4.0/py_geth.egg-info}/PKG-INFO +9 -6
- {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/SOURCES.txt +6 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/pyproject.toml +1 -1
- {py_geth-5.2.1 → py_geth-5.4.0}/setup.py +1 -1
- py_geth-5.4.0/tests/core/accounts/projects/test-01/geth/nodekey +1 -0
- py_geth-5.4.0/tests/core/accounts/projects/test-02/geth/LOCK +0 -0
- py_geth-5.4.0/tests/core/accounts/projects/test-02/geth/nodekey +1 -0
- py_geth-5.4.0/tests/core/accounts/projects/test-03/geth/LOCK +0 -0
- py_geth-5.4.0/tests/core/accounts/projects/test-03/geth/nodekey +1 -0
- py_geth-5.4.0/tests/core/running/test_running_dev_chain.py +95 -0
- py_geth-5.4.0/tests/core/utility/test_validation.py +92 -0
- py_geth-5.4.0/tests/core/waiting/conftest.py +0 -0
- py_geth-5.2.1/tests/core/running/test_running_dev_chain.py +0 -21
- py_geth-5.2.1/tests/core/utility/test_validation.py +0 -269
- {py_geth-5.2.1 → py_geth-5.4.0}/LICENSE +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/MANIFEST.in +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/__init__.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/accounts.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/default_blockchain_password +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/exceptions.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/main.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/mixins.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/py.typed +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/reset.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/types.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/__init__.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/encoding.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/filesystem.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/networking.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/proc.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/thread.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/timeout.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/geth/wrapper.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/dependency_links.txt +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/not-zip-safe +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/requires.txt +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/top_level.txt +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/scripts/release/test_package.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/setup.cfg +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/conftest.py +0 -0
- /py_geth-5.2.1/tests/core/waiting/conftest.py → /py_geth-5.4.0/tests/core/accounts/projects/test-01/geth/LOCK +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/projects/test-01/keystore/UTC--2015-08-24T21-30-14.222885490Z--ae71658b3ab452f7e4f03bda6f777b860b2e2ff2 +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/projects/test-02/keystore/UTC--2015-08-24T21-30-14.222885490Z--ae71658b3ab452f7e4f03bda6f777b860b2e2ff2 +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/projects/test-02/keystore/UTC--2015-08-24T21-32-00.716418819Z--e8e085862a8d951dd78ec5ea784b3e22ee1ca9c6 +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/projects/test-02/keystore/UTC--2015-08-24T21-32-04.748321142Z--0da70f43a568e88168436be52ed129f4a9bbdaf5 +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/test_account_list_parsing.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/test_create_geth_account.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/test_geth_accounts.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_running_mainnet_chain.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_running_sepolia_chain.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_running_with_logging.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_use_as_a_context_manager.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/test_import_and_version.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/test_library_files.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_constructing_test_chain_kwargs.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_geth_version.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_is_live_chain.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_is_sepolia_chain.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/waiting/test_waiting_for_ipc_socket.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/waiting/test_waiting_for_rpc_connection.py +0 -0
- {py_geth-5.2.1 → py_geth-5.4.0}/tests/installation/test_geth_installation.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: py-geth
|
3
|
-
Version: 5.
|
3
|
+
Version: 5.4.0
|
4
4
|
Summary: py-geth: Run Go-Ethereum as a subprocess
|
5
5
|
Home-page: https://github.com/ethereum/py-geth
|
6
6
|
Author: The Ethereum Foundation
|
@@ -54,6 +54,7 @@ Dynamic: description-content-type
|
|
54
54
|
Dynamic: home-page
|
55
55
|
Dynamic: keywords
|
56
56
|
Dynamic: license
|
57
|
+
Dynamic: license-file
|
57
58
|
Dynamic: provides-extra
|
58
59
|
Dynamic: requires-dist
|
59
60
|
Dynamic: requires-python
|
@@ -138,6 +139,8 @@ False
|
|
138
139
|
False
|
139
140
|
>>> geth.is_stopped
|
140
141
|
True
|
142
|
+
>>> geth.version
|
143
|
+
"1.15.7-stable"
|
141
144
|
```
|
142
145
|
|
143
146
|
When testing it can be nice to see the logging output produced by the `geth`
|
@@ -177,19 +180,19 @@ the current list of supported versions.
|
|
177
180
|
Installation can be done via the command line:
|
178
181
|
|
179
182
|
```bash
|
180
|
-
$ python -m geth.install v1.
|
183
|
+
$ python -m geth.install v1.15.7
|
181
184
|
```
|
182
185
|
|
183
186
|
Or from python using the `install_geth` function.
|
184
187
|
|
185
188
|
```python
|
186
189
|
>>> from geth import install_geth
|
187
|
-
>>> install_geth('v1.
|
190
|
+
>>> install_geth('v1.15.7')
|
188
191
|
```
|
189
192
|
|
190
193
|
The installed binary can be found in the `$HOME/.py-geth` directory, under your
|
191
|
-
home directory. The `v1.
|
192
|
-
`$HOME/.py-geth/geth-v1.
|
194
|
+
home directory. The `v1.15.7` binary would be located at
|
195
|
+
`$HOME/.py-geth/geth-v1.15.7/bin/geth`.
|
193
196
|
|
194
197
|
## About `DevGethProcess`
|
195
198
|
|
@@ -77,6 +77,8 @@ False
|
|
77
77
|
False
|
78
78
|
>>> geth.is_stopped
|
79
79
|
True
|
80
|
+
>>> geth.version
|
81
|
+
"1.15.7-stable"
|
80
82
|
```
|
81
83
|
|
82
84
|
When testing it can be nice to see the logging output produced by the `geth`
|
@@ -116,19 +118,19 @@ the current list of supported versions.
|
|
116
118
|
Installation can be done via the command line:
|
117
119
|
|
118
120
|
```bash
|
119
|
-
$ python -m geth.install v1.
|
121
|
+
$ python -m geth.install v1.15.7
|
120
122
|
```
|
121
123
|
|
122
124
|
Or from python using the `install_geth` function.
|
123
125
|
|
124
126
|
```python
|
125
127
|
>>> from geth import install_geth
|
126
|
-
>>> install_geth('v1.
|
128
|
+
>>> install_geth('v1.15.7')
|
127
129
|
```
|
128
130
|
|
129
131
|
The installed binary can be found in the `$HOME/.py-geth` directory, under your
|
130
|
-
home directory. The `v1.
|
131
|
-
`$HOME/.py-geth/geth-v1.
|
132
|
+
home directory. The `v1.15.7` binary would be located at
|
133
|
+
`$HOME/.py-geth/geth-v1.15.7/bin/geth`.
|
132
134
|
|
133
135
|
## About `DevGethProcess`
|
134
136
|
|
@@ -26,7 +26,6 @@ from .utils.filesystem import (
|
|
26
26
|
is_same_path,
|
27
27
|
)
|
28
28
|
from .utils.validation import (
|
29
|
-
fill_default_genesis_data,
|
30
29
|
validate_genesis_data,
|
31
30
|
)
|
32
31
|
from .wrapper import (
|
@@ -118,13 +117,9 @@ def write_genesis_file(
|
|
118
117
|
)
|
119
118
|
|
120
119
|
validate_genesis_data(genesis_data)
|
121
|
-
# use GenesisData model to fill defaults
|
122
|
-
filled_genesis_data_model = fill_default_genesis_data(genesis_data)
|
123
120
|
|
124
121
|
with open(genesis_file_path, "w") as genesis_file:
|
125
|
-
genesis_file.write(
|
126
|
-
json.dumps(force_obj_to_text(filled_genesis_data_model.model_dump()))
|
127
|
-
)
|
122
|
+
genesis_file.write(force_obj_to_text(json.dumps(genesis_data)))
|
128
123
|
|
129
124
|
|
130
125
|
def initialize_chain(genesis_data: GenesisDataTypedDict, data_dir: str) -> None:
|
@@ -16,7 +16,20 @@
|
|
16
16
|
"terminalTotalDifficulty": 0,
|
17
17
|
"terminalTotalDifficultyPassed": true,
|
18
18
|
"shanghaiTime": 0,
|
19
|
-
"cancunTime": 0
|
19
|
+
"cancunTime": 0,
|
20
|
+
"blobSchedule": {
|
21
|
+
"cancun": {
|
22
|
+
"target": 3,
|
23
|
+
"max": 6,
|
24
|
+
"baseFeeUpdateFraction": 3338477
|
25
|
+
},
|
26
|
+
"prague": {
|
27
|
+
"target": 6,
|
28
|
+
"max": 9,
|
29
|
+
"baseFeeUpdateFraction": 5007716
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
20
33
|
},
|
21
34
|
"nonce": "0x0",
|
22
35
|
"timestamp": "0x0",
|
@@ -47,6 +47,14 @@ V1_14_10 = "v1.14.10"
|
|
47
47
|
V1_14_11 = "v1.14.11"
|
48
48
|
V1_14_12 = "v1.14.12"
|
49
49
|
V1_14_13 = "v1.14.13"
|
50
|
+
V1_15_0 = "v1.15.0"
|
51
|
+
V1_15_1 = "v1.15.1"
|
52
|
+
V1_15_2 = "v1.15.2"
|
53
|
+
V1_15_3 = "v1.15.3"
|
54
|
+
V1_15_4 = "v1.15.4"
|
55
|
+
V1_15_5 = "v1.15.5"
|
56
|
+
V1_15_6 = "v1.15.6"
|
57
|
+
V1_15_7 = "v1.15.7"
|
50
58
|
|
51
59
|
|
52
60
|
LINUX = "linux"
|
@@ -343,6 +351,14 @@ install_v1_14_10 = functools.partial(install_from_source_code_release, V1_14_10)
|
|
343
351
|
install_v1_14_11 = functools.partial(install_from_source_code_release, V1_14_11)
|
344
352
|
install_v1_14_12 = functools.partial(install_from_source_code_release, V1_14_12)
|
345
353
|
install_v1_14_13 = functools.partial(install_from_source_code_release, V1_14_13)
|
354
|
+
install_v1_15_0 = functools.partial(install_from_source_code_release, V1_15_0)
|
355
|
+
install_v1_15_1 = functools.partial(install_from_source_code_release, V1_15_1)
|
356
|
+
install_v1_15_2 = functools.partial(install_from_source_code_release, V1_15_2)
|
357
|
+
install_v1_15_3 = functools.partial(install_from_source_code_release, V1_15_3)
|
358
|
+
install_v1_15_4 = functools.partial(install_from_source_code_release, V1_15_4)
|
359
|
+
install_v1_15_5 = functools.partial(install_from_source_code_release, V1_15_5)
|
360
|
+
install_v1_15_6 = functools.partial(install_from_source_code_release, V1_15_6)
|
361
|
+
install_v1_15_7 = functools.partial(install_from_source_code_release, V1_15_7)
|
346
362
|
|
347
363
|
INSTALL_FUNCTIONS = {
|
348
364
|
LINUX: {
|
@@ -359,6 +375,14 @@ INSTALL_FUNCTIONS = {
|
|
359
375
|
V1_14_11: install_v1_14_11,
|
360
376
|
V1_14_12: install_v1_14_12,
|
361
377
|
V1_14_13: install_v1_14_13,
|
378
|
+
V1_15_0: install_v1_15_0,
|
379
|
+
V1_15_1: install_v1_15_1,
|
380
|
+
V1_15_2: install_v1_15_2,
|
381
|
+
V1_15_3: install_v1_15_3,
|
382
|
+
V1_15_4: install_v1_15_4,
|
383
|
+
V1_15_5: install_v1_15_5,
|
384
|
+
V1_15_6: install_v1_15_6,
|
385
|
+
V1_15_7: install_v1_15_7,
|
362
386
|
},
|
363
387
|
OSX: {
|
364
388
|
V1_14_0: install_v1_14_0,
|
@@ -374,6 +398,14 @@ INSTALL_FUNCTIONS = {
|
|
374
398
|
V1_14_11: install_v1_14_11,
|
375
399
|
V1_14_12: install_v1_14_12,
|
376
400
|
V1_14_13: install_v1_14_13,
|
401
|
+
V1_15_0: install_v1_15_0,
|
402
|
+
V1_15_1: install_v1_15_1,
|
403
|
+
V1_15_2: install_v1_15_2,
|
404
|
+
V1_15_3: install_v1_15_3,
|
405
|
+
V1_15_4: install_v1_15_4,
|
406
|
+
V1_15_5: install_v1_15_5,
|
407
|
+
V1_15_6: install_v1_15_6,
|
408
|
+
V1_15_7: install_v1_15_7,
|
377
409
|
},
|
378
410
|
}
|
379
411
|
|
@@ -6,6 +6,7 @@ from abc import (
|
|
6
6
|
ABC,
|
7
7
|
abstractmethod,
|
8
8
|
)
|
9
|
+
import copy
|
9
10
|
import json
|
10
11
|
import logging
|
11
12
|
import os
|
@@ -216,6 +217,10 @@ class BaseGethProcess(ABC):
|
|
216
217
|
time.sleep(0.1)
|
217
218
|
_timeout.check()
|
218
219
|
|
220
|
+
@property
|
221
|
+
def version(self) -> str:
|
222
|
+
return str(get_geth_version(**self.geth_kwargs))
|
223
|
+
|
219
224
|
|
220
225
|
class MainnetGethProcess(BaseGethProcess):
|
221
226
|
def __init__(self, geth_kwargs: GethKwargsTypedDict | None = None):
|
@@ -282,7 +287,8 @@ class DevGethProcess(BaseGethProcess):
|
|
282
287
|
overrides = {}
|
283
288
|
|
284
289
|
if genesis_data is None:
|
285
|
-
|
290
|
+
# deepcopy since we may modify the data on init below
|
291
|
+
genesis_data = GenesisDataTypedDict(**copy.deepcopy(GENESIS_JSON))
|
286
292
|
|
287
293
|
validate_genesis_data(genesis_data)
|
288
294
|
|
@@ -11,6 +11,7 @@ from pydantic import (
|
|
11
11
|
BaseModel,
|
12
12
|
ConfigDict,
|
13
13
|
ValidationError,
|
14
|
+
model_validator,
|
14
15
|
)
|
15
16
|
|
16
17
|
from geth.exceptions import (
|
@@ -72,52 +73,67 @@ def validate_geth_kwargs(geth_kwargs: GethKwargsTypedDict) -> None:
|
|
72
73
|
|
73
74
|
|
74
75
|
class GenesisDataConfig(BaseModel):
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
76
|
+
"""
|
77
|
+
Default values are pulled from the ``genesis.json`` file internal to the repository.
|
78
|
+
"""
|
79
|
+
|
80
|
+
chainId: int | None = None
|
81
|
+
ethash: dict[str, Any] | None = None
|
82
|
+
homesteadBlock: int | None = None
|
83
|
+
daoForkBlock: int | None = None
|
84
|
+
daoForkSupport: bool | None = None
|
85
|
+
eip150Block: int | None = None
|
86
|
+
eip155Block: int | None = None
|
87
|
+
eip158Block: int | None = None
|
88
|
+
byzantiumBlock: int | None = None
|
89
|
+
constantinopleBlock: int | None = None
|
90
|
+
petersburgBlock: int | None = None
|
91
|
+
istanbulBlock: int | None = None
|
92
|
+
berlinBlock: int | None = None
|
93
|
+
londonBlock: int | None = None
|
94
|
+
arrowGlacierBlock: int | None = None
|
95
|
+
grayGlacierBlock: int | None = None
|
91
96
|
# merge
|
92
|
-
terminalTotalDifficulty: int =
|
93
|
-
terminalTotalDifficultyPassed: bool =
|
97
|
+
terminalTotalDifficulty: int | None = None
|
98
|
+
terminalTotalDifficultyPassed: bool | None = None
|
94
99
|
# post-merge, timestamp is used for network transitions
|
95
|
-
shanghaiTime: int =
|
96
|
-
cancunTime: int =
|
97
|
-
|
98
|
-
|
100
|
+
shanghaiTime: int | None = None
|
101
|
+
cancunTime: int | None = None
|
102
|
+
pragueTime: int | None = None
|
103
|
+
# blobs
|
104
|
+
blobSchedule: dict[str, Any] = {}
|
105
|
+
|
106
|
+
@model_validator(mode="after")
|
107
|
+
def check_blob_schedule_required(
|
108
|
+
self,
|
109
|
+
) -> GenesisDataConfig:
|
110
|
+
if self.cancunTime and not self.blobSchedule.get("cancun"):
|
111
|
+
raise PyGethValueError(
|
112
|
+
"blobSchedule 'cancun' value is required when cancunTime is set"
|
113
|
+
)
|
114
|
+
if self.pragueTime and not self.blobSchedule.get("prague"):
|
115
|
+
raise PyGethValueError(
|
116
|
+
"blobSchedule 'prague' value is required when pragueTime is set"
|
117
|
+
)
|
118
|
+
return self
|
99
119
|
|
100
120
|
|
101
121
|
class GenesisData(BaseModel):
|
102
122
|
alloc: dict[str, dict[str, Any]] = {}
|
103
|
-
baseFeePerGas: str =
|
104
|
-
blobGasUsed: str =
|
105
|
-
coinbase: str =
|
123
|
+
baseFeePerGas: str | None = None
|
124
|
+
blobGasUsed: str | None = None
|
125
|
+
coinbase: str | None = None
|
106
126
|
config: dict[str, Any] = GenesisDataConfig().model_dump()
|
107
|
-
difficulty: str =
|
108
|
-
excessBlobGas: str =
|
109
|
-
extraData: str =
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
parentHash: str = (
|
118
|
-
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
119
|
-
)
|
120
|
-
timestamp: str = "0x0"
|
127
|
+
difficulty: str | None = None
|
128
|
+
excessBlobGas: str | None = None
|
129
|
+
extraData: str | None = None
|
130
|
+
gasLimit: str | None = None
|
131
|
+
gasUsed: str | None = None
|
132
|
+
mixHash: str | None = None
|
133
|
+
nonce: str | None = None
|
134
|
+
number: str | None = None
|
135
|
+
parentHash: str | None = None
|
136
|
+
timestamp: str | None = None
|
121
137
|
|
122
138
|
model_config = ConfigDict(extra="forbid")
|
123
139
|
|
@@ -146,35 +162,3 @@ def validate_genesis_data(genesis_data: GenesisDataTypedDict) -> None:
|
|
146
162
|
raise PyGethValueError(
|
147
163
|
f"error while validating genesis_data config field: {e}"
|
148
164
|
)
|
149
|
-
|
150
|
-
|
151
|
-
def fill_default_genesis_data(
|
152
|
-
genesis_data: GenesisDataTypedDict,
|
153
|
-
) -> GenesisData:
|
154
|
-
"""
|
155
|
-
Fills in default values for the genesis data
|
156
|
-
"""
|
157
|
-
try:
|
158
|
-
genesis_data_filled = GenesisData(**genesis_data)
|
159
|
-
except ValidationError as e:
|
160
|
-
raise PyGethValueError(
|
161
|
-
f"genesis_data validation failed while filling defaults: {e}"
|
162
|
-
)
|
163
|
-
except TypeError as e:
|
164
|
-
raise PyGethValueError(f"error while filling default genesis_data: {e}")
|
165
|
-
|
166
|
-
if genesis_data.get("config"):
|
167
|
-
try:
|
168
|
-
genesis_data_config_filled = GenesisDataConfig(**genesis_data["config"])
|
169
|
-
except ValidationError as e:
|
170
|
-
raise PyGethValueError(
|
171
|
-
f"genesis_data validation failed while filling config defaults: {e}"
|
172
|
-
)
|
173
|
-
except TypeError as e:
|
174
|
-
raise PyGethValueError(
|
175
|
-
f"error while filling default genesis_data config: {e}"
|
176
|
-
)
|
177
|
-
|
178
|
-
genesis_data_filled.config = genesis_data_config_filled.model_dump()
|
179
|
-
|
180
|
-
return genesis_data_filled
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: py-geth
|
3
|
-
Version: 5.
|
3
|
+
Version: 5.4.0
|
4
4
|
Summary: py-geth: Run Go-Ethereum as a subprocess
|
5
5
|
Home-page: https://github.com/ethereum/py-geth
|
6
6
|
Author: The Ethereum Foundation
|
@@ -54,6 +54,7 @@ Dynamic: description-content-type
|
|
54
54
|
Dynamic: home-page
|
55
55
|
Dynamic: keywords
|
56
56
|
Dynamic: license
|
57
|
+
Dynamic: license-file
|
57
58
|
Dynamic: provides-extra
|
58
59
|
Dynamic: requires-dist
|
59
60
|
Dynamic: requires-python
|
@@ -138,6 +139,8 @@ False
|
|
138
139
|
False
|
139
140
|
>>> geth.is_stopped
|
140
141
|
True
|
142
|
+
>>> geth.version
|
143
|
+
"1.15.7-stable"
|
141
144
|
```
|
142
145
|
|
143
146
|
When testing it can be nice to see the logging output produced by the `geth`
|
@@ -177,19 +180,19 @@ the current list of supported versions.
|
|
177
180
|
Installation can be done via the command line:
|
178
181
|
|
179
182
|
```bash
|
180
|
-
$ python -m geth.install v1.
|
183
|
+
$ python -m geth.install v1.15.7
|
181
184
|
```
|
182
185
|
|
183
186
|
Or from python using the `install_geth` function.
|
184
187
|
|
185
188
|
```python
|
186
189
|
>>> from geth import install_geth
|
187
|
-
>>> install_geth('v1.
|
190
|
+
>>> install_geth('v1.15.7')
|
188
191
|
```
|
189
192
|
|
190
193
|
The installed binary can be found in the `$HOME/.py-geth` directory, under your
|
191
|
-
home directory. The `v1.
|
192
|
-
`$HOME/.py-geth/geth-v1.
|
194
|
+
home directory. The `v1.15.7` binary would be located at
|
195
|
+
`$HOME/.py-geth/geth-v1.15.7/bin/geth`.
|
193
196
|
|
194
197
|
## About `DevGethProcess`
|
195
198
|
|
@@ -38,10 +38,16 @@ tests/core/accounts/conftest.py
|
|
38
38
|
tests/core/accounts/test_account_list_parsing.py
|
39
39
|
tests/core/accounts/test_create_geth_account.py
|
40
40
|
tests/core/accounts/test_geth_accounts.py
|
41
|
+
tests/core/accounts/projects/test-01/geth/LOCK
|
42
|
+
tests/core/accounts/projects/test-01/geth/nodekey
|
41
43
|
tests/core/accounts/projects/test-01/keystore/UTC--2015-08-24T21-30-14.222885490Z--ae71658b3ab452f7e4f03bda6f777b860b2e2ff2
|
44
|
+
tests/core/accounts/projects/test-02/geth/LOCK
|
45
|
+
tests/core/accounts/projects/test-02/geth/nodekey
|
42
46
|
tests/core/accounts/projects/test-02/keystore/UTC--2015-08-24T21-30-14.222885490Z--ae71658b3ab452f7e4f03bda6f777b860b2e2ff2
|
43
47
|
tests/core/accounts/projects/test-02/keystore/UTC--2015-08-24T21-32-00.716418819Z--e8e085862a8d951dd78ec5ea784b3e22ee1ca9c6
|
44
48
|
tests/core/accounts/projects/test-02/keystore/UTC--2015-08-24T21-32-04.748321142Z--0da70f43a568e88168436be52ed129f4a9bbdaf5
|
49
|
+
tests/core/accounts/projects/test-03/geth/LOCK
|
50
|
+
tests/core/accounts/projects/test-03/geth/nodekey
|
45
51
|
tests/core/running/test_running_dev_chain.py
|
46
52
|
tests/core/running/test_running_mainnet_chain.py
|
47
53
|
tests/core/running/test_running_sepolia_chain.py
|
@@ -37,7 +37,7 @@ with open("./README.md") as readme:
|
|
37
37
|
setup(
|
38
38
|
name="py-geth",
|
39
39
|
# *IMPORTANT*: Don't manually change the version here. Use the 'bump-my-version' utility.
|
40
|
-
version="5.
|
40
|
+
version="5.4.0",
|
41
41
|
description="""py-geth: Run Go-Ethereum as a subprocess""",
|
42
42
|
long_description_content_type="text/markdown",
|
43
43
|
long_description=long_description,
|
@@ -0,0 +1 @@
|
|
1
|
+
46cf87d2c3661d137fa3901cfeff7f58b74a4f118d004199580fd588eba10b5e
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
9fb3c3964107a7f76a2474221384c21dc0288552d59ef9aa3317c4e3a1e2045e
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
b0352dc57ebd8601c833b6079e0140a38174c58f13b24f292e0fccc708fe2e4d
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import copy
|
2
|
+
import json
|
3
|
+
import os
|
4
|
+
import re
|
5
|
+
|
6
|
+
from geth import (
|
7
|
+
DevGethProcess,
|
8
|
+
)
|
9
|
+
|
10
|
+
# open genesis.json file from geth main directory
|
11
|
+
MAIN_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
|
12
|
+
|
13
|
+
with open(os.path.join(MAIN_DIR, "geth", "genesis.json")) as genesis_file:
|
14
|
+
GENESIS_JSON = json.load(genesis_file)
|
15
|
+
|
16
|
+
|
17
|
+
def test_version():
|
18
|
+
geth = DevGethProcess("testing")
|
19
|
+
# x.y.z-stable
|
20
|
+
regex = re.compile(r"\d+\.\d+\.\d+-stable")
|
21
|
+
assert regex.match(geth.version)
|
22
|
+
|
23
|
+
|
24
|
+
def test_with_no_overrides(base_dir):
|
25
|
+
geth = DevGethProcess("testing", base_dir=base_dir)
|
26
|
+
|
27
|
+
geth.start()
|
28
|
+
assert geth.is_running
|
29
|
+
assert geth.is_alive
|
30
|
+
geth.stop()
|
31
|
+
assert geth.is_stopped
|
32
|
+
|
33
|
+
|
34
|
+
def test_dev_geth_process_generates_accounts(base_dir):
|
35
|
+
geth = DevGethProcess("testing", base_dir=base_dir)
|
36
|
+
assert len(set(geth.accounts)) == 1
|
37
|
+
|
38
|
+
|
39
|
+
def test_dev_geth_process_generates_genesis_json_from_genesis_data(base_dir):
|
40
|
+
shanghai_genesis = copy.deepcopy(GENESIS_JSON)
|
41
|
+
config = shanghai_genesis.pop("config")
|
42
|
+
|
43
|
+
# stop at Shanghai, drop any keys in config after `shanghaiTime`
|
44
|
+
shanghai_config = {}
|
45
|
+
for key, _value in config.items():
|
46
|
+
shanghai_config[key] = config[key]
|
47
|
+
if key == "shanghaiTime":
|
48
|
+
break
|
49
|
+
|
50
|
+
assert "cancunTime" not in shanghai_config
|
51
|
+
shanghai_genesis["config"] = shanghai_config
|
52
|
+
|
53
|
+
geth = DevGethProcess("testing", base_dir=base_dir, genesis_data=shanghai_genesis)
|
54
|
+
|
55
|
+
# assert genesis.json exists and has the correct data
|
56
|
+
assert os.path.exists(os.path.join(geth.data_dir, "genesis.json"))
|
57
|
+
with open(os.path.join(geth.data_dir, "genesis.json")) as genesis_file:
|
58
|
+
genesis_data = json.load(genesis_file)
|
59
|
+
|
60
|
+
assert genesis_data == shanghai_genesis
|
61
|
+
|
62
|
+
geth.start()
|
63
|
+
assert geth.is_running
|
64
|
+
assert geth.is_alive
|
65
|
+
geth.stop()
|
66
|
+
assert geth.is_stopped
|
67
|
+
|
68
|
+
|
69
|
+
def test_default_config(base_dir):
|
70
|
+
geth = DevGethProcess("testing", base_dir=base_dir)
|
71
|
+
|
72
|
+
assert os.path.exists(os.path.join(geth.data_dir, "genesis.json"))
|
73
|
+
with open(os.path.join(geth.data_dir, "genesis.json")) as genesis_file:
|
74
|
+
genesis_data = json.load(genesis_file)
|
75
|
+
|
76
|
+
# assert genesis_data == GENESIS_JSON with the exception of an added coinbase and
|
77
|
+
# alloc for that coinbase
|
78
|
+
injected_coinbase = genesis_data.pop("coinbase")
|
79
|
+
assert injected_coinbase in genesis_data["alloc"]
|
80
|
+
assert injected_coinbase in geth.accounts
|
81
|
+
|
82
|
+
injected_cb_alloc = genesis_data["alloc"].pop(injected_coinbase)
|
83
|
+
assert injected_cb_alloc == {"balance": "1000000000000000000000000000000"}
|
84
|
+
|
85
|
+
try:
|
86
|
+
assert genesis_data == GENESIS_JSON
|
87
|
+
except AssertionError:
|
88
|
+
assert geth.version.startswith("1.14.0")
|
89
|
+
assert genesis_data["config"]["terminalTotalDifficulty"] == -1
|
90
|
+
|
91
|
+
geth.start()
|
92
|
+
assert geth.is_running
|
93
|
+
assert geth.is_alive
|
94
|
+
geth.stop()
|
95
|
+
assert geth.is_stopped
|
@@ -0,0 +1,92 @@
|
|
1
|
+
from __future__ import (
|
2
|
+
annotations,
|
3
|
+
)
|
4
|
+
|
5
|
+
import pytest
|
6
|
+
|
7
|
+
from geth.exceptions import (
|
8
|
+
PyGethValueError,
|
9
|
+
)
|
10
|
+
from geth.utils.validation import (
|
11
|
+
validate_genesis_data,
|
12
|
+
validate_geth_kwargs,
|
13
|
+
)
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.mark.parametrize(
|
17
|
+
"geth_kwargs",
|
18
|
+
[
|
19
|
+
{
|
20
|
+
"data_dir": "/tmp",
|
21
|
+
"network_id": "123",
|
22
|
+
"rpc_port": "1234",
|
23
|
+
"dev_mode": True,
|
24
|
+
},
|
25
|
+
],
|
26
|
+
)
|
27
|
+
def test_validate_geth_kwargs_good(geth_kwargs):
|
28
|
+
assert validate_geth_kwargs(geth_kwargs) is None
|
29
|
+
|
30
|
+
|
31
|
+
@pytest.mark.parametrize(
|
32
|
+
"geth_kwargs",
|
33
|
+
[
|
34
|
+
{
|
35
|
+
"data_dir": "/tmp",
|
36
|
+
"network_id": 123,
|
37
|
+
"dev_mode": "abc",
|
38
|
+
}
|
39
|
+
],
|
40
|
+
)
|
41
|
+
def test_validate_geth_kwargs_bad(geth_kwargs):
|
42
|
+
with pytest.raises(PyGethValueError):
|
43
|
+
validate_geth_kwargs(geth_kwargs)
|
44
|
+
|
45
|
+
|
46
|
+
@pytest.mark.parametrize(
|
47
|
+
"genesis_data",
|
48
|
+
[
|
49
|
+
{
|
50
|
+
"difficulty": "0x00012131",
|
51
|
+
"nonce": "abc",
|
52
|
+
"timestamp": "1234",
|
53
|
+
}
|
54
|
+
],
|
55
|
+
)
|
56
|
+
def test_validate_genesis_data_good(genesis_data):
|
57
|
+
assert validate_genesis_data(genesis_data) is None
|
58
|
+
|
59
|
+
|
60
|
+
@pytest.mark.parametrize(
|
61
|
+
"genesis_data",
|
62
|
+
[
|
63
|
+
{
|
64
|
+
"difficulty": "0x00012131",
|
65
|
+
"nonce": "abc",
|
66
|
+
"cats": "1234",
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"difficulty": "0x00012131",
|
70
|
+
"nonce": "abc",
|
71
|
+
"config": "1234",
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"difficulty": "0x00012131",
|
75
|
+
"nonce": "abc",
|
76
|
+
"config": None,
|
77
|
+
},
|
78
|
+
"kangaroo",
|
79
|
+
{
|
80
|
+
"difficulty": "0x00012131",
|
81
|
+
"nonce": "abc",
|
82
|
+
"timestamp": "1234",
|
83
|
+
"config": {
|
84
|
+
"cancunTime": 5,
|
85
|
+
"blobSchedule": {},
|
86
|
+
},
|
87
|
+
},
|
88
|
+
],
|
89
|
+
)
|
90
|
+
def test_validate_genesis_data_bad(genesis_data):
|
91
|
+
with pytest.raises(PyGethValueError):
|
92
|
+
validate_genesis_data(genesis_data)
|
File without changes
|
@@ -1,21 +0,0 @@
|
|
1
|
-
from geth import (
|
2
|
-
DevGethProcess,
|
3
|
-
)
|
4
|
-
|
5
|
-
|
6
|
-
def test_with_no_overrides(base_dir):
|
7
|
-
geth = DevGethProcess("testing", base_dir=base_dir)
|
8
|
-
|
9
|
-
geth.start()
|
10
|
-
|
11
|
-
assert geth.is_running
|
12
|
-
assert geth.is_alive
|
13
|
-
|
14
|
-
geth.stop()
|
15
|
-
|
16
|
-
assert geth.is_stopped
|
17
|
-
|
18
|
-
|
19
|
-
def test_dev_geth_process_generates_accounts(base_dir):
|
20
|
-
geth = DevGethProcess("testing", base_dir=base_dir)
|
21
|
-
assert len(set(geth.accounts)) == 1
|
@@ -1,269 +0,0 @@
|
|
1
|
-
from __future__ import (
|
2
|
-
annotations,
|
3
|
-
)
|
4
|
-
|
5
|
-
import pytest
|
6
|
-
import sys
|
7
|
-
from typing import (
|
8
|
-
get_type_hints,
|
9
|
-
)
|
10
|
-
|
11
|
-
from geth.exceptions import (
|
12
|
-
PyGethValueError,
|
13
|
-
)
|
14
|
-
from geth.types import (
|
15
|
-
GenesisDataTypedDict,
|
16
|
-
)
|
17
|
-
from geth.utils.validation import (
|
18
|
-
GenesisData,
|
19
|
-
fill_default_genesis_data,
|
20
|
-
validate_genesis_data,
|
21
|
-
validate_geth_kwargs,
|
22
|
-
)
|
23
|
-
|
24
|
-
|
25
|
-
@pytest.mark.parametrize(
|
26
|
-
"geth_kwargs",
|
27
|
-
[
|
28
|
-
{
|
29
|
-
"data_dir": "/tmp",
|
30
|
-
"network_id": "123",
|
31
|
-
"rpc_port": "1234",
|
32
|
-
"dev_mode": True,
|
33
|
-
},
|
34
|
-
],
|
35
|
-
)
|
36
|
-
def test_validate_geth_kwargs_good(geth_kwargs):
|
37
|
-
assert validate_geth_kwargs(geth_kwargs) is None
|
38
|
-
|
39
|
-
|
40
|
-
@pytest.mark.parametrize(
|
41
|
-
"geth_kwargs",
|
42
|
-
[
|
43
|
-
{
|
44
|
-
"data_dir": "/tmp",
|
45
|
-
"network_id": 123,
|
46
|
-
"dev_mode": "abc",
|
47
|
-
}
|
48
|
-
],
|
49
|
-
)
|
50
|
-
def test_validate_geth_kwargs_bad(geth_kwargs):
|
51
|
-
with pytest.raises(PyGethValueError):
|
52
|
-
validate_geth_kwargs(geth_kwargs)
|
53
|
-
|
54
|
-
|
55
|
-
@pytest.mark.parametrize(
|
56
|
-
"genesis_data",
|
57
|
-
[
|
58
|
-
{
|
59
|
-
"difficulty": "0x00012131",
|
60
|
-
"nonce": "abc",
|
61
|
-
"timestamp": "1234",
|
62
|
-
}
|
63
|
-
],
|
64
|
-
)
|
65
|
-
def test_validate_genesis_data_good(genesis_data):
|
66
|
-
assert validate_genesis_data(genesis_data) is None
|
67
|
-
|
68
|
-
|
69
|
-
@pytest.mark.parametrize(
|
70
|
-
"genesis_data",
|
71
|
-
[
|
72
|
-
{
|
73
|
-
"difficulty": "0x00012131",
|
74
|
-
"nonce": "abc",
|
75
|
-
"cats": "1234",
|
76
|
-
},
|
77
|
-
{
|
78
|
-
"difficulty": "0x00012131",
|
79
|
-
"nonce": "abc",
|
80
|
-
"config": "1234",
|
81
|
-
},
|
82
|
-
{
|
83
|
-
"difficulty": "0x00012131",
|
84
|
-
"nonce": "abc",
|
85
|
-
"config": None,
|
86
|
-
},
|
87
|
-
"kangaroo",
|
88
|
-
],
|
89
|
-
)
|
90
|
-
def test_validate_genesis_data_bad(genesis_data):
|
91
|
-
with pytest.raises(PyGethValueError):
|
92
|
-
validate_genesis_data(genesis_data)
|
93
|
-
|
94
|
-
|
95
|
-
@pytest.mark.parametrize(
|
96
|
-
"genesis_data,expected",
|
97
|
-
[
|
98
|
-
(
|
99
|
-
{
|
100
|
-
"difficulty": "0x00012131",
|
101
|
-
"nonce": "abc",
|
102
|
-
"timestamp": "1234",
|
103
|
-
},
|
104
|
-
{
|
105
|
-
"alloc": {},
|
106
|
-
"baseFeePerGas": "0x0",
|
107
|
-
"blobGasUsed": "0x0",
|
108
|
-
"coinbase": "0x3333333333333333333333333333333333333333",
|
109
|
-
"config": {
|
110
|
-
"chainId": 0,
|
111
|
-
"ethash": {},
|
112
|
-
"homesteadBlock": 0,
|
113
|
-
"daoForkBlock": 0,
|
114
|
-
"daoForkSupport": True,
|
115
|
-
"eip150Block": 0,
|
116
|
-
"eip155Block": 0,
|
117
|
-
"eip158Block": 0,
|
118
|
-
"byzantiumBlock": 0,
|
119
|
-
"constantinopleBlock": 0,
|
120
|
-
"petersburgBlock": 0,
|
121
|
-
"istanbulBlock": 0,
|
122
|
-
"berlinBlock": 0,
|
123
|
-
"londonBlock": 0,
|
124
|
-
"arrowGlacierBlock": 0,
|
125
|
-
"grayGlacierBlock": 0,
|
126
|
-
"terminalTotalDifficulty": 0,
|
127
|
-
"terminalTotalDifficultyPassed": True,
|
128
|
-
"shanghaiTime": 0,
|
129
|
-
"cancunTime": 0,
|
130
|
-
},
|
131
|
-
"difficulty": "0x00012131",
|
132
|
-
"excessBlobGas": "0x0",
|
133
|
-
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", # noqa: E501
|
134
|
-
"gasLimit": "0x47e7c4",
|
135
|
-
"gasUsed": "0x0",
|
136
|
-
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", # noqa: E501
|
137
|
-
"nonce": "abc",
|
138
|
-
"number": "0x0",
|
139
|
-
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", # noqa: E501
|
140
|
-
"timestamp": "1234",
|
141
|
-
},
|
142
|
-
),
|
143
|
-
(
|
144
|
-
{
|
145
|
-
"difficulty": "0x00012131",
|
146
|
-
"nonce": "abc",
|
147
|
-
"config": {
|
148
|
-
"homesteadBlock": 5,
|
149
|
-
"daoForkBlock": 1,
|
150
|
-
"daoForkSupport": False,
|
151
|
-
"eip150Block": 27777777,
|
152
|
-
"eip155Block": 99,
|
153
|
-
"eip158Block": 32,
|
154
|
-
},
|
155
|
-
},
|
156
|
-
{
|
157
|
-
"alloc": {},
|
158
|
-
"baseFeePerGas": "0x0",
|
159
|
-
"blobGasUsed": "0x0",
|
160
|
-
"coinbase": "0x3333333333333333333333333333333333333333",
|
161
|
-
"config": {
|
162
|
-
"chainId": 0,
|
163
|
-
"ethash": {},
|
164
|
-
"homesteadBlock": 5,
|
165
|
-
"daoForkBlock": 1,
|
166
|
-
"daoForkSupport": False,
|
167
|
-
"eip150Block": 27777777,
|
168
|
-
"eip155Block": 99,
|
169
|
-
"eip158Block": 32,
|
170
|
-
"byzantiumBlock": 0,
|
171
|
-
"constantinopleBlock": 0,
|
172
|
-
"petersburgBlock": 0,
|
173
|
-
"istanbulBlock": 0,
|
174
|
-
"berlinBlock": 0,
|
175
|
-
"londonBlock": 0,
|
176
|
-
"arrowGlacierBlock": 0,
|
177
|
-
"grayGlacierBlock": 0,
|
178
|
-
"terminalTotalDifficulty": 0,
|
179
|
-
"terminalTotalDifficultyPassed": True,
|
180
|
-
"shanghaiTime": 0,
|
181
|
-
"cancunTime": 0,
|
182
|
-
},
|
183
|
-
"difficulty": "0x00012131",
|
184
|
-
"excessBlobGas": "0x0",
|
185
|
-
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", # noqa: E501
|
186
|
-
"gasLimit": "0x47e7c4",
|
187
|
-
"gasUsed": "0x0",
|
188
|
-
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", # noqa: E501
|
189
|
-
"nonce": "abc",
|
190
|
-
"number": "0x0",
|
191
|
-
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", # noqa: E501
|
192
|
-
"timestamp": "0x0",
|
193
|
-
},
|
194
|
-
),
|
195
|
-
],
|
196
|
-
)
|
197
|
-
def test_fill_default_genesis_data_good(genesis_data, expected):
|
198
|
-
genesis_data_td = GenesisDataTypedDict(**genesis_data)
|
199
|
-
filled_genesis_data = fill_default_genesis_data(genesis_data_td).model_dump()
|
200
|
-
assert filled_genesis_data == expected
|
201
|
-
|
202
|
-
|
203
|
-
@pytest.mark.parametrize(
|
204
|
-
"genesis_data,expected_exception,expected_message",
|
205
|
-
[
|
206
|
-
(
|
207
|
-
{
|
208
|
-
"difficulty": "0x00012131",
|
209
|
-
"nonce": "abc",
|
210
|
-
"timestamp": 1234,
|
211
|
-
},
|
212
|
-
PyGethValueError,
|
213
|
-
"genesis_data validation failed while filling defaults: ",
|
214
|
-
),
|
215
|
-
(
|
216
|
-
{
|
217
|
-
"difficulty": "0x00012131",
|
218
|
-
"nonce": "abc",
|
219
|
-
"config": {
|
220
|
-
"homesteadBlock": 5,
|
221
|
-
"daoForkBlock": "beep",
|
222
|
-
"daoForkSupport": False,
|
223
|
-
"eip150Block": 27777777,
|
224
|
-
"eip155Block": 99,
|
225
|
-
"eip158Block": 32,
|
226
|
-
},
|
227
|
-
},
|
228
|
-
PyGethValueError,
|
229
|
-
"genesis_data validation failed while filling config defaults: ",
|
230
|
-
),
|
231
|
-
(
|
232
|
-
"abc123",
|
233
|
-
PyGethValueError,
|
234
|
-
"error while filling default genesis_data: ",
|
235
|
-
),
|
236
|
-
(
|
237
|
-
{"difficulty": "0x00012131", "nonce": "abc", "config": ["beep"]},
|
238
|
-
PyGethValueError,
|
239
|
-
"genesis_data validation failed while filling defaults: ",
|
240
|
-
),
|
241
|
-
],
|
242
|
-
)
|
243
|
-
def test_fill_default_genesis_data_bad(
|
244
|
-
genesis_data, expected_exception, expected_message
|
245
|
-
):
|
246
|
-
with pytest.raises(expected_exception) as excinfo:
|
247
|
-
fill_default_genesis_data(genesis_data)
|
248
|
-
assert str(excinfo.value).startswith(expected_message)
|
249
|
-
|
250
|
-
|
251
|
-
@pytest.mark.skipif(sys.version_info < (3, 9), reason="get_type_hints requires >=py39")
|
252
|
-
@pytest.mark.parametrize(
|
253
|
-
"model, typed_dict",
|
254
|
-
[
|
255
|
-
(GenesisData, GenesisDataTypedDict),
|
256
|
-
],
|
257
|
-
)
|
258
|
-
def test_model_fields_match_typed_dict(model, typed_dict):
|
259
|
-
# Get the fields and types from the Pydantic model
|
260
|
-
model_fields = get_type_hints(model)
|
261
|
-
assert len(model_fields) > 0, "Model has no fields"
|
262
|
-
|
263
|
-
# Get the fields and types from the TypedDict
|
264
|
-
typed_dict_fields = get_type_hints(typed_dict)
|
265
|
-
assert len(typed_dict_fields) > 0, "TypedDict has no fields"
|
266
|
-
assert len(typed_dict_fields) == len(model_fields), "Field counts do not match"
|
267
|
-
|
268
|
-
# Verify that the fields match
|
269
|
-
assert model_fields == typed_dict_fields, "Fields do not match"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|