astreum 0.1.13__py3-none-any.whl → 0.1.15__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,230 @@
1
+ """
2
+ Blockchain state management.
3
+
4
+ This module manages the blockchain state, including accounts, blocks, and
5
+ transactions.
6
+ """
7
+
8
+ import time
9
+ from typing import Dict, List, Optional, Set, Any
10
+ from dataclasses import dataclass, field
11
+ from ..utils import hash_data
12
+ from ..models import Block, Transaction, Account as ModelAccount
13
+ from .account import Account
14
+ from .constants import VALIDATION_ADDRESS, BURN_ADDRESS, MIN_STAKE_AMOUNT
15
+
16
+
17
+ class BlockchainState:
18
+ """
19
+ Manages the state of the blockchain.
20
+
21
+ This class tracks the current state of accounts, blocks, and transactions,
22
+ and provides methods to update the state with new blocks and transactions.
23
+ """
24
+
25
+ def __init__(self, config: Optional[dict] = None):
26
+ """
27
+ Initialize blockchain state.
28
+
29
+ Args:
30
+ config: Optional configuration
31
+ """
32
+ self.config = config or {}
33
+
34
+ # Dictionaries to track blockchain state
35
+ self.accounts = {} # address -> Account
36
+ self.blocks = {} # hash -> Block
37
+ self.transactions = {} # hash -> Transaction
38
+
39
+ # Track the latest block
40
+ self.latest_block = None
41
+
42
+ # Pending transactions
43
+ self.pending_transactions = set() # Set of transaction hashes
44
+
45
+ # State of validators and stakes
46
+ self.validators = {} # address -> stake amount
47
+
48
+ # Initialize the genesis block if not provided
49
+ if not self.latest_block:
50
+ self._initialize_genesis()
51
+
52
+ def _initialize_genesis(self):
53
+ """Initialize the genesis block and state."""
54
+ # In a full implementation, this would initialize the genesis
55
+ # block and state from configuration
56
+ print("Initializing genesis block and state")
57
+
58
+ def add_block(self, block: Block) -> bool:
59
+ """
60
+ Add a block to the blockchain state.
61
+
62
+ Args:
63
+ block: Block to add
64
+
65
+ Returns:
66
+ True if block was added successfully, False otherwise
67
+ """
68
+ # Convert block to validation format directly
69
+ validation_block = {
70
+ 'number': block.number,
71
+ 'timestamp': block.time,
72
+ 'producer': block.validator.public_key if block.validator else b'',
73
+ 'previous': block.previous.get_hash() if block.previous else b'',
74
+ 'transactions': self._extract_transactions(block),
75
+ 'vdf_proof': block.signature[:8], # Use part of signature as VDF proof for demo
76
+ 'signature': block.signature
77
+ }
78
+
79
+ # Check for duplicate (already processed) blocks
80
+ block_hash = block.get_hash()
81
+ if block_hash in self.blocks:
82
+ print(f"Block {block_hash.hex()} already in blockchain")
83
+ return True
84
+
85
+ # Convert block's accounts to validation accounts
86
+ account_dict = {}
87
+ # Here we would deserialize the accounts data from the block
88
+ # In a real implementation, this would reconstruct accounts from serialized data
89
+
90
+ # For now, we'll just log that we would process the block
91
+ print(f"Processing block at height {block.number}")
92
+
93
+ # Add the block to our state
94
+ self.blocks[block_hash] = block
95
+
96
+ # Update latest block if this is a new latest block
97
+ if not self.latest_block or block.number > self.latest_block.number:
98
+ self.latest_block = block
99
+
100
+ # Process transactions in the block
101
+ # This would update account states, apply transaction effects, etc.
102
+
103
+ return True
104
+
105
+ def _extract_transactions(self, block: Block) -> List[dict]:
106
+ """
107
+ Extract transactions from a block.
108
+
109
+ Args:
110
+ block: The model Block instance
111
+
112
+ Returns:
113
+ List of transactions in validation format
114
+ """
115
+ transactions = []
116
+ # Parse transaction data from the block
117
+ # In a real implementation, this would deserialize the transactions field
118
+ # For now, we'll return an empty list as a placeholder
119
+ return transactions
120
+
121
+ def add_transaction(self, transaction: Transaction) -> bool:
122
+ """
123
+ Add a transaction to the pending set.
124
+
125
+ Args:
126
+ transaction: Transaction to add
127
+
128
+ Returns:
129
+ True if transaction was added successfully, False otherwise
130
+ """
131
+ # Convert transaction to validation format directly
132
+ validation_tx = {
133
+ 'sender': transaction.sender.public_key if transaction.sender else b'',
134
+ 'recipient': transaction.receipient.public_key if transaction.receipient else b'',
135
+ 'amount': transaction.amount,
136
+ 'counter': transaction.counter,
137
+ 'data': transaction.data,
138
+ 'signature': transaction.signature
139
+ }
140
+
141
+ # Generate a transaction hash
142
+ tx_hash = hash_data(str(validation_tx).encode())
143
+
144
+ # Check for duplicate transactions
145
+ if tx_hash in self.transactions or tx_hash in self.pending_transactions:
146
+ print(f"Transaction {tx_hash.hex()} already processed or pending")
147
+ return False
148
+
149
+ # Validate the transaction
150
+ # In a real implementation, this would check signature, sender balance, etc.
151
+
152
+ # Add to pending transactions
153
+ self.pending_transactions.add(tx_hash)
154
+
155
+ return True
156
+
157
+ def is_staking_transaction(self, tx: Transaction) -> bool:
158
+ """
159
+ Check if a transaction is a staking transaction.
160
+
161
+ Args:
162
+ tx: The model Transaction instance
163
+
164
+ Returns:
165
+ True if this is a staking transaction, False otherwise
166
+ """
167
+ # A transaction is a staking transaction if it's sending to the validation address
168
+ if tx.receipient and hasattr(tx.receipient, 'public_key'):
169
+ return tx.receipient.public_key == VALIDATION_ADDRESS
170
+ return False
171
+
172
+ def get_account(self, address: bytes) -> Optional[Account]:
173
+ """
174
+ Get an account by address.
175
+
176
+ Args:
177
+ address: Account address
178
+
179
+ Returns:
180
+ Account if found, None otherwise
181
+ """
182
+ return self.accounts.get(address)
183
+
184
+ def get_validator_stake(self, address: bytes) -> int:
185
+ """
186
+ Get the stake of a validator.
187
+
188
+ Args:
189
+ address: Validator address
190
+
191
+ Returns:
192
+ Stake amount (0 if not a validator)
193
+ """
194
+ return self.validators.get(address, 0)
195
+
196
+ def is_validator(self, address: bytes) -> bool:
197
+ """
198
+ Check if an address is a validator.
199
+
200
+ Args:
201
+ address: Address to check
202
+
203
+ Returns:
204
+ True if address is a validator, False otherwise
205
+ """
206
+ return self.get_validator_stake(address) >= MIN_STAKE_AMOUNT
207
+
208
+ def get_pending_transactions(self) -> List[Transaction]:
209
+ """
210
+ Get all pending transactions.
211
+
212
+ Returns:
213
+ List of pending transactions
214
+ """
215
+ # In a real implementation, this would return the actual transaction objects
216
+ # For now, we'll just return an empty list
217
+ return []
218
+
219
+
220
+ def create_blockchain(config: Optional[dict] = None) -> BlockchainState:
221
+ """
222
+ Create a new blockchain state.
223
+
224
+ Args:
225
+ config: Optional configuration
226
+
227
+ Returns:
228
+ New BlockchainState instance
229
+ """
230
+ return BlockchainState(config)
@@ -0,0 +1,80 @@
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,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: astreum
3
- Version: 0.1.13
3
+ Version: 0.1.15
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
@@ -13,6 +13,7 @@ Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: pycryptodomex==3.21.0
15
15
  Requires-Dist: cryptography==44.0.2
