py-geth 4.2.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/reset.py CHANGED
@@ -1,5 +1,23 @@
1
+ from __future__ import (
2
+ annotations,
3
+ )
4
+
1
5
  import os
2
6
 
7
+ from typing_extensions import (
8
+ Unpack,
9
+ )
10
+
11
+ from geth.exceptions import (
12
+ PyGethValueError,
13
+ )
14
+ from geth.types import (
15
+ GethKwargsTypedDict,
16
+ )
17
+ from geth.utils.validation import (
18
+ validate_geth_kwargs,
19
+ )
20
+
3
21
  from .chains import (
4
22
  is_live_chain,
5
23
  is_testnet_chain,
@@ -9,47 +27,53 @@ from .utils.filesystem import (
9
27
  remove_file_if_exists,
10
28
  )
11
29
  from .wrapper import (
12
- spawn_geth_subprocess,
30
+ spawn_geth,
13
31
  )
14
32
 
15
33
 
16
- def soft_reset_chain(allow_live=False, allow_testnet=False, **geth_kwargs):
34
+ def soft_reset_chain(
35
+ allow_live: bool = False,
36
+ allow_testnet: bool = False,
37
+ **geth_kwargs: Unpack[GethKwargsTypedDict],
38
+ ) -> None:
39
+ validate_geth_kwargs(geth_kwargs)
17
40
  data_dir = geth_kwargs.get("data_dir")
18
41
 
19
42
  if data_dir is None or (not allow_live and is_live_chain(data_dir)):
20
- raise ValueError(
43
+ raise PyGethValueError(
21
44
  "To reset the live chain you must call this function with `allow_live=True`"
22
45
  )
23
46
 
24
47
  if not allow_testnet and is_testnet_chain(data_dir):
25
- raise ValueError(
48
+ raise PyGethValueError(
26
49
  "To reset the testnet chain you must call this function with `allow_testnet=True`" # noqa: E501
27
50
  )
28
51
 
29
- suffix_args = geth_kwargs.pop("suffix_args", [])
52
+ suffix_args = geth_kwargs.pop("suffix_args") or []
30
53
  suffix_args.extend(("removedb",))
54
+ geth_kwargs.update({"suffix_args": suffix_args})
31
55
 
32
- geth_kwargs["suffix_args"] = suffix_args
33
-
34
- _, proc = spawn_geth_subprocess(**geth_kwargs)
56
+ _, proc = spawn_geth(geth_kwargs)
35
57
 
36
- stdoutdata, stderrdata = proc.communicate("y")
58
+ stdoutdata, stderrdata = proc.communicate(b"y")
37
59
 
38
- if "Removing chaindata" not in stdoutdata:
39
- raise ValueError(
40
- f"An error occurred while removing the chain:\n\nError:\n{stderrdata}\n\n"
41
- f"Output:\n{stdoutdata}"
60
+ if "Removing chaindata" not in stdoutdata.decode():
61
+ raise PyGethValueError(
62
+ "An error occurred while removing the chain:\n\nError:\n"
63
+ f"{stderrdata.decode()}\n\nOutput:\n{stdoutdata.decode()}"
42
64
  )
43
65
 
44
66
 
45
- def hard_reset_chain(data_dir, allow_live=False, allow_testnet=False):
67
+ def hard_reset_chain(
68
+ data_dir: str, allow_live: bool = False, allow_testnet: bool = False
69
+ ) -> None:
46
70
  if not allow_live and is_live_chain(data_dir):
47
- raise ValueError(
71
+ raise PyGethValueError(
48
72
  "To reset the live chain you must call this function with `allow_live=True`"
49
73
  )
50
74
 
51
75
  if not allow_testnet and is_testnet_chain(data_dir):
52
- raise ValueError(
76
+ raise PyGethValueError(
53
77
  "To reset the testnet chain you must call this function with `allow_testnet=True`" # noqa: E501
54
78
  )
55
79
 
geth/types.py ADDED
@@ -0,0 +1,65 @@
1
+ from __future__ import (
2
+ annotations,
3
+ )
4
+
5
+ from typing import (
6
+ IO,
7
+ Any,
8
+ Literal,
9
+ TypedDict,
10
+ Union,
11
+ )
12
+
13
+ IO_Any = Union[IO[Any], int, None]
14
+
15
+
16
+ class GethKwargsTypedDict(TypedDict, total=False):
17
+ cache: str | None
18
+ data_dir: str | None
19
+ dev_mode: bool | None
20
+ gcmode: Literal["full", "archive"] | None
21
+ geth_executable: str | None
22
+ ipc_disable: bool | None
23
+ ipc_path: str | None
24
+ max_peers: str | None
25
+ network_id: str | None
26
+ nice: bool | None
27
+ no_discover: bool | None
28
+ password: bytes | str | None
29
+ port: str | None
30
+ preload: str | None
31
+ rpc_addr: str | None
32
+ rpc_api: str | None
33
+ rpc_cors_domain: str | None
34
+ rpc_enabled: bool | None
35
+ rpc_port: str | None
36
+ stdin: str | None
37
+ suffix_args: list[str] | None
38
+ suffix_kwargs: dict[str, str] | None
39
+ tx_pool_global_slots: str | None
40
+ tx_pool_lifetime: str | None
41
+ tx_pool_price_limit: str | None
42
+ verbosity: str | None
43
+ ws_addr: str | None
44
+ ws_api: str | None
45
+ ws_enabled: bool | None
46
+ ws_origins: str | None
47
+ ws_port: str | None
48
+
49
+
50
+ class GenesisDataTypedDict(TypedDict, total=False):
51
+ alloc: dict[str, dict[str, Any]]
52
+ baseFeePerGas: str
53
+ blobGasUsed: str
54
+ coinbase: str
55
+ config: dict[str, Any]
56
+ difficulty: str
57
+ excessBlobGas: str
58
+ extraData: str
59
+ gasLimit: str
60
+ gasUsed: str
61
+ mixHash: str
62
+ nonce: str
63
+ number: str
64
+ parentHash: str
65
+ timestamp: str
geth/utils/encoding.py CHANGED
@@ -1,41 +1,53 @@
1
- import codecs
2
-
3
- binary_types = (bytes, bytearray)
4
- text_types = (str,)
5
- string_types = (bytes, str, bytearray)
6
-
7
-
8
- def is_binary(value):
9
- return isinstance(value, binary_types)
1
+ from __future__ import (
2
+ annotations,
3
+ )
10
4
 
5
+ import codecs
6
+ from typing import (
7
+ Any,
8
+ )
11
9
 
12
- def is_text(value):
13
- return isinstance(value, text_types)
10
+ from geth.exceptions import (
11
+ PyGethTypeError,
12
+ )
14
13
 
15
14
 
16
- def is_string(value):
17
- return isinstance(value, string_types)
15
+ def is_string(value: Any) -> bool:
16
+ return isinstance(value, (bytes, bytearray, str))
18
17
 
19
18
 
20
- def force_bytes(value, encoding="iso-8859-1"):
21
- if is_binary(value):
19
+ def force_bytes(value: bytes | bytearray | str, encoding: str = "iso-8859-1") -> bytes:
20
+ if isinstance(value, bytes):
21
+ return value
22
+ elif isinstance(value, bytearray):
22
23
  return bytes(value)
23
- elif is_text(value):
24
- return codecs.encode(value, encoding)
24
+ elif isinstance(value, str):
25
+ encoded = codecs.encode(value, encoding)
26
+ if isinstance(encoded, (bytes, bytearray)):
27
+ return encoded
28
+ else:
29
+ raise PyGethTypeError(
30
+ f"Encoding {encoding!r} produced non-binary result: {encoded!r}"
31
+ )
25
32
  else:
26
- raise TypeError(f"Unsupported type: {type(value)}")
33
+ raise PyGethTypeError(
34
+ f"Unsupported type: {type(value)}, expected bytes, bytearray or str"
35
+ )
27
36
 
28
37
 
29
- def force_text(value, encoding="iso-8859-1"):
30
- if is_text(value):
31
- return value
32
- elif is_binary(value):
38
+ def force_text(value: bytes | bytearray | str, encoding: str = "iso-8859-1") -> str:
39
+ if isinstance(value, (bytes, bytearray)):
33
40
  return codecs.decode(value, encoding)
41
+ elif isinstance(value, str):
42
+ return value
34
43
  else:
35
- raise TypeError(f"Unsupported type: {type(value)}")
44
+ raise PyGethTypeError(
45
+ f"Unsupported type: {type(value)}, "
46
+ "expected value to be bytes, bytearray or str"
47
+ )
36
48
 
37
49
 
38
- def force_obj_to_text(obj):
50
+ def force_obj_to_text(obj: Any) -> Any:
39
51
  if is_string(obj):
40
52
  return force_text(obj)
41
53
  elif isinstance(obj, dict):
geth/utils/filesystem.py CHANGED
@@ -1,19 +1,12 @@
1
- import errno
2
1
  import os
3
2
  import shutil
4
3
 
5
4
 
6
- def mkdir(path):
7
- try:
8
- os.makedirs(path)
9
- except OSError as exc: # Python >2.5
10
- if exc.errno == errno.EEXIST and os.path.isdir(path):
11
- pass
12
- else:
13
- raise
5
+ def mkdir(path: str) -> None:
6
+ os.makedirs(path, exist_ok=True)
14
7
 
15
8
 
16
- def ensure_path_exists(dir_path):
9
+ def ensure_path_exists(dir_path: str) -> bool:
17
10
  """
18
11
  Make sure that a path exists
19
12
  """
@@ -23,22 +16,22 @@ def ensure_path_exists(dir_path):
23
16
  return False
24
17
 
25
18
 
26
- def remove_file_if_exists(path):
19
+ def remove_file_if_exists(path: str) -> bool:
27
20
  if os.path.isfile(path):
28
21
  os.remove(path)
29
22
  return True
30
23
  return False
31
24
 
32
25
 
33
- def remove_dir_if_exists(path):
26
+ def remove_dir_if_exists(path: str) -> bool:
34
27
  if os.path.isdir(path):
35
28
  shutil.rmtree(path)
36
29
  return True
37
30
  return False
38
31
 
39
32
 
40
- def is_executable_available(program):
41
- def is_exe(fpath):
33
+ def is_executable_available(program: str) -> bool:
34
+ def is_exe(fpath: str) -> bool:
42
35
  return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
43
36
 
44
37
  fpath = os.path.dirname(program)
@@ -55,7 +48,7 @@ def is_executable_available(program):
55
48
  return False
56
49
 
57
50
 
58
- def is_same_path(p1, p2):
51
+ def is_same_path(p1: str, p2: str) -> bool:
59
52
  n_p1 = os.path.abspath(os.path.expanduser(p1))
60
53
  n_p2 = os.path.abspath(os.path.expanduser(p2))
61
54
 
geth/utils/networking.py CHANGED
@@ -1,17 +1,24 @@
1
1
  import contextlib
2
2
  import socket
3
3
  import time
4
+ from typing import (
5
+ Generator,
6
+ )
7
+
8
+ from geth.exceptions import (
9
+ PyGethValueError,
10
+ )
4
11
 
5
12
  from .timeout import (
6
13
  Timeout,
7
14
  )
8
15
 
9
16
 
10
- def is_port_open(port):
17
+ def is_port_open(port: int) -> bool:
11
18
  sock = socket.socket()
12
19
  try:
13
20
  sock.bind(("127.0.0.1", port))
14
- except socket.error:
21
+ except OSError:
15
22
  return False
16
23
  else:
17
24
  return True
@@ -19,7 +26,7 @@ def is_port_open(port):
19
26
  sock.close()
20
27
 
21
28
 
22
- def get_open_port():
29
+ def get_open_port() -> str:
23
30
  sock = socket.socket()
24
31
  sock.bind(("127.0.0.1", 0))
25
32
  port = sock.getsockname()[1]
@@ -28,7 +35,9 @@ def get_open_port():
28
35
 
29
36
 
30
37
  @contextlib.contextmanager
31
- def get_ipc_socket(ipc_path, timeout=0.1):
38
+ def get_ipc_socket(
39
+ ipc_path: str, timeout: float = 0.1
40
+ ) -> Generator[socket.socket, None, None]:
32
41
  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
33
42
  sock.connect(ipc_path)
34
43
  sock.settimeout(timeout)
@@ -38,7 +47,7 @@ def get_ipc_socket(ipc_path, timeout=0.1):
38
47
  sock.close()
39
48
 
40
49
 
41
- def wait_for_http_connection(port, timeout=5):
50
+ def wait_for_http_connection(port: int, timeout: int = 5) -> None:
42
51
  with Timeout(timeout) as _timeout:
43
52
  while True:
44
53
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -52,4 +61,7 @@ def wait_for_http_connection(port, timeout=5):
52
61
  else:
53
62
  break
54
63
  else:
55
- raise ValueError("Unable to establish HTTP connection")
64
+ raise PyGethValueError(
65
+ "Unable to establish HTTP connection, "
66
+ f"timed out after {timeout} seconds"
67
+ )
geth/utils/proc.py CHANGED
@@ -1,12 +1,20 @@
1
+ from __future__ import (
2
+ annotations,
3
+ )
4
+
1
5
  import signal
6
+ import subprocess
2
7
  import time
8
+ from typing import (
9
+ AnyStr,
10
+ )
3
11
 
4
12
  from .timeout import (
5
13
  Timeout,
6
14
  )
7
15
 
8
16
 
9
- def wait_for_popen(proc, timeout=30):
17
+ def wait_for_popen(proc: subprocess.Popen[AnyStr], timeout: int = 30) -> None:
10
18
  try:
11
19
  with Timeout(timeout) as _timeout:
12
20
  while proc.poll() is None:
@@ -16,7 +24,7 @@ def wait_for_popen(proc, timeout=30):
16
24
  pass
17
25
 
18
26
 
19
- def kill_proc(proc):
27
+ def kill_proc(proc: subprocess.Popen[AnyStr]) -> None:
20
28
  try:
21
29
  if proc.poll() is None:
22
30
  try:
@@ -43,7 +51,9 @@ def kill_proc(proc):
43
51
  proc.kill()
44
52
 
45
53
 
46
- def format_error_message(prefix, command, return_code, stdoutdata, stderrdata):
54
+ def format_error_message(
55
+ prefix: str, command: list[str], return_code: int, stdoutdata: str, stderrdata: str
56
+ ) -> str:
47
57
  lines = [prefix]
48
58
 
49
59
  lines.append(f"Command : {' '.join(command)}")
geth/utils/thread.py CHANGED
@@ -1,7 +1,11 @@
1
1
  import threading
2
+ from typing import (
3
+ Any,
4
+ Callable,
5
+ )
2
6
 
3
7
 
4
- def spawn(target, *args, **kwargs):
8
+ def spawn(target: Callable[..., Any], *args: Any, **kwargs: Any) -> threading.Thread:
5
9
  thread = threading.Thread(
6
10
  target=target,
7
11
  args=args,
geth/utils/timeout.py CHANGED
@@ -1,4 +1,19 @@
1
+ from __future__ import (
2
+ annotations,
3
+ )
4
+
1
5
  import time
6
+ from types import (
7
+ TracebackType,
8
+ )
9
+ from typing import (
10
+ Any,
11
+ Literal,
12
+ )
13
+
14
+ from geth.exceptions import (
15
+ PyGethValueError,
16
+ )
2
17
 
3
18
 
4
19
  class Timeout(Exception):
@@ -11,43 +26,54 @@ class Timeout(Exception):
11
26
  begun_at = None
12
27
  is_running = None
13
28
 
14
- def __init__(self, seconds=None, exception=None, *args, **kwargs):
29
+ def __init__(
30
+ self,
31
+ seconds: int | None = None,
32
+ exception: Any | None = None,
33
+ *args: Any,
34
+ **kwargs: Any,
35
+ ):
15
36
  self.seconds = seconds
16
37
  self.exception = exception
17
38
 
18
- def __enter__(self):
39
+ def __enter__(self) -> Timeout:
19
40
  self.start()
20
41
  return self
21
42
 
22
- def __exit__(self, exc_type, exc_val, exc_tb):
43
+ def __exit__(
44
+ self,
45
+ exc_type: type[BaseException] | None,
46
+ exc_value: BaseException | None,
47
+ tb: TracebackType | None,
48
+ ) -> Literal[False]:
23
49
  return False
24
50
 
25
- def __str__(self):
51
+ def __str__(self) -> str:
26
52
  if self.seconds is None:
27
53
  return ""
28
54
  return f"{self.seconds} seconds"
29
55
 
30
56
  @property
31
- def expire_at(self):
57
+ def expire_at(self) -> float:
32
58
  if self.seconds is None:
33
- raise ValueError(
59
+ raise PyGethValueError(
34
60
  "Timeouts with `seconds == None` do not have an expiration time"
35
61
  )
36
62
  elif self.begun_at is None:
37
- raise ValueError("Timeout has not been started")
63
+ raise PyGethValueError("Timeout has not been started")
38
64
  return self.begun_at + self.seconds
39
65
 
40
- def start(self):
66
+ def start(self) -> None:
41
67
  if self.is_running is not None:
42
- raise ValueError("Timeout has already been started")
68
+ raise PyGethValueError("Timeout has already been started")
43
69
  self.begun_at = time.time()
44
70
  self.is_running = True
45
71
 
46
- def check(self):
72
+ def check(self) -> None:
47
73
  if self.is_running is None:
48
- raise ValueError("Timeout has not been started")
74
+ raise PyGethValueError("Timeout has not been started")
49
75
  elif self.is_running is False:
50
- raise ValueError("Timeout has already been cancelled")
76
+ raise PyGethValueError("Timeout has already been cancelled")
51
77
  elif self.seconds is None:
52
78
  return
53
79
  elif time.time() > self.expire_at:
@@ -59,5 +85,5 @@ class Timeout(Exception):
59
85
  else:
60
86
  raise self
61
87
 
62
- def cancel(self):
88
+ def cancel(self) -> None:
63
89
  self.is_running = False
@@ -0,0 +1,179 @@
1
+ from __future__ import (
2
+ annotations,
3
+ )
4
+
5
+ from typing import (
6
+ Any,
7
+ Literal,
8
+ )
9
+
10
+ from pydantic import (
11
+ BaseModel,
12
+ ConfigDict,
13
+ ValidationError,
14
+ )
15
+
16
+ from geth.exceptions import (
17
+ PyGethValueError,
18
+ )
19
+ from geth.types import (
20
+ GenesisDataTypedDict,
21
+ GethKwargsTypedDict,
22
+ )
23
+
24
+
25
+ class GethKwargs(BaseModel):
26
+ cache: str | None = None
27
+ data_dir: str | None = None
28
+ dev_mode: bool | None = False
29
+ gcmode: Literal["full", "archive"] | None = None
30
+ geth_executable: str | None = None
31
+ ipc_disable: bool | None = None
32
+ ipc_path: str | None = None
33
+ max_peers: str | None = None
34
+ network_id: str | None = None
35
+ nice: bool | None = True
36
+ no_discover: bool | None = None
37
+ password: bytes | str | None = None
38
+ port: str | None = None
39
+ preload: str | None = None
40
+ rpc_addr: str | None = None
41
+ rpc_api: str | None = None
42
+ rpc_cors_domain: str | None = None
43
+ rpc_enabled: bool | None = None
44
+ rpc_port: str | None = None
45
+ stdin: str | None = None
46
+ suffix_args: list[str] | None = None
47
+ suffix_kwargs: dict[str, str] | None = None
48
+ tx_pool_global_slots: str | None = None
49
+ tx_pool_lifetime: str | None = None
50
+ tx_pool_price_limit: str | None = None
51
+ verbosity: str | None = None
52
+ ws_addr: str | None = None
53
+ ws_api: str | None = None
54
+ ws_enabled: bool | None = None
55
+ ws_origins: str | None = None
56
+ ws_port: str | None = None
57
+
58
+ model_config = ConfigDict(extra="forbid")
59
+
60
+
61
+ def validate_geth_kwargs(geth_kwargs: GethKwargsTypedDict) -> None:
62
+ """
63
+ Converts geth_kwargs to GethKwargs and raises a ValueError if the conversion fails.
64
+ """
65
+ try:
66
+ GethKwargs(**geth_kwargs)
67
+ except ValidationError as e:
68
+ raise PyGethValueError(f"geth_kwargs validation failed: {e}")
69
+ except TypeError as e:
70
+ raise PyGethValueError(f"error while validating geth_kwargs: {e}")
71
+
72
+
73
+ class GenesisDataConfig(BaseModel):
74
+ chainId: int = 0
75
+ ethash: dict[str, Any] = {} # so that geth treats config as PoW -> PoS transition
76
+ homesteadBlock: int = 0
77
+ daoForkBlock: int = 0
78
+ daoForkSupport: bool = True
79
+ eip150Block: int = 0
80
+ eip155Block: int = 0
81
+ eip158Block: int = 0
82
+ byzantiumBlock: int = 0
83
+ constantinopleBlock: int = 0
84
+ petersburgBlock: int = 0
85
+ istanbulBlock: int = 0
86
+ berlinBlock: int = 0
87
+ londonBlock: int = 0
88
+ arrowGlacierBlock: int = 0
89
+ grayGlacierBlock: int = 0
90
+ # merge
91
+ terminalTotalDifficulty: int = 0
92
+ terminalTotalDifficultyPassed: bool = True
93
+ # post-merge, timestamp is used for network transitions
94
+ shanghaiTime: int = 0
95
+ cancunTime: int = 0
96
+
97
+ model_config = ConfigDict(extra="forbid")
98
+
99
+
100
+ class GenesisData(BaseModel):
101
+ alloc: dict[str, dict[str, Any]] = {}
102
+ baseFeePerGas: str = "0x0"
103
+ blobGasUsed: str = "0x0"
104
+ coinbase: str = "0x3333333333333333333333333333333333333333"
105
+ config: dict[str, Any] = GenesisDataConfig().model_dump()
106
+ difficulty: str = "0x0"
107
+ excessBlobGas: str = "0x0"
108
+ extraData: str = (
109
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
110
+ )
111
+ gasLimit: str = "0x47e7c4"
112
+ gasUsed: str = "0x0"
113
+ mixHash: str = "0x0000000000000000000000000000000000000000000000000000000000000000"
114
+ nonce: str = "0x0"
115
+ number: str = "0x0"
116
+ parentHash: str = (
117
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
118
+ )
119
+ timestamp: str = "0x0"
120
+
121
+ model_config = ConfigDict(extra="forbid")
122
+
123
+
124
+ def validate_genesis_data(genesis_data: GenesisDataTypedDict) -> None:
125
+ """
126
+ Validates the genesis data
127
+ """
128
+ try:
129
+ GenesisData(**genesis_data)
130
+ except ValidationError as e:
131
+ raise PyGethValueError(f"genesis_data validation failed: {e}")
132
+ except TypeError as e:
133
+ raise PyGethValueError(f"error while validating genesis_data: {e}")
134
+
135
+ """
136
+ Validates the genesis data config field
137
+ """
138
+ genesis_data_config = genesis_data.get("config", None)
139
+ if genesis_data_config:
140
+ try:
141
+ GenesisDataConfig(**genesis_data_config)
142
+ except ValidationError as e:
143
+ raise PyGethValueError(f"genesis_data config field validation failed: {e}")
144
+ except TypeError as e:
145
+ raise PyGethValueError(
146
+ f"error while validating genesis_data config field: {e}"
147
+ )
148
+
149
+
150
+ def fill_default_genesis_data(
151
+ genesis_data: GenesisDataTypedDict,
152
+ ) -> GenesisData:
153
+ """
154
+ Fills in default values for the genesis data
155
+ """
156
+ try:
157
+ genesis_data_filled = GenesisData(**genesis_data)
158
+ except ValidationError as e:
159
+ raise PyGethValueError(
160
+ f"genesis_data validation failed while filling defaults: {e}"
161
+ )
162
+ except TypeError as e:
163
+ raise PyGethValueError(f"error while filling default genesis_data: {e}")
164
+
165
+ if genesis_data.get("config"):
166
+ try:
167
+ genesis_data_config_filled = GenesisDataConfig(**genesis_data["config"])
168
+ except ValidationError as e:
169
+ raise PyGethValueError(
170
+ f"genesis_data validation failed while filling config defaults: {e}"
171
+ )
172
+ except TypeError as e:
173
+ raise PyGethValueError(
174
+ f"error while filling default genesis_data config: {e}"
175
+ )
176
+
177
+ genesis_data_filled.config = genesis_data_config_filled.model_dump()
178
+
179
+ return genesis_data_filled