Line data Source code
1 : #ifndef HEADER_fd_discof_restore_fd_snapin_tile_private_h
2 : #define HEADER_fd_discof_restore_fd_snapin_tile_private_h
3 :
4 : /* fd_snapin_tile_private.h contains private APIs for the "snapin" tile,
5 : which is the tile responsible for parsing a snapshot, and directing
6 : database writes. */
7 :
8 : #include "utils/fd_ssparse.h"
9 : #include "utils/fd_ssmanifest_parser.h"
10 : #include "utils/fd_slot_delta_parser.h"
11 : #include "utils/fd_ssctrl.h"
12 : #include "../../flamenco/accdb/fd_accdb_admin.h"
13 : #include "../../flamenco/accdb/fd_accdb_user.h"
14 : #include "../../flamenco/runtime/fd_txncache.h"
15 : #include "../../disco/stem/fd_stem.h"
16 : #include "../../vinyl/meta/fd_vinyl_meta.h"
17 :
18 : /* 300 here is from status_cache.rs::MAX_CACHE_ENTRIES which is the most
19 : root slots Agave could possibly serve in a snapshot. */
20 0 : #define FD_SNAPIN_TXNCACHE_MAX_ENTRIES (300UL*FD_PACK_MAX_TXNCACHE_TXN_PER_SLOT)
21 :
22 : struct blockhash_group {
23 : uchar blockhash[ 32UL ];
24 : ulong txnhash_offset;
25 : };
26 :
27 : typedef struct blockhash_group blockhash_group_t;
28 :
29 : struct fd_snapin_out_link {
30 : ulong idx;
31 : fd_wksp_t * mem;
32 : ulong chunk0;
33 : ulong wmark;
34 : ulong chunk;
35 : ulong mtu;
36 : };
37 : typedef struct fd_snapin_out_link fd_snapin_out_link_t;
38 :
39 : struct buffered_account_batch {
40 : uchar const * batch[ FD_SSPARSE_ACC_BATCH_MAX ];
41 : ulong batch_cnt;
42 : ulong slot;
43 : /* index at which to start processing a buffered account batch */
44 : ulong remaining_idx;
45 : };
46 :
47 : typedef struct buffered_account_batch buffered_account_batch_t;
48 :
49 : struct fd_snapin_tile {
50 : int state;
51 : uint full : 1; /* loading a full snapshot? */
52 : uint use_vinyl : 1; /* using vinyl-backed accdb? */
53 : uint lthash_disabled : 1; /* disable lthash checking? */
54 :
55 : ulong seed;
56 : long boot_timestamp;
57 :
58 : fd_accdb_admin_t accdb_admin[1];
59 : fd_accdb_user_t accdb[1];
60 : fd_funk_t * funk;
61 :
62 : fd_txncache_t * txncache;
63 : uchar * acc_data;
64 :
65 : fd_funk_txn_xid_t xid[1]; /* txn XID */
66 :
67 : fd_stem_context_t * stem;
68 :
69 : fd_ssparse_t * ssparse;
70 : fd_ssmanifest_parser_t * manifest_parser;
71 : fd_slot_delta_parser_t * slot_delta_parser;
72 :
73 : buffered_account_batch_t buffered_batch;
74 :
75 : struct {
76 : int manifest_done;
77 : int status_cache_done;
78 : int manifest_processed;
79 : } flags;
80 :
81 : ulong advertised_slot;
82 : ulong bank_slot;
83 : ulong epoch;
84 :
85 : ulong full_genesis_creation_time_seconds;
86 : uchar advertised_hash[ FD_HASH_FOOTPRINT ];
87 :
88 : /* TODO: remove capitalization tracking when snapshot loading into
89 : funk goes away */
90 : ulong capitalization; /* tracks capitalization of all loaded accounts in the current snapshot */
91 : ulong dup_capitalization; /* tracks capitalization of duplicate accounts encountered during incremental snapshot loading */
92 : ulong manifest_capitalization; /* capitalization according to the current snapshot manifest */
93 :
94 : struct {
95 : ulong capitalization;
96 : } recovery; /* stores the capitalization value from the last full snapshot */
97 :
98 : ulong blockhash_offsets_len;
99 : blockhash_group_t * blockhash_offsets;
100 :
101 : ulong txncache_entries_len;
102 : ulong * txncache_entries_len_vinyl_ptr;
103 : fd_sstxncache_entry_t * txncache_entries;
104 :
105 : fd_txncache_fork_id_t txncache_root_fork_id;
106 :
107 : struct {
108 : ulong full_bytes_read;
109 : ulong incremental_bytes_read;
110 :
111 : /* Account counters (full + incremental) */
112 : ulong accounts_loaded;
113 : ulong accounts_replaced;
114 : ulong accounts_ignored;
115 :
116 : /* Account counters (snapshot taken for full snapshot only) */
117 : ulong full_accounts_loaded;
118 : ulong full_accounts_replaced;
119 : ulong full_accounts_ignored;
120 : } metrics;
121 :
122 : struct {
123 : fd_wksp_t * wksp;
124 : ulong chunk0;
125 : ulong wmark;
126 : ulong mtu;
127 : ulong pos;
128 : } in;
129 :
130 : ulong out_ct_idx;
131 : fd_snapin_out_link_t manifest_out;
132 : fd_snapin_out_link_t gui_out;
133 : fd_snapin_out_link_t hash_out;
134 :
135 : ulong gui_config_acct_sz; /* total expected account data length (0 when not accumulating) */
136 : ulong gui_config_acct_off; /* bytes accumulated so far into the current gui_out link chunk */
137 :
138 : struct {
139 : uchar * pair;
140 : ulong pair_sz;
141 :
142 : uchar * dst;
143 : ulong dst_rem;
144 : ulong data_rem;
145 :
146 : fd_vinyl_meta_ele_t * meta_ele;
147 : } vinyl_op;
148 : };
149 :
150 : typedef struct fd_snapin_tile fd_snapin_tile_t;
151 :
152 : /* Funk APIs **********************************************************/
153 :
154 : FD_PROTOTYPES_BEGIN
155 :
156 : int fd_snapin_process_account_header_funk( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
157 : int fd_snapin_process_account_data_funk ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
158 : int fd_snapin_process_account_batch_funk ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result, buffered_account_batch_t * buffered_batch );
159 :
160 : void
161 : fd_snapin_read_account_funk( fd_snapin_tile_t * ctx,
162 : void const * acct_addr,
163 : fd_account_meta_t * meta,
164 : uchar * data,
165 : ulong data_max );
166 :
167 : FD_PROTOTYPES_END
168 :
169 : /* Vinyl APIs *********************************************************/
170 :
171 : FD_PROTOTYPES_BEGIN
172 :
173 : /* Internal APIs for inserting accounts */
174 :
175 : int fd_snapin_process_account_header_vinyl( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
176 : int fd_snapin_process_account_data_vinyl ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
177 : int fd_snapin_process_account_batch_vinyl ( fd_snapin_tile_t * ctx, fd_ssparse_advance_result_t * result );
178 :
179 : FD_PROTOTYPES_END
180 :
181 : /* Generic APIs *******************************************************/
182 :
183 : FD_PROTOTYPES_BEGIN
184 :
185 : /* int return value for fd_snapin_process_account_header,
186 : fd_snapin_process_account_data, and fd_snapin_process_account_batch
187 : indicates whether to yield to stem for credit return */
188 :
189 : static inline int
190 : fd_snapin_process_account_header( fd_snapin_tile_t * ctx,
191 0 : fd_ssparse_advance_result_t * result ) {
192 0 : if( ctx->use_vinyl ) {
193 0 : return fd_snapin_process_account_header_vinyl( ctx, result );
194 0 : } else {
195 0 : return fd_snapin_process_account_header_funk( ctx, result );
196 0 : }
197 0 : return 0;
198 0 : }
199 :
200 : static inline int
201 : fd_snapin_process_account_data( fd_snapin_tile_t * ctx,
202 0 : fd_ssparse_advance_result_t * result ) {
203 0 : if( ctx->use_vinyl ) {
204 0 : return fd_snapin_process_account_data_vinyl( ctx, result );
205 0 : } else {
206 0 : return fd_snapin_process_account_data_funk( ctx, result );
207 0 : }
208 0 : return 0;
209 0 : }
210 :
211 : static inline int
212 : fd_snapin_process_account_batch( fd_snapin_tile_t * ctx,
213 : fd_ssparse_advance_result_t * result,
214 0 : buffered_account_batch_t * buffered_batch ) {
215 0 : if( ctx->use_vinyl ) {
216 0 : return fd_snapin_process_account_batch_vinyl( ctx, result );
217 0 : } else {
218 0 : return fd_snapin_process_account_batch_funk( ctx, result, buffered_batch );
219 0 : }
220 0 : return 0;
221 0 : }
222 :
223 : static inline void
224 : fd_snapin_read_account( fd_snapin_tile_t * ctx,
225 : void const * acct_addr,
226 : fd_account_meta_t * meta,
227 : uchar * data,
228 0 : ulong data_max ) {
229 : /* fd_snapin_read_account will no longer be required in the snapin
230 : tile once funk is deprecated from the snapshot load pipeline.
231 : Under vinyl, this is implemented in the snapwm tile. */
232 0 : if( ctx->use_vinyl ) {
233 0 : FD_LOG_ERR(( "read account is not supported under vinyl" ));
234 0 : } else {
235 0 : fd_snapin_read_account_funk( ctx, acct_addr, meta, data, data_max );
236 0 : }
237 0 : }
238 :
239 : /* fd_snapin_send_duplicate_account sends a duplicate account message
240 : with the signature FD_SNAPSHOT_HASH_MSG_SUB or
241 : FD_SNAPSHOT_HASH_MSG_SUB_HDR, depending on if this duplicate account
242 : contains valid account data. The message is only
243 : sent if lthash verification is enabled in the snapshot loader.
244 :
245 : lamports is account's lamports value. data is the account's data,
246 : which can be optionally null. data_len is the length of the account
247 : data. executable is the account's executable flag. owner points to
248 : the account's owner (32 bytes). pubkey points to the account's
249 : pubkey (32 bytes). early_exit is an optional pointer to an int flag
250 : that is set to 1 if the caller should yield to stem following this
251 : call. */
252 : static inline void
253 : fd_snapin_send_duplicate_account( fd_snapin_tile_t * ctx,
254 : ulong lamports,
255 : uchar const * data,
256 : ulong data_len,
257 : uchar executable,
258 : uchar const * owner,
259 : uchar const * pubkey,
260 : int has_data,
261 0 : int * early_exit ) {
262 0 : if( FD_UNLIKELY( ctx->lthash_disabled ) ) return;
263 :
264 0 : if( FD_LIKELY( has_data ) ) {
265 0 : fd_snapshot_full_account_t * existing_account = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
266 0 : fd_snapshot_account_hdr_init( &existing_account->hdr, pubkey, owner, lamports, executable, data_len );
267 0 : fd_memcpy( existing_account->data, data, data_len );
268 0 : fd_stem_publish( ctx->stem, ctx->out_ct_idx, FD_SNAPSHOT_HASH_MSG_SUB, ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t)+data_len, 0UL, 0UL, 0UL );
269 0 : ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t)+data_len, ctx->hash_out.chunk0, ctx->hash_out.wmark );
270 0 : } else {
271 0 : fd_snapshot_account_hdr_t * acc_hdr = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
272 0 : fd_snapshot_account_hdr_init( acc_hdr, pubkey, owner, lamports, executable, data_len );
273 0 : fd_stem_publish( ctx->stem, ctx->out_ct_idx, FD_SNAPSHOT_HASH_MSG_SUB_HDR, ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t), 0UL, 0UL, 0UL );
274 0 : ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, sizeof(fd_snapshot_account_hdr_t), ctx->hash_out.chunk0, ctx->hash_out.wmark );
275 0 : }
276 0 : if( FD_LIKELY( early_exit ) ) *early_exit = 1;
277 0 : }
278 :
279 : /* fd_snapin_send_duplicate_account_data sends a duplicate account
280 : message with the signature FD_SNAPSHOT_HASH_MSG_SUB_DATA. The
281 : message is only sent if lthash verification is enabled in the
282 : snapshot loader.
283 :
284 : data is the account's data, which cannot be null. data_len is the
285 : length of the account data. early_exit is an optional pointer to an
286 : int flag that is set to 1 if the caller should yield to stem
287 : following this call. */
288 : static inline void
289 : fd_snapin_send_duplicate_account_data( fd_snapin_tile_t * ctx,
290 : uchar const * data,
291 : ulong data_sz,
292 0 : int * early_exit ) {
293 0 : if( FD_UNLIKELY( ctx->lthash_disabled ) ) return;
294 :
295 0 : uchar * drop_account_data = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
296 0 : fd_memcpy( drop_account_data, data, data_sz );
297 0 : fd_stem_publish( ctx->stem, ctx->out_ct_idx, FD_SNAPSHOT_HASH_MSG_SUB_DATA, ctx->hash_out.chunk, data_sz, 0UL, 0UL, 0UL );
298 0 : ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, data_sz, ctx->hash_out.chunk0, ctx->hash_out.wmark );
299 0 : if( FD_LIKELY( early_exit ) ) *early_exit = 1;
300 0 : }
301 :
302 : FD_PROTOTYPES_END
303 :
304 : #endif /* HEADER_fd_discof_restore_fd_snapin_tile_private_h */
|