astreum 0.2.38__tar.gz → 0.2.39__tar.gz
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.
Potentially problematic release.
This version of astreum might be problematic. Click here for more details.
- {astreum-0.2.38/src/astreum.egg-info → astreum-0.2.39}/PKG-INFO +1 -1
- {astreum-0.2.38 → astreum-0.2.39}/pyproject.toml +1 -1
- {astreum-0.2.38/src/astreum/_validation → astreum-0.2.39/src/astreum/_consensus}/__init__.py +6 -4
- {astreum-0.2.38/src/astreum/_validation → astreum-0.2.39/src/astreum/_consensus}/setup.py +2 -14
- astreum-0.2.39/src/astreum/_consensus/transaction.py +172 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_node.py +3 -3
- {astreum-0.2.38 → astreum-0.2.39/src/astreum.egg-info}/PKG-INFO +1 -1
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum.egg-info/SOURCES.txt +7 -6
- {astreum-0.2.38 → astreum-0.2.39}/LICENSE +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/README.md +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/setup.cfg +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_communication/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_communication/peer.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_communication/route.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_communication/setup.py +0 -0
- {astreum-0.2.38/src/astreum/_validation → astreum-0.2.39/src/astreum/_consensus}/block.py +0 -0
- {astreum-0.2.38/src/astreum/_validation → astreum-0.2.39/src/astreum/_consensus}/chain.py +0 -0
- {astreum-0.2.38/src/astreum/_validation → astreum-0.2.39/src/astreum/_consensus}/fork.py +0 -0
- {astreum-0.2.38/src/astreum/_validation → astreum-0.2.39/src/astreum/_consensus}/genesis.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/environment.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/expression.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/high_evaluation.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/low_evaluation.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/meter.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/parser.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_lispeum/tokenizer.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_storage/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/_storage/atom.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/crypto/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/crypto/ed25519.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/crypto/quadratic_form.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/crypto/wesolowski.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/crypto/x25519.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/format.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/lispeum/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/lispeum/environment.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/lispeum/expression.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/lispeum/parser.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/lispeum/tokenizer.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/account.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/accounts.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/block.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/merkle.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/message.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/patricia.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/models/transaction.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/node.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/relay/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/relay/peer.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/relay/route.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/relay/setup.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/storage/__init__.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/storage/object.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum/storage/setup.py +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum.egg-info/dependency_links.txt +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum.egg-info/requires.txt +0 -0
- {astreum-0.2.38 → astreum-0.2.39}/src/astreum.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: astreum
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.39
|
|
4
4
|
Summary: Python library to interact with the Astreum blockchain and its Lispeum virtual machine.
|
|
5
5
|
Author-email: "Roy R. O. Okello" <roy@stelar.xyz>
|
|
6
6
|
Project-URL: Homepage, https://github.com/astreum/lib
|
{astreum-0.2.38/src/astreum/_validation → astreum-0.2.39/src/astreum/_consensus}/__init__.py
RENAMED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from .block import Block
|
|
2
2
|
from .chain import Chain
|
|
3
3
|
from .fork import Fork
|
|
4
|
-
from .
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
from .transaction import Transaction
|
|
5
|
+
from .setup import consensus_setup
|
|
6
|
+
|
|
7
|
+
|
|
7
8
|
__all__ = [
|
|
8
9
|
"Block",
|
|
9
10
|
"Chain",
|
|
10
11
|
"Fork",
|
|
11
|
-
"
|
|
12
|
+
"Transaction",
|
|
13
|
+
"consensus_setup",
|
|
12
14
|
]
|
|
@@ -2,28 +2,16 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import threading
|
|
4
4
|
import time
|
|
5
|
-
from dataclasses import dataclass
|
|
6
5
|
from queue import Empty, Queue
|
|
7
6
|
from typing import Any, Dict, Optional, Tuple
|
|
8
7
|
|
|
9
|
-
from cryptography.hazmat.primitives import serialization
|
|
10
|
-
|
|
11
8
|
from .block import Block
|
|
12
9
|
from .chain import Chain
|
|
13
10
|
from .fork import Fork
|
|
11
|
+
from .transaction import Transaction
|
|
14
12
|
from .._storage.atom import ZERO32, Atom
|
|
15
13
|
|
|
16
14
|
|
|
17
|
-
@dataclass
|
|
18
|
-
class Transaction:
|
|
19
|
-
"""Lightweight transaction view for validation processing."""
|
|
20
|
-
|
|
21
|
-
recipient: bytes
|
|
22
|
-
sender: bytes
|
|
23
|
-
amount: int
|
|
24
|
-
counter: int
|
|
25
|
-
|
|
26
|
-
|
|
27
15
|
def current_validator(node: Any) -> bytes:
|
|
28
16
|
"""Return the current validator identifier. Override downstream."""
|
|
29
17
|
raise NotImplementedError("current_validator must be implemented by the host node")
|
|
@@ -34,7 +22,7 @@ def apply_transaction(node: Any, block: object, transaction_hash: bytes) -> None
|
|
|
34
22
|
pass
|
|
35
23
|
|
|
36
24
|
|
|
37
|
-
def
|
|
25
|
+
def consensus_setup(node: Any) -> None:
|
|
38
26
|
# Shared state
|
|
39
27
|
node.validation_lock = getattr(node, "validation_lock", threading.RLock())
|
|
40
28
|
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Callable, List, Optional, Tuple
|
|
5
|
+
|
|
6
|
+
from .._storage.atom import Atom, ZERO32
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _int_to_be_bytes(value: Optional[int]) -> bytes:
|
|
10
|
+
if value is None:
|
|
11
|
+
return b""
|
|
12
|
+
value = int(value)
|
|
13
|
+
if value == 0:
|
|
14
|
+
return b"\x00"
|
|
15
|
+
size = (value.bit_length() + 7) // 8
|
|
16
|
+
return value.to_bytes(size, "big")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _be_bytes_to_int(data: Optional[bytes]) -> int:
|
|
20
|
+
if not data:
|
|
21
|
+
return 0
|
|
22
|
+
return int.from_bytes(data, "big")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _make_typed_bytes(payload: bytes) -> Tuple[bytes, List[Atom]]:
|
|
26
|
+
value_atom = Atom.from_data(data=payload)
|
|
27
|
+
type_atom = Atom.from_data(data=b"byte", next_hash=value_atom.object_id())
|
|
28
|
+
return type_atom.object_id(), [value_atom, type_atom]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _make_list(child_ids: List[bytes]) -> Tuple[bytes, List[Atom]]:
|
|
32
|
+
atoms: List[Atom] = []
|
|
33
|
+
next_hash = ZERO32
|
|
34
|
+
chain: List[Atom] = []
|
|
35
|
+
for child_id in reversed(child_ids):
|
|
36
|
+
elem = Atom.from_data(data=child_id, next_hash=next_hash)
|
|
37
|
+
next_hash = elem.object_id()
|
|
38
|
+
chain.append(elem)
|
|
39
|
+
|
|
40
|
+
chain.reverse()
|
|
41
|
+
list_value = Atom.from_data(data=len(child_ids).to_bytes(8, "little"), next_hash=next_hash)
|
|
42
|
+
list_type = Atom.from_data(data=b"list", next_hash=list_value.object_id())
|
|
43
|
+
atoms.extend(chain)
|
|
44
|
+
atoms.append(list_value)
|
|
45
|
+
atoms.append(list_type)
|
|
46
|
+
return list_type.object_id(), atoms
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass
|
|
50
|
+
class Transaction:
|
|
51
|
+
amount: int
|
|
52
|
+
counter: int
|
|
53
|
+
data: bytes = b""
|
|
54
|
+
recipient: bytes = b""
|
|
55
|
+
sender: bytes = b""
|
|
56
|
+
signature: bytes = b""
|
|
57
|
+
|
|
58
|
+
def to_atom(self) -> Tuple[bytes, List[Atom]]:
|
|
59
|
+
"""Serialise the transaction, returning (object_id, atoms)."""
|
|
60
|
+
body_child_ids: List[bytes] = []
|
|
61
|
+
acc: List[Atom] = []
|
|
62
|
+
|
|
63
|
+
def emit(payload: bytes) -> None:
|
|
64
|
+
oid, atoms = _make_typed_bytes(payload)
|
|
65
|
+
body_child_ids.append(oid)
|
|
66
|
+
acc.extend(atoms)
|
|
67
|
+
|
|
68
|
+
emit(_int_to_be_bytes(self.amount))
|
|
69
|
+
emit(_int_to_be_bytes(self.counter))
|
|
70
|
+
emit(bytes(self.data))
|
|
71
|
+
emit(bytes(self.recipient))
|
|
72
|
+
emit(bytes(self.sender))
|
|
73
|
+
|
|
74
|
+
body_id, body_atoms = _make_list(body_child_ids)
|
|
75
|
+
acc.extend(body_atoms)
|
|
76
|
+
|
|
77
|
+
type_atom = Atom.from_data(data=b"transaction", next_hash=body_id)
|
|
78
|
+
signature_atom = Atom.from_data(data=bytes(self.signature))
|
|
79
|
+
|
|
80
|
+
top_list_id, top_atoms = _make_list(
|
|
81
|
+
[type_atom.object_id(), body_id, signature_atom.object_id()]
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
atoms: List[Atom] = acc
|
|
85
|
+
atoms.append(type_atom)
|
|
86
|
+
atoms.append(signature_atom)
|
|
87
|
+
atoms.extend(top_atoms)
|
|
88
|
+
return top_list_id, atoms
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def from_atom(
|
|
92
|
+
cls,
|
|
93
|
+
storage_get: Callable[[bytes], Optional[Atom]],
|
|
94
|
+
transaction_id: bytes,
|
|
95
|
+
) -> Transaction:
|
|
96
|
+
top_type_atom = storage_get(transaction_id)
|
|
97
|
+
if top_type_atom is None or top_type_atom.data != b"list":
|
|
98
|
+
raise ValueError("not a transaction (outer list missing)")
|
|
99
|
+
|
|
100
|
+
top_value_atom = storage_get(top_type_atom.next)
|
|
101
|
+
if top_value_atom is None:
|
|
102
|
+
raise ValueError("malformed transaction (outer value missing)")
|
|
103
|
+
|
|
104
|
+
head = top_value_atom.next
|
|
105
|
+
first_elem = storage_get(head)
|
|
106
|
+
if first_elem is None:
|
|
107
|
+
raise ValueError("malformed transaction (type element missing)")
|
|
108
|
+
|
|
109
|
+
type_atom_id = first_elem.data
|
|
110
|
+
type_atom = storage_get(type_atom_id)
|
|
111
|
+
if type_atom is None or type_atom.data != b"transaction":
|
|
112
|
+
raise ValueError("not a transaction (type mismatch)")
|
|
113
|
+
|
|
114
|
+
def read_list_entries(start: bytes) -> List[bytes]:
|
|
115
|
+
entries: List[bytes] = []
|
|
116
|
+
current = start if start != ZERO32 else b""
|
|
117
|
+
while current:
|
|
118
|
+
elem = storage_get(current)
|
|
119
|
+
if elem is None:
|
|
120
|
+
break
|
|
121
|
+
entries.append(elem.data)
|
|
122
|
+
nxt = elem.next
|
|
123
|
+
current = nxt if nxt != ZERO32 else b""
|
|
124
|
+
return entries
|
|
125
|
+
|
|
126
|
+
remainder_entries = read_list_entries(first_elem.next)
|
|
127
|
+
if len(remainder_entries) < 2:
|
|
128
|
+
raise ValueError("malformed transaction (body/signature missing)")
|
|
129
|
+
|
|
130
|
+
body_id, signature_atom_id = remainder_entries[0], remainder_entries[1]
|
|
131
|
+
|
|
132
|
+
body_type_atom = storage_get(body_id)
|
|
133
|
+
if body_type_atom is None or body_type_atom.data != b"list":
|
|
134
|
+
raise ValueError("malformed transaction body (type)")
|
|
135
|
+
|
|
136
|
+
body_value_atom = storage_get(body_type_atom.next)
|
|
137
|
+
if body_value_atom is None:
|
|
138
|
+
raise ValueError("malformed transaction body (value)")
|
|
139
|
+
|
|
140
|
+
body_entries = read_list_entries(body_value_atom.next)
|
|
141
|
+
if len(body_entries) < 5:
|
|
142
|
+
body_entries.extend([ZERO32] * (5 - len(body_entries)))
|
|
143
|
+
|
|
144
|
+
def read_typed_bytes(entry_id: bytes) -> bytes:
|
|
145
|
+
if not entry_id or entry_id == ZERO32:
|
|
146
|
+
return b""
|
|
147
|
+
elem = storage_get(entry_id)
|
|
148
|
+
if elem is None:
|
|
149
|
+
return b""
|
|
150
|
+
type_atom = storage_get(elem.data)
|
|
151
|
+
if type_atom is None or type_atom.data != b"byte":
|
|
152
|
+
return b""
|
|
153
|
+
value_atom = storage_get(type_atom.next)
|
|
154
|
+
return value_atom.data if value_atom is not None else b""
|
|
155
|
+
|
|
156
|
+
amount_bytes = read_typed_bytes(body_entries[0])
|
|
157
|
+
counter_bytes = read_typed_bytes(body_entries[1])
|
|
158
|
+
data_bytes = read_typed_bytes(body_entries[2])
|
|
159
|
+
recipient_bytes = read_typed_bytes(body_entries[3])
|
|
160
|
+
sender_bytes = read_typed_bytes(body_entries[4])
|
|
161
|
+
|
|
162
|
+
signature_atom = storage_get(signature_atom_id)
|
|
163
|
+
signature_bytes = signature_atom.data if signature_atom is not None else b""
|
|
164
|
+
|
|
165
|
+
return cls(
|
|
166
|
+
amount=_be_bytes_to_int(amount_bytes),
|
|
167
|
+
counter=_be_bytes_to_int(counter_bytes),
|
|
168
|
+
data=data_bytes,
|
|
169
|
+
recipient=recipient_bytes,
|
|
170
|
+
sender=sender_bytes,
|
|
171
|
+
signature=signature_bytes,
|
|
172
|
+
)
|
|
@@ -25,9 +25,9 @@ class Node:
|
|
|
25
25
|
communication_setup(node=self, config=config)
|
|
26
26
|
except Exception:
|
|
27
27
|
pass
|
|
28
|
-
try:
|
|
29
|
-
from astreum.
|
|
30
|
-
|
|
28
|
+
try:
|
|
29
|
+
from astreum._consensus import consensus_setup # type: ignore
|
|
30
|
+
consensus_setup(node=self)
|
|
31
31
|
except Exception:
|
|
32
32
|
pass
|
|
33
33
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: astreum
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.39
|
|
4
4
|
Summary: Python library to interact with the Astreum blockchain and its Lispeum virtual machine.
|
|
5
5
|
Author-email: "Roy R. O. Okello" <roy@stelar.xyz>
|
|
6
6
|
Project-URL: Homepage, https://github.com/astreum/lib
|
|
@@ -14,6 +14,13 @@ src/astreum/_communication/__init__.py
|
|
|
14
14
|
src/astreum/_communication/peer.py
|
|
15
15
|
src/astreum/_communication/route.py
|
|
16
16
|
src/astreum/_communication/setup.py
|
|
17
|
+
src/astreum/_consensus/__init__.py
|
|
18
|
+
src/astreum/_consensus/block.py
|
|
19
|
+
src/astreum/_consensus/chain.py
|
|
20
|
+
src/astreum/_consensus/fork.py
|
|
21
|
+
src/astreum/_consensus/genesis.py
|
|
22
|
+
src/astreum/_consensus/setup.py
|
|
23
|
+
src/astreum/_consensus/transaction.py
|
|
17
24
|
src/astreum/_lispeum/__init__.py
|
|
18
25
|
src/astreum/_lispeum/environment.py
|
|
19
26
|
src/astreum/_lispeum/expression.py
|
|
@@ -24,12 +31,6 @@ src/astreum/_lispeum/parser.py
|
|
|
24
31
|
src/astreum/_lispeum/tokenizer.py
|
|
25
32
|
src/astreum/_storage/__init__.py
|
|
26
33
|
src/astreum/_storage/atom.py
|
|
27
|
-
src/astreum/_validation/__init__.py
|
|
28
|
-
src/astreum/_validation/block.py
|
|
29
|
-
src/astreum/_validation/chain.py
|
|
30
|
-
src/astreum/_validation/fork.py
|
|
31
|
-
src/astreum/_validation/genesis.py
|
|
32
|
-
src/astreum/_validation/setup.py
|
|
33
34
|
src/astreum/crypto/__init__.py
|
|
34
35
|
src/astreum/crypto/ed25519.py
|
|
35
36
|
src/astreum/crypto/quadratic_form.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|