astreum 0.3.9__py3-none-any.whl → 0.3.46__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.
- astreum/__init__.py +5 -4
- astreum/communication/__init__.py +15 -11
- astreum/communication/difficulty.py +39 -0
- astreum/communication/disconnect.py +57 -0
- astreum/communication/handlers/handshake.py +105 -89
- astreum/communication/handlers/object_request.py +179 -149
- astreum/communication/handlers/object_response.py +7 -1
- astreum/communication/handlers/ping.py +9 -0
- astreum/communication/handlers/route_request.py +7 -1
- astreum/communication/handlers/route_response.py +7 -1
- astreum/communication/incoming_queue.py +96 -0
- astreum/communication/message_pow.py +36 -0
- astreum/communication/models/peer.py +4 -0
- astreum/communication/models/ping.py +27 -6
- astreum/communication/models/route.py +4 -0
- astreum/communication/{start.py → node.py} +10 -11
- astreum/communication/outgoing_queue.py +108 -0
- astreum/communication/processors/incoming.py +110 -37
- astreum/communication/processors/outgoing.py +35 -2
- astreum/communication/processors/peer.py +134 -0
- astreum/communication/setup.py +273 -112
- astreum/communication/util.py +14 -0
- astreum/node.py +99 -89
- astreum/storage/actions/get.py +79 -48
- astreum/storage/actions/set.py +171 -156
- astreum/storage/providers.py +24 -0
- astreum/storage/setup.py +23 -22
- astreum/utils/config.py +247 -30
- astreum/utils/logging.py +1 -1
- astreum/{consensus → validation}/__init__.py +0 -4
- astreum/validation/constants.py +2 -0
- astreum/{consensus → validation}/genesis.py +4 -6
- astreum/validation/models/block.py +544 -0
- astreum/validation/models/fork.py +511 -0
- astreum/{consensus → validation}/models/receipt.py +17 -4
- astreum/{consensus → validation}/models/transaction.py +45 -3
- astreum/validation/node.py +190 -0
- astreum/{consensus → validation}/validator.py +18 -9
- astreum/validation/workers/__init__.py +8 -0
- astreum/{consensus → validation}/workers/validation.py +361 -307
- astreum/verification/__init__.py +4 -0
- astreum/{consensus/workers/discovery.py → verification/discover.py} +1 -1
- astreum/verification/node.py +61 -0
- astreum/verification/worker.py +183 -0
- {astreum-0.3.9.dist-info → astreum-0.3.46.dist-info}/METADATA +43 -9
- astreum-0.3.46.dist-info/RECORD +79 -0
- astreum/consensus/models/block.py +0 -364
- astreum/consensus/models/chain.py +0 -66
- astreum/consensus/models/fork.py +0 -100
- astreum/consensus/setup.py +0 -83
- astreum/consensus/start.py +0 -67
- astreum/consensus/workers/__init__.py +0 -9
- astreum/consensus/workers/verify.py +0 -90
- astreum-0.3.9.dist-info/RECORD +0 -71
- /astreum/{consensus → validation}/models/__init__.py +0 -0
- /astreum/{consensus → validation}/models/account.py +0 -0
- /astreum/{consensus → validation}/models/accounts.py +0 -0
- {astreum-0.3.9.dist-info → astreum-0.3.46.dist-info}/WHEEL +0 -0
- {astreum-0.3.9.dist-info → astreum-0.3.46.dist-info}/licenses/LICENSE +0 -0
- {astreum-0.3.9.dist-info → astreum-0.3.46.dist-info}/top_level.txt +0 -0
astreum/utils/config.py
CHANGED
|
@@ -1,48 +1,265 @@
|
|
|
1
1
|
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Dict
|
|
4
|
-
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Dict
|
|
4
|
+
|
|
5
5
|
DEFAULT_HOT_STORAGE_LIMIT = 1 << 30 # 1 GiB
|
|
6
6
|
DEFAULT_COLD_STORAGE_LIMIT = 10 << 30 # 10 GiB
|
|
7
|
+
DEFAULT_COLD_STORAGE_ADVERTISE_LIMIT = 1000
|
|
8
|
+
DEFAULT_INCOMING_PORT = 52780
|
|
9
|
+
DEFAULT_LOGGING_RETENTION_DAYS = 90
|
|
10
|
+
DEFAULT_PEER_TIMEOUT_SECONDS = 15 * 60 # 15 minutes
|
|
11
|
+
DEFAULT_PEER_TIMEOUT_INTERVAL_SECONDS = 10 # 10 seconds
|
|
12
|
+
DEFAULT_BOOTSTRAP_RETRY_INTERVAL_SECONDS = 30 # 30 seconds
|
|
13
|
+
DEFAULT_STORAGE_INDEX_INTERVAL_SECONDS = 600 # 10 minutes
|
|
14
|
+
DEFAULT_INCOMING_QUEUE_SIZE_LIMIT_BYTES = 64 * 1024 * 1024 # 64 MiB
|
|
15
|
+
DEFAULT_INCOMING_QUEUE_TIMEOUT_SECONDS = 1.0
|
|
16
|
+
DEFAULT_OUTGOING_QUEUE_SIZE_LIMIT_BYTES = 64 * 1024 * 1024 # 64 MiB
|
|
17
|
+
DEFAULT_OUTGOING_QUEUE_TIMEOUT_SECONDS = 1.0
|
|
18
|
+
DEFAULT_SEED = "bootstrap.astreum.org:52780"
|
|
19
|
+
DEFAULT_VERIFICATION_MAX_STALE_SECONDS = 10
|
|
20
|
+
DEFAULT_VERIFICATION_MAX_FUTURE_SKEW_SECONDS = 2
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def config_setup(config: Dict = {}):
|
|
24
|
+
"""
|
|
25
|
+
Normalize configuration values before the node starts.
|
|
26
|
+
"""
|
|
27
|
+
chain_str = config.get("chain")
|
|
28
|
+
if chain_str not in {"main", "test"}:
|
|
29
|
+
chain_str = None
|
|
30
|
+
chain_id_raw = config.get("chain_id")
|
|
31
|
+
if chain_id_raw is None:
|
|
32
|
+
chain_id = 1 if chain_str == "main" else 0
|
|
33
|
+
else:
|
|
34
|
+
try:
|
|
35
|
+
chain_id = int(chain_id_raw)
|
|
36
|
+
except (TypeError, ValueError) as exc:
|
|
37
|
+
raise ValueError(
|
|
38
|
+
f"chain_id must be an integer: {chain_id_raw!r}"
|
|
39
|
+
) from exc
|
|
40
|
+
if chain_str is None:
|
|
41
|
+
chain_str = "main" if chain_id == 1 else "test"
|
|
42
|
+
config["chain"] = chain_str
|
|
43
|
+
config["chain_id"] = chain_id
|
|
44
|
+
|
|
45
|
+
hot_limit_raw = config.get(
|
|
46
|
+
"hot_storage_limit", config.get("hot_storage_default_limit", DEFAULT_HOT_STORAGE_LIMIT)
|
|
47
|
+
)
|
|
48
|
+
try:
|
|
49
|
+
config["hot_storage_limit"] = int(hot_limit_raw)
|
|
50
|
+
except (TypeError, ValueError) as exc:
|
|
51
|
+
raise ValueError(
|
|
52
|
+
f"hot_storage_limit must be an integer: {hot_limit_raw!r}"
|
|
53
|
+
) from exc
|
|
54
|
+
|
|
55
|
+
cold_limit_raw = config.get("cold_storage_limit", DEFAULT_COLD_STORAGE_LIMIT)
|
|
56
|
+
try:
|
|
57
|
+
config["cold_storage_limit"] = int(cold_limit_raw)
|
|
58
|
+
except (TypeError, ValueError) as exc:
|
|
59
|
+
raise ValueError(
|
|
60
|
+
f"cold_storage_limit must be an integer: {cold_limit_raw!r}"
|
|
61
|
+
) from exc
|
|
62
|
+
|
|
63
|
+
cold_path_raw = config.get("cold_storage_path")
|
|
64
|
+
if cold_path_raw:
|
|
65
|
+
try:
|
|
66
|
+
path_obj = Path(cold_path_raw)
|
|
67
|
+
path_obj.mkdir(parents=True, exist_ok=True)
|
|
68
|
+
config["cold_storage_path"] = str(path_obj)
|
|
69
|
+
except OSError:
|
|
70
|
+
config["cold_storage_path"] = None
|
|
71
|
+
else:
|
|
72
|
+
config["cold_storage_path"] = None
|
|
7
73
|
|
|
74
|
+
advertise_limit_raw = config.get(
|
|
75
|
+
"cold_storage_advertise_limit", DEFAULT_COLD_STORAGE_ADVERTISE_LIMIT
|
|
76
|
+
)
|
|
77
|
+
try:
|
|
78
|
+
advertise_limit = int(advertise_limit_raw)
|
|
79
|
+
except (TypeError, ValueError) as exc:
|
|
80
|
+
raise ValueError(
|
|
81
|
+
"cold_storage_advertise_limit must be an integer: "
|
|
82
|
+
f"{advertise_limit_raw!r}"
|
|
83
|
+
) from exc
|
|
84
|
+
if advertise_limit < -1:
|
|
85
|
+
raise ValueError(
|
|
86
|
+
"cold_storage_advertise_limit must be -1, 0, or a positive integer"
|
|
87
|
+
)
|
|
88
|
+
config["cold_storage_advertise_limit"] = advertise_limit
|
|
89
|
+
|
|
90
|
+
retention_raw = config.get(
|
|
91
|
+
"logging_retention_days",
|
|
92
|
+
config.get("logging_retention", config.get("retention_days", DEFAULT_LOGGING_RETENTION_DAYS)),
|
|
93
|
+
)
|
|
94
|
+
try:
|
|
95
|
+
config["logging_retention_days"] = int(retention_raw)
|
|
96
|
+
except (TypeError, ValueError) as exc:
|
|
97
|
+
raise ValueError(
|
|
98
|
+
f"logging_retention_days must be an integer: {retention_raw!r}"
|
|
99
|
+
) from exc
|
|
100
|
+
|
|
101
|
+
if "incoming_port" in config:
|
|
102
|
+
incoming_port_raw = config["incoming_port"]
|
|
103
|
+
else:
|
|
104
|
+
incoming_port_raw = DEFAULT_INCOMING_PORT
|
|
105
|
+
try:
|
|
106
|
+
config["incoming_port"] = int(incoming_port_raw)
|
|
107
|
+
except (TypeError, ValueError) as exc:
|
|
108
|
+
raise ValueError(
|
|
109
|
+
f"incoming_port must be an integer: {incoming_port_raw!r}"
|
|
110
|
+
) from exc
|
|
111
|
+
if config["incoming_port"] < 0:
|
|
112
|
+
raise ValueError("incoming_port must be 0 or a positive integer")
|
|
8
113
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
114
|
+
incoming_queue_limit_raw = config.get(
|
|
115
|
+
"incoming_queue_size_limit", DEFAULT_INCOMING_QUEUE_SIZE_LIMIT_BYTES
|
|
116
|
+
)
|
|
117
|
+
try:
|
|
118
|
+
incoming_queue_limit = int(incoming_queue_limit_raw)
|
|
119
|
+
except (TypeError, ValueError) as exc:
|
|
120
|
+
raise ValueError(
|
|
121
|
+
f"incoming_queue_size_limit must be an integer: {incoming_queue_limit_raw!r}"
|
|
122
|
+
) from exc
|
|
123
|
+
if incoming_queue_limit < 0:
|
|
124
|
+
raise ValueError("incoming_queue_size_limit must be a non-negative integer")
|
|
125
|
+
config["incoming_queue_size_limit"] = incoming_queue_limit
|
|
18
126
|
|
|
19
|
-
|
|
20
|
-
"
|
|
127
|
+
incoming_queue_timeout_raw = config.get(
|
|
128
|
+
"incoming_queue_timeout", DEFAULT_INCOMING_QUEUE_TIMEOUT_SECONDS
|
|
21
129
|
)
|
|
22
130
|
try:
|
|
23
|
-
|
|
131
|
+
incoming_queue_timeout = float(incoming_queue_timeout_raw)
|
|
24
132
|
except (TypeError, ValueError) as exc:
|
|
25
133
|
raise ValueError(
|
|
26
|
-
f"
|
|
134
|
+
f"incoming_queue_timeout must be a number: {incoming_queue_timeout_raw!r}"
|
|
27
135
|
) from exc
|
|
136
|
+
if incoming_queue_timeout < 0:
|
|
137
|
+
raise ValueError("incoming_queue_timeout must be a non-negative number")
|
|
138
|
+
config["incoming_queue_timeout"] = incoming_queue_timeout
|
|
28
139
|
|
|
29
|
-
|
|
140
|
+
peer_timeout_raw = config.get("peer_timeout", DEFAULT_PEER_TIMEOUT_SECONDS)
|
|
30
141
|
try:
|
|
31
|
-
|
|
142
|
+
peer_timeout = int(peer_timeout_raw)
|
|
32
143
|
except (TypeError, ValueError) as exc:
|
|
33
144
|
raise ValueError(
|
|
34
|
-
f"
|
|
145
|
+
f"peer_timeout must be an integer: {peer_timeout_raw!r}"
|
|
146
|
+
) from exc
|
|
147
|
+
|
|
148
|
+
if peer_timeout <= 0:
|
|
149
|
+
raise ValueError("peer_timeout must be a positive integer")
|
|
150
|
+
|
|
151
|
+
config["peer_timeout"] = peer_timeout
|
|
152
|
+
|
|
153
|
+
interval_raw = config.get("peer_timeout_interval", DEFAULT_PEER_TIMEOUT_INTERVAL_SECONDS)
|
|
154
|
+
try:
|
|
155
|
+
interval = int(interval_raw)
|
|
156
|
+
except (TypeError, ValueError) as exc:
|
|
157
|
+
raise ValueError(
|
|
158
|
+
f"peer_timeout_interval must be an integer: {interval_raw!r}"
|
|
159
|
+
) from exc
|
|
160
|
+
|
|
161
|
+
if interval <= 0:
|
|
162
|
+
raise ValueError("peer_timeout_interval must be a positive integer")
|
|
163
|
+
|
|
164
|
+
config["peer_timeout_interval"] = interval
|
|
165
|
+
|
|
166
|
+
bootstrap_retry_raw = config.get(
|
|
167
|
+
"bootstrap_retry_interval", DEFAULT_BOOTSTRAP_RETRY_INTERVAL_SECONDS
|
|
168
|
+
)
|
|
169
|
+
try:
|
|
170
|
+
bootstrap_retry_interval = int(bootstrap_retry_raw)
|
|
171
|
+
except (TypeError, ValueError) as exc:
|
|
172
|
+
raise ValueError(
|
|
173
|
+
f"bootstrap_retry_interval must be an integer: {bootstrap_retry_raw!r}"
|
|
174
|
+
) from exc
|
|
175
|
+
if bootstrap_retry_interval <= 0:
|
|
176
|
+
raise ValueError("bootstrap_retry_interval must be a positive integer")
|
|
177
|
+
config["bootstrap_retry_interval"] = bootstrap_retry_interval
|
|
178
|
+
|
|
179
|
+
storage_index_raw = config.get(
|
|
180
|
+
"storage_index_interval", DEFAULT_STORAGE_INDEX_INTERVAL_SECONDS
|
|
181
|
+
)
|
|
182
|
+
try:
|
|
183
|
+
storage_index_interval = int(storage_index_raw)
|
|
184
|
+
except (TypeError, ValueError) as exc:
|
|
185
|
+
raise ValueError(
|
|
186
|
+
f"storage_index_interval must be an integer: {storage_index_raw!r}"
|
|
35
187
|
) from exc
|
|
188
|
+
if storage_index_interval <= 0:
|
|
189
|
+
raise ValueError("storage_index_interval must be a positive integer")
|
|
190
|
+
config["storage_index_interval"] = storage_index_interval
|
|
36
191
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
192
|
+
outgoing_queue_limit_raw = config.get(
|
|
193
|
+
"outgoing_queue_size_limit", DEFAULT_OUTGOING_QUEUE_SIZE_LIMIT_BYTES
|
|
194
|
+
)
|
|
195
|
+
try:
|
|
196
|
+
outgoing_queue_limit = int(outgoing_queue_limit_raw)
|
|
197
|
+
except (TypeError, ValueError) as exc:
|
|
198
|
+
raise ValueError(
|
|
199
|
+
f"outgoing_queue_size_limit must be an integer: {outgoing_queue_limit_raw!r}"
|
|
200
|
+
) from exc
|
|
201
|
+
if outgoing_queue_limit < 0:
|
|
202
|
+
raise ValueError("outgoing_queue_size_limit must be a non-negative integer")
|
|
203
|
+
config["outgoing_queue_size_limit"] = outgoing_queue_limit
|
|
204
|
+
|
|
205
|
+
outgoing_queue_timeout_raw = config.get(
|
|
206
|
+
"outgoing_queue_timeout", DEFAULT_OUTGOING_QUEUE_TIMEOUT_SECONDS
|
|
207
|
+
)
|
|
208
|
+
try:
|
|
209
|
+
outgoing_queue_timeout = float(outgoing_queue_timeout_raw)
|
|
210
|
+
except (TypeError, ValueError) as exc:
|
|
211
|
+
raise ValueError(
|
|
212
|
+
f"outgoing_queue_timeout must be a number: {outgoing_queue_timeout_raw!r}"
|
|
213
|
+
) from exc
|
|
214
|
+
if outgoing_queue_timeout < 0:
|
|
215
|
+
raise ValueError("outgoing_queue_timeout must be a non-negative number")
|
|
216
|
+
config["outgoing_queue_timeout"] = outgoing_queue_timeout
|
|
217
|
+
|
|
218
|
+
max_stale_raw = config.get(
|
|
219
|
+
"verification_max_stale_seconds", DEFAULT_VERIFICATION_MAX_STALE_SECONDS
|
|
220
|
+
)
|
|
221
|
+
try:
|
|
222
|
+
max_stale = int(max_stale_raw)
|
|
223
|
+
except (TypeError, ValueError) as exc:
|
|
224
|
+
raise ValueError(
|
|
225
|
+
f"verification_max_stale_seconds must be an integer: {max_stale_raw!r}"
|
|
226
|
+
) from exc
|
|
227
|
+
if max_stale < 0:
|
|
228
|
+
raise ValueError("verification_max_stale_seconds must be a non-negative integer")
|
|
229
|
+
config["verification_max_stale_seconds"] = max_stale
|
|
47
230
|
|
|
48
|
-
|
|
231
|
+
max_future_raw = config.get(
|
|
232
|
+
"verification_max_future_skew", DEFAULT_VERIFICATION_MAX_FUTURE_SKEW_SECONDS
|
|
233
|
+
)
|
|
234
|
+
try:
|
|
235
|
+
max_future = int(max_future_raw)
|
|
236
|
+
except (TypeError, ValueError) as exc:
|
|
237
|
+
raise ValueError(
|
|
238
|
+
f"verification_max_future_skew must be an integer: {max_future_raw!r}"
|
|
239
|
+
) from exc
|
|
240
|
+
if max_future < 0:
|
|
241
|
+
raise ValueError("verification_max_future_skew must be a non-negative integer")
|
|
242
|
+
config["verification_max_future_skew"] = max_future
|
|
243
|
+
|
|
244
|
+
if "default_seeds" in config:
|
|
245
|
+
raise ValueError("default_seeds is no longer supported; use default_seed")
|
|
246
|
+
|
|
247
|
+
if "default_seed" in config:
|
|
248
|
+
default_seed_raw = config["default_seed"]
|
|
249
|
+
else:
|
|
250
|
+
default_seed_raw = DEFAULT_SEED
|
|
251
|
+
|
|
252
|
+
if default_seed_raw is None:
|
|
253
|
+
config["default_seed"] = None
|
|
254
|
+
elif isinstance(default_seed_raw, str):
|
|
255
|
+
config["default_seed"] = default_seed_raw
|
|
256
|
+
else:
|
|
257
|
+
raise ValueError("default_seed must be a string or None")
|
|
258
|
+
|
|
259
|
+
additional_seeds_raw = config.get("additional_seeds", [])
|
|
260
|
+
if isinstance(additional_seeds_raw, (list, tuple)):
|
|
261
|
+
config["additional_seeds"] = list(additional_seeds_raw)
|
|
262
|
+
else:
|
|
263
|
+
raise ValueError("additional_seeds must be a list of strings")
|
|
264
|
+
|
|
265
|
+
return config
|
astreum/utils/logging.py
CHANGED
|
@@ -159,7 +159,7 @@ def logging_setup(config: dict) -> logging.LoggerAdapter:
|
|
|
159
159
|
product = _PRODUCT_NAME
|
|
160
160
|
instance_id = _derive_instance_id()
|
|
161
161
|
|
|
162
|
-
retention_value = config.get("
|
|
162
|
+
retention_value = config.get("logging_retention_days")
|
|
163
163
|
retention_days = int(retention_value) if retention_value is not None else 90
|
|
164
164
|
|
|
165
165
|
verbose = bool(config.get("verbose", False))
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
from .models.account import Account
|
|
2
2
|
from .models.accounts import Accounts
|
|
3
3
|
from .models.block import Block
|
|
4
|
-
from .models.chain import Chain
|
|
5
4
|
from .models.fork import Fork
|
|
6
5
|
from .models.receipt import Receipt
|
|
7
6
|
from .models.transaction import Transaction
|
|
8
|
-
from .setup import consensus_setup
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
__all__ = [
|
|
12
10
|
"Block",
|
|
13
|
-
"Chain",
|
|
14
11
|
"Fork",
|
|
15
12
|
"Receipt",
|
|
16
13
|
"Transaction",
|
|
17
14
|
"Account",
|
|
18
15
|
"Accounts",
|
|
19
|
-
"consensus_setup",
|
|
20
16
|
]
|
|
@@ -2,16 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Any, List
|
|
4
4
|
|
|
5
|
+
from .constants import BURN_ADDRESS, TREASURY_ADDRESS
|
|
5
6
|
from .models.account import Account
|
|
6
7
|
from .models.accounts import Accounts
|
|
7
8
|
from .models.block import Block
|
|
8
9
|
from ..storage.models.atom import ZERO32
|
|
9
10
|
from ..storage.models.trie import Trie
|
|
10
11
|
from ..utils.integer import int_to_bytes
|
|
11
|
-
|
|
12
|
-
TREASURY_ADDRESS = b"\x01" * 32
|
|
13
|
-
BURN_ADDRESS = b"\x00" * 32
|
|
14
|
-
|
|
12
|
+
from time import time
|
|
15
13
|
|
|
16
14
|
def create_genesis_block(
|
|
17
15
|
node: Any,
|
|
@@ -49,13 +47,13 @@ def create_genesis_block(
|
|
|
49
47
|
previous_block_hash=ZERO32,
|
|
50
48
|
previous_block=None,
|
|
51
49
|
number=0,
|
|
52
|
-
timestamp=
|
|
50
|
+
timestamp=int(time()),
|
|
53
51
|
accounts_hash=accounts_root,
|
|
54
52
|
transactions_total_fees=0,
|
|
55
53
|
transactions_hash=ZERO32,
|
|
56
54
|
receipts_hash=ZERO32,
|
|
57
55
|
delay_difficulty=0,
|
|
58
|
-
|
|
56
|
+
validator_public_key_bytes=validator_pk,
|
|
59
57
|
nonce=0,
|
|
60
58
|
signature=b"",
|
|
61
59
|
accounts=accounts,
|