Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_sysvar_fd_sysvar_cache_private_h
2 : #define HEADER_fd_src_flamenco_runtime_sysvar_fd_sysvar_cache_private_h
3 :
4 : #include "fd_sysvar_cache.h"
5 : #include "../fd_system_ids_pp.h"
6 :
7 951 : #define FD_SYSVAR_CACHE_MAGIC (0x1aa5ecb2a49b600aUL) /* random number */
8 :
9 : #define FD_SYSVAR_SIMPLE_ITER( SIMPLE_SYSVAR ) \
10 : SIMPLE_SYSVAR( clock, CLOCK, sol_sysvar_clock ) \
11 : SIMPLE_SYSVAR( epoch_rewards, EPOCH_REWARDS, sysvar_epoch_rewards ) \
12 : SIMPLE_SYSVAR( epoch_schedule, EPOCH_SCHEDULE, epoch_schedule ) \
13 : SIMPLE_SYSVAR( rent, RENT, rent )
14 :
15 : /* Declare a perfect hash table mapping sysvar IDs to sysvar cache slots
16 : Hashes bytes [8,12) of each sysvar address. */
17 :
18 : struct sysvar_lut {
19 : fd_pubkey_t key;
20 : uchar desc_idx;
21 : };
22 : typedef struct sysvar_lut sysvar_tbl_t;
23 :
24 : #define MAP_PERFECT_NAME sysvar_map
25 : #define MAP_PERFECT_LG_TBL_SZ 4
26 : #define MAP_PERFECT_T sysvar_tbl_t
27 1287 : #define MAP_PERFECT_HASH_C 212885
28 : #define MAP_PERFECT_KEY key.uc
29 : #define MAP_PERFECT_KEY_T fd_pubkey_t const *
30 : #define MAP_PERFECT_ZERO_KEY (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
31 : #define MAP_PERFECT_COMPLEX_KEY 1
32 1287 : #define MAP_PERFECT_KEYS_EQUAL(k1,k2) (!memcmp( (k1), (k2), 32UL ))
33 1287 : #define PERFECT_HASH( u ) (((MAP_PERFECT_HASH_C*(u))>>28)&0xFU)
34 : #define MAP_PERFECT_HASH_PP( a00,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15, \
35 : a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31 ) \
36 : PERFECT_HASH( (a08 | (a09<<8) | (a10<<16) | (a11<<24)) )
37 1287 : #define MAP_PERFECT_HASH_R( ptr ) PERFECT_HASH( fd_uint_load_4( (uchar const *)ptr + 8UL ) )
38 : #define MAP_SYSVAR( id, desc ) ( id ), ( desc )
39 : #define MAP_PERFECT_0 MAP_SYSVAR( SYSVAR_CLOCK_ID, FD_SYSVAR_clock_IDX )
40 : #define MAP_PERFECT_1 MAP_SYSVAR( SYSVAR_SLOT_HIST_ID, FD_SYSVAR_slot_history_IDX )
41 : #define MAP_PERFECT_2 MAP_SYSVAR( SYSVAR_SLOT_HASHES_ID, FD_SYSVAR_slot_hashes_IDX )
42 : #define MAP_PERFECT_3 MAP_SYSVAR( SYSVAR_EPOCH_SCHED_ID, FD_SYSVAR_epoch_schedule_IDX )
43 : #define MAP_PERFECT_4 MAP_SYSVAR( SYSVAR_RECENT_BLKHASH_ID, FD_SYSVAR_recent_hashes_IDX )
44 : #define MAP_PERFECT_5 MAP_SYSVAR( SYSVAR_RENT_ID, FD_SYSVAR_rent_IDX )
45 : #define MAP_PERFECT_6 MAP_SYSVAR( SYSVAR_EPOCH_REWARDS_ID, FD_SYSVAR_epoch_rewards_IDX )
46 : #define MAP_PERFECT_7 MAP_SYSVAR( SYSVAR_STAKE_HIST_ID, FD_SYSVAR_stake_history_IDX )
47 : #define MAP_PERFECT_8 MAP_SYSVAR( SYSVAR_LAST_RESTART_ID, FD_SYSVAR_last_restart_slot_IDX )
48 : #include "../../../util/tmpl/fd_map_perfect.c"
49 : #undef PERFECT_HASH
50 :
51 : /* Declare a table giving the buffer offsets and sizes of sysvars in the
52 : cache. */
53 :
54 : struct fd_sysvar_pos {
55 : /* Offsets relative to start of sysvar cache */
56 : uint data_off; /* Raw data offset */
57 : uint obj_off; /* Typed object offset */
58 : uint data_max;
59 : uint obj_max;
60 :
61 : char const * name;
62 :
63 : int (* decode_footprint)( fd_bincode_decode_ctx_t * ctx, ulong * total_sz );
64 : void * (* decode)( void * mem, fd_bincode_decode_ctx_t * ctx );
65 : };
66 : typedef struct fd_sysvar_pos fd_sysvar_pos_t;
67 :
68 : #define TYPES_CALLBACKS( name, suf ) \
69 : .decode_footprint = fd_##name##_decode_footprint, \
70 : .decode = (__typeof__(((fd_sysvar_pos_t *)NULL)->decode))(ulong)fd_##name##_decode##suf
71 :
72 : static fd_sysvar_pos_t const fd_sysvar_pos_tbl[ FD_SYSVAR_CACHE_ENTRY_CNT ] = {
73 : [FD_SYSVAR_clock_IDX] =
74 : { .name="clock",
75 : .data_off=offsetof(fd_sysvar_cache_t, bin_clock ), .data_max=FD_SYSVAR_CLOCK_BINCODE_SZ },
76 : [FD_SYSVAR_epoch_rewards_IDX] =
77 : { .name="epoch rewards",
78 : .data_off=offsetof(fd_sysvar_cache_t, bin_epoch_rewards ), .data_max=FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ,
79 : .obj_off =offsetof(fd_sysvar_cache_t, obj_epoch_rewards ), .obj_max =FD_SYSVAR_EPOCH_REWARDS_FOOTPRINT,
80 : TYPES_CALLBACKS( sysvar_epoch_rewards, ) },
81 : [FD_SYSVAR_epoch_schedule_IDX] =
82 : { .name="epoch schedule",
83 : .data_off=offsetof(fd_sysvar_cache_t, bin_epoch_schedule ), .data_max=FD_SYSVAR_EPOCH_SCHEDULE_BINCODE_SZ,
84 : .obj_off =offsetof(fd_sysvar_cache_t, obj_epoch_schedule ), .obj_max =FD_SYSVAR_EPOCH_SCHEDULE_FOOTPRINT,
85 : TYPES_CALLBACKS( epoch_schedule, ) },
86 : [FD_SYSVAR_last_restart_slot_IDX] =
87 : { .name="last restart slot",
88 : .data_off=offsetof(fd_sysvar_cache_t, bin_last_restart_slot), .data_max=FD_SYSVAR_LAST_RESTART_SLOT_BINCODE_SZ,
89 : .obj_off =offsetof(fd_sysvar_cache_t, obj_last_restart_slot), .obj_max =FD_SYSVAR_LAST_RESTART_SLOT_FOOTPRINT,
90 : },
91 : [FD_SYSVAR_recent_hashes_IDX] =
92 : { .name="recent blockhashes",
93 : .data_off=offsetof(fd_sysvar_cache_t, bin_recent_hashes ), .data_max=FD_SYSVAR_RECENT_HASHES_BINCODE_SZ,
94 : .obj_off =offsetof(fd_sysvar_cache_t, obj_recent_hashes ), .obj_max =FD_SYSVAR_RECENT_HASHES_FOOTPRINT,
95 : TYPES_CALLBACKS( recent_block_hashes, _global ) },
96 : [FD_SYSVAR_rent_IDX] =
97 : { .name="rent",
98 : .data_off=offsetof(fd_sysvar_cache_t, bin_rent ), .data_max=FD_SYSVAR_RENT_BINCODE_SZ,
99 : .obj_off =offsetof(fd_sysvar_cache_t, obj_rent ), .obj_max =FD_SYSVAR_RENT_FOOTPRINT,
100 : TYPES_CALLBACKS( rent, ) },
101 : [FD_SYSVAR_slot_hashes_IDX] =
102 : { .name="slot hashes",
103 : .data_off=offsetof(fd_sysvar_cache_t, bin_slot_hashes ), .data_max=FD_SYSVAR_SLOT_HASHES_BINCODE_SZ,
104 : .obj_off =offsetof(fd_sysvar_cache_t, obj_slot_hashes ), .obj_max =FD_SYSVAR_SLOT_HASHES_FOOTPRINT,
105 : TYPES_CALLBACKS( slot_hashes, _global ) },
106 : [FD_SYSVAR_slot_history_IDX] =
107 : { .name="slot history",
108 : .data_off=offsetof(fd_sysvar_cache_t, bin_slot_history ), .data_max=FD_SYSVAR_SLOT_HISTORY_BINCODE_SZ,
109 : .obj_off =offsetof(fd_sysvar_cache_t, obj_slot_history ), .obj_max =FD_SYSVAR_SLOT_HISTORY_FOOTPRINT,
110 : TYPES_CALLBACKS( slot_history, _global ) },
111 : [FD_SYSVAR_stake_history_IDX] =
112 : { .name="stake history",
113 : .data_off=offsetof(fd_sysvar_cache_t, bin_stake_history ), .data_max=FD_SYSVAR_STAKE_HISTORY_BINCODE_SZ,
114 : .obj_off =offsetof(fd_sysvar_cache_t, obj_stake_history ), .obj_max =FD_SYSVAR_STAKE_HISTORY_FOOTPRINT,
115 : TYPES_CALLBACKS( stake_history, ) },
116 : };
117 :
118 : #undef TYPES_CALLBACKS
119 :
120 : static fd_pubkey_t const fd_sysvar_key_tbl[ FD_SYSVAR_CACHE_ENTRY_CNT ] = {
121 : [ FD_SYSVAR_clock_IDX ] = {{ SYSVAR_CLOCK_ID }},
122 : [ FD_SYSVAR_epoch_rewards_IDX ] = {{ SYSVAR_EPOCH_REWARDS_ID }},
123 : [ FD_SYSVAR_epoch_schedule_IDX ] = {{ SYSVAR_EPOCH_SCHED_ID }},
124 : [ FD_SYSVAR_last_restart_slot_IDX ] = {{ SYSVAR_LAST_RESTART_ID }},
125 : [ FD_SYSVAR_recent_hashes_IDX ] = {{ SYSVAR_RECENT_BLKHASH_ID }},
126 : [ FD_SYSVAR_rent_IDX ] = {{ SYSVAR_RENT_ID }},
127 : [ FD_SYSVAR_slot_hashes_IDX ] = {{ SYSVAR_SLOT_HASHES_ID }},
128 : [ FD_SYSVAR_slot_history_IDX ] = {{ SYSVAR_SLOT_HIST_ID }},
129 : [ FD_SYSVAR_stake_history_IDX ] = {{ SYSVAR_STAKE_HIST_ID }},
130 : };
131 :
132 : /* fd_sysvar_obj_restore restores a typed representation of a sysvar
133 : from serialized data. This is called internally whenever sysvar
134 : serialized data is updated directly. DO NOT USE DIRECTLY. */
135 :
136 : int
137 : fd_sysvar_obj_restore( fd_sysvar_cache_t * cache,
138 : fd_sysvar_desc_t * desc,
139 : fd_sysvar_pos_t const * pos );
140 :
141 : #endif /* HEADER_fd_src_flamenco_runtime_sysvar_fd_sysvar_cache_private_h */
|