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

@@ -0,0 +1,30 @@
1
+ class Block:
2
+ @classmethod
3
+ def from_bytes(cls, validator) -> 'Block':
4
+ """
5
+ Deserialize an Account from its byte representation.
6
+
7
+ Expected format: [balance, code, counter, data]
8
+
9
+ The public_key (and optional secret_key) must be provided separately.
10
+ """
11
+ decoded = bytes_format.decode(data)
12
+ balance, code, counter, account_data = decoded
13
+ return cls(public_key, balance, code, counter, account_data, secret_key=secret_key)
14
+
15
+ def to_bytes(self) -> bytes:
16
+ """
17
+ Serialize the Account into bytes.
18
+
19
+ Format: [balance, code, counter, data]
20
+ """
21
+ return bytes_format.encode([
22
+ self.balance,
23
+ self.code,
24
+ self.counter,
25
+ self.data
26
+ ])
27
+
28
+ class Chain:
29
+ def __init__(self, latest_block: Block):
30
+ self.latest_block = latest_block
@@ -1,4 +1,7 @@
1
- from .account import Account
1
+ from typing import Optional
2
+ import time
3
+ from .account import Account, get_account_from_storage
4
+ import astreum.utils.bytes_format as bytes_format
2
5
 
3
6
  class Transaction:
