astreum 0.2.37__tar.gz → 0.2.38__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.

Files changed (59) hide show
  1. {astreum-0.2.37/src/astreum.egg-info → astreum-0.2.38}/PKG-INFO +1 -1
  2. {astreum-0.2.37 → astreum-0.2.38}/pyproject.toml +1 -1
  3. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_communication/setup.py +14 -5
  4. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_validation/setup.py +81 -1
  5. {astreum-0.2.37 → astreum-0.2.38/src/astreum.egg-info}/PKG-INFO +1 -1
  6. {astreum-0.2.37 → astreum-0.2.38}/LICENSE +0 -0
  7. {astreum-0.2.37 → astreum-0.2.38}/README.md +0 -0
  8. {astreum-0.2.37 → astreum-0.2.38}/setup.cfg +0 -0
  9. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/__init__.py +0 -0
  10. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_communication/__init__.py +0 -0
  11. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_communication/peer.py +0 -0
  12. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_communication/route.py +0 -0
  13. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/__init__.py +0 -0
  14. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/environment.py +0 -0
  15. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/expression.py +0 -0
  16. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/high_evaluation.py +0 -0
  17. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/low_evaluation.py +0 -0
  18. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/meter.py +0 -0
  19. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/parser.py +0 -0
  20. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_lispeum/tokenizer.py +0 -0
  21. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_node.py +0 -0
  22. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_storage/__init__.py +0 -0
  23. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_storage/atom.py +0 -0
  24. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_validation/__init__.py +0 -0
  25. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_validation/block.py +0 -0
  26. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_validation/chain.py +0 -0
  27. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_validation/fork.py +0 -0
  28. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/_validation/genesis.py +0 -0
  29. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/crypto/__init__.py +0 -0
  30. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/crypto/ed25519.py +0 -0
  31. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/crypto/quadratic_form.py +0 -0
  32. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/crypto/wesolowski.py +0 -0
  33. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/crypto/x25519.py +0 -0
  34. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/format.py +0 -0
  35. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/lispeum/__init__.py +0 -0
  36. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/lispeum/environment.py +0 -0
  37. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/lispeum/expression.py +0 -0
  38. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/lispeum/parser.py +0 -0
  39. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/lispeum/tokenizer.py +0 -0
  40. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/__init__.py +0 -0
  41. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/account.py +0 -0
  42. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/accounts.py +0 -0
  43. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/block.py +0 -0
  44. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/merkle.py +0 -0
  45. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/message.py +0 -0
  46. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/patricia.py +0 -0
  47. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/models/transaction.py +0 -0
  48. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/node.py +0 -0
  49. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/relay/__init__.py +0 -0
  50. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/relay/peer.py +0 -0
  51. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/relay/route.py +0 -0
  52. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/relay/setup.py +0 -0
  53. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/storage/__init__.py +0 -0
  54. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/storage/object.py +0 -0
  55. {astreum-0.2.37 → astreum-0.2.38}/src/astreum/storage/setup.py +0 -0
  56. {astreum-0.2.37 → astreum-0.2.38}/src/astreum.egg-info/SOURCES.txt +0 -0
  57. {astreum-0.2.37 → astreum-0.2.38}/src/astreum.egg-info/dependency_links.txt +0 -0
  58. {astreum-0.2.37 → astreum-0.2.38}/src/astreum.egg-info/requires.txt +0 -0
  59. {astreum-0.2.37 → astreum-0.2.38}/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.37
3
+ Version: 0.2.38
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "astreum"
3
- version = "0.2.37"
3
+ version = "0.2.38"
4
4
  authors = [
5
5
  { name="Roy R. O. Okello", email="roy@stelar.xyz" },
6
6
  ]
@@ -1,7 +1,8 @@
1
1
  import socket, threading
2
2
  from queue import Queue
3
3
  from typing import Tuple, Optional
