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.
Files changed (68) hide show
  1. {py_geth-5.2.1/py_geth.egg-info → py_geth-5.4.0}/PKG-INFO +9 -6
  2. {py_geth-5.2.1 → py_geth-5.4.0}/README.md +6 -4
  3. {py_geth-5.2.1 → py_geth-5.4.0}/geth/chain.py +1 -6
  4. {py_geth-5.2.1 → py_geth-5.4.0}/geth/genesis.json +14 -1
  5. {py_geth-5.2.1 → py_geth-5.4.0}/geth/install.py +32 -0
  6. {py_geth-5.2.1 → py_geth-5.4.0}/geth/process.py +7 -1
  7. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/validation.py +55 -71
  8. {py_geth-5.2.1 → py_geth-5.4.0/py_geth.egg-info}/PKG-INFO +9 -6
  9. {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/SOURCES.txt +6 -0
  10. {py_geth-5.2.1 → py_geth-5.4.0}/pyproject.toml +1 -1
  11. {py_geth-5.2.1 → py_geth-5.4.0}/setup.py +1 -1
  12. py_geth-5.4.0/tests/core/accounts/projects/test-01/geth/nodekey +1 -0
  13. py_geth-5.4.0/tests/core/accounts/projects/test-02/geth/LOCK +0 -0
  14. py_geth-5.4.0/tests/core/accounts/projects/test-02/geth/nodekey +1 -0
  15. py_geth-5.4.0/tests/core/accounts/projects/test-03/geth/LOCK +0 -0
  16. py_geth-5.4.0/tests/core/accounts/projects/test-03/geth/nodekey +1 -0
  17. py_geth-5.4.0/tests/core/running/test_running_dev_chain.py +95 -0
  18. py_geth-5.4.0/tests/core/utility/test_validation.py +92 -0
  19. py_geth-5.4.0/tests/core/waiting/conftest.py +0 -0
  20. py_geth-5.2.1/tests/core/running/test_running_dev_chain.py +0 -21
  21. py_geth-5.2.1/tests/core/utility/test_validation.py +0 -269
  22. {py_geth-5.2.1 → py_geth-5.4.0}/LICENSE +0 -0
  23. {py_geth-5.2.1 → py_geth-5.4.0}/MANIFEST.in +0 -0
  24. {py_geth-5.2.1 → py_geth-5.4.0}/geth/__init__.py +0 -0
  25. {py_geth-5.2.1 → py_geth-5.4.0}/geth/accounts.py +0 -0
  26. {py_geth-5.2.1 → py_geth-5.4.0}/geth/default_blockchain_password +0 -0
  27. {py_geth-5.2.1 → py_geth-5.4.0}/geth/exceptions.py +0 -0
  28. {py_geth-5.2.1 → py_geth-5.4.0}/geth/main.py +0 -0
  29. {py_geth-5.2.1 → py_geth-5.4.0}/geth/mixins.py +0 -0
  30. {py_geth-5.2.1 → py_geth-5.4.0}/geth/py.typed +0 -0
  31. {py_geth-5.2.1 → py_geth-5.4.0}/geth/reset.py +0 -0
  32. {py_geth-5.2.1 → py_geth-5.4.0}/geth/types.py +0 -0
  33. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/__init__.py +0 -0
  34. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/encoding.py +0 -0
  35. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/filesystem.py +0 -0
  36. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/networking.py +0 -0
  37. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/proc.py +0 -0
  38. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/thread.py +0 -0
  39. {py_geth-5.2.1 → py_geth-5.4.0}/geth/utils/timeout.py +0 -0
  40. {py_geth-5.2.1 → py_geth-5.4.0}/geth/wrapper.py +0 -0
  41. {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/dependency_links.txt +0 -0
  42. {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/not-zip-safe +0 -0
  43. {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/requires.txt +0 -0
  44. {py_geth-5.2.1 → py_geth-5.4.0}/py_geth.egg-info/top_level.txt +0 -0
  45. {py_geth-5.2.1 → py_geth-5.4.0}/scripts/release/test_package.py +0 -0
  46. {py_geth-5.2.1 → py_geth-5.4.0}/setup.cfg +0 -0
  47. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/conftest.py +0 -0
  48. /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
  49. {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
  50. {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
  51. {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
  52. {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
  53. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/test_account_list_parsing.py +0 -0
  54. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/test_create_geth_account.py +0 -0
  55. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/accounts/test_geth_accounts.py +0 -0
  56. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_running_mainnet_chain.py +0 -0
  57. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_running_sepolia_chain.py +0 -0
  58. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_running_with_logging.py +0 -0
  59. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/running/test_use_as_a_context_manager.py +0 -0
  60. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/test_import_and_version.py +0 -0
  61. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/test_library_files.py +0 -0
  62. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_constructing_test_chain_kwargs.py +0 -0
  63. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_geth_version.py +0 -0
  64. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_is_live_chain.py +0 -0
  65. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/utility/test_is_sepolia_chain.py +0 -0
  66. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/waiting/test_waiting_for_ipc_socket.py +0 -0
  67. {py_geth-5.2.1 → py_geth-5.4.0}/tests/core/waiting/test_waiting_for_rpc_connection.py +0 -0
  68. {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.2
1
+ Metadata-Version: 2.4
2
2
  Name: py-geth
3
- Version: 5.2.1
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.14.13
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.14.13')
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.14.13` binary would be located at
192
- `$HOME/.py-geth/geth-v1.14.13/bin/geth`.
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.14.13
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.14.13')
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.14.13` binary would be located at
131
- `$HOME/.py-geth/geth-v1.14.13/bin/geth`.
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
- genesis_data = GenesisDataTypedDict(**GENESIS_JSON)
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
- chainId: int = 0
76
- ethash: dict[str, Any] = {} # so that geth treats config as PoW -> PoS transition
77
- homesteadBlock: int = 0
78
- daoForkBlock: int = 0
79
- daoForkSupport: bool = True
80
- eip150Block: int = 0
81
- eip155Block: int = 0
82
- eip158Block: int = 0
83
- byzantiumBlock: int = 0
84
- constantinopleBlock: int = 0
85
- petersburgBlock: int = 0
86
- istanbulBlock: int = 0
87
- berlinBlock: int = 0
88
- londonBlock: int = 0
89
- arrowGlacierBlock: int = 0
90
- grayGlacierBlock: int = 0
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 = 0
93
- terminalTotalDifficultyPassed: bool = True
97
+ terminalTotalDifficulty: int | None = None
98
+ terminalTotalDifficultyPassed: bool | None = None
94
99
  # post-merge, timestamp is used for network transitions
95
- shanghaiTime: int = 0
96
- cancunTime: int = 0
97
-
98
- model_config = ConfigDict(extra="forbid")
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 = "0x0"
104
- blobGasUsed: str = "0x0"
105
- coinbase: str = "0x3333333333333333333333333333333333333333"
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 = "0x0"
108
- excessBlobGas: str = "0x0"
109
- extraData: str = (
110
- "0x0000000000000000000000000000000000000000000000000000000000000000"
111
- )
112
- gasLimit: str = "0x47e7c4"
113
- gasUsed: str = "0x0"
114
- mixHash: str = "0x0000000000000000000000000000000000000000000000000000000000000000"
115
- nonce: str = "0x0"
116
- number: str = "0x0"
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.2
1
+ Metadata-Version: 2.4
2
2
  Name: py-geth
3
- Version: 5.2.1
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.14.13
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.14.13')
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.14.13` binary would be located at
192
- `$HOME/.py-geth/geth-v1.14.13/bin/geth`.
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
@@ -125,7 +125,7 @@ name = "Removals"
125
125
  showcontent = true
126
126
 
127
127
  [tool.bumpversion]
128
- current_version = "5.2.1"
128
+ current_version = "5.4.0"
129
129
  parse = """
130
130
  (?P<major>\\d+)
131
131
  \\.(?P<minor>\\d+)
@@ -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.2.1",
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
@@ -0,0 +1 @@
1
+ 9fb3c3964107a7f76a2474221384c21dc0288552d59ef9aa3317c4e3a1e2045e
@@ -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