4
7
  def __init__(
@@ -17,6 +20,59 @@ class Transaction:
17
20
  self.timestamp = time.time()
18
21
  self.signature = None
19
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 = bytes_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 bytes_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
+
20
76
 
21
77
  def get_tx_from_storage(hash: bytes) -> Optional[Transaction]:
22
78
  """Resolves storage objects to get a transaction.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astreum
3
- Version: 0.1.16
3
+ Version: 0.1.18
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
@@ -21,37 +21,38 @@ astreum/lispeum/special/number/addition.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
21
21
  astreum/machine/__init__.py,sha256=GOdZl1tS9uIJHbq5WVcplifMDPDLQroX7CVew-K2YbA,15262
22
22
  astreum/machine/environment.py,sha256=K0084U6B7wwjrDZ9b2_7cEcbBzsB7UOy_Zpbrr7B3GY,834
23
23
  astreum/machine/error.py,sha256=MvqBaZZt33rNELNhUJ2lER3TE3aS8WVqsWF2hz2AwoA,38
24
- astreum/node/__init__.py,sha256=K7F21c7V9vlJuTWoSw9arsLA8RF5KNR5I6QS3Frl_Ys,19481
24
+ astreum/node/__init__.py,sha256=zY4rD4knr8zPOmXX3eL-VENCQ-SGDccUQlTLEzzQaAA,20073
25
25
  astreum/node/utils.py,sha256=amGhNYHVMjvAO-9vBRAcim-S5LlLSRudqooBN-XPdm4,702
26
26
  astreum/node/crypto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  astreum/node/crypto/ed25519.py,sha256=FRnvlN0kZlxn4j-sJKl-C9tqiz_0z4LZyXLj3KIj1TQ,1760
28
28
  astreum/node/crypto/x25519.py,sha256=i29v4BmwKRcbz9E7NKqFDQyxzFtJUqN0St9jd7GS1uA,1137
29
- astreum/node/relay/__init__.py,sha256=0zvbchIbLUPqGA7QXJbXokKupcIq6Iu3X3VUpxejIQc,14981
29
+ astreum/node/relay/__init__.py,sha256=A6br8QSGLW7qmKYBJNIC4bEf5QMzLBFaa_FH3MaOJrs,15069
30
30
  astreum/node/relay/bucket.py,sha256=pcmollbbM-xeHlmDxLZnzvf0Ut-9v9RoN6SijYiQuu8,2893
31
31
  astreum/node/relay/envelope.py,sha256=sDKsIvJruQKLWgWs92sx1mCjMHF7yQVoLguPygw2Pz8,10037
32
32
  astreum/node/relay/message.py,sha256=uezmGjNaQK4fZmYQLCHd2YpiosaaFb8DOa3H58HS1jA,2887
33
33
  astreum/node/relay/peer.py,sha256=DlvTR9j0BZQ1dW-p_9UGgfLvQqwNdpNLMSCYEW4FhyI,5899
34
34
  astreum/node/relay/route.py,sha256=fyOSsAe1mfsCVeN6LtQ_OEUEb1FiC5dobZBEJKNGU9U,5814
35
35
  astreum/node/storage/__init__.py,sha256=eJL7ILUGKSKDhXZqkn3Rk5TUza39vIcwPwAW_AaIHTk,326
36
- astreum/node/storage/merkle.py,sha256=gZf18ZhaJffckmuQbc92MwfxepBLwINdORuM6EeyJBc,23879
36
+ astreum/node/storage/merkle.py,sha256=sC7gfxPDUBgv3iiFs5PyxPgYbC4CoE-If5TQvkuoTGU,10295
37
+ astreum/node/storage/patricia.py,sha256=zP4whShdB7yOFcEPLE1-1PIFfx_LdK8DyMSadnF0KT0,11588
37
38
  astreum/node/storage/storage.py,sha256=czJDhRK2rQxjOo88fhZ6j10f55RW8hWp1qq7c4yur6Y,10086
38
- astreum/node/storage/trie.py,sha256=DrYNEgTS6j7WL-LtVzzCIDjSmjphjV-jL1bGXBlcyfQ,4930
39
39
  astreum/node/storage/utils.py,sha256=CxKH9GbW31aVYs2Hwg1SirCykSnH_3_JisEayDrpOvY,5169
40
40
  astreum/node/validation/__init__.py,sha256=D9Gmc5x5V5xgXtM32axuDMSzgKiDCz7MiUShNnuFKYc,1636
41
- astreum/node/validation/account.py,sha256=gFoJHoSAZs7BKGaewNaLiziivKINTCh8MBpOoN-YajA,27951
41
+ astreum/node/validation/account.py,sha256=mKbJSi3sfQ5K9a4zwgdyPGqT3gXHekI55yDDVpzcolo,3650
42
+ astreum/node/validation/block.py,sha256=ff4ZvMtIBuoY232SHxtRiwU3J-ku_hQOiqssHhIqbXY,934
42
43
  astreum/node/validation/constants.py,sha256=ImIdLZFtMKx1iWg60YssEKl2tdDqZQnIa2JaJE6CX0o,422
43
44
  astreum/node/validation/stake.py,sha256=Z9EPM-X9c92fpsZIYsdVpvgz4DhxQViPM-RDktWUZq8,7141
44
45
  astreum/node/validation/state.py,sha256=QMXY7h4da-o79wMjJW93ixtepyhgcbJEf101yVuZurg,7661
45
- astreum/node/validation/transaction.py,sha256=mHnQX5AAVlVb6GXvty20SnARU0qMidjxyU4bLN_hL9o,2315
46
+ astreum/node/validation/transaction.py,sha256=Lovx1CWIxL45glFU-LBDxI1argBLxSmDAcg1TteaOlY,4701
46
47
  astreum/node/validation/vdf.py,sha256=HDdnqn9O_LicfE7SNCmncawKoR-ojLyjlpn74OvRNOU,2194
47
- astreum/node/validation/block/__init__.py,sha256=n2HaMG_5cpa7y5xko-c7vbHz8rL-1wAGthmr8boNrCs,216
48
- astreum/node/validation/block/create.py,sha256=apD9h92b9Y146zeppSzKNk_NJPgyBy7FhxoEkypQQNk,2515
49
- astreum/node/validation/block/model.py,sha256=d7x3_tX2MPLnGODL_5_vNjQfLdYa405blc-zL9o8HFA,2589
50
- astreum/node/validation/block/validate.py,sha256=niLexCNhEwUJLclyrdNZSvHcVa_J6jlu7J3FiWY7XBU,6232
48
+ astreum/node/validation/_block/__init__.py,sha256=n2HaMG_5cpa7y5xko-c7vbHz8rL-1wAGthmr8boNrCs,216
49
+ astreum/node/validation/_block/create.py,sha256=apD9h92b9Y146zeppSzKNk_NJPgyBy7FhxoEkypQQNk,2515
50
+ astreum/node/validation/_block/model.py,sha256=d7x3_tX2MPLnGODL_5_vNjQfLdYa405blc-zL9o8HFA,2589
51
+ astreum/node/validation/_block/validate.py,sha256=niLexCNhEwUJLclyrdNZSvHcVa_J6jlu7J3FiWY7XBU,6232
51
52
  astreum/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
53
  astreum/utils/bytes_format.py,sha256=X4tG5GGPweNCE54bHYkLFiuLTbmpy5upO_s1Cef-MGA,2711
53
- astreum-0.1.16.dist-info/licenses/LICENSE,sha256=gYBvRDP-cPLmTyJhvZ346QkrYW_eleke4Z2Yyyu43eQ,1089
54
- astreum-0.1.16.dist-info/METADATA,sha256=cNSuluyEijqvfLHqHOrtPE3Jy-09CsIXIvXzJvoSId8,3312
55
- astreum-0.1.16.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
56
- astreum-0.1.16.dist-info/top_level.txt,sha256=1EG1GmkOk3NPmUA98FZNdKouhRyget-KiFiMk0i2Uz0,8
57
- astreum-0.1.16.dist-info/RECORD,,
54
+ astreum-0.1.18.dist-info/licenses/LICENSE,sha256=gYBvRDP-cPLmTyJhvZ346QkrYW_eleke4Z2Yyyu43eQ,1089
55
+ astreum-0.1.18.dist-info/METADATA,sha256=k1Eptg-mbsR5Ddo2ky6JCIgkKlXO0WqovKe5zKDSZ3c,3312
56
+ astreum-0.1.18.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
57
+ astreum-0.1.18.dist-info/top_level.txt,sha256=1EG1GmkOk3NPmUA98FZNdKouhRyget-KiFiMk0i2Uz0,8
58
+ astreum-0.1.18.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (79.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,146 +0,0 @@
1
- from astreum.utils.bytes_format import encode, decode
2
- from astreum.utils.hash import hash_data
3
- from typing import Optional, List
4
- from ..storage import Storage
5
-
6
-
7
- class Trie:
8
- def __init__(self, root: TrieNode, storage: Storage):
9
- self.root = root
10
- self.storage = storage
11
-
12
- def insert(self, key: bytes, data: bytes):
13
- self.root = self._insert(self.root, key, data)
14
-
15
- def _insert(self, node: TrieNode, key: bytes, data: bytes) -> TrieNode:
16
- if node is None:
17
- return TrieNode(key, data)
18
- if key < node.key:
19
- node.children = self._insert(node.children, key, data)
20
- elif key > node.key:
21
- node.children = self._insert(node.children, key, data)
22
- else:
23
- node.data = data
24
- return node
25
-
26
- def lookup(self, key: bytes) -> bytes:
27
- """
28
- Look up a key in the trie.
29
-
30
- Args:
31
- key: The key to look up
32
-
33
- Returns:
34
- The data associated with the key, or None if not found
35
- """
36
- return self._lookup(self.root, key)
37
-
38
- def _lookup(self, node: Optional[TrieNode], key: bytes) -> bytes:
39
- """
40
- Recursive helper for looking up a key in the trie.
41
-
42
- Args:
43
- node: The current node being examined
44
- key: The key to look up
45
-
46
- Returns:
47
- The data associated with the key, or None if not found
48
- """
49
- if node is None:
50
- return None
51
-
52
- # If we found an exact match, return the data
53
- if node.key == key:
54
- return node.data
55
-
56
- # Make sure node has a storage reference
57
- if node.storage is None:
58
- node.storage = self.storage
59
-
60
- # Use child_lookup to find the most promising child
61
- child_node = node.child_lookup(key)
62
- if child_node is None:
63
- return None
64
-
65
- # Create and traverse to the child node
66
- child_node = TrieNode.from_bytes(child_data, self.storage)
67
- return self._lookup(child_node, key)
68
-
69
- class TrieNode:
70
- """
71
- A node in a trie.
72
-
73
- Attributes:
74
- key: The key of the node
75
- data: The data stored in the node
76
- children: The children of the node
77
- storage: Reference to storage service (not serialized)
78
- """
79
- def __init__(self, key: bytes, data: bytes = None, children: bytes = None, storage = None):
80
- """
81
- Initialize a new TrieNode.
82
-
83
- Args:
84
- key: The key of the node
85
- data: The data stored in the node
86
- children: a byte string of children hashes each are 32 bytes long
87
- storage: Storage instance for retrieving child nodes (not serialized)
88
- """
89
- self.key = key
90
- self.data = data
91
- self.children = children
92
- self.storage = storage
93
-
94
- def to_bytes(self) -> bytes:
95
- """Serialize the node data (excluding storage reference)"""
96
- return encode([self.key, self.data, self.children])
97
-
98
- @classmethod
99
- def from_bytes(cls, data: bytes, storage = None) -> 'TrieNode':
100
- """
101
- Deserialize node data and optionally attach a storage reference.
102
-
103
- Args:
104
- data: The serialized node data
105
- storage: Optional storage instance to attach to the node
106
-
107
- Returns:
108
- A new TrieNode instance
109
- """
110
- key, data, children = decode(data)
111
- return TrieNode(key, data, children, storage)
112
-
113
- def hash(self) -> bytes:
114
- return hash_data(self.to_bytes())
115
-
116
- def child_lookup(self, key: bytes) -> Optional[TrieNode]:
117
- """
118
- Does a binary lookup of the keys in the children of this node.
119
- Uses storage to look up children and finds a starting match for the key.
120
- """
121
- if self.children is None or self.storage is None:
122
- return None
123
-
124
- # Parse children bytes into a list of 32-byte hashes
125
- children_hashes = []
126
- for i in range(0, len(self.children), 32):
127
- if i + 32 <= len(self.children):
128
- children_hashes.append(self.children[i:i+32])
129
-
130
- # Look up each child in storage and compare keys
131
- for child_hash in children_hashes:
132
- # Get child node data from storage
133
- child_data = self.storage.get(child_hash)
134
- if child_data is None:
135
- continue # Skip if not found in storage
136
-
137
- # Deserialize the child node
138
- child_node = TrieNode.from_bytes(child_data, self.storage)
139
-
140
- # Check if this child's key is a prefix of the lookup key
141
- # or if the lookup key is a prefix of this child's key
142
- min_len = min(len(child_node.key), len(key))
143
- if child_node.key[:min_len] == key[:min_len]:
144
- return child_node
145
-
146
- return None
File without changes
File without changes
File without changes
File without changes