4
- from cryptography.hazmat.primitives.asymmetric import ed25519
4
+ from cryptography.hazmat.primitives.asymmetric import ed25519
5
+ from cryptography.hazmat.primitives import serialization
5
6
  from cryptography.hazmat.primitives.asymmetric.x25519 import (
6
7
  X25519PrivateKey,
7
8
  X25519PublicKey,
@@ -67,10 +68,18 @@ def communication_setup(node: "Node", config: dict):
67
68
 
68
69
  # key loading
69
70
  node.relay_secret_key = load_x25519(config.get('relay_secret_key'))
70
- node.validation_secret_key = load_ed25519(config.get('validation_secret_key'))
71
-
72
- # derive pubs + routes
73
- node.relay_public_key = node.relay_secret_key.public_key()
71
+ node.validation_secret_key = load_ed25519(config.get('validation_secret_key'))
72
+
73
+ # derive pubs + routes
74
+ node.relay_public_key = node.relay_secret_key.public_key()
75
+ node.validation_public_key = (
76
+ node.validation_secret_key.public_key().public_bytes(
77
+ encoding=serialization.Encoding.Raw,
78
+ format=serialization.PublicFormat.Raw,
79
+ )
80
+ if node.validation_secret_key
81
+ else None
82
+ )
74
83
  node.peer_route, node.validation_route = make_routes(
75
84
  node.relay_public_key,
76
85
  node.validation_secret_key
@@ -2,15 +2,38 @@ from __future__ import annotations
2
2
 
3
3
  import threading
4
4
  import time
5
- from queue import Queue, Empty
5
+ from dataclasses import dataclass
6
+ from queue import Empty, Queue
6
7
  from typing import Any, Dict, Optional, Tuple
7
8
 
9
+ from cryptography.hazmat.primitives import serialization
10
+
8
11
  from .block import Block
9
12
  from .chain import Chain
10
13
  from .fork import Fork
11
14
  from .._storage.atom import ZERO32, Atom
12
15
 
13
16
 
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
+ def current_validator(node: Any) -> bytes:
28
+ """Return the current validator identifier. Override downstream."""
29
+ raise NotImplementedError("current_validator must be implemented by the host node")
30
+
31
+
32
+ def apply_transaction(node: Any, block: object, transaction_hash: bytes) -> None:
33
+ """Apply transaction to the candidate block. Override downstream."""
34
+ pass
35
+
36
+
14
37
  def validation_setup(node: Any) -> None:
15
38
  # Shared state
16
39
  node.validation_lock = getattr(node, "validation_lock", threading.RLock())
@@ -21,6 +44,10 @@ def validation_setup(node: Any) -> None:
21
44
  node.chains = getattr(node, "chains", {})
22
45
  node.forks = getattr(node, "forks", {})
23
46
 
47
+ # Pending transactions queue (hash-only entries)
48
+ node._validation_transaction_queue = getattr(
49
+ node, "_validation_transaction_queue", Queue()
50
+ )
24
51
  # Single work queue of grouped items: (latest_block_hash, set(peer_ids))
25
52
  node._validation_verify_queue = getattr(
26
53
  node, "_validation_verify_queue", Queue()
@@ -29,6 +56,14 @@ def validation_setup(node: Any) -> None:
29
56
  node, "_validation_stop_event", threading.Event()
30
57
  )
31
58
 
59
+ def enqueue_transaction_hash(tx_hash: bytes) -> None:
60
+ """Schedule a transaction hash for validation processing."""
61
+ if not isinstance(tx_hash, (bytes, bytearray)):
62
+ raise TypeError("transaction hash must be bytes-like")
63
+ node._validation_transaction_queue.put(bytes(tx_hash))
64
+
65
+ node.enqueue_transaction_hash = enqueue_transaction_hash
66
+
32
67
  def _process_peers_latest_block(latest_block_hash: bytes, peer_ids: set[Any]) -> None:
33
68
  """Assign a peer to a fork for its latest block without merging forks.
34
69
 
@@ -130,6 +165,46 @@ def validation_setup(node: Any) -> None:
130
165
  except Exception:
131
166
  pass
132
167
 
168
+ def _validation_worker() -> None:
169
+ """Consume pending transactions when scheduled to validate."""
170
+ stop = node._validation_stop_event
171
+ while not stop.is_set():
172
+ validation_public_key = getattr(node, "validation_public_key", None)
173
+ if not validation_public_key:
174
+ time.sleep(0.5)
175
+ continue
176
+
177
+ scheduled_validator = current_validator(node)
178
+
179
+ if scheduled_validator != validation_public_key:
180
+ time.sleep(0.5)
181
+ continue
182
+
183
+ try:
184
+ current_hash = node._validation_transaction_queue.get_nowait()
185
+ except Empty:
186
+ time.sleep(0.1)
187
+ continue
188
+
189
+ new_block = Block()
190
+ new_block.validator_public_key = getattr(node, "validation_public_key", None)
191
+
192
+ while True:
193
+ try:
194
+ apply_transaction(node, new_block, current_hash)
195
+ except NotImplementedError:
196
+ node._validation_transaction_queue.put(current_hash)
197
+ time.sleep(0.5)
198
+ break
199
+ except Exception:
200
+ # Skip problematic transaction; leave block as-is.
201
+ pass
202
+
203
+ try:
204
+ current_hash = node._validation_transaction_queue.get_nowait()
205
+ except Empty:
206
+ break
207
+
133
208
  # Start workers as daemons
134
209
  node.validation_discovery_thread = threading.Thread(
135
210
  target=_discovery_worker, daemon=True, name="validation-discovery"
@@ -137,5 +212,10 @@ def validation_setup(node: Any) -> None:
137
212
  node.validation_verify_thread = threading.Thread(
138
213
  target=_verify_worker, daemon=True, name="validation-verify"
139
214
  )
215
+ node.validation_worker_thread = threading.Thread(
216
+ target=_validation_worker, daemon=True, name="validation-worker"
217
+ )
140
218
  node.validation_discovery_thread.start()
141
219
  node.validation_verify_thread.start()
220
+ if getattr(node, "validation_secret_key", None):
221
+ node.validation_worker_thread.start()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astreum
3
- Version: 0.2.37
3
+ Version: 0.2.38
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes