0
# Network and Sysvars
1
2
Network configuration, system variables, and blockchain state including clock information, rent parameters, epoch scheduling, and validator information. These provide essential network parameters and real-time blockchain state for building robust Solana applications.
3
4
## Capabilities
5
6
### System Variables (Sysvars)
7
8
System accounts that contain network configuration and state information accessible to all programs.
9
10
```python { .api }
11
# Sysvar Account IDs - Well-known addresses for system variables
12
CLOCK: Final[Pubkey] = Pubkey.from_string("SysvarC1ock11111111111111111111111111111111")
13
RECENT_BLOCKHASHES: Final[Pubkey] = Pubkey.from_string("SysvarRecentB1ockHashes11111111111111111111")
14
RENT: Final[Pubkey] = Pubkey.from_string("SysvarRent111111111111111111111111111111111")
15
REWARDS: Final[Pubkey] = Pubkey.from_string("SysvarRewards111111111111111111111111111111")
16
STAKE_HISTORY: Final[Pubkey] = Pubkey.from_string("SysvarStakeHistory1111111111111111111111111")
17
EPOCH_SCHEDULE: Final[Pubkey] = Pubkey.from_string("SysvarEpochSchedu1e111111111111111111111111111")
18
INSTRUCTIONS: Final[Pubkey] = Pubkey.from_string("Sysvar1nstructions1111111111111111111111111")
19
SLOT_HASHES: Final[Pubkey] = Pubkey.from_string("SysvarS1otHashes111111111111111111111111111")
20
```
21
22
### Clock Information
23
24
Network time and slot information for transaction timing and epoch tracking.
25
26
```python { .api }
27
class Clock:
28
"""
29
Network time information including slot, epoch, and timestamp data.
30
"""
31
def __init__(
32
self,
33
slot: int,
34
epoch_start_timestamp: Optional[int],
35
epoch: int,
36
leader_schedule_epoch: int,
37
unix_timestamp: int
38
):
39
"""
40
Create clock information.
41
42
Parameters:
43
- slot: int, current slot number
44
- epoch_start_timestamp: Optional[int], Unix timestamp when current epoch started
45
- epoch: int, current epoch number
46
- leader_schedule_epoch: int, epoch for which leader schedule is valid
47
- unix_timestamp: int, estimated current Unix timestamp
48
"""
49
50
@classmethod
51
def deserialize(cls, data: bytes) -> 'Clock':
52
"""
53
Deserialize clock from sysvar account data.
54
55
Parameters:
56
- data: bytes, clock sysvar account data
57
58
Returns:
59
Clock object
60
"""
61
62
def serialize(self) -> bytes:
63
"""
64
Serialize clock to bytes.
65
66
Returns:
67
bytes, serialized clock data
68
"""
69
70
@property
71
def slot(self) -> int:
72
"""Current slot number."""
73
74
@property
75
def epoch_start_timestamp(self) -> Optional[int]:
76
"""Unix timestamp when current epoch started."""
77
78
@property
79
def epoch(self) -> int:
80
"""Current epoch number."""
81
82
@property
83
def leader_schedule_epoch(self) -> int:
84
"""Epoch for which leader schedule is valid."""
85
86
@property
87
def unix_timestamp(self) -> int:
88
"""Estimated current Unix timestamp."""
89
90
def slots_since_epoch_start(self) -> int:
91
"""
92
Calculate slots elapsed in current epoch.
93
94
Returns:
95
int, number of slots since epoch started
96
"""
97
98
def time_since_epoch_start(self) -> Optional[int]:
99
"""
100
Calculate time elapsed in current epoch.
101
102
Returns:
103
Optional[int], seconds since epoch started (None if no epoch start timestamp)
104
"""
105
```
106
107
### Network Timing Constants
108
109
Fundamental timing parameters that define network behavior and performance characteristics.
110
111
```python { .api }
112
# Default timing configuration for mainnet
113
DEFAULT_DEV_SLOTS_PER_EPOCH: Final[int] = 8192 # Development/testnet epoch length
114
DEFAULT_SLOTS_PER_EPOCH: Final[int] = 432000 # Production epoch length (~2 days)
115
DEFAULT_MS_PER_SLOT: Final[int] = 400 # Target slot duration (400ms)
116
DEFAULT_S_PER_SLOT: Final[float] = 0.4 # Target slot duration (0.4s)
117
DEFAULT_TICKS_PER_SLOT: Final[int] = 64 # Ticks per slot
118
DEFAULT_TICKS_PER_SECOND: Final[int] = 160 # Target tick rate
119
DEFAULT_HASHES_PER_SECOND: Final[int] = 1000000 # Hash rate target
120
DEFAULT_HASHES_PER_TICK: Final[int] = 6250 # Hashes per tick
121
122
# Epoch and slot configuration
123
GENESIS_EPOCH: Final[int] = 0 # First epoch number
124
INITIAL_RENT_EPOCH: Final[int] = 0 # Initial rent collection epoch
125
126
# Transaction timing limits
127
MAX_HASH_AGE_IN_SECONDS: Final[int] = 120 # Maximum blockhash age (2 minutes)
128
MAX_PROCESSING_AGE: Final[int] = 150 # Maximum transaction processing age
129
MAX_RECENT_BLOCKHASHES: Final[int] = 300 # Maximum tracked recent blockhashes
130
131
# Leader scheduling
132
NUM_CONSECUTIVE_LEADER_SLOTS: Final[int] = 4 # Consecutive slots per leader
133
FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET: Final[int] = 2 # Transaction forwarding offset
134
HOLD_TRANSACTIONS_SLOT_OFFSET: Final[int] = 20 # Transaction hold duration
135
136
# GPU-specific timing
137
MAX_TRANSACTION_FORWARDING_DELAY: Final[int] = 6 # Max forwarding delay (slots)
138
MAX_TRANSACTION_FORWARDING_DELAY_GPU: Final[int] = 2 # Max GPU forwarding delay
139
140
# Time constants
141
MS_PER_TICK: Final[float] = 6.25 # Milliseconds per tick
142
SECONDS_PER_DAY: Final[int] = 86400 # Seconds per day
143
TICKS_PER_DAY: Final[int] = 13824000 # Ticks per day (86400 / 0.0625 * 1000)
144
```
145
146
### Rent Configuration
147
148
Account rent parameters and exemption thresholds for storage cost calculation.
149
150
```python { .api }
151
class Rent:
152
"""
153
Rent calculation configuration and exemption parameters.
154
"""
155
def __init__(
156
self,
157
lamports_per_byte_year: int,
158
exemption_threshold: float,
159
burn_percent: int
160
):
161
"""
162
Create rent configuration.
163
164
Parameters:
165
- lamports_per_byte_year: int, cost per byte per year in lamports
166
- exemption_threshold: float, years worth of rent for exemption
167
- burn_percent: int, percentage of collected rent to burn
168
"""
169
170
@classmethod
171
def default() -> 'Rent':
172
"""
173
Create default rent configuration.
174
175
Returns:
176
Rent with mainnet default parameters
177
"""
178
179
@classmethod
180
def deserialize(cls, data: bytes) -> 'Rent':
181
"""
182
Deserialize rent from sysvar account data.
183
184
Parameters:
185
- data: bytes, rent sysvar account data
186
187
Returns:
188
Rent object
189
"""
190
191
def serialize(self) -> bytes:
192
"""
193
Serialize rent to bytes.
194
195
Returns:
196
bytes, serialized rent data
197
"""
198
199
@property
200
def lamports_per_byte_year(self) -> int:
201
"""Cost per byte per year in lamports."""
202
203
@property
204
def exemption_threshold(self) -> float:
205
"""Years worth of rent required for exemption."""
206
207
@property
208
def burn_percent(self) -> int:
209
"""Percentage of collected rent to burn (0-100)."""
210
211
def minimum_balance(self, data_len: int) -> int:
212
"""
213
Calculate minimum lamports for rent exemption.
214
215
Parameters:
216
- data_len: int, account data size in bytes
217
218
Returns:
219
int, minimum lamports needed for rent exemption
220
"""
221
222
def due(self, lamports: int, data_len: int, years_elapsed: float) -> int:
223
"""
224
Calculate rent due for account.
225
226
Parameters:
227
- lamports: int, current account balance
228
- data_len: int, account data size
229
- years_elapsed: float, time elapsed since last rent payment
230
231
Returns:
232
int, rent due in lamports (0 if rent exempt)
233
"""
234
235
def is_exempt(self, lamports: int, data_len: int) -> bool:
236
"""
237
Check if account is rent exempt.
238
239
Parameters:
240
- lamports: int, account balance
241
- data_len: int, account data size
242
243
Returns:
244
bool, True if account is rent exempt
245
"""
246
247
# Rent configuration constants
248
ACCOUNT_STORAGE_OVERHEAD: Final[int] = 128 # Additional bytes per account
249
DEFAULT_LAMPORTS_PER_BYTE_YEAR: Final[int] = 3480 # Default storage cost
250
DEFAULT_EXEMPTION_THRESHOLD: Final[float] = 2.0 # Default exemption threshold (2 years)
251
DEFAULT_BURN_PERCENT: Final[int] = 50 # Default burn percentage
252
```
253
254
### Epoch Information and Scheduling
255
256
Epoch timing, slot allocation, and validator scheduling parameters.
257
258
```python { .api }
259
class EpochInfo:
260
"""
261
Current epoch information including progress and timing.
262
"""
263
def __init__(
264
self,
265
epoch: int,
266
slot_index: int,
267
slots_in_epoch: int,
268
absolute_slot: int,
269
block_height: int,
270
transaction_count: Optional[int]
271
):
272
"""
273
Create epoch information.
274
275
Parameters:
276
- epoch: int, current epoch number
277
- slot_index: int, slot index within current epoch
278
- slots_in_epoch: int, total slots in current epoch
279
- absolute_slot: int, absolute slot number since genesis
280
- block_height: int, current block height
281
- transaction_count: Optional[int], total transaction count
282
"""
283
284
@property
285
def epoch(self) -> int:
286
"""Current epoch number."""
287
288
@property
289
def slot_index(self) -> int:
290
"""Slot index within current epoch."""
291
292
@property
293
def slots_in_epoch(self) -> int:
294
"""Total slots in current epoch."""
295
296
@property
297
def absolute_slot(self) -> int:
298
"""Absolute slot number since genesis."""
299
300
@property
301
def block_height(self) -> int:
302
"""Current block height."""
303
304
@property
305
def transaction_count(self) -> Optional[int]:
306
"""Total transaction count (if available)."""
307
308
def progress(self) -> float:
309
"""
310
Calculate epoch completion percentage.
311
312
Returns:
313
float, completion percentage (0.0 to 1.0)
314
"""
315
316
def slots_remaining(self) -> int:
317
"""
318
Calculate slots remaining in epoch.
319
320
Returns:
321
int, number of slots until epoch end
322
"""
323
324
class EpochSchedule:
325
"""
326
Epoch scheduling configuration and timing parameters.
327
"""
328
def __init__(
329
self,
330
slots_per_epoch: int,
331
leader_schedule_slot_offset: int,
332
warmup: bool,
333
first_normal_epoch: int,
334
first_normal_slot: int
335
):
336
"""
337
Create epoch schedule configuration.
338
339
Parameters:
340
- slots_per_epoch: int, slots per epoch after warmup
341
- leader_schedule_slot_offset: int, offset for leader schedule calculation
342
- warmup: bool, whether network is in warmup period
343
- first_normal_epoch: int, first epoch with normal slot count
344
- first_normal_slot: int, first slot of first normal epoch
345
"""
346
347
@classmethod
348
def default() -> 'EpochSchedule':
349
"""
350
Create default epoch schedule.
351
352
Returns:
353
EpochSchedule with mainnet parameters
354
"""
355
356
@classmethod
357
def deserialize(cls, data: bytes) -> 'EpochSchedule':
358
"""
359
Deserialize epoch schedule from sysvar account data.
360
361
Parameters:
362
- data: bytes, epoch schedule sysvar data
363
364
Returns:
365
EpochSchedule object
366
"""
367
368
def serialize(self) -> bytes:
369
"""
370
Serialize epoch schedule to bytes.
371
372
Returns:
373
bytes, serialized schedule data
374
"""
375
376
@property
377
def slots_per_epoch(self) -> int:
378
"""Slots per epoch after warmup."""
379
380
@property
381
def leader_schedule_slot_offset(self) -> int:
382
"""Offset for leader schedule calculation."""
383
384
@property
385
def warmup(self) -> bool:
386
"""Whether network is in warmup period."""
387
388
@property
389
def first_normal_epoch(self) -> int:
390
"""First epoch with normal slot count."""
391
392
@property
393
def first_normal_slot(self) -> int:
394
"""First slot of first normal epoch."""
395
396
def get_epoch(self, slot: int) -> int:
397
"""
398
Calculate epoch number for given slot.
399
400
Parameters:
401
- slot: int, slot number
402
403
Returns:
404
int, epoch containing the slot
405
"""
406
407
def get_epoch_and_slot_index(self, slot: int) -> tuple[int, int]:
408
"""
409
Calculate epoch and slot index for given slot.
410
411
Parameters:
412
- slot: int, slot number
413
414
Returns:
415
tuple[int, int], (epoch, slot_index_in_epoch)
416
"""
417
418
def get_first_slot_in_epoch(self, epoch: int) -> int:
419
"""
420
Calculate first slot of given epoch.
421
422
Parameters:
423
- epoch: int, epoch number
424
425
Returns:
426
int, first slot in epoch
427
"""
428
429
def get_last_slot_in_epoch(self, epoch: int) -> int:
430
"""
431
Calculate last slot of given epoch.
432
433
Parameters:
434
- epoch: int, epoch number
435
436
Returns:
437
int, last slot in epoch
438
"""
439
440
def get_slots_in_epoch(self, epoch: int) -> int:
441
"""
442
Calculate number of slots in given epoch.
443
444
Parameters:
445
- epoch: int, epoch number
446
447
Returns:
448
int, slots in epoch
449
"""
450
```
451
452
### Stake and Validator Information
453
454
Historical stake information and validator performance tracking.
455
456
```python { .api }
457
class StakeHistory:
458
"""
459
Historical stake activation information across epochs.
460
"""
461
def __init__(self, entries: List['StakeHistoryEntry']):
462
"""
463
Create stake history with epoch entries.
464
465
Parameters:
466
- entries: List[StakeHistoryEntry], historical stake data
467
"""
468
469
@classmethod
470
def deserialize(cls, data: bytes) -> 'StakeHistory':
471
"""
472
Deserialize stake history from sysvar account data.
473
474
Parameters:
475
- data: bytes, stake history sysvar data
476
477
Returns:
478
StakeHistory object
479
"""
480
481
def serialize(self) -> bytes:
482
"""
483
Serialize stake history to bytes.
484
485
Returns:
486
bytes, serialized stake history
487
"""
488
489
@property
490
def entries(self) -> List['StakeHistoryEntry']:
491
"""Historical stake entries by epoch."""
492
493
def get_stake_history_entry(self, epoch: int) -> Optional['StakeHistoryEntry']:
494
"""
495
Get stake information for specific epoch.
496
497
Parameters:
498
- epoch: int, epoch number to query
499
500
Returns:
501
Optional[StakeHistoryEntry], stake info for epoch (None if not found)
502
"""
503
504
class StakeHistoryEntry:
505
"""
506
Stake information for a single epoch.
507
"""
508
def __init__(self, effective: int, activating: int, deactivating: int):
509
"""
510
Create stake history entry.
511
512
Parameters:
513
- effective: int, effective stake amount in lamports
514
- activating: int, stake being activated in lamports
515
- deactivating: int, stake being deactivated in lamports
516
"""
517
518
@property
519
def effective(self) -> int:
520
"""Effective stake amount in lamports."""
521
522
@property
523
def activating(self) -> int:
524
"""Stake being activated in lamports."""
525
526
@property
527
def deactivating(self) -> int:
528
"""Stake being deactivated in lamports."""
529
530
def total_stake(self) -> int:
531
"""
532
Calculate total stake (effective + activating).
533
534
Returns:
535
int, total stake amount
536
"""
537
538
class SlotHistory:
539
"""
540
Historical slot information and confirmation bitmap.
541
"""
542
def __init__(self, bits: bytes, next_slot: int):
543
"""
544
Create slot history with confirmation bitmap.
545
546
Parameters:
547
- bits: bytes, bitmap of confirmed slots
548
- next_slot: int, next slot to be recorded
549
"""
550
551
@classmethod
552
def deserialize(cls, data: bytes) -> 'SlotHistory':
553
"""
554
Deserialize slot history from sysvar account data.
555
556
Returns:
557
SlotHistory object
558
"""
559
560
def serialize(self) -> bytes:
561
"""Serialize slot history to bytes."""
562
563
@property
564
def bits(self) -> bytes:
565
"""Bitmap of confirmed slots."""
566
567
@property
568
def next_slot(self) -> int:
569
"""Next slot to be recorded."""
570
571
def check_slot(self, slot: int) -> 'SlotHistoryCheck':
572
"""
573
Check if slot is in history and confirmed.
574
575
Parameters:
576
- slot: int, slot number to check
577
578
Returns:
579
SlotHistoryCheck, validation result
580
"""
581
582
class SlotHistoryCheck:
583
"""Result of slot history validation."""
584
Found: 'SlotHistoryCheck' # Slot found and confirmed
585
NotFound: 'SlotHistoryCheck' # Slot not in history
586
TooOld: 'SlotHistoryCheck' # Slot too old (outside history window)
587
TooNew: 'SlotHistoryCheck' # Slot too new (future slot)
588
```
589
590
### Reward Information
591
592
Epoch reward distribution and inflation parameters.
593
594
```python { .api }
595
class EpochRewards:
596
"""
597
Epoch reward distribution information.
598
"""
599
def __init__(
600
self,
601
distribution_starting_block_height: int,
602
num_partitions: int,
603
parent_blockhash: Hash,
604
total_reward: int,
605
distributed_rewards: int,
606
active: bool
607
):
608
"""
609
Create epoch rewards information.
610
611
Parameters:
612
- distribution_starting_block_height: int, block height when distribution started
613
- num_partitions: int, number of reward distribution partitions
614
- parent_blockhash: Hash, parent blockhash for reward calculation
615
- total_reward: int, total rewards for epoch in lamports
616
- distributed_rewards: int, rewards distributed so far in lamports
617
- active: bool, whether reward distribution is active
618
"""
619
620
@property
621
def distribution_starting_block_height(self) -> int:
622
"""Block height when distribution started."""
623
624
@property
625
def num_partitions(self) -> int:
626
"""Number of reward distribution partitions."""
627
628
@property
629
def parent_blockhash(self) -> Hash:
630
"""Parent blockhash for reward calculation."""
631
632
@property
633
def total_reward(self) -> int:
634
"""Total rewards for epoch in lamports."""
635
636
@property
637
def distributed_rewards(self) -> int:
638
"""Rewards distributed so far in lamports."""
639
640
@property
641
def active(self) -> bool:
642
"""Whether reward distribution is active."""
643
644
def remaining_rewards(self) -> int:
645
"""
646
Calculate remaining rewards to distribute.
647
648
Returns:
649
int, undistributed rewards in lamports
650
"""
651
652
def distribution_progress(self) -> float:
653
"""
654
Calculate reward distribution progress.
655
656
Returns:
657
float, distribution completion (0.0 to 1.0)
658
"""
659
```
660
661
## Usage Examples
662
663
### Reading System Variables
664
665
```python
666
from solders.clock import Clock
667
from solders.rent import Rent
668
from solders.epoch_schedule import EpochSchedule
669
from solders.sysvar import CLOCK, RENT, EPOCH_SCHEDULE
670
from solders.rpc.requests import GetAccountInfo
671
672
# Read clock sysvar
673
clock_request = GetAccountInfo(CLOCK)
674
# After RPC call, deserialize the account data:
675
# clock = Clock.deserialize(account.data)
676
677
# Read rent sysvar
678
rent_request = GetAccountInfo(RENT)
679
# rent = Rent.deserialize(account.data)
680
681
# Read epoch schedule
682
schedule_request = GetAccountInfo(EPOCH_SCHEDULE)
683
# epoch_schedule = EpochSchedule.deserialize(account.data)
684
```
685
686
### Working with Clock Information
687
688
```python
689
# Assuming clock data was retrieved from RPC
690
clock_data = bytes(40) # Clock sysvar data from RPC response
691
clock = Clock.deserialize(clock_data)
692
693
print(f"Current slot: {clock.slot}")
694
print(f"Current epoch: {clock.epoch}")
695
print(f"Unix timestamp: {clock.unix_timestamp}")
696
697
# Calculate elapsed time in epoch
698
slots_elapsed = clock.slots_since_epoch_start()
699
print(f"Slots since epoch start: {slots_elapsed}")
700
701
# Estimate time since epoch start
702
if clock.epoch_start_timestamp:
703
time_elapsed = clock.time_since_epoch_start()
704
print(f"Seconds since epoch start: {time_elapsed}")
705
706
# Calculate slot timing
707
slot_duration_ms = DEFAULT_MS_PER_SLOT
708
estimated_next_slot_time = clock.unix_timestamp + (slot_duration_ms / 1000)
709
print(f"Estimated next slot at: {estimated_next_slot_time}")
710
```
711
712
### Rent Calculations
713
714
```python
715
# Example rent calculations
716
rent = Rent.default()
717
718
# Calculate rent exemption for different account types
719
token_account_size = 165
720
minimum_for_token = rent.minimum_balance(token_account_size)
721
print(f"Minimum for token account: {minimum_for_token} lamports ({minimum_for_token / 1e9:.9f} SOL)")
722
723
mint_account_size = 82
724
minimum_for_mint = rent.minimum_balance(mint_account_size)
725
print(f"Minimum for mint account: {minimum_for_mint} lamports ({minimum_for_mint / 1e9:.9f} SOL)")
726
727
# Check if account is rent exempt
728
account_balance = 2500000 # 0.0025 SOL
729
account_size = 100
730
731
if rent.is_exempt(account_balance, account_size):
732
print("Account is rent exempt")
733
else:
734
needed = rent.minimum_balance(account_size) - account_balance
735
print(f"Need {needed} more lamports for rent exemption")
736
737
# Calculate rent due (for non-exempt accounts)
738
years_elapsed = 0.1 # ~36 days
739
rent_due = rent.due(account_balance, account_size, years_elapsed)
740
print(f"Rent due: {rent_due} lamports")
741
```
742
743
### Epoch Information and Scheduling
744
745
```python
746
# Working with epoch schedule
747
epoch_schedule = EpochSchedule.default()
748
749
current_slot = 100000000
750
current_epoch = epoch_schedule.get_epoch(current_slot)
751
epoch_info = epoch_schedule.get_epoch_and_slot_index(current_slot)
752
753
print(f"Slot {current_slot} is in epoch {current_epoch}")
754
print(f"Epoch: {epoch_info[0]}, Slot index: {epoch_info[1]}")
755
756
# Calculate epoch boundaries
757
first_slot = epoch_schedule.get_first_slot_in_epoch(current_epoch)
758
last_slot = epoch_schedule.get_last_slot_in_epoch(current_epoch)
759
slots_in_epoch = epoch_schedule.get_slots_in_epoch(current_epoch)
760
761
print(f"Epoch {current_epoch}: slots {first_slot} to {last_slot} ({slots_in_epoch} total)")
762
763
# Calculate progress through epoch
764
slot_index = current_slot - first_slot
765
progress = slot_index / slots_in_epoch
766
print(f"Epoch progress: {progress:.2%}")
767
768
# Estimate time remaining in epoch
769
slots_remaining = last_slot - current_slot
770
time_remaining_ms = slots_remaining * DEFAULT_MS_PER_SLOT
771
hours_remaining = (time_remaining_ms / 1000) / 3600
772
print(f"Estimated time remaining in epoch: {hours_remaining:.1f} hours")
773
```
774
775
### Validator and Stake Information
776
777
```python
778
# Working with stake history (example)
779
# stake_history = StakeHistory.deserialize(stake_history_sysvar_data)
780
781
def analyze_stake_trend(stake_history: StakeHistory, epochs_back: int = 10):
782
"""Analyze stake trend over recent epochs."""
783
current_epoch = 500 # Would get from clock or epoch info
784
785
stake_values = []
786
for i in range(epochs_back):
787
epoch = current_epoch - i
788
entry = stake_history.get_stake_history_entry(epoch)
789
if entry:
790
total_stake = entry.total_stake()
791
stake_values.append((epoch, total_stake))
792
793
if len(stake_values) >= 2:
794
recent = stake_values[0][1]
795
older = stake_values[-1][1]
796
change = ((recent - older) / older) * 100
797
print(f"Stake change over {epochs_back} epochs: {change:+.2f}%")
798
799
return stake_values
800
801
# Check slot confirmation
802
# slot_history = SlotHistory.deserialize(slot_history_sysvar_data)
803
def check_slot_confirmation(slot_history: SlotHistory, slot: int):
804
"""Check if a slot was confirmed."""
805
result = slot_history.check_slot(slot)
806
807
if result == SlotHistoryCheck.Found:
808
print(f"Slot {slot} was confirmed")
809
elif result == SlotHistoryCheck.NotFound:
810
print(f"Slot {slot} was not confirmed")
811
elif result == SlotHistoryCheck.TooOld:
812
print(f"Slot {slot} is too old (outside history window)")
813
elif result == SlotHistoryCheck.TooNew:
814
print(f"Slot {slot} is too new (future slot)")
815
```
816
817
### Network Timing Calculations
818
819
```python
820
# Calculate network timing metrics
821
def calculate_network_metrics(current_slot: int, target_slot: int):
822
"""Calculate timing for reaching target slot."""
823
slots_to_wait = target_slot - current_slot
824
825
if slots_to_wait <= 0:
826
print("Target slot already passed")
827
return
828
829
# Time estimates
830
ms_to_wait = slots_to_wait * DEFAULT_MS_PER_SLOT
831
seconds_to_wait = ms_to_wait / 1000
832
minutes_to_wait = seconds_to_wait / 60
833
834
print(f"Slots to wait: {slots_to_wait}")
835
print(f"Estimated time: {minutes_to_wait:.1f} minutes")
836
837
# Account for network variability
838
min_time = seconds_to_wait * 0.8 # Slots can be faster
839
max_time = seconds_to_wait * 1.2 # Slots can be slower
840
841
print(f"Time range: {min_time/60:.1f} - {max_time/60:.1f} minutes")
842
843
# Transaction timing validation
844
def validate_transaction_timing(blockhash_age_slots: int) -> bool:
845
"""Validate if blockhash is still valid for transactions."""
846
max_age_slots = MAX_HASH_AGE_IN_SECONDS / DEFAULT_S_PER_SLOT
847
848
if blockhash_age_slots > max_age_slots:
849
print(f"Blockhash too old: {blockhash_age_slots} slots (max {max_age_slots})")
850
return False
851
852
slots_remaining = max_age_slots - blockhash_age_slots
853
time_remaining = slots_remaining * DEFAULT_S_PER_SLOT
854
855
print(f"Blockhash valid for {slots_remaining:.0f} more slots ({time_remaining:.0f}s)")
856
return True
857
858
# Usage
859
current_slot = 100000000
860
target_slot = 100000100
861
calculate_network_metrics(current_slot, target_slot)
862
863
# Check blockhash validity
864
blockhash_slot = 99999900 # Slot when blockhash was created
865
age_in_slots = current_slot - blockhash_slot
866
is_valid = validate_transaction_timing(age_in_slots)
867
```
868
869
### Epoch Reward Tracking
870
871
```python
872
# Working with epoch rewards (example)
873
def track_reward_distribution(epoch_rewards: EpochRewards):
874
"""Track epoch reward distribution progress."""
875
print(f"Total rewards: {epoch_rewards.total_reward / 1e9:.6f} SOL")
876
print(f"Distributed: {epoch_rewards.distributed_rewards / 1e9:.6f} SOL")
877
878
remaining = epoch_rewards.remaining_rewards()
879
print(f"Remaining: {remaining / 1e9:.6f} SOL")
880
881
progress = epoch_rewards.distribution_progress()
882
print(f"Distribution progress: {progress:.1%}")
883
884
if epoch_rewards.active:
885
print("Distribution is currently active")
886
887
# Estimate completion time based on distribution rate
888
if progress > 0:
889
# This would require historical data to calculate rate
890
print("Estimating completion time...")
891
else:
892
print("Distribution completed or not started")
893
```
894
895
## Constants and Network Parameters
896
897
### Network Identifiers
898
899
```python { .api }
900
# Network-specific parameters (examples for different networks)
901
class NetworkParams:
902
# Mainnet parameters
903
MAINNET_GENESIS_HASH = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d"
904
905
# Devnet parameters
906
DEVNET_SLOTS_PER_EPOCH = DEFAULT_DEV_SLOTS_PER_EPOCH
907
908
# Testnet parameters
909
TESTNET_SLOTS_PER_EPOCH = DEFAULT_SLOTS_PER_EPOCH
910
```
911
912
### Performance Benchmarks
913
914
```python { .api }
915
# Network performance targets
916
TARGET_TRANSACTIONS_PER_SECOND = 65000 # Peak TPS target
917
TARGET_CONFIRMATION_TIME_MS = 400 # Target confirmation time
918
TARGET_FINALIZATION_TIME_MS = 12800 # Target finalization time (32 slots)
919
920
# Practical limits
921
MAX_TRANSACTIONS_PER_BLOCK = 512 # Current block limit
922
AVERAGE_TRANSACTION_SIZE = 200 # Average transaction size in bytes
923
```