16
+ Requires-Dist: blake3==1.0.4
16
17
 
17
18
  # lib
18
19
 
@@ -2,8 +2,9 @@ astreum/__init__.py,sha256=di8SwGUW1lNKUwvNWCjH9eLmz__sk1SbtuNZVjjpRe4,59
2
2
  astreum/lispeum/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  astreum/lispeum/expression.py,sha256=3zOEoXFHpzEFUIi1clONY55WYAh5K0YkYhaLmtvQj0I,2939
4
4
  astreum/lispeum/parser.py,sha256=SU8mjPj1ub4xQbU4CeX15HmKZAj4vI6TeefX2B72VCo,1191
5
- astreum/lispeum/storage.py,sha256=34BXwn6RVPqdGc6q-SxHT8Qn-lH8YDtnvwJh_7E-gNQ,13948
5
+ astreum/lispeum/storage.py,sha256=l_ch4Ch180FvduaSe71bG4-68E8oojsZSvcsU3Eu3so,13836
6
6
  astreum/lispeum/tokenizer.py,sha256=4obr1Jt-k1TqhsImHWUn7adQl9Ks5_VmcEFOTlQwocQ,1437
7
+ astreum/lispeum/utils.py,sha256=R68KoM_HdEDQeowxWJUswAgdHdwrfrlsB1zwuZURaVg,279
7
8
  astreum/lispeum/special/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
