Line data Source code
1 : #include "fd_capture_ctx.h"
2 : #include "fd_solcap_writer.h"
3 : #include "../../tango/mcache/fd_mcache.h"
4 : #include "../../tango/dcache/fd_dcache.h"
5 : #include "../../tango/fd_tango_base.h"
6 : #include "../../tango/fseq/fd_fseq.h"
7 :
8 : void *
9 0 : fd_capture_ctx_new( void * mem ) {
10 0 : if( FD_UNLIKELY( !mem ) ) {
11 0 : FD_LOG_WARNING(( "NULL mem" ));
12 0 : return NULL;
13 0 : }
14 :
15 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_capture_ctx_align() ) ) ) {
16 0 : FD_LOG_WARNING(( "misaligned mem" ));
17 0 : return NULL;
18 0 : }
19 :
20 0 : FD_SCRATCH_ALLOC_INIT( l, mem );
21 0 : fd_capture_ctx_t * capture_ctx = FD_SCRATCH_ALLOC_APPEND( l, fd_capture_ctx_align(), sizeof(fd_capture_ctx_t) );
22 0 : fd_solcap_writer_t * capture = FD_SCRATCH_ALLOC_APPEND( l, fd_solcap_writer_align(), fd_solcap_writer_footprint() );
23 0 : FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_capture_ctx_align() ) == (ulong)mem + fd_capture_ctx_footprint() );
24 :
25 0 : fd_memset( capture_ctx, 0, sizeof(fd_capture_ctx_t) );
26 0 : fd_memset(capture, 0, sizeof(fd_solcap_writer_t));
27 :
28 : /* Link the capture writer to the context */
29 0 : capture_ctx->capture = capture;
30 :
31 0 : FD_COMPILER_MFENCE();
32 0 : FD_VOLATILE( capture_ctx->magic ) = FD_CAPTURE_CTX_MAGIC;
33 0 : FD_COMPILER_MFENCE();
34 :
35 0 : return mem;
36 0 : }
37 :
38 : fd_capture_ctx_t *
39 0 : fd_capture_ctx_join( void * mem ) {
40 0 : if( FD_UNLIKELY( !mem ) ) {
41 0 : FD_LOG_WARNING(( "NULL block" ));
42 0 : return NULL;
43 0 : }
44 :
45 0 : fd_capture_ctx_t * ctx = (fd_capture_ctx_t *) mem;
46 :
47 0 : if( FD_UNLIKELY( ctx->magic!=FD_CAPTURE_CTX_MAGIC ) ) {
48 0 : FD_LOG_WARNING(( "bad magic" ));
49 0 : return NULL;
50 0 : }
51 :
52 0 : return ctx;
53 0 : }
54 :
55 : void *
56 0 : fd_capture_ctx_leave( fd_capture_ctx_t * ctx) {
57 0 : if( FD_UNLIKELY( !ctx ) ) {
58 0 : FD_LOG_WARNING(( "NULL block" ));
59 0 : return NULL;
60 0 : }
61 :
62 0 : if( FD_UNLIKELY( ctx->magic!=FD_CAPTURE_CTX_MAGIC ) ) {
63 0 : FD_LOG_WARNING(( "bad magic" ));
64 0 : return NULL;
65 0 : }
66 :
67 0 : return (void *) ctx;
68 0 : }
69 :
70 : void *
71 0 : fd_capture_ctx_delete( void * mem ) {
72 0 : if( FD_UNLIKELY( !mem ) ) {
73 0 : FD_LOG_WARNING(( "NULL mem" ));
74 0 : return NULL;
75 0 : }
76 :
77 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_capture_ctx_align() ) ) ) {
78 0 : FD_LOG_WARNING(( "misaligned mem" ));
79 0 : return NULL;
80 0 : }
81 :
82 0 : fd_capture_ctx_t * hdr = (fd_capture_ctx_t *)mem;
83 0 : if( FD_UNLIKELY( hdr->magic!=FD_CAPTURE_CTX_MAGIC ) ) {
84 0 : FD_LOG_WARNING(( "bad magic" ));
85 0 : return NULL;
86 0 : }
87 :
88 0 : FD_COMPILER_MFENCE();
89 0 : FD_VOLATILE( hdr->magic ) = 0UL;
90 0 : FD_COMPILER_MFENCE();
91 :
92 0 : return mem;
93 0 : }
94 :
95 :
96 : static void
97 0 : wait_to_write_solcap_msg( fd_capture_link_buf_t * buf ) {
98 0 : if( FD_LIKELY( buf->fseq ) ) {
99 0 : while( FD_UNLIKELY( fd_seq_diff( buf->seq, fd_fseq_query( buf->fseq ) ) > 2L ) ) {
100 0 : FD_SPIN_PAUSE();
101 0 : }
102 0 : }
103 0 : }
104 :
105 : static uint
106 : valid_slot_range(fd_capture_ctx_t * ctx,
107 0 : ulong slot ) {
108 : /* When solcap_start_slot is 0 (not set), capture all slots */
109 0 : if( FD_LIKELY( ctx->solcap_start_slot == 0UL ) ) {
110 0 : return 1;
111 0 : }
112 0 : if( FD_UNLIKELY( slot < ctx->solcap_start_slot ) ) {
113 0 : return 0;
114 0 : }
115 0 : return 1;
116 0 : }
117 :
118 : void
119 : fd_capture_link_write_account_update_buf( fd_capture_ctx_t * ctx,
120 : ulong txn_idx,
121 : fd_pubkey_t const * key,
122 : fd_solana_account_meta_t const * info,
123 : ulong slot,
124 : uchar const * data,
125 0 : ulong data_sz ) {
126 :
127 0 : if( FD_UNLIKELY( !ctx || !ctx->capctx_type.buf ) ) FD_LOG_ERR(( "NULL ctx (%p) or buf (%p)", (void *)ctx, (void *)ctx->capctx_type.buf ));
128 0 : if( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
129 :
130 0 : fd_capture_link_buf_t * buf = ctx->capctx_type.buf;
131 0 : wait_to_write_solcap_msg( buf );
132 :
133 0 : ulong msg_sz = sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_account_update_hdr_t);
134 :
135 0 : uchar * dst = (uchar *)fd_chunk_to_laddr( buf->mem, buf->chunk );
136 0 : char * ptr = (char *)dst;
137 :
138 0 : fd_solcap_buf_msg_t msg = {
139 0 : .sig = SOLCAP_WRITE_ACCOUNT,
140 0 : .slot = slot,
141 0 : .txn_idx = txn_idx,
142 0 : };
143 0 : fd_memcpy( ptr, &msg, sizeof(fd_solcap_buf_msg_t) );
144 0 : ptr += sizeof(fd_solcap_buf_msg_t);
145 :
146 0 : fd_solcap_account_update_hdr_t account_hdr = {
147 0 : .key = *key,
148 0 : .info = *info,
149 0 : .data_sz = data_sz,
150 0 : };
151 :
152 0 : fd_memcpy( ptr, &account_hdr, sizeof(fd_solcap_account_update_hdr_t) );
153 :
154 0 : ulong write_cnt = (data_sz + SOLCAP_WRITE_ACCOUNT_DATA_MTU - 1) / SOLCAP_WRITE_ACCOUNT_DATA_MTU;
155 0 : if( data_sz == 0 ) write_cnt = 0;
156 :
157 0 : int has_data = (write_cnt > 0);
158 0 : ulong ctl = fd_frag_meta_ctl( 0UL, 1UL, has_data ? 0UL : 1UL, 0UL );
159 0 : fd_mcache_publish( buf->mcache, buf->depth, buf->seq, 0UL, buf->chunk, msg_sz, ctl, 0UL, 0UL );
160 0 : buf->chunk = fd_dcache_compact_next( buf->chunk, msg_sz, buf->chunk0, buf->wmark );
161 0 : buf->seq++;
162 :
163 0 : if( !has_data ) return;
164 :
165 0 : for ( ulong i = 0; i < write_cnt; i++ ) {
166 0 : wait_to_write_solcap_msg( buf );
167 :
168 0 : dst = (uchar *)fd_chunk_to_laddr( buf->mem, buf->chunk );
169 0 : ptr = (char *)dst;
170 :
171 0 : ulong fragment_data_sz = SOLCAP_WRITE_ACCOUNT_DATA_MTU;
172 0 : int is_last = (i == write_cnt - 1);
173 :
174 0 : if( is_last ) {
175 0 : fragment_data_sz = data_sz - i * SOLCAP_WRITE_ACCOUNT_DATA_MTU;
176 0 : }
177 :
178 0 : fd_memcpy( ptr, data + i * SOLCAP_WRITE_ACCOUNT_DATA_MTU, fragment_data_sz );
179 :
180 0 : msg_sz = fragment_data_sz;
181 :
182 0 : ctl = fd_frag_meta_ctl( 0UL, 0UL, is_last ? 1UL : 0UL, 0UL );
183 :
184 0 : fd_mcache_publish( buf->mcache, buf->depth, buf->seq, 0UL, buf->chunk, msg_sz, ctl, 0UL, 0UL );
185 0 : buf->chunk = fd_dcache_compact_next( buf->chunk, msg_sz, buf->chunk0, buf->wmark );
186 0 : buf->seq++;
187 0 : }
188 :
189 0 : }
190 :
191 : void
192 : fd_capture_link_write_account_update_file( fd_capture_ctx_t * ctx,
193 : ulong txn_idx,
194 : fd_pubkey_t const * key,
195 : fd_solana_account_meta_t const * info,
196 : ulong slot,
197 : uchar const * data,
198 0 : ulong data_sz ) {
199 0 : if( FD_UNLIKELY( !ctx || !ctx->capture ) ) return;
200 0 : if( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
201 :
202 0 : fd_solcap_writer_t * writer = ctx->capture;
203 :
204 : /* Prepare message header */
205 0 : fd_solcap_buf_msg_t msg_hdr = {
206 0 : .sig = SOLCAP_WRITE_ACCOUNT,
207 0 : .slot = slot,
208 0 : .txn_idx = txn_idx,
209 0 : };
210 :
211 : /* Prepare account update header */
212 0 : fd_solcap_account_update_hdr_t account_update = {
213 0 : .key = *key,
214 0 : .info = *info,
215 0 : .data_sz = data_sz,
216 0 : };
217 :
218 : /* Write the header (EPB + internal header + account metadata) */
219 0 : uint block_len = fd_solcap_write_account_hdr( writer, &msg_hdr, &account_update );
220 :
221 : /* Write the account data */
222 0 : fd_solcap_write_data( writer, data, data_sz );
223 :
224 : /* Write the footer */
225 0 : fd_solcap_write_ftr( writer, block_len );
226 0 : }
227 :
228 : void
229 : fd_capture_link_write_bank_preimage_buf( fd_capture_ctx_t * ctx,
230 : ulong slot,
231 : fd_hash_t const * bank_hash,
232 : fd_hash_t const * prev_bank_hash,
233 : fd_hash_t const * accounts_lt_hash_checksum,
234 : fd_hash_t const * poh_hash,
235 0 : ulong signature_cnt) {
236 0 : if( FD_UNLIKELY( !ctx || !ctx->capctx_type.buf ) ) FD_LOG_ERR(( "NULL ctx (%p) or buf (%p)", (void *)ctx, (void *)ctx->capctx_type.buf ));
237 0 : if ( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
238 :
239 0 : fd_capture_link_buf_t * buf = ctx->capctx_type.buf;
240 :
241 0 : wait_to_write_solcap_msg( buf );
242 :
243 0 : uchar * dst = (uchar *)fd_chunk_to_laddr( buf->mem, buf->chunk );
244 0 : char * ptr = (char *)dst;
245 :
246 0 : fd_solcap_buf_msg_t msg = {
247 0 : .sig = SOLCAP_WRITE_BANK_PREIMAGE,
248 0 : .slot = slot,
249 0 : .txn_idx = 0
250 0 : };
251 0 : fd_memcpy( ptr, &msg, sizeof(fd_solcap_buf_msg_t) );
252 0 : ptr += sizeof(fd_solcap_buf_msg_t);
253 :
254 0 : fd_solcap_bank_preimage_t bank_preimage = {
255 0 : .bank_hash = *bank_hash,
256 0 : .prev_bank_hash = *prev_bank_hash,
257 0 : .accounts_lt_hash_checksum = *accounts_lt_hash_checksum,
258 0 : .poh_hash = *poh_hash,
259 0 : .signature_cnt = signature_cnt
260 0 : };
261 0 : fd_memcpy( ptr, &bank_preimage, sizeof(fd_solcap_bank_preimage_t) );
262 0 : ulong ctl = fd_frag_meta_ctl( 0UL, 1UL, 1UL, 0UL );
263 0 : fd_mcache_publish( buf->mcache, buf->depth, buf->seq, 0UL, buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_bank_preimage_t), ctl, 0UL, 0UL );
264 0 : buf->chunk = fd_dcache_compact_next( buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_bank_preimage_t), buf->chunk0, buf->wmark );
265 0 : buf->seq++;
266 0 : }
267 :
268 : void
269 : fd_capture_link_write_bank_preimage_file( fd_capture_ctx_t * ctx,
270 : ulong slot,
271 : fd_hash_t const * bank_hash,
272 : fd_hash_t const * prev_bank_hash,
273 : fd_hash_t const * accounts_lt_hash_checksum,
274 : fd_hash_t const * poh_hash,
275 0 : ulong signature_cnt ) {
276 0 : if( FD_UNLIKELY( !ctx || !ctx->capture ) ) return;
277 0 : if ( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
278 :
279 0 : fd_solcap_writer_t * writer = ctx->capture;
280 :
281 0 : fd_solcap_buf_msg_t msg_hdr = {
282 0 : .sig = SOLCAP_WRITE_BANK_PREIMAGE,
283 0 : .slot = slot,
284 0 : .txn_idx = 0
285 0 : };
286 :
287 0 : fd_solcap_bank_preimage_t bank_preimage = {
288 0 : .bank_hash = *bank_hash,
289 0 : .prev_bank_hash = *prev_bank_hash,
290 0 : .accounts_lt_hash_checksum = *accounts_lt_hash_checksum,
291 0 : .poh_hash = *poh_hash,
292 0 : .signature_cnt = signature_cnt
293 0 : };
294 :
295 0 : uint block_len = fd_solcap_write_bank_preimage( writer, &msg_hdr, &bank_preimage );
296 :
297 0 : fd_solcap_write_ftr( writer, block_len );
298 0 : }
299 :
300 : void
301 : fd_capture_link_write_stake_rewards_begin_buf( fd_capture_ctx_t * ctx,
302 : ulong slot,
303 : ulong payout_epoch,
304 : ulong reward_epoch,
305 : ulong inflation_lamports,
306 0 : ulong total_points ) {
307 0 : if( FD_UNLIKELY( !ctx || !ctx->capctx_type.buf ) ) FD_LOG_ERR(( "NULL ctx (%p) or buf (%p)", (void *)ctx, (void *)ctx->capctx_type.buf ));
308 0 : if ( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
309 :
310 0 : fd_capture_link_buf_t * buf = ctx->capctx_type.buf;
311 :
312 0 : wait_to_write_solcap_msg( buf );
313 :
314 0 : uchar * dst = (uchar *)fd_chunk_to_laddr( buf->mem, buf->chunk );
315 0 : char * ptr = (char *)dst;
316 :
317 0 : fd_solcap_buf_msg_t msg = {
318 0 : .sig = SOLCAP_STAKE_REWARDS_BEGIN,
319 0 : .slot = slot,
320 0 : .txn_idx = 0
321 0 : };
322 :
323 0 : fd_memcpy( ptr, &msg, sizeof(fd_solcap_buf_msg_t) );
324 0 : ptr += sizeof(fd_solcap_buf_msg_t);
325 :
326 0 : fd_solcap_stake_rewards_begin_t stake_rewards_begin = {
327 0 : .payout_epoch = payout_epoch,
328 0 : .reward_epoch = reward_epoch,
329 0 : .inflation_lamports = inflation_lamports,
330 0 : .total_points = total_points
331 0 : };
332 0 : fd_memcpy( ptr, &stake_rewards_begin, sizeof(fd_solcap_stake_rewards_begin_t) );
333 0 : ulong ctl = fd_frag_meta_ctl( 0UL, 1UL, 1UL, 0UL );
334 0 : fd_mcache_publish( buf->mcache, buf->depth, buf->seq, 0UL, buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_stake_rewards_begin_t), ctl, 0UL, 0UL );
335 0 : buf->chunk = fd_dcache_compact_next( buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_stake_rewards_begin_t), buf->chunk0, buf->wmark );
336 0 : buf->seq++;
337 0 : }
338 :
339 : void
340 : fd_capture_link_write_stake_rewards_begin_file( fd_capture_ctx_t * ctx,
341 : ulong slot,
342 : ulong payout_epoch,
343 : ulong reward_epoch,
344 : ulong inflation_lamports,
345 0 : ulong total_points ) {
346 0 : if( FD_UNLIKELY( !ctx || !ctx->capture ) ) return;
347 0 : if ( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
348 :
349 0 : fd_solcap_writer_t * writer = ctx->capture;
350 :
351 0 : fd_solcap_buf_msg_t msg_hdr = {
352 0 : .sig = SOLCAP_STAKE_REWARDS_BEGIN,
353 0 : .slot = slot,
354 0 : .txn_idx = 0
355 0 : };
356 :
357 0 : fd_solcap_stake_rewards_begin_t stake_rewards_begin = {
358 0 : .payout_epoch = payout_epoch,
359 0 : .reward_epoch = reward_epoch,
360 0 : .inflation_lamports = inflation_lamports,
361 0 : .total_points = total_points
362 0 : };
363 :
364 0 : uint block_len = fd_solcap_write_stake_rewards_begin( writer, &msg_hdr, &stake_rewards_begin );
365 :
366 0 : fd_solcap_write_ftr( writer, block_len );
367 0 : }
368 :
369 : void
370 : fd_capture_link_write_stake_reward_event_buf( fd_capture_ctx_t * ctx,
371 : ulong slot,
372 : fd_pubkey_t stake_acc_addr,
373 : fd_pubkey_t vote_acc_addr,
374 : uint commission,
375 : long vote_rewards,
376 : long stake_rewards,
377 0 : long new_credits_observed ) {
378 0 : if( FD_UNLIKELY( !ctx || !ctx->capctx_type.buf ) ) FD_LOG_ERR(( "NULL ctx (%p) or buf (%p)", (void *)ctx, (void *)ctx->capctx_type.buf ));
379 0 : if ( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
380 :
381 0 : fd_capture_link_buf_t * buf = ctx->capctx_type.buf;
382 :
383 0 : wait_to_write_solcap_msg( buf );
384 :
385 0 : uchar * dst = (uchar *)fd_chunk_to_laddr( buf->mem, buf->chunk );
386 0 : char * ptr = (char *)dst;
387 :
388 0 : fd_solcap_buf_msg_t msg = {
389 0 : .sig = SOLCAP_STAKE_REWARD_EVENT,
390 0 : .slot = slot,
391 0 : .txn_idx = 0
392 0 : };
393 0 : fd_memcpy( ptr, &msg, sizeof(fd_solcap_buf_msg_t) );
394 0 : ptr += sizeof(fd_solcap_buf_msg_t);
395 :
396 0 : fd_solcap_stake_reward_event_t stake_reward_event = {
397 0 : .stake_acc_addr = stake_acc_addr,
398 0 : .vote_acc_addr = vote_acc_addr,
399 0 : .commission = commission,
400 0 : .vote_rewards = vote_rewards,
401 0 : .stake_rewards = stake_rewards,
402 0 : .new_credits_observed = new_credits_observed
403 0 : };
404 0 : fd_memcpy( ptr, &stake_reward_event, sizeof(fd_solcap_stake_reward_event_t) );
405 0 : ulong ctl = fd_frag_meta_ctl( 0UL, 1UL, 1UL, 0UL );
406 0 : fd_mcache_publish( buf->mcache, buf->depth, buf->seq, 0UL, buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_stake_reward_event_t), ctl, 0UL, 0UL );
407 0 : buf->chunk = fd_dcache_compact_next( buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_stake_reward_event_t), buf->chunk0, buf->wmark );
408 0 : buf->seq++;
409 0 : }
410 :
411 : void
412 : fd_capture_link_write_stake_reward_event_file( fd_capture_ctx_t * ctx,
413 : ulong slot,
414 : fd_pubkey_t stake_acc_addr,
415 : fd_pubkey_t vote_acc_addr,
416 : uint commission,
417 : long vote_rewards,
418 : long stake_rewards,
419 0 : long new_credits_observed ) {
420 0 : if( FD_UNLIKELY( !ctx || !ctx->capture ) ) return;
421 0 : if ( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
422 :
423 0 : fd_solcap_writer_t * writer = ctx->capture;
424 :
425 0 : fd_solcap_buf_msg_t msg_hdr = {
426 0 : .sig = SOLCAP_STAKE_REWARD_EVENT,
427 0 : .slot = slot,
428 0 : .txn_idx = 0
429 0 : };
430 :
431 0 : fd_solcap_stake_reward_event_t stake_reward_event = {
432 0 : .stake_acc_addr = stake_acc_addr,
433 0 : .vote_acc_addr = vote_acc_addr,
434 0 : .commission = commission,
435 0 : .vote_rewards = vote_rewards,
436 0 : .stake_rewards = stake_rewards,
437 0 : .new_credits_observed = new_credits_observed
438 0 : };
439 0 : uint block_len = fd_solcap_write_stake_reward_event( writer, &msg_hdr, &stake_reward_event );
440 0 : fd_solcap_write_ftr( writer, block_len );
441 0 : }
442 :
443 : void
444 : fd_capture_link_write_stake_account_payout_buf( fd_capture_ctx_t * ctx,
445 : ulong slot,
446 : fd_pubkey_t stake_acc_addr,
447 : ulong update_slot,
448 : ulong lamports,
449 : long lamports_delta,
450 : ulong credits_observed,
451 : long credits_observed_delta,
452 : ulong delegation_stake,
453 0 : long delegation_stake_delta ) {
454 0 : if( FD_UNLIKELY( !ctx || !ctx->capctx_type.buf ) ) FD_LOG_ERR(( "NULL ctx (%p) or buf (%p)", (void *)ctx, (void *)ctx->capctx_type.buf ));
455 0 : if ( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
456 :
457 0 : fd_capture_link_buf_t * buf = ctx->capctx_type.buf;
458 :
459 0 : wait_to_write_solcap_msg( buf );
460 :
461 0 : uchar * dst = (uchar *)fd_chunk_to_laddr( buf->mem, buf->chunk );
462 0 : char * ptr = (char *)dst;
463 :
464 0 : fd_solcap_buf_msg_t msg = {
465 0 : .sig = SOLCAP_STAKE_ACCOUNT_PAYOUT,
466 0 : .slot = slot,
467 0 : .txn_idx = 0
468 0 : };
469 0 : fd_memcpy( ptr, &msg, sizeof(fd_solcap_buf_msg_t) );
470 0 : ptr += sizeof(fd_solcap_buf_msg_t);
471 :
472 0 : fd_solcap_stake_account_payout_t stake_account_payout = {
473 0 : .stake_acc_addr = stake_acc_addr,
474 0 : .update_slot = update_slot,
475 0 : .lamports = lamports,
476 0 : .lamports_delta = lamports_delta,
477 0 : .credits_observed = credits_observed,
478 0 : .credits_observed_delta = credits_observed_delta,
479 0 : .delegation_stake = delegation_stake,
480 0 : .delegation_stake_delta = delegation_stake_delta,
481 0 : };
482 0 : fd_memcpy( ptr, &stake_account_payout, sizeof(fd_solcap_stake_account_payout_t) );
483 0 : ulong ctl = fd_frag_meta_ctl( 0UL, 1UL, 1UL, 0UL );
484 0 : fd_mcache_publish( buf->mcache, buf->depth, buf->seq, 0UL, buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_stake_account_payout_t), ctl, 0UL, 0UL );
485 0 : buf->chunk = fd_dcache_compact_next( buf->chunk, sizeof(fd_solcap_buf_msg_t) + sizeof(fd_solcap_stake_account_payout_t), buf->chunk0, buf->wmark );
486 0 : buf->seq++;
487 0 : }
488 :
489 : void
490 : fd_capture_link_write_stake_account_payout_file( fd_capture_ctx_t * ctx,
491 : ulong slot,
492 : fd_pubkey_t stake_acc_addr,
493 : ulong update_slot,
494 : ulong lamports,
495 : long lamports_delta,
496 : ulong credits_observed,
497 : long credits_observed_delta,
498 : ulong delegation_stake,
499 0 : long delegation_stake_delta ) {
500 0 : if( FD_UNLIKELY( !ctx || !ctx->capture ) ) return;
501 0 : if( FD_UNLIKELY( !valid_slot_range( ctx, slot ) ) ) return;
502 :
503 0 : fd_solcap_writer_t * writer = ctx->capture;
504 :
505 0 : fd_solcap_buf_msg_t msg_hdr = {
506 0 : .sig = SOLCAP_STAKE_ACCOUNT_PAYOUT,
507 0 : .slot = slot,
508 0 : .txn_idx = 0
509 0 : };
510 :
511 0 : fd_solcap_stake_account_payout_t stake_account_payout = {
512 0 : .stake_acc_addr = stake_acc_addr,
513 0 : .update_slot = update_slot,
514 0 : .lamports = lamports,
515 0 : .lamports_delta = lamports_delta,
516 0 : .credits_observed = credits_observed,
517 0 : .credits_observed_delta = credits_observed_delta,
518 0 : .delegation_stake = delegation_stake,
519 0 : .delegation_stake_delta = delegation_stake_delta,
520 0 : };
521 0 : uint block_len = fd_solcap_write_stake_account_payout( writer, &msg_hdr, &stake_account_payout );
522 0 : fd_solcap_write_ftr( writer, block_len );
523 0 : }
|