astreum 0.3.16__py3-none-any.whl → 0.3.48__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.
Files changed (65) hide show
  1. astreum/__init__.py +1 -2
  2. astreum/communication/__init__.py +15 -11
  3. astreum/communication/difficulty.py +39 -0
  4. astreum/communication/disconnect.py +57 -0
  5. astreum/communication/handlers/handshake.py +105 -62
  6. astreum/communication/handlers/object_request.py +226 -138
  7. astreum/communication/handlers/object_response.py +118 -10
  8. astreum/communication/handlers/ping.py +9 -0
  9. astreum/communication/handlers/route_request.py +7 -1
  10. astreum/communication/handlers/route_response.py +7 -1
  11. astreum/communication/incoming_queue.py +96 -0
  12. astreum/communication/message_pow.py +36 -0
  13. astreum/communication/models/peer.py +4 -0
  14. astreum/communication/models/ping.py +27 -6
  15. astreum/communication/models/route.py +4 -0
  16. astreum/communication/{start.py → node.py} +10 -11
  17. astreum/communication/outgoing_queue.py +108 -0
  18. astreum/communication/processors/incoming.py +110 -37
  19. astreum/communication/processors/outgoing.py +35 -2
  20. astreum/communication/processors/peer.py +133 -58
  21. astreum/communication/setup.py +272 -113
  22. astreum/communication/util.py +14 -0
  23. astreum/machine/evaluations/low_evaluation.py +5 -5
  24. astreum/machine/models/expression.py +5 -5
  25. astreum/node.py +96 -87
  26. astreum/storage/actions/get.py +285 -183
  27. astreum/storage/actions/set.py +171 -156
  28. astreum/storage/models/atom.py +0 -14
  29. astreum/storage/models/trie.py +2 -2
  30. astreum/storage/providers.py +24 -0
  31. astreum/storage/requests.py +13 -10
  32. astreum/storage/setup.py +20 -15
  33. astreum/utils/config.py +260 -43
  34. astreum/utils/logging.py +1 -1
  35. astreum/{consensus → validation}/__init__.py +0 -4
  36. astreum/validation/constants.py +2 -0
  37. astreum/{consensus → validation}/genesis.py +4 -6
  38. astreum/{consensus → validation}/models/account.py +1 -1
  39. astreum/validation/models/block.py +544 -0
  40. astreum/validation/models/fork.py +511 -0
  41. astreum/{consensus → validation}/models/receipt.py +18 -5
  42. astreum/{consensus → validation}/models/transaction.py +50 -8
  43. astreum/validation/node.py +190 -0
  44. astreum/{consensus → validation}/validator.py +1 -1
  45. astreum/validation/workers/__init__.py +8 -0
  46. astreum/{consensus → validation}/workers/validation.py +360 -333
  47. astreum/verification/__init__.py +4 -0
  48. astreum/{consensus/workers/discovery.py → verification/discover.py} +1 -1
  49. astreum/verification/node.py +61 -0
  50. astreum/verification/worker.py +183 -0
  51. {astreum-0.3.16.dist-info → astreum-0.3.48.dist-info}/METADATA +45 -9
  52. astreum-0.3.48.dist-info/RECORD +79 -0
  53. astreum/consensus/models/block.py +0 -364
  54. astreum/consensus/models/chain.py +0 -66
  55. astreum/consensus/models/fork.py +0 -100
  56. astreum/consensus/setup.py +0 -83
  57. astreum/consensus/start.py +0 -67
  58. astreum/consensus/workers/__init__.py +0 -9
  59. astreum/consensus/workers/verify.py +0 -90
  60. astreum-0.3.16.dist-info/RECORD +0 -72
  61. /astreum/{consensus → validation}/models/__init__.py +0 -0
  62. /astreum/{consensus → validation}/models/accounts.py +0 -0
  63. {astreum-0.3.16.dist-info → astreum-0.3.48.dist-info}/WHEEL +0 -0
  64. {astreum-0.3.16.dist-info → astreum-0.3.48.dist-info}/licenses/LICENSE +0 -0
  65. {astreum-0.3.16.dist-info → astreum-0.3.48.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,4 @@
1
+ from .worker import make_verify_worker
2
+ from .node import verify_blockchain
3
+
4
+ __all__ = ["make_verify_worker", "verify_blockchain"]
@@ -14,7 +14,7 @@ def make_discovery_worker(node: Any):
14
14
 
15
15
  def _discovery_worker() -> None:
16
16
  node.logger.info("Discovery worker started")
17
- stop = node._validation_stop_event
17
+ stop = node._verify_stop_event
18
18
  while not stop.is_set():
19
19
  try:
20
20
  peers = getattr(node, "peers", None)
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ import threading
4
+ from queue import Queue
5
+ from typing import Any
6
+
7
+ from astreum.communication.node import connect_node
8
+
9
+ from .discover import make_discovery_worker
10
+ from .worker import make_verify_worker
11
+
12
+
13
+ def verify_blockchain(self: Any):
14
+ """Ensure verification primitives exist, then start discovery and verify workers."""
15
+ connect_node(self)
16
+
17
+ self._validation_verify_queue = Queue()
18
+
19
+ self.chains = {}
20
+ self.forks = {}
21
+ self.logger.debug(
22
+ "Consensus maps ready for verification (chains=%s, forks=%s)",
23
+ len(self.chains),
24
+ len(self.forks),
25
+ )
26
+
27
+ stop_event = getattr(self, "_verify_stop_event", None)
28
+ if stop_event is None:
29
+ stop_event = threading.Event()
30
+ self._verify_stop_event = stop_event
31
+ stop_event.clear()
32
+
33
+ discovery_thread = getattr(self, "latest_block_discovery_thread", None)
34
+ if discovery_thread is not None and discovery_thread.is_alive():
35
+ self.logger.debug("Consensus discovery thread already running")
36
+ else:
37
+ discovery_worker = make_discovery_worker(self)
38
+ discovery_thread = threading.Thread(
39
+ target=discovery_worker,
40
+ daemon=True,
41
+ name="latest-block-discovery",
42
+ )
43
+ self.latest_block_discovery_thread = discovery_thread
44
+ discovery_thread.start()
45
+ self.logger.info(
46
+ "Started latest-block discovery thread (%s)", discovery_thread.name
47
+ )
48
+
49
+ verify_thread = getattr(self, "verify_thread", None)
50
+ if verify_thread is not None and verify_thread.is_alive():
51
+ self.logger.debug("Consensus verify thread already running")
52
+ return verify_thread
53
+
54
+ verify_worker = make_verify_worker(self)
55
+ verify_thread = threading.Thread(
56
+ target=verify_worker, daemon=True, name="verify-worker"
57
+ )
58
+ self.verify_thread = verify_thread
59
+ verify_thread.start()
60
+ self.logger.info("Started verify thread (%s)", verify_thread.name)
61
+ return verify_thread
@@ -0,0 +1,183 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from queue import Empty
5
+ from typing import Any, Optional, Set, Tuple
6
+
7
+ from astreum.validation.models.fork import Fork
8
+ from astreum.validation.models.block import Block
9
+
10
+
11
+ def _process_peers_latest_block(
12
+ node: Any, latest_block_hash: bytes, peer_ids: Set[Any]
13
+ ) -> None:
14
+ """Assign peers to the fork that matches their reported head."""
15
+ node.logger.debug(
16
+ "Processing %d peers reporting block %s",
17
+ len(peer_ids),
18
+ latest_block_hash.hex()
19
+ if isinstance(latest_block_hash, (bytes, bytearray))
20
+ else latest_block_hash,
21
+ )
22
+ new_fork = Fork(head=latest_block_hash)
23
+
24
+ new_fork.verify(node)
25
+
26
+ if new_fork.validated_upto and new_fork.validated_upto in node.forks:
27
+ ref = node.forks[new_fork.validated_upto]
28
+ if getattr(ref, "malicious_block_hash", None):
29
+ node.logger.warning(
30
+ "Skipping fork from block %s referencing malicious fork %s",
31
+ latest_block_hash.hex()
32
+ if isinstance(latest_block_hash, (bytes, bytearray))
33
+ else latest_block_hash,
34
+ new_fork.validated_upto.hex()
35
+ if isinstance(new_fork.validated_upto, (bytes, bytearray))
36
+ else new_fork.validated_upto,
37
+ )
38
+ return
39
+ new_fork.root = ref.root
40
+ new_fork.validated_upto = ref.validated_upto
41
+ new_fork.chain_fork_position = ref.chain_fork_position
42
+
43
+ for peer_id in peer_ids:
44
+ new_fork.add_peer(peer_id)
45
+ for head, fork in list(node.forks.items()):
46
+ if head != latest_block_hash:
47
+ fork.remove_peer(peer_id)
48
+
49
+ node.forks[latest_block_hash] = new_fork
50
+ node.logger.debug(
51
+ "Fork %s now has %d peers (total forks %d)",
52
+ latest_block_hash.hex()
53
+ if isinstance(latest_block_hash, (bytes, bytearray))
54
+ else latest_block_hash,
55
+ len(new_fork.peers),
56
+ len(node.forks),
57
+ )
58
+
59
+
60
+ def _select_best_fork_head(node: Any) -> Optional[Tuple[bytes, Block, int]]:
61
+ forks = getattr(node, "forks", None)
62
+ if not isinstance(forks, dict) or not forks:
63
+ return None
64
+
65
+ config = getattr(node, "config", {}) or {}
66
+ try:
67
+ max_stale = int(config.get("verification_max_stale_seconds", 10))
68
+ except (TypeError, ValueError):
69
+ max_stale = 10
70
+ try:
71
+ max_future = int(config.get("verification_max_future_skew", 2))
72
+ except (TypeError, ValueError):
73
+ max_future = 2
74
+
75
+ now = int(time.time())
76
+ current_head = getattr(node, "latest_block_hash", None)
77
+
78
+ best_head: Optional[bytes] = None
79
+ best_block: Optional[Block] = None
80
+ best_height: int = -1
81
+
82
+ for head, fork in list(forks.items()):
83
+ if getattr(fork, "malicious_block_hash", None):
84
+ continue
85
+ if not getattr(fork, "validated_upto", None):
86
+ continue
87
+ if not getattr(fork, "peers", None):
88
+ continue
89
+ if not isinstance(head, (bytes, bytearray)):
90
+ continue
91
+
92
+ try:
93
+ block = Block.from_atom(node, head)
94
+ except Exception:
95
+ continue
96
+
97
+ ts = getattr(block, "timestamp", None)
98
+ if ts is None:
99
+ continue
100
+ ts_int = int(ts)
101
+ if max_stale >= 0 and (now - ts_int) > max_stale:
102
+ continue
103
+ if max_future >= 0 and (ts_int - now) > max_future:
104
+ continue
105
+
106
+ height = int(getattr(block, "number", 0) or 0)
107
+ if height > best_height:
108
+ best_head = bytes(head)
109
+ best_block = block
110
+ best_height = height
111
+ continue
112
+ if height == best_height:
113
+ if current_head == head:
114
+ best_head = bytes(head)
115
+ best_block = block
116
+ best_height = height
117
+ elif current_head != best_head and best_head is not None:
118
+ if bytes(head) < bytes(best_head):
119
+ best_head = bytes(head)
120
+ best_block = block
121
+ best_height = height
122
+
123
+ if best_head is None or best_block is None:
124
+ return None
125
+ return best_head, best_block, best_height
126
+
127
+
128
+ def make_verify_worker(node: Any):
129
+ """Build the verify worker bound to the given node."""
130
+
131
+ def _verify_worker() -> None:
132
+ node.logger.info("Verify worker started")
133
+ stop = node._verify_stop_event
134
+ while not stop.is_set():
135
+ batch: list[tuple[bytes, Set[Any]]] = []
136
+ try:
137
+ while True:
138
+ latest_b, peers = node._validation_verify_queue.get_nowait()
139
+ batch.append((latest_b, peers))
140
+ except Empty:
141
+ pass
142
+
143
+ if not batch:
144
+ node.logger.debug("Verify queue empty; sleeping")
145
+ time.sleep(0.1)
146
+ continue
147
+
148
+ batch.sort(key=lambda item: len(item[1]), reverse=True)
149
+
150
+ for latest_b, peers in batch:
151
+ try:
152
+ _process_peers_latest_block(node, latest_b, peers)
153
+ node.logger.debug(
154
+ "Updated forks from block %s for %d peers",
155
+ latest_b.hex()
156
+ if isinstance(latest_b, (bytes, bytearray))
157
+ else latest_b,
158
+ len(peers),
159
+ )
160
+ except Exception:
161
+ latest_hex = (
162
+ latest_b.hex()
163
+ if isinstance(latest_b, (bytes, bytearray))
164
+ else latest_b
165
+ )
166
+ node.logger.exception(
167
+ "Failed processing verification batch for %s", latest_hex
168
+ )
169
+
170
+ selected = _select_best_fork_head(node)
171
+ if selected is not None:
172
+ selected_head, selected_block, selected_height = selected
173
+ if getattr(node, "latest_block_hash", None) != selected_head:
174
+ node.latest_block_hash = selected_head
175
+ node.latest_block = selected_block
176
+ node.logger.info(
177
+ "Selected verified head %s (height=%s)",
178
+ selected_head.hex(),
179
+ selected_height,
180
+ )
181
+ node.logger.info("Verify worker stopped")
182
+
183
+ return _verify_worker
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astreum
3
- Version: 0.3.16
3
+ Version: 0.3.48
4
4
  Summary: Python library to interact with the Astreum blockchain and its virtual machine.
5
5
  Author-email: "Roy R. O. Okello" <roy@stelar.xyz>
6
6
  Project-URL: Homepage, https://github.com/astreum/lib-py
@@ -33,18 +33,31 @@ When initializing an `astreum.Node`, pass a dictionary with any of the options b
33
33
  | `hot_storage_limit` | int | `1073741824` | Maximum bytes kept in the hot cache before new atoms are skipped (1 GiB). |
34
34
  | `cold_storage_limit` | int | `10737418240` | Cold storage write threshold (10 GiB by default); set to `0` to skip the limit. |
35
35
  | `cold_storage_path` | string | `None` | Directory where persisted atoms live; Astreum creates it on startup and skips cold storage when unset. |
36
- | `logging_retention` | int | `90` | Number of days to keep rotated log files (daily gzip). |
36
+ | `atom_fetch_interval` | float | `0.25` | Poll interval (seconds) while waiting for missing atoms in `get_atom_list_from_storage`; `0` disables waiting. |
37
+ | `atom_fetch_retries` | int | `8` | Number of poll attempts for missing atoms; max wait is roughly `interval * retries`, `0` disables waiting. |
38
+ | `logging_retention_days` | int | `90` | Number of days to keep rotated log files (daily gzip). |
39
+ | `chain_id` | int | `0` | Chain identifier used for validation (0 = test, 1 = main). |
37
40
  | `verbose` | bool | `False` | When **True**, also mirror JSON logs to stdout with a human-readable format. |
38
41
 
39
- ### Networking
42
+ ### Communication
40
43
 
41
44
  | Parameter | Type | Default | Description |
42
45
  | ------------------------ | ----------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
43
46
  | `relay_secret_key` | hex string | Auto-generated | X25519 private key used for the relay route; a new keypair is created when this field is omitted. |
44
47
  | `validation_secret_key` | hex string | `None` | Optional Ed25519 key that lets the node join the validation route; leave blank to opt out of validation. |
45
48
  | `use_ipv6` | bool | `False` | Bind the incoming/outgoing sockets on IPv6 (the OS still listens on IPv4 if a peer speaks both). |
46
- | `incoming_port` | int | `7373` | UDP port the relay binds to; pass `0` or omit to let the OS pick an ephemeral port. |
47
- | `bootstrap` | list\[str\] | `[]` | Addresses to ping with a handshake before joining; each must look like `host:port` or `[ipv6]:port`. |
49
+ | `incoming_port` | int | `52780` | UDP port the relay binds to; pass `0` or omit to let the OS pick an ephemeral port. |
50
+ | `default_seed` | string | `"bootstrap.astreum.org:52780"` | Default address to ping before joining; set to `None` to disable the built-in default. |
51
+ | `additional_seeds` | list\[str\] | `[]` | Extra addresses appended to the bootstrap list; each must look like `host:port` or `[ipv6]:port`. |
52
+ | `peer_timeout` | int | `900` | Evict peers that have not been seen within this many seconds (15 minutes). |
53
+ | `peer_timeout_interval` | int | `10` | How often (seconds) the peer manager checks for stale peers. |
54
+ | `bootstrap_retry_interval` | int | `30` | How often (seconds) to retry bootstrapping when the peer list is empty. |
55
+ | `storage_index_interval` | int | `600` | How often (seconds) to re-advertise cold storage atoms to the closest known peer. |
56
+ | `cold_storage_advertise_limit` | int | `1000` | Max cold storage atoms advertised per cycle using last-modified time; `-1` unlimited, `0` disable. |
57
+ | `incoming_queue_size_limit` | int | `67108864` | Soft cap (bytes) for inbound queue usage tracked by `enqueue_incoming`; set to `0` to disable. |
58
+ | `incoming_queue_timeout` | float | `1.0` | When > 0, `enqueue_incoming` waits up to this many seconds for space before dropping the payload. |
59
+ | `outgoing_queue_size_limit` | int | `67108864` | Soft cap (bytes) for `enqueue_outgoing`-tracked outgoing queue usage; set to `0` to disable. |
60
+ | `outgoing_queue_timeout` | float | `1.0` | When > 0, `enqueue_outgoing` waits up to this many seconds for space before dropping the payload. |
48
61
 
49
62
  > **Note**
50
63
  > The peer‑to‑peer *route* used for object discovery is always enabled.
@@ -61,10 +74,11 @@ config = {
61
74
  "hot_storage_limit": 1073741824, # cap hot cache at 1 GiB
62
75
  "cold_storage_limit": 10737418240, # cap cold storage at 10 GiB
63
76
  "cold_storage_path": "./data/node1",
64
- "incoming_port": 7373,
77
+ "cold_storage_advertise_limit": 1000, # -1 unlimited, 0 disable, >0 limit
78
+ "incoming_port": 52780,
65
79
  "use_ipv6": False,
66
- "bootstrap": [
67
- "bootstrap.astreum.org:7373",
80
+ "default_seed": None,
81
+ "additional_seeds": [
68
82
  "127.0.0.1:7374"
69
83
  ]
70
84
  }
@@ -145,7 +159,7 @@ except ParseError as e:
145
159
  Every `Node` instance wires up structured logging automatically:
146
160
 
147
161
  - Logs land in per-instance files named `node.log` under `%LOCALAPPDATA%\Astreum\lib-py\logs/<instance_id>` on Windows and `$XDG_STATE_HOME` (or `~/.local/state`)/`Astreum/lib-py/logs/<instance_id>` on other platforms. The `<instance_id>` is the first 16 hex characters of a BLAKE3 hash of the caller's file path, so running the node from different entry points keeps their logs isolated.
148
- - Files rotate at midnight UTC with gzip compression (`node-YYYY-MM-DD.log.gz`) and retain 90 days by default. Override via `config["logging_retention"]`.
162
+ - Files rotate at midnight UTC with gzip compression (`node-YYYY-MM-DD.log.gz`) and retain 90 days by default. Override via `config["logging_retention_days"]`.
149
163
  - Each event is a single JSON line containing timestamp, level, logger, message, process/thread info, module/function, and the derived `instance_id`.
150
164
  - Set `config["verbose"] = True` to mirror logs to stdout in a human-friendly format like `[2025-04-13-42-59] [info] Starting Astreum Node`.
151
165
  - The very first entry emitted is the banner `Starting Astreum Node`, signalling that the logging pipeline is live before other subsystems spin up.
@@ -156,5 +170,27 @@ Every `Node` instance wires up structured logging automatically:
156
170
  python3 -m venv venv
157
171
  source venv/bin/activate
158
172
  pip install -e .
173
+ ```
174
+
175
+ for all tests
176
+ ```
159
177
  python3 -m unittest discover -s tests
160
178
  ```
179
+
180
+ for individual tests
181
+ ```
182
+ python3 -m unittest tests.node.test_atom_get
183
+ python3 -m unittest tests.node.test_current_validator
184
+ python3 -m unittest tests.node.test_node_connection
185
+ python3 -m unittest tests.node.test_node_init
186
+ python3 -m unittest tests.node.test_node_validation
187
+ python3 -m unittest tests.node.config.default_seed
188
+ python3 -m unittest tests.node.tokenize
189
+ python3 -m unittest tests.node.parse
190
+ python3 -m unittest tests.node.function
191
+ python3 -m unittest tests.node.stack
192
+ python3 -m unittest tests.models.test_merkle
193
+ python3 -m unittest tests.models.test_patricia
194
+ python3 -m unittest tests.block.atom
195
+ python3 -m unittest tests.block.nonce
196
+ ```
@@ -0,0 +1,79 @@
1
+ astreum/__init__.py,sha256=ibzwB_Rq3mBCgzFBVx7ssHo7-MFxpiayn5cHMIZ3Gd4,351
2
+ astreum/node.py,sha256=6K6XeAd6h9b9LYtXE9MeJ2med0eOMZbEU5I1_RoLt30,3174
3
+ astreum/communication/__init__.py,sha256=E0-UtzXwyX6svdbL52fI3tnUY8ILmQJ6rqw3qX2YZi0,357
4
+ astreum/communication/difficulty.py,sha256=XUw3xfppecVy_kBsaOXBCcxICz4d3qwKvu8L4rXNtyY,886
5
+ astreum/communication/disconnect.py,sha256=m5rwR_TJxBk4KWAUtF-qcikssVj2u-6zse1TTYZquj4,1613
6
+ astreum/communication/incoming_queue.py,sha256=ccKmjSmkMt8Kvi7XS8Mr-iI-swJSWxjmLeABywuKokc,3357
7
+ astreum/communication/message_pow.py,sha256=diDxc2aXjTxBQw5GWK5b-8Gybxa8AWSAcGmxF-tODnI,1103
8
+ astreum/communication/node.py,sha256=GrcPRffWEv74W_gezYRnKVvGHBblmGEsn5Wvtw8pxC8,1700
9
+ astreum/communication/outgoing_queue.py,sha256=CDA-A9vrkNmK-Gm4wS5htnhQhFaLaejW8dKNTsFDSNo,3818
10
+ astreum/communication/setup.py,sha256=I1uZDxb5qyPVZ6XNi_tngtgF1CXGV4otxdNoUeRoKHs,11911
11
+ astreum/communication/util.py,sha256=tDF6TNP-u7Q7K96JhnuWHEwfq4pASoYYcF5MakBicrg,1942
12
+ astreum/communication/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ astreum/communication/handlers/handshake.py,sha256=XGeHslDhDn0zJS-DvvcxHwrPzmIhTMpunKOjGc8F2pg,3525
14
+ astreum/communication/handlers/object_request.py,sha256=Wik_jEA9GiwuIaliUYThGvCLojiC2CbdGu0DfULAUa4,10791
15
+ astreum/communication/handlers/object_response.py,sha256=nDHn81GAWMFe6iOhw4NyR0ZQxGxfr0ehZ7HcISWdtZA,7671
16
+ astreum/communication/handlers/ping.py,sha256=bbB8JQfLR0oYgdharx0xarsn7YIaCdxlZb-AdmLw99g,1345
17
+ astreum/communication/handlers/route_request.py,sha256=lZgapJH0RfLgp9c14H864BU3K3t03WHRGLcgpeu7SEg,2584
18
+ astreum/communication/handlers/route_response.py,sha256=ktEft9XevZYVp6rZNCrbFIZ-HZTlYZLIUZcdRR4vkU8,1857
19
+ astreum/communication/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ astreum/communication/models/message.py,sha256=2qln_PpKkVEoPdSGeQxUWAFxcEsHB-lz7dzTAsO94HU,4485
21
+ astreum/communication/models/peer.py,sha256=IxZ0p8Sz6s6rsQVs8u7CB9ci17lSgXXgsHd1D4jjbXY,1845
22
+ astreum/communication/models/ping.py,sha256=oD7IJt6JJvB2iXqkvdxMs7TwNWlK_3yk7lE7NZ-jnpA,1728
23
+ astreum/communication/models/route.py,sha256=nb2sILlh0j1ZTyWJZBfF-jUZ1ECdAPXsin2h-_yX4Bk,3965
24
+ astreum/communication/processors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ astreum/communication/processors/incoming.py,sha256=v2D7SZmwJEv5QOjdb6JYfnJ04Mnlswk2e2mHef7OXHM,6339
26
+ astreum/communication/processors/outgoing.py,sha256=soI-QsO5pBqss8s6mIzTkIR7IvOS1xH9nyRM2X7un0E,1976
27
+ astreum/communication/processors/peer.py,sha256=0NtxYXxb0PJfOfkXKvNXVWY1GYO4Ww7nSYA0AQ06ri8,4750
28
+ astreum/crypto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ astreum/crypto/chacha20poly1305.py,sha256=01VtLx_bdJC86ifQeTA494ZdKbPM2MswDTLmAs9bl8c,2479
30
+ astreum/crypto/ed25519.py,sha256=FRnvlN0kZlxn4j-sJKl-C9tqiz_0z4LZyXLj3KIj1TQ,1760
31
+ astreum/crypto/quadratic_form.py,sha256=pJgbORey2NTWbQNhdyvrjy_6yjORudQ67jBz2ScHptg,4037
32
+ astreum/crypto/wesolowski.py,sha256=SUgGXW3Id07dJtWzDcs4dluIhjqbRWQ8YWjn_mK78AQ,4092
33
+ astreum/crypto/x25519.py,sha256=i29v4BmwKRcbz9E7NKqFDQyxzFtJUqN0St9jd7GS1uA,1137
34
+ astreum/machine/__init__.py,sha256=TjWf9RlGuOGbCqdjJKidh8W4pCzUoLpi3FgutssEGoQ,479
35
+ astreum/machine/parser.py,sha256=Z_Y0Sax0rPh8JcIo19-iNDQoc5GTdGQkmfFyLpCB4bw,1757
36
+ astreum/machine/tokenizer.py,sha256=6wPqR_D3h5BEvR78XKtD45ouy77RZBbz4Yh4jHSmN4o,2394
37
+ astreum/machine/evaluations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ astreum/machine/evaluations/high_evaluation.py,sha256=cqYudR9WAdVz9dURDyuQhZsuhWbmjbdw9x3UxDEYpPI,9971
39
+ astreum/machine/evaluations/low_evaluation.py,sha256=t3xfZCKrvRMBTmc4PUp8tywr2uIOScgQnWaR6eMG3wE,10370
40
+ astreum/machine/evaluations/script_evaluation.py,sha256=eWouYUwTYzaqUyXqEe-lAJFIluW0gMeCDdXqle88oWw,864
41
+ astreum/machine/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ astreum/machine/models/environment.py,sha256=WjP6GRX_8e0-BAhzRLvQ6fYtKQEVR0LZi7DZNZS0TSE,1019
43
+ astreum/machine/models/expression.py,sha256=KjN6TxikqpRK_vwx5f4N4RNZCqoKYBdR6rGBBJp2-Bk,7637
44
+ astreum/machine/models/meter.py,sha256=5q2PFW7_jmgKVM1-vwE4RRjMfPEthUA4iu1CwR-Axws,505
45
+ astreum/storage/__init__.py,sha256=Flk6WXT2xGFHWWJiZHK3O5OpjoLTOFMqqIiJTtD58kY,111
46
+ astreum/storage/providers.py,sha256=-nOEfoecraTBhPA3ERgz8UwEOJ9DKD-wnHtaSoR6WjU,740
47
+ astreum/storage/requests.py,sha256=5D9F2uWdwqhvfPM3TWrtCMopseFyPV6WKNKbxT5uLlY,1067
48
+ astreum/storage/setup.py,sha256=t6EtAan9N7wrTEcU927z-sM5L5mboMnKk218fwfTRy8,893
49
+ astreum/storage/actions/get.py,sha256=2yA00Odjefzf2v5Qpwl6H0LSG8sb7KLmfbxkA9Fnivo,11088
50
+ astreum/storage/actions/set.py,sha256=TGD1JS9zRLO7AVDTWwP2st7DWabfB51trVAghUrja4A,6386
51
+ astreum/storage/models/atom.py,sha256=fAIXW7bMzsyioZL4UOyu_Rpjvw2amWNQNbyTE3m56sk,2707
52
+ astreum/storage/models/trie.py,sha256=kZelNuMTGKnG21Rt4Fo72bp4d1P_5W8zAH7hWk4zN1k,17577
53
+ astreum/utils/bytes.py,sha256=9QTWC2JCdwWLB5R2mPtmjPro0IUzE58DL3uEul4AheE,846
54
+ astreum/utils/config.py,sha256=b2ei_LtPxnQs__dJvBnNfjQiQjnLOJM0-EGrO_1PEYw,11256
55
+ astreum/utils/integer.py,sha256=iQt-klWOYVghu_NOT341MmHbOle4FDT3by4PNKNXscg,736
56
+ astreum/utils/logging.py,sha256=YbFtt_h6_3mpnOomffGW0DnI1Y1cwl_vb6Zsu1_W_Xg,6692
57
+ astreum/validation/__init__.py,sha256=cRlrwE3MqtBrda9ZxLmtCEOY3P5oJnXpjE4YDNHCnpI,322
58
+ astreum/validation/constants.py,sha256=p-hO8u3PJob5UFNHzSm-HqIe6z-QC7L4TldRXA7IsvQ,60
59
+ astreum/validation/genesis.py,sha256=7JSZEa5-AdaWn2sCO0G2bh8-4OG-mio585U1lJ9ZjWk,1992
60
+ astreum/validation/node.py,sha256=AuY186eqlmXMIbFnQrDO8tn6gmuaj-sI6l1htIwoxnA,6935
61
+ astreum/validation/validator.py,sha256=MmxkOMWQeUg4peIt5FHz1A1Fv-RvbGNCa49sDj8b7QM,3873
62
+ astreum/validation/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
+ astreum/validation/models/account.py,sha256=WRRaNHqQuoc0hBrDmPF2gZvQCl5557QX1FOYDOmpkqE,2666
64
+ astreum/validation/models/accounts.py,sha256=iUMs6LvmMea-gxd6-ujkFjqhWmuW1cl9XTWGXQkpLys,2388
65
+ astreum/validation/models/block.py,sha256=SfjKO3mez67vHHxOdpsJn1WihKlBou0RsBzl7KiOnqI,21081
66
+ astreum/validation/models/fork.py,sha256=R9yBKThlvAzqGf4nAe5yVyFDX7tIX5TfnH_KDEZ7Azg,20630
67
+ astreum/validation/models/receipt.py,sha256=IRDrAEApdMIuBnRUuvueZ0X45Fq2iEvl40sbW3u1mso,3883
68
+ astreum/validation/models/transaction.py,sha256=TKylwk3AqWW6pcXFAowR7A4BT43nQxPRQ-NseE3ELtQ,8825
69
+ astreum/validation/workers/__init__.py,sha256=GH8G4j7ONbtcoqBiX1d1I16Ikiu3fjGM6pUSQXqDtiw,228
70
+ astreum/validation/workers/validation.py,sha256=60L5KiX6e5-5KN4NLAF9jclfyRqDX_ju4qOTx92PnY4,15349
71
+ astreum/verification/__init__.py,sha256=Ec7_CTXbHYtiw1KK3oJx0s96loSnVX0i863_FLHv_es,130
72
+ astreum/verification/discover.py,sha256=ubMdNTE8gzDQ9B8NzycrHpKVHfnqaBQgNkEHywoVjws,2449
73
+ astreum/verification/node.py,sha256=xYhVRhRW_wKIdFiWzrC5A-xeHy1P6cRJwG5MWRA8KTM,2005
74
+ astreum/verification/worker.py,sha256=BM8feAJ0IVKyHYzdC3YRZwEItOxUhQdmtu2RtksIMvI,6460
75
+ astreum-0.3.48.dist-info/licenses/LICENSE,sha256=gYBvRDP-cPLmTyJhvZ346QkrYW_eleke4Z2Yyyu43eQ,1089
76
+ astreum-0.3.48.dist-info/METADATA,sha256=pR6MmP4QXroddMYtP9BHnOaVA1C_glrH5fY42waippM,10987
77
+ astreum-0.3.48.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
78
+ astreum-0.3.48.dist-info/top_level.txt,sha256=1EG1GmkOk3NPmUA98FZNdKouhRyget-KiFiMk0i2Uz0,8
79
+ astreum-0.3.48.dist-info/RECORD,,