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 : /* Information from the accounts database as of the start of the slot
70 : determined by the bank above that is necessary to crank the bundle
71 : tip programs properly. If bundles are not enabled (determined
72 : externally, but the relevant tiles should know), these fields are
73 : set to 0. */
74 : struct {
75 : fd_bundle_crank_tip_payment_config_t config[1];
76 : uchar tip_receiver_owner[32];
77 : uchar last_blockhash[32];
78 : } bundle[1];
79 : };
80 : typedef struct fd_became_leader fd_became_leader_t;
81 :
82 : struct fd_rooted_bank {
83 : void * bank;
84 : ulong slot;
85 : };
86 :
87 : typedef struct fd_rooted_bank fd_rooted_bank_t;
88 :
89 : struct fd_completed_bank {
90 : ulong slot;
91 : uchar hash[32];
92 : };
93 :
94 : typedef struct fd_completed_bank fd_completed_bank_t;
95 :
96 : struct fd_microblock_trailer {
97 : /* The hash of the transactions in the microblock, ready to be
98 : mixed into PoH. */
99 : uchar hash[ 32UL ];
100 :
101 : /* If this is a microblock for the last transaction in a bundle,
102 : (or always true, if not a bundle). Useful for monitoring tools to
103 : determine when the bank is done executing. */
104 : uchar is_last_in_bundle;
105 : };
106 : typedef struct fd_microblock_trailer fd_microblock_trailer_t;
107 :
108 : struct fd_done_packing {
109 : ulong microblocks_in_slot;
110 : };
111 : typedef struct fd_done_packing fd_done_packing_t;
112 :
113 : struct fd_microblock_bank_trailer {
114 : /* An opaque pointer to the bank to use when executing and committing
115 : transactions. The lifetime of the bank is owned by the PoH tile,
116 : which guarantees it is valid while pack or bank tiles might be
117 : using it. */
118 : void const * bank;
119 :
120 : /* The sequentially increasing index of the microblock, across all
121 : banks. This is used by PoH to ensure microblocks get committed
122 : in the same order they are executed. */
123 : ulong microblock_idx;
124 :
125 : /* If the microblock is a bundle, with a set of potentially
126 : conflciting transactions that should be executed in order, and
127 : all either commit or fail atomically. */
128 : int is_bundle;
129 : };
130 : typedef struct fd_microblock_bank_trailer fd_microblock_bank_trailer_t;
131 :
132 : typedef struct __attribute__((packed)) {
133 : ulong tick_duration_ns;
134 : ulong hashcnt_per_tick;
135 : ulong ticks_per_slot;
136 : ulong tick_height;
137 : uchar last_entry_hash[32];
138 : } fd_poh_init_msg_t;
139 :
140 : /* A fd_txn_m_t is a parsed meta transaction, containing not just the
141 : payload */
142 :
143 : struct fd_txn_m {
144 : /* The computed slot that this transaction is referencing, aka. the
145 : slot number of the reference_blockhash. If it could not be
146 : determined, this will be the current slot. */
147 : ulong reference_slot;
148 :
149 : ushort payload_sz;
150 :
151 : /* Can be computed from the txn_t but it's expensive to parse again,
152 : so we just store this redundantly. */
153 : ushort txn_t_sz;
154 :
155 : /* 4 bytes of padding here */
156 :
157 : struct {
158 : /* If the transaction is part of a bundle, the bundle_id will be
159 : non-zero, and if this transaction is the first one in the
160 : bundle, bundle_txn_cnt will be non-zero.
161 :
162 : The pack tile can accumulate transactions from a bundle until
163 : it has all of them, at which point the bundle is schedulable.
164 :
165 : Bundles will not arrive to pack interleaved with other bundles
166 : (although might be interleaved with other non-bundle
167 : transactions), so if pack sees the bundle_id change before
168 : collecting all the bundle_txn_cnt transactions, it should
169 : abandon the bundle, as one or more of the transactions failed
170 : to signature verify or resolve.
171 :
172 : The commission and commission_pubkey fields are provided by
173 : the block engine, and the validator will crank the tip payment
174 : program with these values, if it is not using them already.
175 : These fields are only provided on the first transaction in a
176 : bundle. */
177 : ulong bundle_id;
178 : ulong bundle_txn_cnt;
179 : uchar commission;
180 : uchar commission_pubkey[ 32 ];
181 : } block_engine;
182 :
183 : /* alignof is 8, so 7 bytes of padding here */
184 :
185 : /* There are three additional fields at the end here, which are
186 : variable length and not included in the size of this struct.
187 : uchar payload[ ]
188 : fd_txn_t txn_t[ ]
189 : fd_acct_addr_t alut[ ] */
190 : };
191 :
192 : typedef struct fd_txn_m fd_txn_m_t;
193 :
194 : static FD_FN_CONST inline ulong
195 0 : fd_txn_m_align( void ) {
196 0 : return alignof( fd_txn_m_t );
197 0 : }
198 :
199 : static inline ulong
200 : fd_txn_m_footprint( ulong payload_sz,
201 : ulong instr_cnt,
202 : ulong addr_table_lookup_cnt,
203 0 : ulong addr_table_adtl_cnt ) {
204 0 : ulong l = FD_LAYOUT_INIT;
205 0 : l = FD_LAYOUT_APPEND( l, alignof(fd_txn_m_t), sizeof(fd_txn_m_t) );
206 0 : l = FD_LAYOUT_APPEND( l, 1UL, payload_sz );
207 0 : l = FD_LAYOUT_APPEND( l, fd_txn_align(), fd_txn_footprint( instr_cnt, addr_table_lookup_cnt ) );
208 0 : l = FD_LAYOUT_APPEND( l, alignof(fd_acct_addr_t), addr_table_adtl_cnt*sizeof(fd_acct_addr_t) );
209 0 : return FD_LAYOUT_FINI( l, fd_txn_m_align() );
210 0 : }
211 :
212 : static inline uchar *
213 0 : fd_txn_m_payload( fd_txn_m_t * txnm ) {
214 0 : return (uchar *)(txnm+1UL);
215 0 : }
216 :
217 : static inline fd_txn_t *
218 0 : fd_txn_m_txn_t( fd_txn_m_t * txnm ) {
219 0 : return (fd_txn_t *)fd_ulong_align_up( (ulong)(txnm+1UL) + txnm->payload_sz, alignof( fd_txn_t ) );
220 0 : }
221 :
222 : static inline fd_txn_t const *
223 0 : fd_txn_m_txn_t_const( fd_txn_m_t const * txnm ) {
224 0 : return (fd_txn_t const *)fd_ulong_align_up( (ulong)(txnm+1UL) + txnm->payload_sz, alignof( fd_txn_t ) );
225 0 : }
226 :
227 : static inline fd_acct_addr_t *
228 0 : fd_txn_m_alut( fd_txn_m_t * txnm ) {
229 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 ) );
230 0 : }
231 :
232 : static inline ulong
233 : fd_txn_m_realized_footprint( fd_txn_m_t const * txnm,
234 : int include_txn_t,
235 0 : int include_alut ) {
236 0 : if( FD_LIKELY( include_txn_t ) ) {
237 0 : return fd_txn_m_footprint( txnm->payload_sz,
238 0 : fd_txn_m_txn_t_const( txnm )->instr_cnt,
239 0 : fd_txn_m_txn_t_const( txnm )->addr_table_lookup_cnt,
240 0 : include_alut ? fd_txn_m_txn_t_const( txnm )->addr_table_adtl_cnt : 0UL );
241 0 : } else {
242 0 : ulong l = FD_LAYOUT_INIT;
243 0 : l = FD_LAYOUT_APPEND( l, alignof(fd_txn_m_t), sizeof(fd_txn_m_t) );
244 0 : l = FD_LAYOUT_APPEND( l, 1UL, txnm->payload_sz );
245 0 : return FD_LAYOUT_FINI( l, fd_txn_m_align() );
246 0 : }
247 0 : }
248 :
249 : #define FD_TPU_RAW_MTU FD_ULONG_ALIGN_UP( \
250 : sizeof(fd_txn_m_t)+FD_TPU_MTU, \
251 : alignof(fd_txn_m_t) )
252 :
253 21 : #define FD_TPU_PARSED_MTU FD_ULONG_ALIGN_UP( \
254 21 : FD_ULONG_ALIGN_UP( \
255 21 : sizeof(fd_txn_m_t)+FD_TPU_MTU, \
256 21 : alignof(fd_txn_t) ) \
257 21 : +FD_TXN_MAX_SZ, \
258 21 : alignof(fd_txn_m_t) )
259 :
260 3 : #define FD_TPU_RESOLVED_MTU FD_ULONG_ALIGN_UP( \
261 3 : FD_ULONG_ALIGN_UP( \
262 3 : FD_ULONG_ALIGN_UP( \
263 3 : sizeof(fd_txn_m_t)+FD_TPU_MTU, \
264 3 : alignof(fd_txn_t) ) \
265 3 : +FD_TXN_MAX_SZ, \
266 3 : alignof(fd_acct_addr_t) ) \
267 3 : +256UL*sizeof(fd_acct_addr_t), \
268 3 : alignof(fd_txn_m_t) )
269 :
270 : #endif /* HEADER_fd_src_app_fdctl_run_tiles_h */
|