py-geth 4.3.0__py3-none-any.whl → 5.2.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.
- geth/__init__.py +12 -2
- geth/accounts.py +87 -36
- geth/chain.py +68 -83
- geth/exceptions.py +86 -13
- geth/genesis.json +25 -8
- geth/install.py +126 -136
- geth/main.py +27 -5
- geth/mixins.py +54 -29
- geth/process.py +148 -124
- geth/py.typed +0 -0
- geth/reset.py +40 -16
- geth/types.py +65 -0
- geth/utils/encoding.py +36 -24
- geth/utils/filesystem.py +8 -15
- geth/utils/networking.py +18 -6
- geth/utils/proc.py +13 -3
- geth/utils/thread.py +5 -1
- geth/utils/timeout.py +39 -13
- geth/utils/validation.py +179 -0
- geth/wrapper.py +120 -169
- {py_geth-4.3.0.dist-info → py_geth-5.2.0.dist-info}/LICENSE +1 -1
- {py_geth-4.3.0.dist-info → py_geth-5.2.0.dist-info}/METADATA +54 -63
- py_geth-5.2.0.dist-info/RECORD +27 -0
- {py_geth-4.3.0.dist-info → py_geth-5.2.0.dist-info}/WHEEL +1 -1
- geth/utils/dag.py +0 -45
- py_geth-4.3.0.dist-info/RECORD +0 -25
- {py_geth-4.3.0.dist-info → py_geth-5.2.0.dist-info}/top_level.txt +0 -0
geth/wrapper.py
CHANGED
@@ -1,12 +1,29 @@
|
|
1
|
+
from __future__ import (
|
2
|
+
annotations,
|
3
|
+
)
|
4
|
+
|
1
5
|
import functools
|
2
|
-
import logging
|
3
6
|
import os
|
4
7
|
import subprocess
|
5
8
|
import sys
|
6
9
|
import tempfile
|
10
|
+
from typing import (
|
11
|
+
Any,
|
12
|
+
Iterable,
|
13
|
+
cast,
|
14
|
+
)
|
15
|
+
|
16
|
+
from typing_extensions import (
|
17
|
+
Unpack,
|
18
|
+
)
|
7
19
|
|
8
20
|
from geth.exceptions import (
|
9
|
-
|
21
|
+
PyGethGethError,
|
22
|
+
PyGethValueError,
|
23
|
+
)
|
24
|
+
from geth.types import (
|
25
|
+
GethKwargsTypedDict,
|
26
|
+
IO_Any,
|
10
27
|
)
|
11
28
|
from geth.utils.encoding import (
|
12
29
|
force_bytes,
|
@@ -18,6 +35,10 @@ from geth.utils.networking import (
|
|
18
35
|
get_open_port,
|
19
36
|
is_port_open,
|
20
37
|
)
|
38
|
+
from geth.utils.validation import (
|
39
|
+
GethKwargs,
|
40
|
+
validate_geth_kwargs,
|
41
|
+
)
|
21
42
|
|
22
43
|
is_nice_available = functools.partial(is_executable_available, "nice")
|
23
44
|
|
@@ -28,10 +49,10 @@ PYGETH_DIR = os.path.abspath(os.path.dirname(__file__))
|
|
28
49
|
DEFAULT_PASSWORD_PATH = os.path.join(PYGETH_DIR, "default_blockchain_password")
|
29
50
|
|
30
51
|
|
31
|
-
ALL_APIS = "admin,
|
52
|
+
ALL_APIS = "admin,debug,eth,net,txpool,web3"
|
32
53
|
|
33
54
|
|
34
|
-
def get_max_socket_path_length():
|
55
|
+
def get_max_socket_path_length() -> int:
|
35
56
|
if "UNIX_PATH_MAX" in os.environ:
|
36
57
|
return int(os.environ["UNIX_PATH_MAX"])
|
37
58
|
if sys.platform.startswith("darwin"):
|
@@ -42,10 +63,12 @@ def get_max_socket_path_length():
|
|
42
63
|
return 260
|
43
64
|
|
44
65
|
|
45
|
-
def construct_test_chain_kwargs(
|
46
|
-
overrides
|
66
|
+
def construct_test_chain_kwargs(
|
67
|
+
**overrides: Unpack[GethKwargsTypedDict],
|
68
|
+
) -> GethKwargsTypedDict:
|
69
|
+
validate_geth_kwargs(overrides)
|
70
|
+
overrides.setdefault("dev_mode", True)
|
47
71
|
overrides.setdefault("password", DEFAULT_PASSWORD_PATH)
|
48
|
-
overrides.setdefault("mine", True)
|
49
72
|
overrides.setdefault("no_discover", True)
|
50
73
|
overrides.setdefault("max_peers", "0")
|
51
74
|
overrides.setdefault("network_id", "1234")
|
@@ -56,7 +79,6 @@ def construct_test_chain_kwargs(**overrides):
|
|
56
79
|
overrides.setdefault("port", get_open_port())
|
57
80
|
|
58
81
|
overrides.setdefault("ws_enabled", True)
|
59
|
-
overrides.setdefault("ws_addr", "127.0.0.1")
|
60
82
|
overrides.setdefault("ws_api", ALL_APIS)
|
61
83
|
|
62
84
|
if is_port_open(8546):
|
@@ -65,7 +87,6 @@ def construct_test_chain_kwargs(**overrides):
|
|
65
87
|
overrides.setdefault("ws_port", get_open_port())
|
66
88
|
|
67
89
|
overrides.setdefault("rpc_enabled", True)
|
68
|
-
overrides.setdefault("rpc_addr", "127.0.0.1")
|
69
90
|
overrides.setdefault("rpc_api", ALL_APIS)
|
70
91
|
if is_port_open(8545):
|
71
92
|
overrides.setdefault("rpc_port", "8545")
|
@@ -75,11 +96,10 @@ def construct_test_chain_kwargs(**overrides):
|
|
75
96
|
if "ipc_path" not in overrides:
|
76
97
|
# try to use a `geth.ipc` within the provided data_dir if the path is
|
77
98
|
# short enough.
|
78
|
-
if "data_dir"
|
99
|
+
if overrides.get("data_dir") is not None:
|
100
|
+
data_dir = cast(str, overrides["data_dir"])
|
79
101
|
max_path_length = get_max_socket_path_length()
|
80
|
-
geth_ipc_path = os.path.abspath(
|
81
|
-
os.path.join(overrides["data_dir"], "geth.ipc")
|
82
|
-
)
|
102
|
+
geth_ipc_path = os.path.abspath(os.path.join(data_dir, "geth.ipc"))
|
83
103
|
if len(geth_ipc_path) <= max_path_length:
|
84
104
|
overrides.setdefault("ipc_path", geth_ipc_path)
|
85
105
|
|
@@ -90,213 +110,140 @@ def construct_test_chain_kwargs(**overrides):
|
|
90
110
|
)
|
91
111
|
|
92
112
|
overrides.setdefault("verbosity", "5")
|
93
|
-
overrides.setdefault("allow_insecure_unlock", True)
|
94
113
|
|
95
114
|
return overrides
|
96
115
|
|
97
116
|
|
98
|
-
def get_geth_binary_path():
|
117
|
+
def get_geth_binary_path() -> str:
|
99
118
|
return os.environ.get("GETH_BINARY", "geth")
|
100
119
|
|
101
120
|
|
102
121
|
class CommandBuilder:
|
103
|
-
def __init__(self):
|
104
|
-
self.command = []
|
122
|
+
def __init__(self) -> None:
|
123
|
+
self.command: list[str] = []
|
105
124
|
|
106
|
-
def append(self, value):
|
125
|
+
def append(self, value: Any) -> None:
|
107
126
|
self.command.append(str(value))
|
108
127
|
|
109
|
-
def extend(self, value_list):
|
128
|
+
def extend(self, value_list: Iterable[Any]) -> None:
|
110
129
|
self.command.extend([str(v) for v in value_list])
|
111
130
|
|
112
131
|
|
113
|
-
def construct_popen_command(
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
nice=True,
|
124
|
-
unlock=None,
|
125
|
-
password=None,
|
126
|
-
preload=None,
|
127
|
-
port=None,
|
128
|
-
verbosity=None,
|
129
|
-
ipc_disable=None,
|
130
|
-
ipc_path=None,
|
131
|
-
ipc_api=None, # deprecated.
|
132
|
-
ipc_disabled=None,
|
133
|
-
rpc_enabled=None,
|
134
|
-
rpc_addr=None,
|
135
|
-
rpc_port=None,
|
136
|
-
rpc_api=None,
|
137
|
-
rpc_cors_domain=None,
|
138
|
-
ws_enabled=None,
|
139
|
-
ws_addr=None,
|
140
|
-
ws_origins=None,
|
141
|
-
ws_port=None,
|
142
|
-
ws_api=None,
|
143
|
-
suffix_args=None,
|
144
|
-
suffix_kwargs=None,
|
145
|
-
shh=None,
|
146
|
-
allow_insecure_unlock=None,
|
147
|
-
tx_pool_global_slots=None,
|
148
|
-
tx_pool_price_limit=None,
|
149
|
-
cache=None,
|
150
|
-
gcmode=None,
|
151
|
-
):
|
152
|
-
if geth_executable is None:
|
153
|
-
geth_executable = get_geth_binary_path()
|
154
|
-
|
155
|
-
if not is_executable_available(geth_executable):
|
156
|
-
raise ValueError(
|
132
|
+
def construct_popen_command(**geth_kwargs: Unpack[GethKwargsTypedDict]) -> list[str]:
|
133
|
+
# validate geth_kwargs and fill defaults that may not have been provided
|
134
|
+
validate_geth_kwargs(geth_kwargs)
|
135
|
+
gk = GethKwargs(**geth_kwargs)
|
136
|
+
|
137
|
+
if gk.geth_executable is None:
|
138
|
+
gk.geth_executable = get_geth_binary_path()
|
139
|
+
|
140
|
+
if not is_executable_available(gk.geth_executable):
|
141
|
+
raise PyGethValueError(
|
157
142
|
"No geth executable found. Please ensure geth is installed and "
|
158
143
|
"available on your PATH or use the GETH_BINARY environment variable"
|
159
144
|
)
|
160
145
|
|
161
|
-
if ipc_api is not None:
|
162
|
-
raise DeprecationWarning(
|
163
|
-
"The ipc_api flag has been deprecated. The ipc API is now on by "
|
164
|
-
"default. Use `ipc_disable=True` to disable this API"
|
165
|
-
)
|
166
146
|
builder = CommandBuilder()
|
167
147
|
|
168
|
-
if nice and is_nice_available():
|
148
|
+
if gk.nice and is_nice_available():
|
169
149
|
builder.extend(("nice", "-n", "20"))
|
170
150
|
|
171
|
-
builder.append(geth_executable)
|
151
|
+
builder.append(gk.geth_executable)
|
152
|
+
|
153
|
+
if gk.dev_mode:
|
154
|
+
builder.append("--dev")
|
172
155
|
|
173
|
-
if rpc_enabled:
|
156
|
+
if gk.rpc_enabled:
|
174
157
|
builder.append("--http")
|
175
158
|
|
176
|
-
if rpc_addr is not None:
|
177
|
-
builder.extend(("--http.addr", rpc_addr))
|
159
|
+
if gk.rpc_addr is not None:
|
160
|
+
builder.extend(("--http.addr", gk.rpc_addr))
|
178
161
|
|
179
|
-
if rpc_port is not None:
|
180
|
-
builder.extend(("--http.port", rpc_port))
|
162
|
+
if gk.rpc_port is not None:
|
163
|
+
builder.extend(("--http.port", gk.rpc_port))
|
181
164
|
|
182
|
-
if rpc_api is not None:
|
183
|
-
builder.extend(("--http.api", rpc_api))
|
165
|
+
if gk.rpc_api is not None:
|
166
|
+
builder.extend(("--http.api", gk.rpc_api))
|
184
167
|
|
185
|
-
if rpc_cors_domain is not None:
|
186
|
-
builder.extend(("--http.corsdomain", rpc_cors_domain))
|
168
|
+
if gk.rpc_cors_domain is not None:
|
169
|
+
builder.extend(("--http.corsdomain", gk.rpc_cors_domain))
|
187
170
|
|
188
|
-
if ws_enabled:
|
171
|
+
if gk.ws_enabled:
|
189
172
|
builder.append("--ws")
|
190
173
|
|
191
|
-
if ws_addr is not None:
|
192
|
-
builder.extend(("--ws.addr", ws_addr))
|
174
|
+
if gk.ws_addr is not None:
|
175
|
+
builder.extend(("--ws.addr", gk.ws_addr))
|
193
176
|
|
194
|
-
if ws_origins is not None:
|
195
|
-
builder.extend(("--ws.origins", ws_port))
|
177
|
+
if gk.ws_origins is not None:
|
178
|
+
builder.extend(("--ws.origins", gk.ws_port))
|
196
179
|
|
197
|
-
if ws_port is not None:
|
198
|
-
builder.extend(("--ws.port", ws_port))
|
180
|
+
if gk.ws_port is not None:
|
181
|
+
builder.extend(("--ws.port", gk.ws_port))
|
199
182
|
|
200
|
-
if ws_api is not None:
|
201
|
-
builder.extend(("--ws.api", ws_api))
|
183
|
+
if gk.ws_api is not None:
|
184
|
+
builder.extend(("--ws.api", gk.ws_api))
|
202
185
|
|
203
|
-
if data_dir is not None:
|
204
|
-
builder.extend(("--datadir", data_dir))
|
186
|
+
if gk.data_dir is not None:
|
187
|
+
builder.extend(("--datadir", gk.data_dir))
|
205
188
|
|
206
|
-
if max_peers is not None:
|
207
|
-
builder.extend(("--maxpeers", max_peers))
|
189
|
+
if gk.max_peers is not None:
|
190
|
+
builder.extend(("--maxpeers", gk.max_peers))
|
208
191
|
|
209
|
-
if network_id is not None:
|
210
|
-
builder.extend(("--networkid", network_id))
|
192
|
+
if gk.network_id is not None:
|
193
|
+
builder.extend(("--networkid", gk.network_id))
|
211
194
|
|
212
|
-
if port is not None:
|
213
|
-
builder.extend(("--port", port))
|
195
|
+
if gk.port is not None:
|
196
|
+
builder.extend(("--port", gk.port))
|
214
197
|
|
215
|
-
if ipc_disable:
|
198
|
+
if gk.ipc_disable:
|
216
199
|
builder.append("--ipcdisable")
|
217
200
|
|
218
|
-
if ipc_path is not None:
|
219
|
-
builder.extend(("--ipcpath", ipc_path))
|
201
|
+
if gk.ipc_path is not None:
|
202
|
+
builder.extend(("--ipcpath", gk.ipc_path))
|
220
203
|
|
221
|
-
if verbosity is not None:
|
222
|
-
builder.extend(
|
223
|
-
(
|
224
|
-
"--verbosity",
|
225
|
-
verbosity,
|
226
|
-
)
|
227
|
-
)
|
228
|
-
|
229
|
-
if unlock is not None:
|
230
|
-
builder.extend(
|
231
|
-
(
|
232
|
-
"--unlock",
|
233
|
-
unlock,
|
234
|
-
)
|
235
|
-
)
|
204
|
+
if gk.verbosity is not None:
|
205
|
+
builder.extend(("--verbosity", gk.verbosity))
|
236
206
|
|
237
|
-
if password is not None:
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
)
|
243
|
-
)
|
207
|
+
if isinstance(gk.password, str) and gk.password is not None:
|
208
|
+
# If password is a string, it's a file path
|
209
|
+
# If password is bytes, it's the password itself and is passed directly to
|
210
|
+
# the geth process elsewhere
|
211
|
+
builder.extend(("--password", gk.password))
|
244
212
|
|
245
|
-
if preload is not None:
|
246
|
-
builder.extend(("--preload", preload))
|
213
|
+
if gk.preload is not None:
|
214
|
+
builder.extend(("--preload", gk.preload))
|
247
215
|
|
248
|
-
if no_discover:
|
216
|
+
if gk.no_discover:
|
249
217
|
builder.append("--nodiscover")
|
250
218
|
|
251
|
-
if
|
252
|
-
|
253
|
-
raise ValueError("Cannot mine without an unlocked account")
|
254
|
-
builder.append("--mine")
|
255
|
-
|
256
|
-
if miner_threads is not None:
|
257
|
-
logging.warning(
|
258
|
-
"`--miner.threads` is deprecated and will be removed in a future release."
|
259
|
-
)
|
260
|
-
if not mine:
|
261
|
-
raise ValueError("`mine` must be truthy when specifying `miner_threads`")
|
262
|
-
builder.extend(("--miner.threads", miner_threads))
|
219
|
+
if gk.tx_pool_global_slots is not None:
|
220
|
+
builder.extend(("--txpool.globalslots", gk.tx_pool_global_slots))
|
263
221
|
|
264
|
-
if
|
265
|
-
|
266
|
-
raise ValueError("`mine` must be truthy when specifying `miner_etherbase`")
|
267
|
-
builder.extend(("--miner.etherbase", miner_etherbase))
|
222
|
+
if gk.tx_pool_lifetime is not None:
|
223
|
+
builder.extend(("--txpool.lifetime", gk.tx_pool_lifetime))
|
268
224
|
|
269
|
-
if
|
270
|
-
builder.
|
225
|
+
if gk.tx_pool_price_limit is not None:
|
226
|
+
builder.extend(("--txpool.pricelimit", gk.tx_pool_price_limit))
|
271
227
|
|
272
|
-
if
|
273
|
-
builder.
|
228
|
+
if gk.cache:
|
229
|
+
builder.extend(("--cache", gk.cache))
|
274
230
|
|
275
|
-
if
|
276
|
-
builder.
|
231
|
+
if gk.gcmode:
|
232
|
+
builder.extend(("--gcmode", gk.gcmode))
|
277
233
|
|
278
|
-
if
|
279
|
-
builder.extend(
|
234
|
+
if gk.suffix_kwargs:
|
235
|
+
builder.extend(gk.suffix_kwargs)
|
280
236
|
|
281
|
-
if
|
282
|
-
builder.extend(
|
283
|
-
|
284
|
-
if cache:
|
285
|
-
builder.extend(("--cache", cache))
|
286
|
-
|
287
|
-
if gcmode:
|
288
|
-
builder.extend(("--gcmode", gcmode))
|
289
|
-
|
290
|
-
if suffix_kwargs:
|
291
|
-
builder.extend(suffix_kwargs)
|
292
|
-
|
293
|
-
if suffix_args:
|
294
|
-
builder.extend(suffix_args)
|
237
|
+
if gk.suffix_args:
|
238
|
+
builder.extend(gk.suffix_args)
|
295
239
|
|
296
240
|
return builder.command
|
297
241
|
|
298
242
|
|
299
|
-
def geth_wrapper(
|
243
|
+
def geth_wrapper(
|
244
|
+
**geth_kwargs: Unpack[GethKwargsTypedDict],
|
245
|
+
) -> tuple[bytes, bytes, list[str], subprocess.Popen[bytes]]:
|
246
|
+
validate_geth_kwargs(geth_kwargs)
|
300
247
|
stdin = geth_kwargs.pop("stdin", None)
|
301
248
|
command = construct_popen_command(**geth_kwargs)
|
302
249
|
|
@@ -306,14 +253,14 @@ def geth_wrapper(**geth_kwargs):
|
|
306
253
|
stdout=subprocess.PIPE,
|
307
254
|
stderr=subprocess.PIPE,
|
308
255
|
)
|
309
|
-
|
256
|
+
stdin_bytes: bytes | None = None
|
310
257
|
if stdin is not None:
|
311
|
-
|
258
|
+
stdin_bytes = force_bytes(stdin)
|
312
259
|
|
313
|
-
stdoutdata, stderrdata = proc.communicate(
|
260
|
+
stdoutdata, stderrdata = proc.communicate(stdin_bytes)
|
314
261
|
|
315
262
|
if proc.returncode != 0:
|
316
|
-
raise
|
263
|
+
raise PyGethGethError(
|
317
264
|
command=command,
|
318
265
|
return_code=proc.returncode,
|
319
266
|
stdin_data=stdin,
|
@@ -325,8 +272,12 @@ def geth_wrapper(**geth_kwargs):
|
|
325
272
|
|
326
273
|
|
327
274
|
def spawn_geth(
|
328
|
-
geth_kwargs
|
329
|
-
|
275
|
+
geth_kwargs: GethKwargsTypedDict,
|
276
|
+
stdin: IO_Any = subprocess.PIPE,
|
277
|
+
stdout: IO_Any = subprocess.PIPE,
|
278
|
+
stderr: IO_Any = subprocess.PIPE,
|
279
|
+
) -> tuple[list[str], subprocess.Popen[bytes]]:
|
280
|
+
validate_geth_kwargs(geth_kwargs)
|
330
281
|
command = construct_popen_command(**geth_kwargs)
|
331
282
|
|
332
283
|
proc = subprocess.Popen(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2016-
|
3
|
+
Copyright (c) 2016-2025 The Ethereum Foundation
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: py-geth
|
3
|
-
Version:
|
3
|
+
Version: 5.2.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
|
@@ -16,29 +16,48 @@ Classifier: Programming Language :: Python :: 3.8
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.9
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
19
21
|
Requires-Python: >=3.8, <4
|
20
22
|
Description-Content-Type: text/markdown
|
21
23
|
License-File: LICENSE
|
22
|
-
Requires-Dist:
|
24
|
+
Requires-Dist: eval_type_backport>=0.1.0; python_version < "3.10"
|
25
|
+
Requires-Dist: pydantic>=2.6.0
|
26
|
+
Requires-Dist: requests>=2.23
|
27
|
+
Requires-Dist: semantic-version>=2.6.0
|
28
|
+
Requires-Dist: types-requests>=2.0.0
|
29
|
+
Requires-Dist: typing-extensions>=4.0.1
|
23
30
|
Provides-Extra: dev
|
24
|
-
Requires-Dist: build
|
25
|
-
Requires-Dist:
|
26
|
-
Requires-Dist: ipython
|
27
|
-
Requires-Dist:
|
28
|
-
Requires-Dist:
|
29
|
-
Requires-Dist: tox
|
30
|
-
Requires-Dist: twine
|
31
|
-
Requires-Dist: wheel
|
32
|
-
Requires-Dist: towncrier
|
33
|
-
Requires-Dist: flaky
|
34
|
-
Requires-Dist: pytest
|
35
|
-
Requires-Dist: pytest-xdist
|
31
|
+
Requires-Dist: build>=0.9.0; extra == "dev"
|
32
|
+
Requires-Dist: bump_my_version>=0.19.0; extra == "dev"
|
33
|
+
Requires-Dist: ipython; extra == "dev"
|
34
|
+
Requires-Dist: mypy==1.10.0; extra == "dev"
|
35
|
+
Requires-Dist: pre-commit>=3.4.0; extra == "dev"
|
36
|
+
Requires-Dist: tox>=4.0.0; extra == "dev"
|
37
|
+
Requires-Dist: twine; extra == "dev"
|
38
|
+
Requires-Dist: wheel; extra == "dev"
|
39
|
+
Requires-Dist: towncrier<25,>=24; extra == "dev"
|
40
|
+
Requires-Dist: flaky>=3.2.0; extra == "dev"
|
41
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
42
|
+
Requires-Dist: pytest-xdist>=2.4.0; extra == "dev"
|
36
43
|
Provides-Extra: docs
|
37
|
-
Requires-Dist: towncrier
|
44
|
+
Requires-Dist: towncrier<25,>=24; extra == "docs"
|
38
45
|
Provides-Extra: test
|
39
|
-
Requires-Dist: flaky
|
40
|
-
Requires-Dist: pytest
|
41
|
-
Requires-Dist: pytest-xdist
|
46
|
+
Requires-Dist: flaky>=3.2.0; extra == "test"
|
47
|
+
Requires-Dist: pytest>=7.0.0; extra == "test"
|
48
|
+
Requires-Dist: pytest-xdist>=2.4.0; extra == "test"
|
49
|
+
Dynamic: author
|
50
|
+
Dynamic: author-email
|
51
|
+
Dynamic: classifier
|
52
|
+
Dynamic: description
|
53
|
+
Dynamic: description-content-type
|
54
|
+
Dynamic: home-page
|
55
|
+
Dynamic: keywords
|
56
|
+
Dynamic: license
|
57
|
+
Dynamic: provides-extra
|
58
|
+
Dynamic: requires-dist
|
59
|
+
Dynamic: requires-python
|
60
|
+
Dynamic: summary
|
42
61
|
|
43
62
|
# py-geth
|
44
63
|
|
@@ -57,8 +76,6 @@ This library requires the `geth` executable to be present.
|
|
57
76
|
|
58
77
|
## Installation
|
59
78
|
|
60
|
-
Installation
|
61
|
-
|
62
79
|
```bash
|
63
80
|
python -m pip install py-geth
|
64
81
|
```
|
@@ -68,12 +85,12 @@ python -m pip install py-geth
|
|
68
85
|
To run geth connected to the mainnet
|
69
86
|
|
70
87
|
```python
|
71
|
-
>>> from geth import
|
72
|
-
>>> geth =
|
88
|
+
>>> from geth import MainnetGethProcess
|
89
|
+
>>> geth = MainnetGethProcess()
|
73
90
|
>>> geth.start()
|
74
91
|
```
|
75
92
|
|
76
|
-
Or
|
93
|
+
Or in dev mode for testing. These require you to give them a name.
|
77
94
|
|
78
95
|
```python
|
79
96
|
>>> from geth import DevGethProcess
|
@@ -138,83 +155,57 @@ and stderr output to a logfile.
|
|
138
155
|
All logs will be written to logfiles in `./logs/` in the current directory.
|
139
156
|
|
140
157
|
The underlying `geth` process can take additional time to open the RPC or IPC
|
141
|
-
connections
|
142
|
-
can use the following interfaces to query whether these are ready.
|
158
|
+
connections. You can use the following interfaces to query whether these are ready.
|
143
159
|
|
144
160
|
```python
|
145
|
-
>>> geth.is_rpc_ready
|
146
|
-
True
|
147
161
|
>>> geth.wait_for_rpc(timeout=30) # wait up to 30 seconds for the RPC connection to open
|
148
|
-
>>> geth.
|
162
|
+
>>> geth.is_rpc_ready
|
149
163
|
True
|
150
164
|
>>> geth.wait_for_ipc(timeout=30) # wait up to 30 seconds for the IPC socket to open
|
151
|
-
>>> geth.
|
152
|
-
True
|
153
|
-
>>> geth.is_mining
|
165
|
+
>>> geth.is_ipc_ready
|
154
166
|
True
|
155
|
-
>>> geth.wait_for_dag(timeout=600) # wait up to 10 minutes for the DAG to generate.
|
156
167
|
```
|
157
168
|
|
158
|
-
> The DAG functionality currently only applies to the DAG for epoch 0.
|
159
|
-
|
160
169
|
## Installing specific versions of `geth`
|
161
170
|
|
162
171
|
> This feature is experimental and subject to breaking changes.
|
163
172
|
|
164
|
-
Versions of `geth` dating back to v1.
|
173
|
+
Versions of `geth` dating back to v1.14.0 can be installed using `py-geth`.
|
165
174
|
See [install.py](https://github.com/ethereum/py-geth/blob/main/geth/install.py) for
|
166
175
|
the current list of supported versions.
|
167
176
|
|
168
177
|
Installation can be done via the command line:
|
169
178
|
|
170
179
|
```bash
|
171
|
-
$ python -m geth.install v1.
|
180
|
+
$ python -m geth.install v1.14.12
|
172
181
|
```
|
173
182
|
|
174
183
|
Or from python using the `install_geth` function.
|
175
184
|
|
176
185
|
```python
|
177
186
|
>>> from geth import install_geth
|
178
|
-
>>> install_geth('v1.
|
187
|
+
>>> install_geth('v1.14.12')
|
179
188
|
```
|
180
189
|
|
181
190
|
The installed binary can be found in the `$HOME/.py-geth` directory, under your
|
182
|
-
home directory. The `v1.
|
183
|
-
`$HOME/.py-geth/geth-v1.
|
191
|
+
home directory. The `v1.14.12` binary would be located at
|
192
|
+
`$HOME/.py-geth/geth-v1.14.12/bin/geth`.
|
184
193
|
|
185
194
|
## About `DevGethProcess`
|
186
195
|
|
187
|
-
The `DevGethProcess` is designed to facilitate testing.
|
188
|
-
preconfigured as follows.
|
196
|
+
The `DevGethProcess` will run geth in `--dev` mode and is designed to facilitate testing.
|
197
|
+
In that regard, it is preconfigured as follows.
|
189
198
|
|
190
|
-
- A single account is created
|
199
|
+
- A single account is created, allocated 1 billion ether, and assigned as the coinbase.
|
191
200
|
- All APIs are enabled on both `rpc` and `ipc` interfaces.
|
192
|
-
- Account 0 is unlocked
|
193
201
|
- Networking is configured to not look for or connect to any peers.
|
194
202
|
- The `networkid` of `1234` is used.
|
195
203
|
- Verbosity is set to `5` (DEBUG)
|
196
|
-
- Mining is enabled with a single thread.
|
197
204
|
- The RPC interface *tries* to bind to 8545 but will find an open port if this
|
198
205
|
port is not available.
|
199
206
|
- The DevP2P interface *tries* to bind to 30303 but will find an open port if this
|
200
207
|
port is not available.
|
201
208
|
|
202
|
-
## Gotchas
|
203
|
-
|
204
|
-
If you are running with `mining` enabled, which is default for `DevGethProcess`,
|
205
|
-
then you will likely need to generate the `DAG` manually. If you do not, then
|
206
|
-
it will auto-generate the first time you run the process and this takes a
|
207
|
-
while.
|
208
|
-
|
209
|
-
To generate it manually:
|
210
|
-
|
211
|
-
```sh
|
212
|
-
$ geth makedag 0 ~/.ethash
|
213
|
-
```
|
214
|
-
|
215
|
-
This is especially important in CI environments like Travis-CI where your
|
216
|
-
process will likely timeout during generation.
|
217
|
-
|
218
209
|
## Development
|
219
210
|
|
220
211
|
Clone the repository:
|
@@ -297,14 +288,14 @@ the version for the one you wish to add support for. Note that the `v` in the ve
|
|
297
288
|
optional.
|
298
289
|
|
299
290
|
```shell
|
300
|
-
$ python update_geth.py
|
291
|
+
$ python update_geth.py v1_14_0
|
301
292
|
```
|
302
293
|
|
303
294
|
To introduce support for more than one version, pass in the versions in increasing order,
|
304
295
|
ending with the latest version.
|
305
296
|
|
306
297
|
```shell
|
307
|
-
$ python update_geth.py
|
298
|
+
$ python update_geth.py v1_14_0 v1_14_2 v1_14_3
|
308
299
|
```
|
309
300
|
|
310
301
|
Always review your changes before committing as something may cause this existing pattern to change at some point.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
geth/__init__.py,sha256=vPIxujjhq68syWZuHJQy6vNxW6yqbi7M8hmEtYVoKWs,583
|
2
|
+
geth/accounts.py,sha256=QxhjdyFT5JSgTswQiPsMMgCpTcV9-vaZiksDoWfePTI,5943
|
3
|
+
geth/chain.py,sha256=VMbb1OMI8z-HRteYg7bDgDpf9-SyLYioy2OIYO7oW5s,3879
|
4
|
+
geth/default_blockchain_password,sha256=7ZYUjo1py5Wh_uA_WvoXQG8mPv2CiJ07tI2tOodTLi8,30
|
5
|
+
geth/exceptions.py,sha256=yLGBkLabY_W-43kW9iYPM3FaoR08JWgTWYW1RHukaeU,2643
|
6
|
+
geth/genesis.json,sha256=E6pcGhk0pz1ByhRvyqeVbNAteOB4U1jOj4KiHtR2tAM,901
|
7
|
+
geth/install.py,sha256=slY0AvnYCXvxznUdvkCJ_pPAhmePgux8WlZ7QMQaoKk,11459
|
8
|
+
geth/main.py,sha256=jgWIs3o9BfHcqWfuq6l4JBjcdQzDy13-EJDP1c2ouhQ,1463
|
9
|
+
geth/mixins.py,sha256=cpls-_Z9WZdmYbjhOZL-y6F1xRYAvmfWRed2DODe6D8,5639
|
10
|
+
geth/process.py,sha256=SumVj-2Q7PQ-HZBaCcpN_PY9WkIqlRuy9hRo0VCpb2A,8864
|
11
|
+
geth/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
+
geth/reset.py,sha256=IlKfr5PyjVi0rHjoGUY5kbjtnR9ZAsfSb1Jgzh0dDo0,2639
|
13
|
+
geth/types.py,sha256=El5Q7ZnR7d_z7jliYhbH2df1FxaKOVHgxlyD8U-qzt0,1454
|
14
|
+
geth/wrapper.py,sha256=yPr0wyczd7ngLRJekIPinXyTP7cLtwyiWDTYxMlo-oU,7882
|
15
|
+
geth/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
+
geth/utils/encoding.py,sha256=YguGD7mEUN2eSMPkBREalKK1VQfOsLcj1WWJLR0HTxY,1618
|
17
|
+
geth/utils/filesystem.py,sha256=yg8m8n99-N0FA4NcNtu9V8mett2WTQPKHGjThrbk974,1320
|
18
|
+
geth/utils/networking.py,sha256=ntH6CZuGcTJJ0BIdT4rI-EMz703VDbJAJzGcxufDQMo,1488
|
19
|
+
geth/utils/proc.py,sha256=0CcHzOTkSzikrli_2ooQT6iHpPaTRYsshcvrGYC7btA,1801
|
20
|
+
geth/utils/thread.py,sha256=IL4C-AvzYbOwW2qOIMS63GVEqiWLe9TiMXX20qT1UaY,315
|
21
|
+
geth/utils/timeout.py,sha256=Uiz90EKJJm7UmKmVx2FhBpIblnvg9dTqszsanvfOtFM,2259
|
22
|
+
geth/utils/validation.py,sha256=YG3l98_EaweqUjElRJRxtdEldRwOz9cYii00PR74RkI,5396
|
23
|
+
py_geth-5.2.0.dist-info/LICENSE,sha256=ENGC4gSn0kYaC_mlaXOEwCKmA6W7Z9MeSemc5O2k-h0,1095
|
24
|
+
py_geth-5.2.0.dist-info/METADATA,sha256=6npuEUtNiQVeddMOdsikaJdTD2o1ZdCJJUIz-QmGDGA,9214
|
25
|
+
py_geth-5.2.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
26
|
+
py_geth-5.2.0.dist-info/top_level.txt,sha256=o8Gvkxt3xBR7BNG2p9_G1J3GnGlTrBMEhYJBdAzBWDU,5
|
27
|
+
py_geth-5.2.0.dist-info/RECORD,,
|