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.
- astreum/__init__.py +1 -2
- astreum/communication/__init__.py +15 -11
- astreum/communication/difficulty.py +39 -0
- astreum/communication/disconnect.py +57 -0
- astreum/communication/handlers/handshake.py +105 -62
- astreum/communication/handlers/object_request.py +226 -138
- astreum/communication/handlers/object_response.py +118 -10
- 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 +133 -58
- astreum/communication/setup.py +272 -113
- astreum/communication/util.py +14 -0
- astreum/machine/evaluations/low_evaluation.py +5 -5
- astreum/machine/models/expression.py +5 -5
- astreum/node.py +96 -87
- astreum/storage/actions/get.py +285 -183
- astreum/storage/actions/set.py +171 -156
- astreum/storage/models/atom.py +0 -14
- astreum/storage/models/trie.py +2 -2
- astreum/storage/providers.py +24 -0
- astreum/storage/requests.py +13 -10
- astreum/storage/setup.py +20 -15
- astreum/utils/config.py +260 -43
- 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/{consensus → validation}/models/account.py +1 -1
- astreum/validation/models/block.py +544 -0
- astreum/validation/models/fork.py +511 -0
- astreum/{consensus → validation}/models/receipt.py +18 -5
- astreum/{consensus → validation}/models/transaction.py +50 -8
- astreum/validation/node.py +190 -0
- astreum/{consensus → validation}/validator.py +1 -1
- astreum/validation/workers/__init__.py +8 -0
- astreum/{consensus → validation}/workers/validation.py +360 -333
- 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.16.dist-info → astreum-0.3.48.dist-info}/METADATA +45 -9
- astreum-0.3.48.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.16.dist-info/RECORD +0 -72
- /astreum/{consensus → validation}/models/__init__.py +0 -0
- /astreum/{consensus → validation}/models/accounts.py +0 -0
- {astreum-0.3.16.dist-info → astreum-0.3.48.dist-info}/WHEEL +0 -0
- {astreum-0.3.16.dist-info → astreum-0.3.48.dist-info}/licenses/LICENSE +0 -0
- {astreum-0.3.16.dist-info → astreum-0.3.48.dist-info}/top_level.txt +0 -0
|
@@ -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.
|
|
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.
|
|
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
|
-
| `
|
|
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
|
-
###
|
|
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 | `
|
|
47
|
-
| `
|
|
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
|
-
"
|
|
77
|
+
"cold_storage_advertise_limit": 1000, # -1 unlimited, 0 disable, >0 limit
|
|
78
|
+
"incoming_port": 52780,
|
|
65
79
|
"use_ipv6": False,
|
|
66
|
-
"
|
|
67
|
-
|
|
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["
|
|
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,,
|