Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_capture_fd_capture_ctx_h
2 : #define HEADER_fd_src_flamenco_capture_fd_capture_ctx_h
3 :
4 : /* fd_capture_ctx provides a context for capturing Solana runtime data
5 : during transaction execution. The capture system supports two output
6 : modes:
7 :
8 : 1. Buffer mode: writes to a shared memory buffer that is consumed by
9 : a capture tile and subsequently written to a file. This is the
10 : default for live firedancer execution and backtest.
11 :
12 : 2. File mode: writes directly to a file. This is used for single-
13 : threaded harnesses that don't need the capture tile.
14 :
15 : Captured data includes account updates, bank preimages, and other
16 : runtime events in the solcap format. */
17 :
18 : #include "fd_solcap_writer.h"
19 : #include "../../util/fd_util_base.h"
20 : #include "../../util/log/fd_log.h"
21 : #include <sys/types.h>
22 : #include "../../tango/fd_tango_base.h"
23 :
24 : typedef struct fd_capture_link_vt fd_capture_link_vt_t;
25 :
26 : /* fd_capture_link_t is the base type for capture links. It uses a
27 : v-table pattern to support polymorphic write operations to either
28 : buffer or file destinations. */
29 :
30 : struct fd_capture_link {
31 : fd_capture_link_vt_t const * vt; /* Virtual function table for this link type */
32 : };
33 : typedef struct fd_capture_link fd_capture_link_t;
34 :
35 : /* fd_capture_link_buf_t is a capture link that writes to a shared
36 : memory buffer (frag stream). This buffer is consumed by a capture
37 : tile which writes the data to a file. */
38 :
39 : struct fd_capture_link_buf {
40 : fd_capture_link_t base;
41 : ulong idx;
42 : fd_wksp_t * mem;
43 : ulong chunk0;
44 : ulong wmark;
45 : ulong chunk;
46 : fd_frag_meta_t * mcache;
47 : ulong depth;
48 : ulong seq;
49 : ulong * fseq;
50 : };
51 : typedef struct fd_capture_link_buf fd_capture_link_buf_t;
52 :
53 : /* fd_capture_link_file_t is a capture link that writes directly to a
54 : file. Used in single-threaded harness mode. */
55 :
56 : struct fd_capture_link_file {
57 : fd_capture_link_t base;
58 : int fd;
59 : };
60 : typedef struct fd_capture_link_file fd_capture_link_file_t;
61 :
62 : /* fd_capture_link_vt_t is the virtual function table for capture
63 : links. This allows the capture context to write to different
64 : destinations (buffer or file) without needing to check the link type
65 : at each call site. */
66 :
67 : struct fd_capture_link_vt {
68 : void (* write_account_update)( fd_capture_ctx_t * ctx,
69 : ulong txn_idx,
70 : fd_pubkey_t const * key,
71 : fd_solana_account_meta_t const * info,
72 : ulong slot,
73 : uchar const * data,
74 : ulong data_sz);
75 :
76 : void (* write_bank_preimage)( fd_capture_ctx_t * ctx,
77 : ulong slot,
78 : fd_hash_t const * bank_hash,
79 : fd_hash_t const * prev_bank_hash,
80 : fd_hash_t const * accounts_lt_hash_checksum,
81 : fd_hash_t const * poh_hash,
82 : ulong signature_cnt);
83 :
84 : void (* write_stake_rewards_begin)( fd_capture_ctx_t * ctx,
85 : ulong slot,
86 : ulong payout_epoch,
87 : ulong reward_epoch,
88 : ulong inflation_lamports,
89 : ulong total_points);
90 :
91 : void (* write_stake_reward_event)( fd_capture_ctx_t * ctx,
92 : ulong slot,
93 : fd_pubkey_t stake_acc_addr,
94 : fd_pubkey_t vote_acc_addr,
95 : uint commission,
96 : long vote_rewards,
97 : long stake_rewards,
98 : long new_credits_observed );
99 :
100 : void (* write_stake_account_payout)( fd_capture_ctx_t * ctx,
101 : ulong slot,
102 : fd_pubkey_t stake_acc_addr,
103 : ulong update_slot,
104 : ulong lamports,
105 : long lamports_delta,
106 : ulong credits_observed,
107 : long credits_observed_delta,
108 : ulong delegation_stake,
109 : long delegation_stake_delta );
110 : };
111 :
112 :
113 : /* Context needed to do solcap capture during execution of transactions */
114 :
115 : struct fd_capture_ctx {
116 : ulong magic; /* ==FD_CAPTURE_CTX_MAGIC */
117 :
118 : int capture_solcap;
119 : fd_capture_link_t * capture_link;
120 : union {
121 : fd_capture_link_buf_t * buf;
122 : fd_capture_link_file_t * file;
123 : } capctx_type;
124 :
125 : /* Solcap */
126 : ulong solcap_start_slot;
127 : fd_solcap_writer_t * capture;
128 :
129 : ulong current_txn_idx;
130 : };
131 : typedef struct fd_capture_ctx fd_capture_ctx_t;
132 :
133 : static inline ulong
134 0 : fd_capture_ctx_align( void ) {
135 0 : return fd_ulong_max( alignof(fd_capture_ctx_t), fd_solcap_writer_align() );
136 0 : }
137 :
138 : static inline ulong
139 0 : fd_capture_ctx_footprint( void ) {
140 0 : ulong l = FD_LAYOUT_INIT;
141 0 : l = FD_LAYOUT_APPEND ( l, fd_capture_ctx_align(), sizeof(fd_capture_ctx_t) );
142 0 : l = FD_LAYOUT_APPEND ( l, fd_solcap_writer_align(), fd_solcap_writer_footprint() );
143 0 : return FD_LAYOUT_FINI ( l, fd_capture_ctx_align() );
144 0 : }
145 :
146 0 : #define FD_CAPTURE_CTX_MAGIC (0x193ECD2A6C395195UL) /* random */
147 :
148 : FD_PROTOTYPES_BEGIN
149 :
150 : void *
151 : fd_capture_ctx_new( void * mem );
152 :
153 : fd_capture_ctx_t *
154 : fd_capture_ctx_join( void * mem );
155 :
156 : void *
157 : fd_capture_ctx_leave( fd_capture_ctx_t * ctx );
158 :
159 : void *
160 : fd_capture_ctx_delete( void * mem );
161 :
162 : FD_PROTOTYPES_END
163 :
164 : /* Solcap capture link functions
165 :
166 : The following functions write solcap messages to either a buffer or
167 : file. They are used as v-table implementations for the capture link
168 : abstraction.
169 :
170 : For each message type, there are two implementations:
171 : - _buf: writes to a shared memory frag stream (buffer mode)
172 : - _file: writes directly to a file descriptor (file mode)
173 :
174 : The v-table dispatch mechanism automatically selects the correct
175 : implementation based on the link type, so callers use the inline
176 : wrapper functions below instead of calling these directly.
177 :
178 : */
179 :
180 : void
181 : fd_capture_link_write_account_update_buf( fd_capture_ctx_t * ctx,
182 : ulong txn_idx,
183 : fd_pubkey_t const * key,
184 : fd_solana_account_meta_t const * info,
185 : ulong slot,
186 : uchar const * data,
187 : ulong data_sz );
188 :
189 : void
190 : fd_capture_link_write_account_update_file( fd_capture_ctx_t * ctx,
191 : ulong txn_idx,
192 : fd_pubkey_t const * key,
193 : fd_solana_account_meta_t const * info,
194 : ulong slot,
195 : uchar const * data,
196 : ulong data_sz );
197 :
198 : /* fd_capture_link_write_account_update writes an account update to the
199 : capture link. Uses v-table dispatch to automatically route to the
200 : correct implementation (buffer or file) based on the link type. */
201 :
202 : static inline void
203 : fd_capture_link_write_account_update( fd_capture_ctx_t * ctx,
204 : ulong txn_idx,
205 : fd_pubkey_t const * key,
206 : fd_solana_account_meta_t const * info,
207 : ulong slot,
208 : uchar const * data,
209 0 : ulong data_sz ) {
210 0 : FD_TEST( ctx && ctx->capture_link );
211 0 : ctx->capture_link->vt->write_account_update( ctx, txn_idx, key, info, slot, data, data_sz );
212 0 : }
213 :
214 : void
215 : fd_capture_link_write_bank_preimage_buf( fd_capture_ctx_t * ctx,
216 : ulong slot,
217 : fd_hash_t const * bank_hash,
218 : fd_hash_t const * prev_bank_hash,
219 : fd_hash_t const * accounts_lt_hash_checksum,
220 : fd_hash_t const * poh_hash,
221 : ulong signature_cnt );
222 :
223 : void
224 : fd_capture_link_write_bank_preimage_file( fd_capture_ctx_t * ctx,
225 : ulong slot,
226 : fd_hash_t const * bank_hash,
227 : fd_hash_t const * prev_bank_hash,
228 : fd_hash_t const * accounts_lt_hash_checksum,
229 : fd_hash_t const * poh_hash,
230 : ulong signature_cnt );
231 :
232 : /* fd_capture_link_write_bank_preimage writes a bank preimage to the
233 : capture link. Uses v-table dispatch to automatically route to the
234 : correct implementation (buffer or file) based on the link type. */
235 :
236 : static inline void
237 : fd_capture_link_write_bank_preimage( fd_capture_ctx_t * ctx,
238 : ulong slot,
239 : fd_hash_t const * bank_hash,
240 : fd_hash_t const * prev_bank_hash,
241 : fd_hash_t const * accounts_lt_hash_checksum,
242 : fd_hash_t const * poh_hash,
243 0 : ulong signature_cnt ) {
244 0 : FD_TEST( ctx && ctx->capture_link );
245 0 : ctx->capture_link->vt->write_bank_preimage( ctx, slot, bank_hash, prev_bank_hash, accounts_lt_hash_checksum, poh_hash, signature_cnt );
246 0 : }
247 :
248 : /* fd_capture_link_write_stake_rewards_begin writes a stake rewards begin to the
249 : capture link. Uses v-table dispatch to automatically route to the
250 : correct implementation (buffer or file) based on the link type. */
251 :
252 : void
253 : fd_capture_link_write_stake_rewards_begin_buf( fd_capture_ctx_t * ctx,
254 : ulong slot,
255 : ulong payout_epoch,
256 : ulong reward_epoch,
257 : ulong inflation_lamports,
258 : ulong total_points );
259 :
260 : void
261 : fd_capture_link_write_stake_rewards_begin_file( fd_capture_ctx_t * ctx,
262 : ulong slot,
263 : ulong payout_epoch,
264 : ulong reward_epoch,
265 : ulong inflation_lamports,
266 : ulong total_points );
267 :
268 : static inline void
269 : fd_capture_link_write_stake_rewards_begin( fd_capture_ctx_t * ctx,
270 : ulong slot,
271 : ulong payout_epoch,
272 : ulong reward_epoch,
273 : ulong inflation_lamports,
274 0 : ulong total_points ) {
275 0 : FD_TEST( ctx && ctx->capture_link );
276 0 : ctx->capture_link->vt->write_stake_rewards_begin( ctx, slot, payout_epoch, reward_epoch, inflation_lamports, total_points );
277 0 : }
278 :
279 : void
280 : fd_capture_link_write_stake_reward_event_buf( fd_capture_ctx_t * ctx,
281 : ulong slot,
282 : fd_pubkey_t stake_acc_addr,
283 : fd_pubkey_t vote_acc_addr,
284 : uint commission,
285 : long vote_rewards,
286 : long stake_rewards,
287 : long new_credits_observed );
288 :
289 : void
290 : fd_capture_link_write_stake_reward_event_file( fd_capture_ctx_t * ctx,
291 : ulong slot,
292 : fd_pubkey_t stake_acc_addr,
293 : fd_pubkey_t vote_acc_addr,
294 : uint commission,
295 : long vote_rewards,
296 : long stake_rewards,
297 : long new_credits_observed );
298 :
299 : static inline void
300 : fd_capture_link_write_stake_reward_event( fd_capture_ctx_t * ctx,
301 : ulong slot,
302 : fd_pubkey_t stake_acc_addr,
303 : fd_pubkey_t vote_acc_addr,
304 : uint commission,
305 : long vote_rewards,
306 : long stake_rewards,
307 0 : long new_credits_observed ) {
308 0 : FD_TEST( ctx && ctx->capture_link );
309 0 : ctx->capture_link->vt->write_stake_reward_event( ctx, slot, stake_acc_addr, vote_acc_addr, commission, vote_rewards, stake_rewards, new_credits_observed );
310 0 : }
311 :
312 : void
313 : fd_capture_link_write_stake_account_payout_buf( fd_capture_ctx_t * ctx,
314 : ulong slot,
315 : fd_pubkey_t stake_acc_addr,
316 : ulong update_slot,
317 : ulong lamports,
318 : long lamports_delta,
319 : ulong credits_observed,
320 : long credits_observed_delta,
321 : ulong delegation_stake,
322 : long delegation_stake_delta );
323 : void
324 : fd_capture_link_write_stake_account_payout_file( fd_capture_ctx_t * ctx,
325 : ulong slot,
326 : fd_pubkey_t stake_acc_addr,
327 : ulong update_slot,
328 : ulong lamports,
329 : long lamports_delta,
330 : ulong credits_observed,
331 : long credits_observed_delta,
332 : ulong delegation_stake,
333 : long delegation_stake_delta );
334 :
335 : static inline void
336 : fd_capture_link_write_stake_account_payout( fd_capture_ctx_t * ctx,
337 : ulong slot,
338 : fd_pubkey_t stake_acc_addr,
339 : ulong update_slot,
340 : ulong lamports,
341 : long lamports_delta,
342 : ulong credits_observed,
343 : long credits_observed_delta,
344 : ulong delegation_stake,
345 0 : long delegation_stake_delta ) {
346 0 : FD_TEST( ctx && ctx->capture_link );
347 0 : ctx->capture_link->vt->write_stake_account_payout( ctx, slot, stake_acc_addr, update_slot, lamports, lamports_delta, credits_observed, credits_observed_delta, delegation_stake, delegation_stake_delta );
348 0 : }
349 :
350 : /* fd_capture_link_buf_vt is the v-table for buffer mode capture links.
351 : It routes all write operations to the buffer implementations. */
352 :
353 : static const
354 : fd_capture_link_vt_t fd_capture_link_buf_vt = {
355 : .write_account_update = fd_capture_link_write_account_update_buf,
356 : .write_bank_preimage = fd_capture_link_write_bank_preimage_buf,
357 : .write_stake_rewards_begin = fd_capture_link_write_stake_rewards_begin_buf,
358 : .write_stake_reward_event = fd_capture_link_write_stake_reward_event_buf,
359 : .write_stake_account_payout = fd_capture_link_write_stake_account_payout_buf,
360 : };
361 :
362 : /* fd_capture_link_file_vt is the v-table for file mode capture links.
363 : It routes all write operations to the file implementations. */
364 :
365 : static const
366 : fd_capture_link_vt_t fd_capture_link_file_vt = {
367 : .write_account_update = fd_capture_link_write_account_update_file,
368 : .write_bank_preimage = fd_capture_link_write_bank_preimage_file,
369 : .write_stake_rewards_begin = fd_capture_link_write_stake_rewards_begin_file,
370 : .write_stake_reward_event = fd_capture_link_write_stake_reward_event_file,
371 : .write_stake_account_payout = fd_capture_link_write_stake_account_payout_file,
372 : };
373 :
374 : #endif /* HEADER_fd_src_flamenco_capture_fd_capture_ctx_h */
375 :
|