astreum 0.2.4__py3-none-any.whl → 0.2.5__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.

Potentially problematic release.


This version of astreum might be problematic. Click here for more details.

Files changed (44) hide show
  1. {astreum-0.2.4.dist-info → astreum-0.2.5.dist-info}/METADATA +1 -1
  2. astreum-0.2.5.dist-info/RECORD +18 -0
  3. astreum/_node/relay/__init__.py +0 -371
  4. astreum/_node/relay/bucket.py +0 -90
  5. astreum/_node/relay/envelope.py +0 -280
  6. astreum/_node/relay/message.py +0 -110
  7. astreum/_node/relay/peer.py +0 -174
  8. astreum/_node/relay/route.py +0 -161
  9. astreum/_node/storage/storage.py +0 -253
  10. astreum/_node/storage/utils.py +0 -137
  11. astreum/_node/utils.py +0 -34
  12. astreum/_node/validation/__init__.py +0 -0
  13. astreum/_node/validation/_block/__init__.py +0 -0
  14. astreum/_node/validation/_block/create.py +0 -98
  15. astreum/_node/validation/_block/model.py +0 -81
  16. astreum/_node/validation/_block/validate.py +0 -196
  17. astreum/_node/validation/account.py +0 -99
  18. astreum/_node/validation/block.py +0 -21
  19. astreum/_node/validation/constants.py +0 -15
  20. astreum/_node/validation/stake.py +0 -229
  21. astreum/_node/validation/transaction.py +0 -146
  22. astreum/_node/validation/vdf.py +0 -80
  23. astreum/lispeum/expression.py +0 -95
  24. astreum/lispeum/special/__init__.py +0 -0
  25. astreum/lispeum/special/definition.py +0 -27
  26. astreum/lispeum/special/list/__init__.py +0 -0
  27. astreum/lispeum/special/list/all.py +0 -32
  28. astreum/lispeum/special/list/any.py +0 -32
  29. astreum/lispeum/special/list/fold.py +0 -29
  30. astreum/lispeum/special/list/get.py +0 -20
  31. astreum/lispeum/special/list/insert.py +0 -23
  32. astreum/lispeum/special/list/map.py +0 -30
  33. astreum/lispeum/special/list/position.py +0 -33
  34. astreum/lispeum/special/list/remove.py +0 -22
  35. astreum/lispeum/special/number/__init__.py +0 -0
  36. astreum/lispeum/special/number/addition.py +0 -0
  37. astreum/lispeum/storage.py +0 -410
  38. astreum/machine/__init__.py +0 -352
  39. astreum/machine/environment.py +0 -4
  40. astreum/machine/error.py +0 -0
  41. astreum-0.2.4.dist-info/RECORD +0 -56
  42. {astreum-0.2.4.dist-info → astreum-0.2.5.dist-info}/WHEEL +0 -0
  43. {astreum-0.2.4.dist-info → astreum-0.2.5.dist-info}/licenses/LICENSE +0 -0
  44. {astreum-0.2.4.dist-info → astreum-0.2.5.dist-info}/top_level.txt +0 -0