9
  astreum/lispeum/special/definition.py,sha256=ukQJ-Mz57bpqbTPQiwmevdE4uxec3Zt--apT3VhUYqU,840
9
10
  astreum/lispeum/special/list/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -20,18 +21,33 @@ astreum/lispeum/special/number/addition.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
20
21
  astreum/machine/__init__.py,sha256=GOdZl1tS9uIJHbq5WVcplifMDPDLQroX7CVew-K2YbA,15262
21
22
  astreum/machine/environment.py,sha256=K0084U6B7wwjrDZ9b2_7cEcbBzsB7UOy_Zpbrr7B3GY,834
22
23
  astreum/machine/error.py,sha256=MvqBaZZt33rNELNhUJ2lER3TE3aS8WVqsWF2hz2AwoA,38
23
- astreum/node/__init__.py,sha256=VlyhTLOjqy5VJlcLiTfTqgcsWuN3mudv_WtM5ixrojc,24121
24
- astreum/node/models.py,sha256=9Uf2_u55uxWG0ujjySvFJUO5Ub-EzlMnnMJWcgJHjHk,11980
25
- astreum/node/relay/__init__.py,sha256=k-_lEenUvLnBriSqjsqpnbwua1j6ZUghqkGD_Jc9ZYM,13493
24
+ astreum/node/__init__.py,sha256=K7F21c7V9vlJuTWoSw9arsLA8RF5KNR5I6QS3Frl_Ys,19481
25
+ astreum/node/utils.py,sha256=amGhNYHVMjvAO-9vBRAcim-S5LlLSRudqooBN-XPdm4,702
26
+ astreum/node/relay/__init__.py,sha256=0zvbchIbLUPqGA7QXJbXokKupcIq6Iu3X3VUpxejIQc,14981
26
27
  astreum/node/relay/bucket.py,sha256=pcmollbbM-xeHlmDxLZnzvf0Ut-9v9RoN6SijYiQuu8,2893
27
- astreum/node/relay/envelope.py,sha256=TfkynttoPX7smvMV7xEAdtIlfz-Z-EZjuhZ826csZxA,10078
28
+ astreum/node/relay/envelope.py,sha256=sDKsIvJruQKLWgWs92sx1mCjMHF7yQVoLguPygw2Pz8,10037
28
29
  astreum/node/relay/message.py,sha256=uezmGjNaQK4fZmYQLCHd2YpiosaaFb8DOa3H58HS1jA,2887
29
30
  astreum/node/relay/peer.py,sha256=DlvTR9j0BZQ1dW-p_9UGgfLvQqwNdpNLMSCYEW4FhyI,5899
30
31
  astreum/node/relay/route.py,sha256=fyOSsAe1mfsCVeN6LtQ_OEUEb1FiC5dobZBEJKNGU9U,5814
