Line data Source code
1 : #ifndef HEADER_fd_src_app_fdctl_run_tiles_h
2 : #define HEADER_fd_src_app_fdctl_run_tiles_h
3 :
4 : #include "stem/fd_stem.h"
5 : #include "shred/fd_shredder.h"
6 : #include "../ballet/shred/fd_shred.h"
7 : #include "pack/fd_pack.h"
8 : #include "topo/fd_topo.h"
9 : #include "plugin/fd_bundle_crank.h"
10 :
11 : #include <linux/filter.h>
12 :
13 : /* fd_shred34 is a collection of up to 34 shreds batched in a way that's
14 : convenient for use in a dcache and for access from Rust. The limit of
15 : 34 comes so that sizeof( fd_shred34_t ) < USHORT_MAX. */
16 :
17 : struct __attribute__((aligned(FD_CHUNK_ALIGN))) fd_shred34 {
18 : ulong shred_cnt;
19 :
20 : /* est_txn_cnt: An estimate of the number of transactions contained in this
21 : shred34_t. The true value might not be a whole number, but this is
22 : helpful for diagnostic purposes. */
23 : ulong est_txn_cnt;
24 : ulong stride;
25 : ulong offset;
26 : ulong shred_sz; /* The size of each shred */
27 : /* For i in [0, shred_cnt), shred i's payload spans bytes
28 : [i*stride+offset, i*stride+offset+shred_sz ), counting from the
29 : start of the struct, not this point. */
30 : union {
31 : fd_shred_t shred;
32 : uchar buffer[ FD_SHRED_MAX_SZ ];
33 : } pkts[ 34 ];
34 : };
35 : typedef struct fd_shred34 fd_shred34_t;
36 :
37 : struct fd_became_leader {
38 : /* Start and end time of the slot in nanoseconds (from
39 : fd_log_wallclock()). */
40 : long slot_start_ns;
41 : long slot_end_ns;
42 :
43 : /* An opaque pointer to a Rust Arc<Bank> object, which should only
44 : be used with fd_ext_* functions to execute transactions or drop
45 : the bank. The ownership is complicated, but basically any bank
46 : tile that receives this frag has a strong refcnt to the bank and
47 : should release it when done, other tiles should ignore and never
48 : use the bank. */
49 : void const * bank;
50 :
51 : /* The maximum number of microblocks that pack is allowed to put
52 : into the block. This allows PoH to accurately track and make sure
53 : microblocks do not need to be dropped. */
54 : ulong max_microblocks_in_slot;
55 :
56 : /* The number of ticks (effectively empty microblocks) that the PoH
57 : tile will put in the block. This is used to adjust some pack
58 : limits. */
59 : ulong ticks_per_slot;
60 :
61 : /* The number of ticks that the PoH tile has skipped, but needs to
62 : publish to show peers they were skipped correctly. This is used
63 : to adjust some pack limits. */
64 : ulong total_skipped_ticks;
65 :
66 : /* The epoch of the slot for which we are becoming leader. */
67 : ulong epoch;
68 :
69 : /* Consensus-critical cost limits for the slot we are becoming leader.
70 : These are typically unchanging, but may change after a feature
71 : activation. */
72 : struct {
73 : ulong slot_max_cost;
74 : ulong slot_max_vote_cost;
75 : ulong slot_max_write_cost_per_acct;
76 : } limits;
77 :
78 : /* Information from the accounts database as of the start of the slot
79 : determined by the bank above that is necessary to crank the bundle
80 : tip programs properly. If bundles are not enabled (determined
81 : externally, but the relevant tiles should know), these fields are
82 : set to 0. */
83 : struct {
84 : fd_bundle_crank_tip_payment_config_t config[1];
85 : uchar tip_receiver_owner[32];
86 : uchar last_blockhash[32];
87 : } bundle[1];
88 : };
89 : typedef struct fd_became_leader fd_became_leader_t;
90 :
91 : struct fd_rooted_bank {
92 : void * bank;
93 : ulong slot;
94 : };
95 :
96 : typedef struct fd_rooted_bank fd_rooted_bank_t;
97 :
98 : struct fd_completed_bank {
99 : ulong slot;
100 : uchar hash[32];
101 : };
102 :
103 : typedef struct fd_completed_bank fd_completed_bank_t;
104 :
105 : struct fd_microblock_trailer {
106 : /* The hash of the transactions in the microblock, ready to be
107 : mixed into PoH. */
108 : uchar hash[ 32UL ];
109 :
110 : /* A sequentially increasing index of the first transaction in the
111 : microblock, across all slots ever processed by pack. This is used
112 : by monitoring tools that maintain an ordered history of
113 : transactions. */
114 : ulong pack_txn_idx;
115 :
116 : /* The tips included in the transaction, in lamports. 0 for non-bundle
117 : transactions */
118 : ulong tips;
119 :
120 : /* If the duration of a microblock is the difference between the
121 : publish timestamp of the microblock from pack and the publish
122 : timestamp of the microblock from bank, then these represent the
123 : elapsed time between the start of the microblock and the 3 state
124 : transitions (ready->start loading, loading -> execute, execute ->
125 : done) for the first transaction.
126 :
127 : For example, if a microblock starts at t=10 and ends at t=20, and
128 : txn_exec_end_pct is UCHAR_MAX / 2, then this transaction started
129 : executing at roughly 10+(20-10)*(128/UCHAR_MAX)=15 */
130 : uchar txn_start_pct;
131 : uchar txn_load_end_pct;
132 : uchar txn_end_pct;
133 : };
134 : typedef struct fd_microblock_trailer fd_microblock_trailer_t;
135 :
136 : struct fd_done_packing {
137 : ulong microblocks_in_slot;
138 : };
139 : typedef struct fd_done_packing fd_done_packing_t;
140 :
141 : struct fd_microblock_bank_trailer {
142 : /* An opaque pointer to the bank to use when executing and committing
143 : transactions. The lifetime of the bank is owned by the PoH tile,
144 : which guarantees it is valid while pack or bank tiles might be
145 : using it. */
146 : void const * bank;
147 :
148 : /* The sequentially increasing index of the microblock, across all
149 : banks. This is used by PoH to ensure microblocks get committed
150 : in the same order they are executed. */
151 : ulong microblock_idx;
152 :
153 : /* A sequentially increasing index of the first transaction in the
154 : microblock, across all slots ever processed by pack. This is used
155 : by monitoring tools that maintain an ordered history of
156 : transactions. */
157 : ulong pack_txn_idx;
158 :
159 : /* If the microblock is a bundle, with a set of potentially
160 : conflicting transactions that should be executed in order, and
161 : all either commit or fail atomically. */
162 : int is_bundle;
163 : };
164 : typedef struct fd_microblock_bank_trailer fd_microblock_bank_trailer_t;
165 :
166 : typedef struct __attribute__((packed)) {
167 : ulong tick_duration_ns;
168 : ulong hashcnt_per_tick;
169 : ulong ticks_per_slot;
170 : ulong tick_height;
171 : uchar last_entry_hash[32];
172 : } fd_poh_init_msg_t;
173 :
174 : /* A fd_txn_m_t is a parsed meta transaction, containing not just the
175 : payload */
176 :
177 : struct fd_txn_m {
178 : /* The computed slot that this transaction is referencing, aka. the
179 : slot number of the reference_blockhash. If it could not be
180 : determined, this will be the current slot. */
181 : ulong reference_slot;
182 :
183 : ushort payload_sz;
184 :
185 : /* Can be computed from the txn_t but it's expensive to parse again,
186 : so we just store this redundantly. */
187 : ushort txn_t_sz;
188 :
189 : /* 4 bytes of padding here */
190 :
191 : struct {
192 : /* If the transaction is part of a bundle, the bundle_id will be
193 : non-zero, and if this transaction is the first one in the
194 : bundle, bundle_txn_cnt will be non-zero.
195 :
196 : The pack tile can accumulate transactions from a bundle until
197 : it has all of them, at which point the bundle is schedulable.
198 :
199 : Bundles will not arrive to pack interleaved with other bundles
200 : (although might be interleaved with other non-bundle
201 : transactions), so if pack sees the bundle_id change before
202 : collecting all the bundle_txn_cnt transactions, it should
203 : abandon the bundle, as one or more of the transactions failed
204 : to signature verify or resolve.
205 :
206 : The commission and commission_pubkey fields are provided by
207 : the block engine, and the validator will crank the tip payment
208 : program with these values, if it is not using them already.
209 : These fields are only provided on the first transaction in a
210 : bundle. */
211 : ulong bundle_id;
212 : ulong bundle_txn_cnt;
213 : uchar commission;
214 : uchar commission_pubkey[ 32 ];
215 : } block_engine;
216 :
217 : /* alignof is 8, so 7 bytes of padding here */
218 :
219 : /* There are three additional fields at the end here, which are
220 : variable length and not included in the size of this struct.
221 : uchar payload[ ]
222 : fd_txn_t txn_t[ ]
223 : fd_acct_addr_t alut[ ] */
224 : };
225 :
226 : typedef struct fd_txn_m fd_txn_m_t;
227 :
228 : static FD_FN_CONST inline ulong
229 0 : fd_txn_m_align( void ) {
230 0 : return alignof( fd_txn_m_t );
231 0 : }
232 :
233 : static inline ulong
234 : fd_txn_m_footprint( ulong payload_sz,
235 : ulong instr_cnt,
236 : ulong addr_table_lookup_cnt,
237 0 : ulong addr_table_adtl_cnt ) {
238 0 : ulong l = FD_LAYOUT_INIT;
239 0 : l = FD_LAYOUT_APPEND( l, alignof(fd_txn_m_t), sizeof(fd_txn_m_t) );
240 0 : l = FD_LAYOUT_APPEND( l, 1UL, payload_sz );
241 0 : l = FD_LAYOUT_APPEND( l, fd_txn_align(), fd_txn_footprint( instr_cnt, addr_table_lookup_cnt ) );
242 0 : l = FD_LAYOUT_APPEND( l, alignof(fd_acct_addr_t), addr_table_adtl_cnt*sizeof(fd_acct_addr_t) );
243 0 : return FD_LAYOUT_FINI( l, fd_txn_m_align() );
244 0 : }
245 :
246 : static inline uchar *
247 0 : fd_txn_m_payload( fd_txn_m_t * txnm ) {
248 0 : return (uchar *)(txnm+1UL);
249 0 : }
250 :
251 : static inline fd_txn_t *
252 0 : fd_txn_m_txn_t( fd_txn_m_t * txnm ) {
253 0 : return (fd_txn_t *)fd_ulong_align_up( (ulong)(txnm+1UL) + txnm->payload_sz, alignof( fd_txn_t ) );
254 0 : }
255 :
256 : static inline fd_txn_t const *
257 0 : fd_txn_m_txn_t_const( fd_txn_m_t const * txnm ) {
258 0 : return (fd_txn_t const *)fd_ulong_align_up( (ulong)(txnm+1UL) + txnm->payload_sz, alignof( fd_txn_t ) );
259 0 : }
260 :
261 : static inline fd_acct_addr_t *
262 0 : fd_txn_m_alut( fd_txn_m_t * txnm ) {
263 0 : return (fd_acct_addr_t *)fd_ulong_align_up( fd_ulong_align_up( (ulong)(txnm+1UL) + txnm->payload_sz, alignof( fd_txn_t ) )+txnm->txn_t_sz, alignof( fd_acct_addr_t ) );
264 0 : }
265 :
266 : static inline ulong
267 : fd_txn_m_realized_footprint( fd_txn_m_t const * txnm,
268 : int include_txn_t,
269 0 : int include_alut ) {
270 0 : if( FD_LIKELY( include_txn_t ) ) {
271 0 : return fd_txn_m_footprint( txnm->payload_sz,
272 0 : fd_txn_m_txn_t_const( txnm )->instr_cnt,
273 0 : fd_txn_m_txn_t_const( txnm )->addr_table_lookup_cnt,
274 0 : include_alut ? fd_txn_m_txn_t_const( txnm )->addr_table_adtl_cnt : 0UL );
275 0 : } else {
276 0 : ulong l = FD_LAYOUT_INIT;
277 0 : l = FD_LAYOUT_APPEND( l, alignof(fd_txn_m_t), sizeof(fd_txn_m_t) );
278 0 : l = FD_LAYOUT_APPEND( l, 1UL, txnm->payload_sz );
279 0 : return FD_LAYOUT_FINI( l, fd_txn_m_align() );
280 0 : }
281 0 : }
282 :
283 : #define FD_TPU_RAW_MTU FD_ULONG_ALIGN_UP( \
284 : sizeof(fd_txn_m_t)+FD_TPU_MTU, \
285 : alignof(fd_txn_m_t) )
286 :
287 21 : #define FD_TPU_PARSED_MTU FD_ULONG_ALIGN_UP( \
288 21 : FD_ULONG_ALIGN_UP( \
289 21 : sizeof(fd_txn_m_t)+FD_TPU_MTU, \
290 21 : alignof(fd_txn_t) ) \
291 21 : +FD_TXN_MAX_SZ, \
292 21 : alignof(fd_txn_m_t) )
293 :
294 3 : #define FD_TPU_RESOLVED_MTU FD_ULONG_ALIGN_UP( \
295 3 : FD_ULONG_ALIGN_UP( \
296 3 : FD_ULONG_ALIGN_UP( \
297 3 : sizeof(fd_txn_m_t)+FD_TPU_MTU, \
298 3 : alignof(fd_txn_t) ) \
299 3 : +FD_TXN_MAX_SZ, \
300 3 : alignof(fd_acct_addr_t) ) \
301 3 : +256UL*sizeof(fd_acct_addr_t), \
302 3 : alignof(fd_txn_m_t) )
303 :
304 : #endif /* HEADER_fd_src_app_fdctl_run_tiles_h */
|