@@ -1,146 +0,0 @@
1
- from typing import Optional
2
- import time
3
- from .account import Account, get_account_from_storage
4
- import astreum.format as format
5
-
6
- class Transaction:
7
- def __init__(
8
- self,
9
- sender: Account,
10
- recipient: Account,
11
- amount: int,
12
- data: bytes = None,
13
- counter: int = 0
14
- ):
15
- self.sender = sender
16
- self.recipient = recipient
17
- self.amount = amount
18
- self.data = data
19
- self.counter = counter
20
- self.timestamp = time.time()
21
- self.signature = None
22
-
23
- @classmethod
24
- def from_bytes(cls, data: bytes, resolve_accounts: bool = False, accounts=None, storage=None) -> 'Transaction':
25
- """
26
- Deserialize a Transaction from its byte representation.
27
-
28
- Expected format: [sender_hash, recipient_hash, amount, data, counter, timestamp, signature]
29
-
30
- Args:
31
- data: Serialized transaction data
32
- resolve_accounts: If True, attempts to resolve account objects from storage
33
- accounts: Accounts instance (required if resolve_accounts is True)
34
- storage: Storage instance (required if resolve_accounts is True)
35
-
36
- Returns:
37
- Transaction object
38
- """
39
- decoded = format.decode(data)
40
- sender_public_key, recipient_public_key, amount, tx_data, counter, timestamp, signature = decoded
41
-
42
- sender_account = None
43
- recipient_account = None
44
-
45
- if resolve_accounts:
46
- if accounts is None or storage is None:
47
- raise ValueError("Both accounts and storage must be provided when resolve_accounts is True")
48
- sender_account = get_account_from_storage(sender_public_key, accounts, storage)
49
- recipient_account = get_account_from_storage(recipient_public_key, accounts, storage)
50
- else:
51
- # Create minimal Account objects with just the public keys
52
- sender_account = Account(sender_public_key, 0, b'', 0, b'')
53
- recipient_account = Account(recipient_public_key, 0, b'', 0, b'')
54
-
55
- transaction = cls(sender_account, recipient_account, amount, tx_data, counter)
56
- transaction.timestamp = timestamp
57
- transaction.signature = signature
58
- return transaction
59
-
60
- def to_bytes(self) -> bytes:
61
- """
62
- Serialize the Transaction into bytes.
63
-
64
- Format: [sender_hash, recipient_hash, amount, data, counter, timestamp, signature]
65
- """
66
- return format.encode([
67
- self.sender.public_key,
68
- self.recipient.public_key,
69
- self.amount,
70
- self.data,
71
- self.counter,
72
- self.timestamp,
73
- self.signature
74
- ])
75
-
76
-
77
- def get_tx_from_storage(hash: bytes) -> Optional[Transaction]:
78
- """Resolves storage objects to get a transaction.
79
-
80
- Args:
81
- hash: Hash of the transaction and merkle root of the transaction
82
-
83
- Returns:
84
- Transaction object if found, None otherwise
85
- """
86
- return None
87
-
88
-
89
- def put_tx_to_storage(transaction: Transaction):
90
- """Puts a transaction into storage.
91
-
92
- Args:
93
- transaction: Transaction object to put into storage
94
-
95
- Returns:
96
- None
97
- """
98
- return None
99
-
100
-
101
- def get_tx_hash(transaction: Transaction) -> bytes:
102
- """Get the hash of a transaction.
103
-
104
- Args:
105
- transaction: Transaction object to get hash for
106
-
107
- Returns:
108
- Merkle root of the transaction body hash and signature
109
- """
110
- return hash_data(get_tx_body_hash(transaction) + hash_data(transaction.signature))
111
-
112
- def get_tx_body_hash(transaction: Transaction) -> bytes:
113
- """Get the hash of the transaction body.
114
-
115
- Args:
116
- transaction: Transaction object to get hash for
117
-
118
- Returns:
119
- Hash of the transaction body
120
- """
121
- return hash_data(transaction)
122
-
123
- def sign_tx(transaction: Transaction, private_key: bytes) -> Transaction:
124
- """Sign a transaction.
125
-
126
- Args:
127
- transaction: Transaction object to sign
128
- private_key: Private key to sign with
129
-
130
- Returns:
131
- Signed transaction
132
- """
133
- transaction.signature = hash_data(get_tx_body_hash(transaction) + private_key)
134
- return transaction
135
-
136
-
137
- def verify_tx(transaction: Transaction) -> bool:
138
- """Verify a transaction.
139
-
140
- Args:
141
- transaction: Transaction object to verify,with sender public key
142
-
143
- Returns:
144
- True if the transaction is valid, False otherwise
145
- """
146
- return True
@@ -1,80 +0,0 @@
1
- """
2
- Verifiable Delay Function (VDF) implementation for Astreum.
3
-
4
- This module provides functionality for computing and verifying VDFs,
5
- which are used in the consensus mechanism to create artificial time delays.
6
- """
7
-
8
- import time
9
- import hashlib
10
- from typing import Optional
11
- from .constants import VDF_DIFFICULTY
12
-
13
-
14
- def compute_vdf(input_data: bytes, difficulty: Optional[int] = None) -> bytes:
15
- """
16
- Compute VDF output for given input data.
17
-
18
- Args:
19
- input_data: Input data for VDF
20
- difficulty: VDF difficulty level (if None, uses default)
21
-
22
- Returns:
23
- VDF output
24
- """
25
- if difficulty is None:
26
- difficulty = VDF_DIFFICULTY
27
-
28
- # Simple VDF implementation
29
- # In a real implementation, this would be a proper VDF algorithm
30
- # like Wesolowski VDF or Pietrzak VDF
31
-
32
- # For this implementation, we'll use a simple hash-based time delay
33
- result = input_data
34
- for _ in range(difficulty):
35
- result = hashlib.sha256(result).digest()
36
-
37
- return result
38
-
39
-
40
- def verify_vdf(input_data: bytes, output: bytes, difficulty: Optional[int] = None) -> bool:
41
- """
42
- Verify VDF computation.
43
-
44
- Args:
45
- input_data: Input data for VDF
46
- output: Purported VDF output
47
- difficulty: VDF difficulty level (if None, uses default)
48
-
49
- Returns:
50
- True if output is valid, False otherwise
51
- """
52
- if difficulty is None:
53
- difficulty = VDF_DIFFICULTY
54
-
55
- # Compute expected output and compare
56
- expected = compute_vdf(input_data, difficulty)
57
- return expected == output
58
-
59
-
60
- def validate_block_vdf(block_number: int, previous_hash: bytes, vdf_proof: bytes) -> bool:
61
- """
62
- Validate the VDF proof for a block.
63
-
64
- Args:
65
- block_number: Block number
66
- previous_hash: Hash of previous block
67
- vdf_proof: VDF proof to validate
68
-
69
- Returns:
70
- True if VDF proof is valid, False otherwise
71
- """
72
- # Skip VDF validation for genesis block
73
- if block_number == 0:
74
- return True
75
-
76
- # Compute expected input for the VDF
77
- vdf_input = previous_hash
78
-
79
- # Verify the VDF
80
- return verify_vdf(vdf_input, vdf_proof)
@@ -1,95 +0,0 @@
1
- from typing import List, Union
2
-
3
- class Expr:
4
- class ListExpr:
5
- def __init__(self, elements: List['Expr']):
6
- self.elements = elements
7
-
8
- def __eq__(self, other):
9
- if not isinstance(other, Expr.ListExpr):
10
- return NotImplemented
11
- return self.elements == other.elements
12
-
13
- def __ne__(self, other):
14
- return not self.__eq__(other)
15
-
16
- @property
17
- def value(self):
18
- inner = " ".join(str(e) for e in self.elements)
19
- return f"({inner})"
20
-
21
-
22
- def __repr__(self):
23
- if not self.elements:
24
- return "()"
25
-
26
- inner = " ".join(str(e) for e in self.elements)
27
- return f"({inner})"
28
-
29
- def __iter__(self):
30
- return iter(self.elements)
31
-
32
- def __getitem__(self, index: Union[int, slice]):
33
- return self.elements[index]
34
-
35
- def __len__(self):
36
- return len(self.elements)
37
-
38
- class Symbol:
39
- def __init__(self, value: str):
40
- self.value = value
41
-
42
- def __repr__(self):
43
- return self.value
44
-
45
- class Integer:
46
- def __init__(self, value: int):
47
- self.value = value
48
-
49
- def __repr__(self):
50
- return str(self.value)
51
-
52
- class String:
53
- def __init__(self, value: str):
54
- self.value = value
55
-
56
- def __repr__(self):
57
- return f'"{self.value}"'
58
-
59
- class Boolean:
60
- def __init__(self, value: bool):
61
- self.value = value
62
-
63
- def __repr__(self):
64
- return "true" if self.value else "false"
65
-
66
- class Function:
67
- def __init__(self, params: List[str], body: 'Expr'):
68
- self.params = params
69
- self.body = body
70
-
71
- def __repr__(self):
72
- params_str = " ".join(self.params)
73
- body_str = str(self.body)
74
- return f"(fn ({params_str}) {body_str})"
75
-
76
- class Error:
77
- """
78
- Represents an error with a freeform category and message.
79
- - `category`: A string identifying the type of error (e.g., 'SyntaxError').
80
- - `message`: A human-readable description of the error.
81
- - `details`: Optional, additional information about the error.
82
- """
83
- def __init__(self, category: str, message: str, details: str = None):
84
- if not category:
85
- raise ValueError("Error category must be provided.")
86
- if not message:
87
- raise ValueError("Error message must be provided.")
88
- self.category = category
89
- self.message = message
90
- self.details = details
91
-
92
- def __repr__(self):
93
- if self.details:
94
- return f'({self.category} "{self.message}" {self.details})'
95
- return f'({self.category} "{self.message}")'
File without changes
@@ -1,27 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
- from astreum.machine.environment import Environment
3
-
4
-
5
- def handle_definition(machine, args: Expr.ListExpr, env: Environment) -> Expr:
6
- if len(args) != 2:
7
- return Expr.Error(
8
- category="SyntaxError",
9
- message="def expects exactly two arguments: a symbol and an expression"
10
- )
11
-
12
- if not isinstance(args[0], Expr.Symbol):
13
- return Expr.Error(
14
- category="TypeError",
15
- message="First argument to def must be a symbol"
16
- )
17
-
18
- var_name = args[0].value
19
-
20
- result = machine.evaluate_expression(args[1], env)
21
-
22
- if isinstance(result, Expr.Error):
23
- return result
24
-
25
- env.set(var_name, result)
26
-
27
- return result
File without changes
@@ -1,32 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
- from astreum.machine.environment import Environment
3
-
4
- def handle_list_all(machine, list: Expr.ListExpr, predicate: Expr.Function, env: Environment) -> Expr:
5
- if not isinstance(list, Expr.ListExpr):
6
- return Expr.ListExpr([
7
- Expr.ListExpr([]),
8
- Expr.String("First argument must be a list")
9
- ])
10
-
11
- if not isinstance(predicate, Expr.Function):
12
- return Expr.ListExpr([
13
- Expr.ListExpr([]),
14
- Expr.String("Second argument must be a function")
15
- ])
16
-
17
- for elem in list.elements:
18
- new_env = Environment(parent=env)
19
- new_env.set(predicate.params[0], elem)
20
-
21
- result, _ = machine.evaluate_expression(predicate, new_env)
22
-
23
- if result == Expr.Boolean(False):
24
- return Expr.ListExpr([
25
- Expr.Boolean(False),
26
- Expr.ListExpr([])
27
- ])
28
-
29
- return Expr.ListExpr([
30
- Expr.Boolean(True),
31
- Expr.ListExpr([])
32
- ])
@@ -1,32 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
- from astreum.machine.environment import Environment
3
-
4
- def handle_list_any(machine, list: Expr.ListExpr, predicate: Expr.Function, env: Environment) -> Expr:
5
- if not isinstance(list, Expr.ListExpr):
6
- return Expr.ListExpr([
7
- Expr.ListExpr([]),
8
- Expr.String("First argument must be a list")
9
- ])
10
-
11
- if not isinstance(predicate, Expr.Function):
12
- return Expr.ListExpr([
13
- Expr.ListExpr([]),
14
- Expr.String("Second argument must be a function")
15
- ])
16
-
17
- for elem in list.elements:
18
- new_env = Environment(parent=env)
19
- new_env.set(predicate.params[0], elem)
20
-
21
- result, _ = machine.evaluate_expression(predicate, new_env)
22
-
23
- if result == Expr.Boolean(True):
24
- return Expr.ListExpr([
25
- Expr.Boolean(True),
26
- Expr.ListExpr([])
27
- ])
28
-
29
- return Expr.ListExpr([
30
- Expr.Boolean(False),
31
- Expr.ListExpr([])
32
- ])
@@ -1,29 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
- from astreum.machine.environment import Environment
3
-
4
-
5
- def handle_list_fold(machine, list: Expr.ListExpr, initial: Expr, func: Expr.Function, env: Environment) -> Expr:
6
- if not isinstance(list, Expr.ListExpr):
7
- return Expr.ListExpr([
8
- Expr.ListExpr([]),
9
- Expr.String("First argument must be a list")
10
- ])
11
-
12
- if not isinstance(func, Expr.Function):
13
- return Expr.ListExpr([
14
- Expr.ListExpr([]),
15
- Expr.String("Third argument must be a function")
16
- ])
17
-
18
- result = initial
19
- for elem in list.elements:
20
- new_env = Environment(parent=env)
21
- new_env.set(func.params[0], result)
22
- new_env.set(func.params[1], elem)
23
-
24
- result = machine.evaluate_expression(func, new_env)
25
-
26
- return Expr.ListExpr([
27
- result,
28
- Expr.ListExpr([])
29
- ])
@@ -1,20 +0,0 @@
1
-
2
-
3
- from astreum.lispeum.expression import Expr
4
- from astreum.machine.environment import Environment
5
-
6
-
7
- def handle_list_get(machine, list: Expr.ListExpr, index: Expr.Integer, env: Environment) -> Expr:
8
- if not isinstance(list, Expr.ListExpr):
9
- return Expr.ListExpr([
10
- Expr.ListExpr([]),
11
- Expr.String("First argument must be a list")
12
- ])
13
-
14
- if index.value < 0 or index.value >= len(list.elements):
15
- return Expr.ListExpr([
16
- Expr.ListExpr([]),
17
- Expr.String("Index out of bounds")
18
- ])
19
-
20
- return machine.evaluate_expression(list.elements[index])
@@ -1,23 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
-
3
-
4
- def handle_list_insert(list: Expr.ListExpr, index: Expr.Integer, value: Expr) -> Expr:
5
- if not isinstance(list, Expr.ListExpr):
6
- return Expr.ListExpr([
7
- Expr.ListExpr([]),
8
- Expr.String("First argument must be a list")
9
- ])
10
-
11
- if index.value < 0 or index.value > len(list.elements):
12
- return Expr.ListExpr([
13
- Expr.ListExpr([]),
14
- Expr.String("Index out of bounds")
15
- ])
16
-
17
- new_elements = list.elements[:index.value] + [value] + list.elements[index.value:]
18
-
19
- return Expr.ListExpr([
20
- Expr.ListExpr(new_elements),
21
- Expr.ListExpr([])
22
- ])
23
-
@@ -1,30 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
- from astreum.machine.environment import Environment
3
-
4
-
5
- def handle_list_map(machine, list: Expr.ListExpr, func: Expr.Function, env: Environment) -> Expr:
6
- if not isinstance(list, Expr.ListExpr):
7
- return Expr.ListExpr([
8
- Expr.ListExpr([]),
9
- Expr.String("First argument must be a list")
10
- ])
11
-
12
- if not isinstance(func, Expr.Function):
13
- return Expr.ListExpr([
14
- Expr.ListExpr([]),
15
- Expr.String("Second argument must be a function")
16
- ])
17
-
18
- mapped_elements = []
19
- for elem in list.elements:
20
- new_env = Environment(parent=env)
21
- new_env.set(func.params[0], elem)
22
-
23
- mapped_elem = machine.evaluate_expression(func.body, new_env)
24
-
25
- mapped_elements.append(mapped_elem)
26
-
27
- return Expr.ListExpr([
28
- Expr.ListExpr(mapped_elements),
29
- Expr.ListExpr([])
30
- ])
@@ -1,33 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
- from astreum.machine.environment import Environment
3
-
4
-
5
- def handle_list_position(machine, list: Expr.ListExpr, predicate: Expr.Function, env: Environment) -> Expr:
6
- if not isinstance(list, Expr.ListExpr):
7
- return Expr.ListExpr([
8
- Expr.ListExpr([]),
9
- Expr.String("First argument must be a list")
10
- ])
11
-
12
- if not isinstance(predicate, Expr.Function):
13
- return Expr.ListExpr([
14
- Expr.ListExpr([]),
15
- Expr.String("Second argument must be a function")
16
- ])
17
-
18
- for idx, elem in enumerate(list.elements):
19
- new_env = Environment(parent=env)
20
- new_env.set(predicate.params[0], elem)
21
-
22
- result, _ = machine.evaluate_expression(predicate, new_env)
23
-
24
- if result == Expr.Boolean(True):
25
- return Expr.ListExpr([
26
- Expr.Integer(idx),
27
- Expr.ListExpr([])
28
- ])
29
-
30
- return Expr.ListExpr([
31
- Expr.ListExpr([]),
32
- Expr.ListExpr([])
33
- ])
@@ -1,22 +0,0 @@
1
- from astreum.lispeum.expression import Expr
2
-
3
-
4
- def handle_list_remove(list: Expr.ListExpr, index: Expr.Integer) -> Expr:
5
- if not isinstance(list, Expr.ListExpr):
6
- return Expr.ListExpr([
7
- Expr.ListExpr([]),
8
- Expr.String("First argument must be a list")
9
- ])
10
-
11
- if index.value < 0 or index.value >= len(list.elements):
12
- return Expr.ListExpr([
13
- Expr.ListExpr([]),
14
- Expr.String("Index out of bounds")
15
- ])
16
-
17
- new_elements = list.elements[:index.value] + list.elements[index.value + 1:]
18
-
19
- return Expr.ListExpr([
20
- Expr.ListExpr(new_elements),
21
- Expr.ListExpr([])
22
- ])
File without changes
File without changes