32
+ astreum/node/storage/__init__.py,sha256=eJL7ILUGKSKDhXZqkn3Rk5TUza39vIcwPwAW_AaIHTk,326
33
+ astreum/node/storage/merkle.py,sha256=gZf18ZhaJffckmuQbc92MwfxepBLwINdORuM6EeyJBc,23879
34
+ astreum/node/storage/storage.py,sha256=czJDhRK2rQxjOo88fhZ6j10f55RW8hWp1qq7c4yur6Y,10086
35
+ astreum/node/storage/trie.py,sha256=DrYNEgTS6j7WL-LtVzzCIDjSmjphjV-jL1bGXBlcyfQ,4930
36
+ astreum/node/storage/utils.py,sha256=CxKH9GbW31aVYs2Hwg1SirCykSnH_3_JisEayDrpOvY,5169
37
+ astreum/node/validation/__init__.py,sha256=D9Gmc5x5V5xgXtM32axuDMSzgKiDCz7MiUShNnuFKYc,1636
38
+ astreum/node/validation/account.py,sha256=gFoJHoSAZs7BKGaewNaLiziivKINTCh8MBpOoN-YajA,27951
39
+ astreum/node/validation/constants.py,sha256=ImIdLZFtMKx1iWg60YssEKl2tdDqZQnIa2JaJE6CX0o,422
40
+ astreum/node/validation/stake.py,sha256=Z9EPM-X9c92fpsZIYsdVpvgz4DhxQViPM-RDktWUZq8,7141
41
+ astreum/node/validation/state.py,sha256=QMXY7h4da-o79wMjJW93ixtepyhgcbJEf101yVuZurg,7661
42
+ astreum/node/validation/vdf.py,sha256=HDdnqn9O_LicfE7SNCmncawKoR-ojLyjlpn74OvRNOU,2194
43
+ astreum/node/validation/block/__init__.py,sha256=n2HaMG_5cpa7y5xko-c7vbHz8rL-1wAGthmr8boNrCs,216
44
+ astreum/node/validation/block/create.py,sha256=apD9h92b9Y146zeppSzKNk_NJPgyBy7FhxoEkypQQNk,2515
45
+ astreum/node/validation/block/model.py,sha256=d7x3_tX2MPLnGODL_5_vNjQfLdYa405blc-zL9o8HFA,2589
46
+ astreum/node/validation/block/validate.py,sha256=niLexCNhEwUJLclyrdNZSvHcVa_J6jlu7J3FiWY7XBU,6232
31
47
  astreum/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
48
  astreum/utils/bytes_format.py,sha256=X4tG5GGPweNCE54bHYkLFiuLTbmpy5upO_s1Cef-MGA,2711
33
- astreum-0.1.13.dist-info/LICENSE,sha256=gYBvRDP-cPLmTyJhvZ346QkrYW_eleke4Z2Yyyu43eQ,1089
34
- astreum-0.1.13.dist-info/METADATA,sha256=0wxUc4qtd3ipFd3-IwFjDcsWTBqAK8I-u3hrgBmgVX8,3261
35
- astreum-0.1.13.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
36
- astreum-0.1.13.dist-info/top_level.txt,sha256=1EG1GmkOk3NPmUA98FZNdKouhRyget-KiFiMk0i2Uz0,8
37
- astreum-0.1.13.dist-info/RECORD,,
49
+ astreum-0.1.15.dist-info/LICENSE,sha256=gYBvRDP-cPLmTyJhvZ346QkrYW_eleke4Z2Yyyu43eQ,1089
50
+ astreum-0.1.15.dist-info/METADATA,sha256=dkXfuFNHZTgGlPpIHmcYC8hReofWF52gD_4_6JcCQSA,3290
51
+ astreum-0.1.15.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
52
+ astreum-0.1.15.dist-info/top_level.txt,sha256=1EG1GmkOk3NPmUA98FZNdKouhRyget-KiFiMk0i2Uz0,8
53
+ astreum-0.1.15.dist-info/RECORD,,