astreum 0.2.61__py3-none-any.whl → 0.3.9__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 +16 -7
- astreum/{_communication → communication}/__init__.py +3 -3
- astreum/communication/handlers/handshake.py +89 -0
- astreum/communication/handlers/object_request.py +176 -0
- astreum/communication/handlers/object_response.py +115 -0
- astreum/communication/handlers/ping.py +34 -0
- astreum/communication/handlers/route_request.py +76 -0
- astreum/communication/handlers/route_response.py +53 -0
- astreum/communication/models/__init__.py +0 -0
- astreum/communication/models/message.py +124 -0
- astreum/communication/models/peer.py +51 -0
- astreum/{_communication → communication/models}/route.py +7 -12
- astreum/communication/processors/__init__.py +0 -0
- astreum/communication/processors/incoming.py +98 -0
- astreum/communication/processors/outgoing.py +20 -0
- astreum/communication/setup.py +166 -0
- astreum/communication/start.py +37 -0
- astreum/{_communication → communication}/util.py +7 -0
- astreum/consensus/__init__.py +20 -0
- astreum/consensus/genesis.py +66 -0
- astreum/consensus/models/__init__.py +0 -0
- astreum/consensus/models/account.py +84 -0
- astreum/consensus/models/accounts.py +72 -0
- astreum/consensus/models/block.py +364 -0
- astreum/{_consensus → consensus/models}/chain.py +7 -7
- astreum/{_consensus → consensus/models}/fork.py +8 -8
- astreum/consensus/models/receipt.py +98 -0
- astreum/{_consensus → consensus/models}/transaction.py +76 -78
- astreum/{_consensus → consensus}/setup.py +18 -50
- astreum/consensus/start.py +67 -0
- astreum/consensus/validator.py +95 -0
- astreum/{_consensus → consensus}/workers/discovery.py +19 -1
- astreum/consensus/workers/validation.py +307 -0
- astreum/{_consensus → consensus}/workers/verify.py +29 -2
- astreum/crypto/chacha20poly1305.py +74 -0
- astreum/machine/__init__.py +20 -0
- astreum/machine/evaluations/__init__.py +0 -0
- astreum/{_lispeum → machine/evaluations}/high_evaluation.py +237 -236
- astreum/machine/evaluations/low_evaluation.py +281 -0
- astreum/machine/evaluations/script_evaluation.py +27 -0
- astreum/machine/models/__init__.py +0 -0
- astreum/machine/models/environment.py +31 -0
- astreum/{_lispeum → machine/models}/expression.py +36 -8
- astreum/machine/tokenizer.py +90 -0
- astreum/node.py +78 -767
- astreum/storage/__init__.py +7 -0
- astreum/storage/actions/get.py +183 -0
- astreum/storage/actions/set.py +178 -0
- astreum/{_storage → storage/models}/atom.py +55 -57
- astreum/{_storage/patricia.py → storage/models/trie.py} +227 -203
- astreum/storage/requests.py +28 -0
- astreum/storage/setup.py +22 -15
- astreum/utils/config.py +48 -0
- {astreum-0.2.61.dist-info → astreum-0.3.9.dist-info}/METADATA +27 -26
- astreum-0.3.9.dist-info/RECORD +71 -0
- astreum/_communication/message.py +0 -101
- astreum/_communication/peer.py +0 -23
- astreum/_communication/setup.py +0 -322
- astreum/_consensus/__init__.py +0 -20
- astreum/_consensus/account.py +0 -95
- astreum/_consensus/accounts.py +0 -38
- astreum/_consensus/block.py +0 -311
- astreum/_consensus/genesis.py +0 -72
- astreum/_consensus/receipt.py +0 -136
- astreum/_consensus/workers/validation.py +0 -125
- astreum/_lispeum/__init__.py +0 -16
- astreum/_lispeum/environment.py +0 -13
- astreum/_lispeum/low_evaluation.py +0 -123
- astreum/_lispeum/tokenizer.py +0 -22
- astreum/_node.py +0 -198
- astreum/_storage/__init__.py +0 -7
- astreum/_storage/setup.py +0 -35
- astreum/format.py +0 -75
- astreum/models/block.py +0 -441
- astreum/models/merkle.py +0 -205
- astreum/models/patricia.py +0 -393
- astreum/storage/object.py +0 -68
- astreum-0.2.61.dist-info/RECORD +0 -57
- /astreum/{models → communication/handlers}/__init__.py +0 -0
- /astreum/{_communication → communication/models}/ping.py +0 -0
- /astreum/{_consensus → consensus}/workers/__init__.py +0 -0
- /astreum/{_lispeum → machine/models}/meter.py +0 -0
- /astreum/{_lispeum → machine}/parser.py +0 -0
- {astreum-0.2.61.dist-info → astreum-0.3.9.dist-info}/WHEEL +0 -0
- {astreum-0.2.61.dist-info → astreum-0.3.9.dist-info}/licenses/LICENSE +0 -0
- {astreum-0.2.61.dist-info → astreum-0.3.9.dist-info}/top_level.txt +0 -0
astreum/utils/config.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Dict
|
|
4
|
+
|
|
5
|
+
DEFAULT_HOT_STORAGE_LIMIT = 1 << 30 # 1 GiB
|
|
6
|
+
DEFAULT_COLD_STORAGE_LIMIT = 10 << 30 # 10 GiB
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def config_setup(config: Dict = {}):
|
|
10
|
+
"""
|
|
11
|
+
Normalize configuration values before the node starts.
|
|
12
|
+
"""
|
|
13
|
+
chain_str = config.get("chain", "test")
|
|
14
|
+
if chain_str not in {"main", "test"}:
|
|
15
|
+
chain_str = "test"
|
|
16
|
+
config["chain"] = chain_str
|
|
17
|
+
config["chain_id"] = 1 if chain_str == "main" else 0
|
|
18
|
+
|
|
19
|
+
hot_limit_raw = config.get(
|
|
20
|
+
"hot_storage_limit", config.get("hot_storage_default_limit", DEFAULT_HOT_STORAGE_LIMIT)
|
|
21
|
+
)
|
|
22
|
+
try:
|
|
23
|
+
config["hot_storage_default_limit"] = int(hot_limit_raw)
|
|
24
|
+
except (TypeError, ValueError) as exc:
|
|
25
|
+
raise ValueError(
|
|
26
|
+
f"hot_storage_limit must be an integer: {hot_limit_raw!r}"
|
|
27
|
+
) from exc
|
|
28
|
+
|
|
29
|
+
cold_limit_raw = config.get("cold_storage_limit", DEFAULT_COLD_STORAGE_LIMIT)
|
|
30
|
+
try:
|
|
31
|
+
config["cold_storage_limit"] = int(cold_limit_raw)
|
|
32
|
+
except (TypeError, ValueError) as exc:
|
|
33
|
+
raise ValueError(
|
|
34
|
+
f"cold_storage_limit must be an integer: {cold_limit_raw!r}"
|
|
35
|
+
) from exc
|
|
36
|
+
|
|
37
|
+
cold_path_raw = config.get("cold_storage_path")
|
|
38
|
+
if cold_path_raw:
|
|
39
|
+
try:
|
|
40
|
+
path_obj = Path(cold_path_raw)
|
|
41
|
+
path_obj.mkdir(parents=True, exist_ok=True)
|
|
42
|
+
config["cold_storage_path"] = str(path_obj)
|
|
43
|
+
except OSError:
|
|
44
|
+
config["cold_storage_path"] = None
|
|
45
|
+
else:
|
|
46
|
+
config["cold_storage_path"] = None
|
|
47
|
+
|
|
48
|
+
return config
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: astreum
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Python library to interact with the Astreum blockchain and its
|
|
3
|
+
Version: 0.3.9
|
|
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
|
-
Project-URL: Homepage, https://github.com/astreum/lib
|
|
7
|
-
Project-URL: Issues, https://github.com/astreum/lib/issues
|
|
6
|
+
Project-URL: Homepage, https://github.com/astreum/lib-py
|
|
7
|
+
Project-URL: Issues, https://github.com/astreum/lib-py/issues
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
@@ -18,7 +18,7 @@ Dynamic: license-file
|
|
|
18
18
|
|
|
19
19
|
# lib
|
|
20
20
|
|
|
21
|
-
Python library to interact with the Astreum blockchain and its
|
|
21
|
+
Python library to interact with the Astreum blockchain and its virtual machine.
|
|
22
22
|
|
|
23
23
|
[View on PyPI](https://pypi.org/project/astreum/)
|
|
24
24
|
|
|
@@ -30,21 +30,21 @@ When initializing an `astreum.Node`, pass a dictionary with any of the options b
|
|
|
30
30
|
|
|
31
31
|
| Parameter | Type | Default | Description |
|
|
32
32
|
| --------------------------- | ---------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `storage_path` | string | `None` | Directory where objects are persisted. If *None*, the node uses an in‑memory store. |
|
|
37
|
-
| `storage_get_relay_timeout` | float | `5` | Seconds to wait for an object requested from peers before timing‑out. |
|
|
33
|
+
| `hot_storage_limit` | int | `1073741824` | Maximum bytes kept in the hot cache before new atoms are skipped (1 GiB). |
|
|
34
|
+
| `cold_storage_limit` | int | `10737418240` | Cold storage write threshold (10 GiB by default); set to `0` to skip the limit. |
|
|
35
|
+
| `cold_storage_path` | string | `None` | Directory where persisted atoms live; Astreum creates it on startup and skips cold storage when unset. |
|
|
38
36
|
| `logging_retention` | int | `90` | Number of days to keep rotated log files (daily gzip). |
|
|
39
37
|
| `verbose` | bool | `False` | When **True**, also mirror JSON logs to stdout with a human-readable format. |
|
|
40
38
|
|
|
41
39
|
### Networking
|
|
42
40
|
|
|
43
|
-
| Parameter
|
|
44
|
-
|
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
41
|
+
| Parameter | Type | Default | Description |
|
|
42
|
+
| ------------------------ | ----------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| `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
|
+
| `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
|
+
| `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`. |
|
|
48
48
|
|
|
49
49
|
> **Note**
|
|
50
50
|
> The peer‑to‑peer *route* used for object discovery is always enabled.
|
|
@@ -56,16 +56,16 @@ When initializing an `astreum.Node`, pass a dictionary with any of the options b
|
|
|
56
56
|
from astreum.node import Node
|
|
57
57
|
|
|
58
58
|
config = {
|
|
59
|
-
"machine-only": False, # run full node
|
|
60
59
|
"relay_secret_key": "ab…cd", # optional – hex encoded
|
|
61
60
|
"validation_secret_key": "12…34", # optional – validator
|
|
62
|
-
"
|
|
63
|
-
"
|
|
61
|
+
"hot_storage_limit": 1073741824, # cap hot cache at 1 GiB
|
|
62
|
+
"cold_storage_limit": 10737418240, # cap cold storage at 10 GiB
|
|
63
|
+
"cold_storage_path": "./data/node1",
|
|
64
64
|
"incoming_port": 7373,
|
|
65
65
|
"use_ipv6": False,
|
|
66
66
|
"bootstrap": [
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
"bootstrap.astreum.org:7373",
|
|
68
|
+
"127.0.0.1:7374"
|
|
69
69
|
]
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -73,9 +73,10 @@ node = Node(config)
|
|
|
73
73
|
# … your code …
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
## Lispeum Machine Quickstart
|
|
77
76
|
|
|
78
|
-
|
|
77
|
+
## Astreum Machine Quickstart
|
|
78
|
+
|
|
79
|
+
The Astreum virtual machine (VM) is embedded inside `astreum.Node`. You feed it Astreum script, and the node tokenizes, parses, and evaluates.
|
|
79
80
|
|
|
80
81
|
```python
|
|
81
82
|
# Define a named function int.add (stack body) and call it with bytes 1 and 2
|
|
@@ -108,15 +109,15 @@ params = Expr.ListExpr([Expr.Symbol("a"), Expr.Symbol("b")])
|
|
|
108
109
|
int_add_fn = Expr.ListExpr([fn_body, params, Expr.Symbol("fn")])
|
|
109
110
|
|
|
110
111
|
# 4) Store under the name "int.add"
|
|
111
|
-
node.env_set(env_id,
|
|
112
|
+
node.env_set(env_id, "int.add", int_add_fn)
|
|
112
113
|
|
|
113
114
|
# 5) Retrieve the function and call it with bytes 1 and 2
|
|
114
|
-
bound = node.env_get(env_id,
|
|
115
|
-
call = Expr.ListExpr([Expr.
|
|
115
|
+
bound = node.env_get(env_id, "int.add")
|
|
116
|
+
call = Expr.ListExpr([Expr.Bytes(b"\x01"), Expr.Bytes(b"\x02"), bound])
|
|
116
117
|
res = node.high_eval(env_id, call)
|
|
117
118
|
|
|
118
119
|
# sk returns a list of bytes; for 1+2 expect a single byte with value 3
|
|
119
|
-
print([b.value for b in res.elements]) # [3]
|
|
120
|
+
print([int.from_bytes(b.value, 'big', signed=True) for b in res.elements]) # [3]
|
|
120
121
|
```
|
|
121
122
|
|
|
122
123
|
### Handling errors
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
astreum/__init__.py,sha256=GkEW_ReYore8_0nEOvPnZLUa3lO7CgMWu6LeEjrGXEk,325
|
|
2
|
+
astreum/node.py,sha256=naKGkn97M3Khux3r8mZ81wsiAI6JFr4uhly4X_BspmU,2689
|
|
3
|
+
astreum/communication/__init__.py,sha256=wNxzsAk8Fol9cGMPuVvY4etrrMqn3SjZq1dE82kFrxw,228
|
|
4
|
+
astreum/communication/setup.py,sha256=We43HOZG0v18TZhEdkc8MWCvI9YvHw8s4fmauHEXDUc,5887
|
|
5
|
+
astreum/communication/start.py,sha256=wxL1cgChebhnaeEaY9flS6qybo_cFW2-tcRvjLxC8Hw,1823
|
|
6
|
+
astreum/communication/util.py,sha256=fS3u3giOOXmvN0_reb0oIaXsFESHAWz-bbAuzdzdGQ4,1575
|
|
7
|
+
astreum/communication/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
astreum/communication/handlers/handshake.py,sha256=79Y5ei8RHg53WIwzP1eO4dpDYdKvhr1qrbWMECf9D-E,2781
|
|
9
|
+
astreum/communication/handlers/object_request.py,sha256=n_ThJomdYXm6HPfkLMmCqRxO58xPCUOHXf1ddmG-OC8,7163
|
|
10
|
+
astreum/communication/handlers/object_response.py,sha256=X5MfYxd_b4SfKq3129Fi29ZfLynWNRyhGuoISiMHy20,3959
|
|
11
|
+
astreum/communication/handlers/ping.py,sha256=2fVynfVIsbWHtf7lpM6fTYWmeG0I1WSU3tmgCh9di7A,916
|
|
12
|
+
astreum/communication/handlers/route_request.py,sha256=KrucRgiM_oFNmwt93bRzNpeVHFATq3uhlNjGJIvzu-c,2477
|
|
13
|
+
astreum/communication/handlers/route_response.py,sha256=ZUKyXPpZzpVYKBgygMIlPjcmjrxi0s8M3COFfY5aO4A,1744
|
|
14
|
+
astreum/communication/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
astreum/communication/models/message.py,sha256=2qln_PpKkVEoPdSGeQxUWAFxcEsHB-lz7dzTAsO94HU,4485
|
|
16
|
+
astreum/communication/models/peer.py,sha256=834UyyErBGbZs4dxe_SWz3gnRGnvFyc-7XQPrdNvDFE,1669
|
|
17
|
+
astreum/communication/models/ping.py,sha256=u_DQTZJsbMdYiDDqjdZDsLaN5na2m9WZjVeEM3zq9_Y,955
|
|
18
|
+
astreum/communication/models/route.py,sha256=NdmnI1J1wFs2pkm6W0Kv-29JeqGiHcKlw4-esT5ZFLA,3797
|
|
19
|
+
astreum/communication/processors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
astreum/communication/processors/incoming.py,sha256=10l6Az-Ul_2BvYpTXgPiL9bL0te1q3GB3aET0JednKE,3325
|
|
21
|
+
astreum/communication/processors/outgoing.py,sha256=09nAeTzvo3jGWl3SLgIQr8vfmO_IvdDqSG7_ZKThYPk,593
|
|
22
|
+
astreum/consensus/__init__.py,sha256=VZR_NyGSD5VvZp3toD2zpdYwFDLBIcckeVZXFPlruuU,425
|
|
23
|
+
astreum/consensus/genesis.py,sha256=RI9AzQFmDTgNFuiiTmW2dDiGcURIUGmThdRpxWrUOBk,1962
|
|
24
|
+
astreum/consensus/setup.py,sha256=lrEapfpJXKqw4iwST11-tqPAI2VW2h3H6Ue4JDAtrP4,3142
|
|
25
|
+
astreum/consensus/start.py,sha256=DM45Pw6JL5rew-KpcspINguH43ZUHr4v99tXjYqaEkE,2551
|
|
26
|
+
astreum/consensus/validator.py,sha256=cqcmw1WEB8DkznNX_Mn8tmE956rVSNCPv1FicdL8EAQ,3647
|
|
27
|
+
astreum/consensus/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
astreum/consensus/models/account.py,sha256=3QcT59QUZynysLSbiywidFYVzYJ3LR6qia7JwXOwn4I,2690
|
|
29
|
+
astreum/consensus/models/accounts.py,sha256=iUMs6LvmMea-gxd6-ujkFjqhWmuW1cl9XTWGXQkpLys,2388
|
|
30
|
+
astreum/consensus/models/block.py,sha256=nNtw9TbEAF1mIEfgJr1fuswcZ0B63SVnuBANqJ5Zaac,13531
|
|
31
|
+
astreum/consensus/models/chain.py,sha256=SIIDFSYbag76kTUNwnuJ2_zyuhFsvT7n5HgrVTxBrvE,2797
|
|
32
|
+
astreum/consensus/models/fork.py,sha256=IbXRB93bUg2k3q3oQ9dOPzozV-rY-TEDFjYrw-WBymE,3859
|
|
33
|
+
astreum/consensus/models/receipt.py,sha256=KjKKjYp_LnP2zkX1FLIwD_4hqKV1b2TPfp43tY701q4,3336
|
|
34
|
+
astreum/consensus/models/transaction.py,sha256=AYa1Q-BaYW3mkOv1e3WbvDFEsYamKMiFrja-eO2zU_Y,7475
|
|
35
|
+
astreum/consensus/workers/__init__.py,sha256=bS5FjbevbIR5FHbVGnT4Jli17VIld_5auemRw4CaHFU,278
|
|
36
|
+
astreum/consensus/workers/discovery.py,sha256=u6HyxamMVJjYnPFPa_U95I2pN9UzHRQ-LOa7YYZT808,2453
|
|
37
|
+
astreum/consensus/workers/validation.py,sha256=uBkZVduHtwz8hUwDf_gFDiY8TfFaoYj40jx-s-EzuEU,13358
|
|
38
|
+
astreum/consensus/workers/verify.py,sha256=tBBrAHH8Xcg3uopmQSjT6iuZd1s-9FkLnJ_JgeW5HdU,3423
|
|
39
|
+
astreum/crypto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
+
astreum/crypto/chacha20poly1305.py,sha256=01VtLx_bdJC86ifQeTA494ZdKbPM2MswDTLmAs9bl8c,2479
|
|
41
|
+
astreum/crypto/ed25519.py,sha256=FRnvlN0kZlxn4j-sJKl-C9tqiz_0z4LZyXLj3KIj1TQ,1760
|
|
42
|
+
astreum/crypto/quadratic_form.py,sha256=pJgbORey2NTWbQNhdyvrjy_6yjORudQ67jBz2ScHptg,4037
|
|
43
|
+
astreum/crypto/wesolowski.py,sha256=SUgGXW3Id07dJtWzDcs4dluIhjqbRWQ8YWjn_mK78AQ,4092
|
|
44
|
+
astreum/crypto/x25519.py,sha256=i29v4BmwKRcbz9E7NKqFDQyxzFtJUqN0St9jd7GS1uA,1137
|
|
45
|
+
astreum/machine/__init__.py,sha256=TjWf9RlGuOGbCqdjJKidh8W4pCzUoLpi3FgutssEGoQ,479
|
|
46
|
+
astreum/machine/parser.py,sha256=Z_Y0Sax0rPh8JcIo19-iNDQoc5GTdGQkmfFyLpCB4bw,1757
|
|
47
|
+
astreum/machine/tokenizer.py,sha256=6wPqR_D3h5BEvR78XKtD45ouy77RZBbz4Yh4jHSmN4o,2394
|
|
48
|
+
astreum/machine/evaluations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
+
astreum/machine/evaluations/high_evaluation.py,sha256=cqYudR9WAdVz9dURDyuQhZsuhWbmjbdw9x3UxDEYpPI,9971
|
|
50
|
+
astreum/machine/evaluations/low_evaluation.py,sha256=_93r6DKkCwnaOKmVGSp8JBlUPZpKrA1GECqVnwLb9es,10370
|
|
51
|
+
astreum/machine/evaluations/script_evaluation.py,sha256=eWouYUwTYzaqUyXqEe-lAJFIluW0gMeCDdXqle88oWw,864
|
|
52
|
+
astreum/machine/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
+
astreum/machine/models/environment.py,sha256=WjP6GRX_8e0-BAhzRLvQ6fYtKQEVR0LZi7DZNZS0TSE,1019
|
|
54
|
+
astreum/machine/models/expression.py,sha256=yYr9ktk-NWPL4EXwHz7ePvr9eNvfSBQe3yzRUz06yas,7675
|
|
55
|
+
astreum/machine/models/meter.py,sha256=5q2PFW7_jmgKVM1-vwE4RRjMfPEthUA4iu1CwR-Axws,505
|
|
56
|
+
astreum/storage/__init__.py,sha256=Flk6WXT2xGFHWWJiZHK3O5OpjoLTOFMqqIiJTtD58kY,111
|
|
57
|
+
astreum/storage/requests.py,sha256=q_rxG_k7POth93HmsUTCLSyNw-4EdFqqNExhIwm7Q0g,818
|
|
58
|
+
astreum/storage/setup.py,sha256=fnDZCxVskOAPDl-oTwq-iLiRCD3CKHOEgI4LALNJQWI,612
|
|
59
|
+
astreum/storage/actions/get.py,sha256=yf1HMYPMxRXTbZbSoe8JI6C4eWkcbScFQj-nGozBsCQ,6845
|
|
60
|
+
astreum/storage/actions/set.py,sha256=8MvlZS3MFvLc-apDb6mucxt1JBxw82lxMVoa0sTvdo8,5751
|
|
61
|
+
astreum/storage/models/atom.py,sha256=FY_bgtoju59Yo7TL1DTFTr9_pRMNBuH6-u59D6bz2fc,3163
|
|
62
|
+
astreum/storage/models/trie.py,sha256=Bn3ssPGI7YGS4iUH5ESvpG1NE6Ljx2Xo7wkEpQhjKUY,17587
|
|
63
|
+
astreum/utils/bytes.py,sha256=9QTWC2JCdwWLB5R2mPtmjPro0IUzE58DL3uEul4AheE,846
|
|
64
|
+
astreum/utils/config.py,sha256=jiobdNFiF44BMmoifAG3feq57ZPIhjUG4FG71cn-kgY,1527
|
|
65
|
+
astreum/utils/integer.py,sha256=iQt-klWOYVghu_NOT341MmHbOle4FDT3by4PNKNXscg,736
|
|
66
|
+
astreum/utils/logging.py,sha256=mRDtWSCj8vKt58WGKLNSkK9Oa0graNVSoS8URby4Q9g,6684
|
|
67
|
+
astreum-0.3.9.dist-info/licenses/LICENSE,sha256=gYBvRDP-cPLmTyJhvZ346QkrYW_eleke4Z2Yyyu43eQ,1089
|
|
68
|
+
astreum-0.3.9.dist-info/METADATA,sha256=vlvV1wwS4GiKwUQhpEg3FqJ_I_5m4efioshBzwhs4bk,7766
|
|
69
|
+
astreum-0.3.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
70
|
+
astreum-0.3.9.dist-info/top_level.txt,sha256=1EG1GmkOk3NPmUA98FZNdKouhRyget-KiFiMk0i2Uz0,8
|
|
71
|
+
astreum-0.3.9.dist-info/RECORD,,
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
from enum import IntEnum
|
|
2
|
-
from typing import Optional
|
|
3
|
-
from cryptography.hazmat.primitives import serialization
|
|
4
|
-
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PublicKey
|
|
5
|
-
|
|
6
|
-
class MessageTopic(IntEnum):
|
|
7
|
-
PING = 0
|
|
8
|
-
OBJECT_REQUEST = 1
|
|
9
|
-
OBJECT_RESPONSE = 2
|
|
10
|
-
ROUTE_REQUEST = 3
|
|
11
|
-
ROUTE_RESPONSE = 4
|
|
12
|
-
TRANSACTION = 5
|
|
13
|
-
STORAGE_REQUEST = 6
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Message:
|
|
17
|
-
handshake: bool
|
|
18
|
-
sender: Optional[X25519PublicKey]
|
|
19
|
-
|
|
20
|
-
topic: Optional[MessageTopic]
|
|
21
|
-
content: bytes
|
|
22
|
-
|
|
23
|
-
def __init__(
|
|
24
|
-
self,
|
|
25
|
-
*,
|
|
26
|
-
handshake: bool = False,
|
|
27
|
-
sender: Optional[X25519PublicKey] = None,
|
|
28
|
-
topic: Optional[MessageTopic] = None,
|
|
29
|
-
content: bytes = b"",
|
|
30
|
-
body: Optional[bytes] = None,
|
|
31
|
-
) -> None:
|
|
32
|
-
if body is not None:
|
|
33
|
-
if content and content != b"":
|
|
34
|
-
raise ValueError("specify only one of 'content' or 'body'")
|
|
35
|
-
content = body
|
|
36
|
-
|
|
37
|
-
self.handshake = handshake
|
|
38
|
-
self.sender = sender
|
|
39
|
-
self.topic = topic
|
|
40
|
-
self.content = content or b""
|
|
41
|
-
|
|
42
|
-
if self.handshake:
|
|
43
|
-
if self.sender is None:
|
|
44
|
-
raise ValueError("handshake Message requires a sender public key")
|
|
45
|
-
self.topic = None
|
|
46
|
-
self.content = b""
|
|
47
|
-
else:
|
|
48
|
-
if self.topic is None:
|
|
49
|
-
raise ValueError("non-handshake Message requires a topic")
|
|
50
|
-
|
|
51
|
-
def to_bytes(self):
|
|
52
|
-
if self.handshake:
|
|
53
|
-
# handshake byte (1) + raw public key bytes
|
|
54
|
-
return bytes([1]) + self.sender.public_bytes(
|
|
55
|
-
encoding=serialization.Encoding.Raw,
|
|
56
|
-
format=serialization.PublicFormat.Raw
|
|
57
|
-
)
|
|
58
|
-
else:
|
|
59
|
-
# normal message: 0 + topic + content
|
|
60
|
-
return bytes([0, self.topic.value]) + self.content
|
|
61
|
-
|
|
62
|
-
@classmethod
|
|
63
|
-
def from_bytes(cls, data: bytes) -> "Message":
|
|
64
|
-
if len(data) < 1:
|
|
65
|
-
raise ValueError("Cannot parse Message: no data")
|
|
66
|
-
flag = data[0]
|
|
67
|
-
# create empty instance
|
|
68
|
-
msg = cls.__new__(cls)
|
|
69
|
-
|
|
70
|
-
if flag == 1:
|
|
71
|
-
# handshake message: the rest is the peer’s public key
|
|
72
|
-
key_bytes = data[1:]
|
|
73
|
-
if not key_bytes:
|
|
74
|
-
raise ValueError("Handshake message missing sender public key bytes")
|
|
75
|
-
try:
|
|
76
|
-
sender = X25519PublicKey.from_public_bytes(key_bytes)
|
|
77
|
-
except ValueError:
|
|
78
|
-
raise ValueError("Invalid public key bytes")
|
|
79
|
-
if sender is None:
|
|
80
|
-
raise ValueError("Handshake message missing sender public key")
|
|
81
|
-
msg.handshake = True
|
|
82
|
-
msg.sender = sender
|
|
83
|
-
msg.topic = None
|
|
84
|
-
msg.content = b''
|
|
85
|
-
elif flag == 0:
|
|
86
|
-
# normal message: next byte is topic, rest is content
|
|
87
|
-
if len(data) < 2:
|
|
88
|
-
raise ValueError("Cannot parse Message: missing topic byte")
|
|
89
|
-
topic_val = data[1]
|
|
90
|
-
try:
|
|
91
|
-
topic = MessageTopic(topic_val)
|
|
92
|
-
except ValueError:
|
|
93
|
-
raise ValueError(f"Unknown MessageTopic: {topic_val}")
|
|
94
|
-
msg.handshake = False
|
|
95
|
-
msg.sender = None
|
|
96
|
-
msg.topic = topic
|
|
97
|
-
msg.content = data[2:]
|
|
98
|
-
else:
|
|
99
|
-
raise ValueError(f"Invalid handshake flag: {flag}")
|
|
100
|
-
|
|
101
|
-
return msg
|
astreum/_communication/peer.py
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey, X25519PublicKey
|
|
2
|
-
from cryptography.hazmat.primitives import serialization
|
|
3
|
-
from datetime import datetime, timezone
|
|
4
|
-
from typing import Optional, Tuple
|
|
5
|
-
|
|
6
|
-
class Peer:
|
|
7
|
-
shared_key: bytes
|
|
8
|
-
timestamp: datetime
|
|
9
|
-
latest_block: bytes
|
|
10
|
-
address: Optional[Tuple[str, int]]
|
|
11
|
-
public_key: X25519PublicKey
|
|
12
|
-
public_key_bytes: bytes
|
|
13
|
-
|
|
14
|
-
def __init__(self, my_sec_key: X25519PrivateKey, peer_pub_key: X25519PublicKey):
|
|
15
|
-
self.shared_key = my_sec_key.exchange(peer_pub_key)
|
|
16
|
-
self.timestamp = datetime.now(timezone.utc)
|
|
17
|
-
self.latest_block = b""
|
|
18
|
-
self.address = None
|
|
19
|
-
self.public_key = peer_pub_key
|
|
20
|
-
self.public_key_bytes = peer_pub_key.public_bytes(
|
|
21
|
-
encoding=serialization.Encoding.Raw,
|
|
22
|
-
format=serialization.PublicFormat.Raw,
|
|
23
|
-
)
|