Line data Source code
1 : #include "../shared/fd_config.h"
2 :
3 : #include "../../disco/net/fd_net_tile.h"
4 : #include "../../disco/quic/fd_tpu.h"
5 : #include "../../disco/tiles.h"
6 : #include "../../disco/topo/fd_topob.h"
7 : #include "../../disco/topo/fd_cpu_topo.h"
8 : #include "../../disco/bundle/fd_bundle_tile.h"
9 : #include "../../util/pod/fd_pod_format.h"
10 : #include "../../util/net/fd_ip4.h"
11 :
12 : extern fd_topo_obj_callbacks_t * CALLBACKS[];
13 :
14 : static void
15 0 : parse_ip_port( const char * name, const char * ip_port, fd_topo_ip_port_t *parsed_ip_port) {
16 0 : char buf[ sizeof( "255.255.255.255:65536" ) ];
17 0 : memcpy( buf, ip_port, sizeof( buf ) );
18 0 : char *ip_end = strchr( buf, ':' );
19 0 : if( FD_UNLIKELY( !ip_end ) )
20 0 : FD_LOG_ERR(( "[%s] must in the form ip:port", name ));
21 0 : *ip_end = '\0';
22 :
23 0 : if( FD_UNLIKELY( !fd_cstr_to_ip4_addr( buf, &( parsed_ip_port->ip ) ) ) ) {
24 0 : FD_LOG_ERR(( "could not parse IP %s in [%s]", buf, name ));
25 0 : }
26 :
27 0 : parsed_ip_port->port = fd_cstr_to_ushort( ip_end+1 );
28 0 : if( FD_UNLIKELY( !parsed_ip_port->port ) )
29 0 : FD_LOG_ERR(( "could not parse port %s in [%s]", ip_end+1, name ));
30 0 : }
31 :
32 : void
33 : fd_topo_configure_tile( fd_topo_tile_t * tile,
34 : fd_config_t * config );
35 :
36 : void
37 0 : fd_topo_initialize( config_t * config ) {
38 0 : ulong net_tile_cnt = config->layout.net_tile_count;
39 0 : ulong quic_tile_cnt = config->layout.quic_tile_count;
40 0 : ulong verify_tile_cnt = config->layout.verify_tile_count;
41 0 : ulong resolh_tile_cnt = config->frankendancer.layout.resolh_tile_count;
42 0 : ulong bank_tile_cnt = config->frankendancer.layout.bank_tile_count;
43 0 : ulong shred_tile_cnt = config->layout.shred_tile_count;
44 0 : fd_topo_t * topo = { fd_topob_new( &config->topo, config->name ) };
45 0 : topo->max_page_size = fd_cstr_to_shmem_page_sz( config->hugetlbfs.max_page_size );
46 0 : topo->gigantic_page_threshold = config->hugetlbfs.gigantic_page_threshold_mib << 20;
47 :
48 : /* topo, name */
49 0 : fd_topob_wksp( topo, "metric_in" );
50 0 : fd_topob_wksp( topo, "net_quic" );
51 0 : fd_topob_wksp( topo, "net_shred" );
52 0 : fd_topob_wksp( topo, "quic_verify" );
53 0 : fd_topob_wksp( topo, "verify_dedup" );
54 0 : fd_topob_wksp( topo, "dedup_resolh" );
55 0 : fd_topob_wksp( topo, "resolh_pack" );
56 0 : fd_topob_wksp( topo, "pack_bank" );
57 0 : fd_topob_wksp( topo, "pack_pohh" );
58 0 : fd_topob_wksp( topo, "bank_pack" );
59 0 : fd_topob_wksp( topo, "bank_pohh" );
60 0 : fd_topob_wksp( topo, "bank_busy" );
61 0 : fd_topob_wksp( topo, "pohh_shred" );
62 0 : fd_topob_wksp( topo, "gossip_dedup" );
63 0 : fd_topob_wksp( topo, "shred_store" );
64 0 : fd_topob_wksp( topo, "stake_out" );
65 0 : fd_topob_wksp( topo, "executed_txn" );
66 :
67 0 : fd_topob_wksp( topo, "shred_sign" );
68 0 : fd_topob_wksp( topo, "sign_shred" );
69 :
70 0 : fd_topob_wksp( topo, "quic" );
71 0 : fd_topob_wksp( topo, "verify" );
72 0 : fd_topob_wksp( topo, "dedup" );
73 0 : fd_topob_wksp( topo, "resolh" );
74 0 : fd_topob_wksp( topo, "pack" );
75 0 : fd_topob_wksp( topo, "bank" );
76 0 : fd_topob_wksp( topo, "pohh" );
77 0 : fd_topob_wksp( topo, "shred" );
78 0 : fd_topob_wksp( topo, "store" );
79 0 : fd_topob_wksp( topo, "sign" )->core_dump_level = FD_TOPO_CORE_DUMP_LEVEL_NEVER;
80 0 : fd_topob_wksp( topo, "metric" );
81 0 : fd_topob_wksp( topo, "diag" );
82 :
83 0 : #define FOR(cnt) for( ulong i=0UL; i<cnt; i++ )
84 :
85 : /* topo, link_name, wksp_name, depth, mtu, burst */
86 0 : FOR(quic_tile_cnt) fd_topob_link( topo, "quic_net", "net_quic", config->net.ingress_buffer_size, FD_NET_MTU, 1UL );
87 0 : FOR(shred_tile_cnt) fd_topob_link( topo, "shred_net", "net_shred", 32768UL, FD_NET_MTU, 1UL );
88 0 : FOR(quic_tile_cnt) fd_topob_link( topo, "quic_verify", "quic_verify", config->tiles.verify.receive_buffer_size, sizeof(fd_tpu_msg_t), config->tiles.quic.txn_reassembly_count );
89 0 : FOR(verify_tile_cnt) fd_topob_link( topo, "verify_dedup", "verify_dedup", config->tiles.verify.receive_buffer_size, FD_TPU_PARSED_MTU, 1UL );
90 0 : /**/ fd_topob_link( topo, "gossip_dedup", "gossip_dedup", 2048UL, FD_TPU_RAW_MTU, 1UL );
91 : /* dedup_resolh is large currently because pack can encounter stalls when running at very high throughput rates that would
92 : otherwise cause drops. */
93 0 : /**/ fd_topob_link( topo, "dedup_resolh", "dedup_resolh", 65536UL, FD_TPU_PARSED_MTU, 1UL );
94 0 : FOR(resolh_tile_cnt) fd_topob_link( topo, "resolh_pack", "resolh_pack", 65536UL, FD_TPU_RESOLVED_MTU, 1UL );
95 0 : /**/ fd_topob_link( topo, "stake_out", "stake_out", 128UL, FD_STAKE_OUT_MTU, 1UL );
96 0 : FOR(bank_tile_cnt) fd_topob_link( topo, "pack_bank", "pack_bank", 256UL, USHORT_MAX, 1UL );
97 0 : /**/ fd_topob_link( topo, "pack_pohh", "pack_pohh", 65536UL, sizeof(fd_done_packing_t), 1UL );
98 0 : FOR(bank_tile_cnt) fd_topob_link( topo, "bank_pohh", "bank_pohh", 16384UL, USHORT_MAX, 1UL );
99 0 : FOR(bank_tile_cnt) fd_topob_link( topo, "bank_pack", "bank_pack", 16384UL, USHORT_MAX, 3UL );
100 0 : /**/ fd_topob_link( topo, "pohh_pack", "bank_pohh", 128UL, sizeof(fd_became_leader_t), 1UL );
101 0 : /**/ fd_topob_link( topo, "pohh_shred", "pohh_shred", 16384UL, USHORT_MAX, 2UL );
102 0 : /**/ fd_topob_link( topo, "crds_shred", "pohh_shred", 128UL, 8UL + 108000UL * 46UL, 1UL );
103 0 : /**/ fd_topob_link( topo, "replay_resol", "bank_pohh", 128UL, sizeof(fd_completed_bank_t), 1UL );
104 0 : /**/ fd_topob_link( topo, "executed_txn", "executed_txn", 16384UL, 64UL, 1UL );
105 : /* See long comment in fd_shred.c for an explanation about the size of this dcache. */
106 0 : FOR(shred_tile_cnt) fd_topob_link( topo, "shred_store", "shred_store", 65536UL, 4UL*FD_SHRED_STORE_MTU, 4UL+config->tiles.shred.max_pending_shred_sets );
107 :
108 0 : FOR(shred_tile_cnt) fd_topob_link( topo, "shred_sign", "shred_sign", 128UL, 32UL, 1UL );
109 0 : FOR(shred_tile_cnt) fd_topob_link( topo, "sign_shred", "sign_shred", 128UL, 64UL, 1UL );
110 :
111 0 : ushort parsed_tile_to_cpu[ FD_TILE_MAX ];
112 : /* Unassigned tiles will be floating, unless auto topology is enabled. */
113 0 : for( ulong i=0UL; i<FD_TILE_MAX; i++ ) parsed_tile_to_cpu[ i ] = USHORT_MAX;
114 :
115 0 : int is_auto_affinity = !strcmp( config->layout.affinity, "auto" );
116 0 : int is_agave_auto_affinity = !strcmp( config->frankendancer.layout.agave_affinity, "auto" );
117 :
118 0 : if( FD_UNLIKELY( is_auto_affinity != is_agave_auto_affinity ) ) {
119 0 : FD_LOG_ERR(( "The CPU affinity string in the configuration file under [layout.affinity] and [layout.agave_affinity] must both be set to 'auto' or both be set to a specific CPU affinity string." ));
120 0 : }
121 :
122 0 : fd_topo_cpus_t cpus[1];
123 0 : fd_topo_cpus_init( cpus );
124 :
125 0 : ulong affinity_tile_cnt = 0UL;
126 0 : if( FD_LIKELY( !is_auto_affinity ) ) affinity_tile_cnt = fd_topob_parse_affinity_cstr( config->layout.affinity, parsed_tile_to_cpu, 0, 1 );
127 :
128 0 : ulong tile_to_cpu[ FD_TILE_MAX ] = {0};
129 0 : for( ulong i=0UL; i<affinity_tile_cnt; i++ ) {
130 0 : ushort cpu_idx = (ushort)( parsed_tile_to_cpu[ i ] & ~FD_TOPOB_CPU_SHARED );
131 0 : if( FD_UNLIKELY( parsed_tile_to_cpu[ i ]!=USHORT_MAX && cpu_idx>=cpus->cpu_cnt ) )
132 0 : FD_LOG_ERR(( "The CPU affinity string in the configuration file under [layout.affinity] specifies a CPU index of %hu, but the system "
133 0 : "only has %lu CPUs. You should either change the CPU allocations in the affinity string, or increase the number of CPUs "
134 0 : "in the system.",
135 0 : cpu_idx, cpus->cpu_cnt ));
136 0 : tile_to_cpu[ i ] = fd_ulong_if( parsed_tile_to_cpu[ i ]==USHORT_MAX, ULONG_MAX, (ulong)parsed_tile_to_cpu[ i ] );
137 0 : }
138 :
139 0 : int xsk_core_dump = config->development.core_dump_level >= FD_TOPO_CORE_DUMP_LEVEL_REGULAR ? 1 : 0;
140 0 : fd_topos_net_tiles( topo, config->layout.net_tile_count, &config->net, config->tiles.netlink.max_routes, config->tiles.netlink.max_peer_routes, config->tiles.netlink.max_neighbors, xsk_core_dump, tile_to_cpu );
141 :
142 0 : FOR(net_tile_cnt) fd_topos_net_rx_link( topo, "net_quic", i, config->net.ingress_buffer_size );
143 0 : FOR(net_tile_cnt) fd_topos_net_rx_link( topo, "net_shred", i, config->net.ingress_buffer_size );
144 :
145 : /* topo, tile_name, tile_wksp, metrics_wksp, cpu_idx, is_agave, uses_id_keyswitch, uses_av_keyswitch, is_waker_client */
146 0 : FOR(quic_tile_cnt) fd_topob_tile( topo, "quic", "quic", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0, 0, 0 );
147 0 : FOR(verify_tile_cnt) fd_topob_tile( topo, "verify", "verify", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0, 0, 0 );
148 0 : /**/ fd_topob_tile( topo, "dedup", "dedup", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0, 0, 0 );
149 0 : FOR(resolh_tile_cnt) fd_topob_tile( topo, "resolh", "resolh", "metric_in", tile_to_cpu[ topo->tile_cnt ], 1, 0, 0, 0 );
150 0 : /**/ fd_topob_tile( topo, "pack", "pack", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, config->tiles.bundle.enabled, 0, 0 );
151 0 : FOR(bank_tile_cnt) fd_topob_tile( topo, "bank", "bank", "metric_in", tile_to_cpu[ topo->tile_cnt ], 1, 0, 0, 0 );
152 0 : /**/ fd_topob_tile( topo, "pohh", "pohh", "metric_in", tile_to_cpu[ topo->tile_cnt ], 1, 1, 0, 0 );
153 0 : FOR(shred_tile_cnt) fd_topob_tile( topo, "shred", "shred", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 1, 0, 0 );
154 0 : /**/ fd_topob_tile( topo, "store", "store", "metric_in", tile_to_cpu[ topo->tile_cnt ], 1, 0, 0, 0 );
155 0 : /**/ fd_topob_tile( topo, "sign", "sign", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 1, 0, 0 );
156 0 : /**/ fd_topob_tile( topo, "metric", "metric", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0, 0, 1 );
157 0 : /**/ fd_topob_tile( topo, "diag", "diag", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0, 0, 0 );
158 :
159 : /* topo, tile_name, tile_kind_id, fseq_wksp, link_name, link_kind_id, reliable, polled */
160 0 : for( ulong j=0UL; j<quic_tile_cnt; j++ )
161 0 : fd_topos_tile_in_net( topo, "metric_in", "quic_net", j, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED ); /* No reliable consumers of networking fragments, may be dropped or overrun */
162 0 : for( ulong j=0UL; j<shred_tile_cnt; j++ )
163 0 : fd_topos_tile_in_net( topo, "metric_in", "shred_net", j, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED ); /* No reliable consumers of networking fragments, may be dropped or overrun */
164 :
165 0 : FOR(quic_tile_cnt) for( ulong j=0UL; j<net_tile_cnt; j++ )
166 0 : fd_topob_tile_in( topo, "quic", i, "metric_in", "net_quic", j, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED ); /* No reliable consumers of networking fragments, may be dropped or overrun */
167 0 : FOR(quic_tile_cnt) fd_topob_tile_out( topo, "quic", i, "quic_verify", i );
168 0 : FOR(quic_tile_cnt) fd_topob_tile_out( topo, "quic", i, "quic_net", i );
169 : /* All verify tiles read from all QUIC tiles, packets are round robin. */
170 0 : FOR(verify_tile_cnt) for( ulong j=0UL; j<quic_tile_cnt; j++ )
171 0 : fd_topob_tile_in( topo, "verify", i, "metric_in", "quic_verify", j, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED ); /* No reliable consumers, verify tiles may be overrun */
172 0 : FOR(verify_tile_cnt) fd_topob_tile_out( topo, "verify", i, "verify_dedup", i );
173 : /* Declare the single gossip link before the variable length verify-dedup links so we could have a compile-time index to the gossip link. */
174 0 : /**/ fd_topob_tile_in( topo, "dedup", 0UL, "metric_in", "gossip_dedup", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
175 0 : FOR(verify_tile_cnt) fd_topob_tile_in( topo, "dedup", 0UL, "metric_in", "verify_dedup", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
176 0 : /**/ fd_topob_tile_in( topo, "dedup", 0UL, "metric_in", "executed_txn", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
177 0 : /**/ fd_topob_tile_out( topo, "dedup", 0UL, "dedup_resolh", 0UL );
178 0 : FOR(resolh_tile_cnt) fd_topob_tile_in( topo, "resolh", i, "metric_in", "dedup_resolh", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
179 0 : FOR(resolh_tile_cnt) fd_topob_tile_in( topo, "resolh", i, "metric_in", "replay_resol", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
180 0 : FOR(resolh_tile_cnt) fd_topob_tile_out( topo, "resolh", i, "resolh_pack", i );
181 0 : FOR(resolh_tile_cnt) fd_topob_tile_in( topo, "pack", 0UL, "metric_in", "resolh_pack", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
182 : /* The PoH to pack link is reliable, and must be. The fragments going
183 : across here are "you became leader" which pack must respond to
184 : by publishing microblocks, otherwise the leader TPU will hang
185 : forever.
186 :
187 : It's marked as unreliable since otherwise we have a reliable credit
188 : loop which will also starve the pack tile. This is OK because we
189 : will never send more than one leader message until the pack tile
190 : must acknowledge it with a packing done frag, so there will be at
191 : most one in flight at any time. */
192 0 : /**/ fd_topob_tile_in( topo, "pack", 0UL, "metric_in", "pohh_pack", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
193 0 : /**/ fd_topob_tile_in( topo, "pack", 0UL, "metric_in", "executed_txn", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
194 0 : FOR(bank_tile_cnt) fd_topob_tile_out( topo, "pack", 0UL, "pack_bank", i );
195 0 : /**/ fd_topob_tile_out( topo, "pack", 0UL, "pack_pohh", 0UL );
196 0 : FOR(bank_tile_cnt) fd_topob_tile_in( topo, "bank", i, "metric_in", "pack_bank", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
197 0 : FOR(bank_tile_cnt) fd_topob_tile_out( topo, "bank", i, "bank_pohh", i );
198 0 : FOR(bank_tile_cnt) fd_topob_tile_out( topo, "bank", i, "bank_pack", i );
199 0 : FOR(bank_tile_cnt) fd_topob_tile_in( topo, "pohh", 0UL, "metric_in", "bank_pohh", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
200 0 : if( FD_LIKELY( config->tiles.pack.use_consumed_cus ) )
201 0 : FOR(bank_tile_cnt) fd_topob_tile_in( topo, "pack", 0UL, "metric_in", "bank_pack", i, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
202 0 : /**/ fd_topob_tile_in( topo, "pohh", 0UL, "metric_in", "stake_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
203 0 : /**/ fd_topob_tile_in( topo, "pohh", 0UL, "metric_in", "pack_pohh", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
204 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "pohh_shred", 0UL );
205 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "pohh_pack", 0UL );
206 0 : FOR(shred_tile_cnt) for( ulong j=0UL; j<net_tile_cnt; j++ )
207 0 : fd_topob_tile_in( topo, "shred", i, "metric_in", "net_shred", j, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED ); /* No reliable consumers of networking fragments, may be dropped or overrun */
208 0 : FOR(shred_tile_cnt) fd_topob_tile_in( topo, "shred", i, "metric_in", "pohh_shred", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
209 0 : FOR(shred_tile_cnt) fd_topob_tile_in( topo, "shred", i, "metric_in", "stake_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
210 0 : FOR(shred_tile_cnt) fd_topob_tile_in( topo, "shred", i, "metric_in", "crds_shred", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
211 0 : FOR(shred_tile_cnt) fd_topob_tile_in( topo, "shred", i, "metric_in", "replay_resol", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
212 0 : FOR(shred_tile_cnt) fd_topob_tile_out( topo, "shred", i, "shred_store", i );
213 0 : FOR(shred_tile_cnt) fd_topob_tile_out( topo, "shred", i, "shred_net", i );
214 0 : FOR(shred_tile_cnt) fd_topob_tile_in( topo, "store", 0UL, "metric_in", "shred_store", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
215 :
216 : /* Sign links don't need to be reliable because they are synchronous,
217 : so there's at most one fragment in flight at a time anyway. The
218 : sign links are also not polled by fd_stem, instead the tiles will
219 : read the sign responses out of band in a dedicated spin loop. */
220 :
221 0 : for( ulong i=0UL; i<shred_tile_cnt; i++ ) {
222 0 : /**/ fd_topob_tile_in( topo, "sign", 0UL, "metric_in", "shred_sign", i, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
223 0 : /**/ fd_topob_tile_out( topo, "shred", i, "shred_sign", i );
224 0 : /**/ fd_topob_tile_in( topo, "shred", i, "metric_in", "sign_shred", i, FD_TOPOB_UNRELIABLE, FD_TOPOB_UNPOLLED );
225 0 : /**/ fd_topob_tile_out( topo, "sign", 0UL, "sign_shred", i );
226 0 : }
227 :
228 : /* PoH tile represents the Agave address space, so it's
229 : responsible for publishing Agave provided data to
230 : these links. */
231 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "gossip_dedup", 0UL );
232 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "stake_out", 0UL );
233 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "crds_shred", 0UL );
234 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "replay_resol", 0UL );
235 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "executed_txn", 0UL );
236 :
237 : /* For now the only plugin consumer is the GUI */
238 0 : int plugins_enabled = config->tiles.gui.enabled;
239 0 : if( FD_LIKELY( plugins_enabled ) ) {
240 0 : fd_topob_wksp( topo, "plugin_in" );
241 0 : fd_topob_wksp( topo, "plugin_out" );
242 0 : fd_topob_wksp( topo, "plugin" );
243 :
244 : /* The size of plugin_out is the max of the message size from
245 : gossip_plugi and stake_out. */
246 0 : ulong plugin_out_mtu = fd_ulong_max( FD_STAKE_OUT_MTU, 8UL+108000UL*(60UL+12UL*6UL) );
247 0 : /**/ fd_topob_link( topo, "plugin_out", "plugin_out", 128UL, plugin_out_mtu, 1UL );
248 0 : /**/ fd_topob_link( topo, "replay_plugi", "plugin_in", 128UL, 4098*8UL, 1UL );
249 0 : /**/ fd_topob_link( topo, "gossip_plugi", "plugin_in", 128UL, 8UL+108000UL*(60UL+12UL*6UL), 1UL );
250 0 : /**/ fd_topob_link( topo, "pohh_plugin", "plugin_in", 128UL, 16UL, 1UL );
251 0 : /**/ fd_topob_link( topo, "startp_plugi", "plugin_in", 128UL, 56UL, 1UL );
252 0 : /**/ fd_topob_link( topo, "votel_plugin", "plugin_in", 128UL, 8UL, 1UL );
253 0 : /**/ fd_topob_link( topo, "valcfg_plugi", "plugin_in", 128UL, 608UL, 1UL );
254 :
255 : /**/ fd_topob_tile( topo, "plugin", "plugin", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0, 0, 0 );
256 :
257 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "replay_plugi", 0UL );
258 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "gossip_plugi", 0UL );
259 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "pohh_plugin", 0UL );
260 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "startp_plugi", 0UL );
261 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "votel_plugin", 0UL );
262 0 : /**/ fd_topob_tile_out( topo, "plugin", 0UL, "plugin_out", 0UL );
263 0 : /**/ fd_topob_tile_out( topo, "pohh", 0UL, "valcfg_plugi", 0UL );
264 :
265 0 : /**/ fd_topob_tile_in( topo, "plugin", 0UL, "metric_in", "replay_plugi", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
266 0 : /**/ fd_topob_tile_in( topo, "plugin", 0UL, "metric_in", "gossip_plugi", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
267 0 : /**/ fd_topob_tile_in( topo, "plugin", 0UL, "metric_in", "stake_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
268 0 : /**/ fd_topob_tile_in( topo, "plugin", 0UL, "metric_in", "pohh_plugin", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
269 0 : /**/ fd_topob_tile_in( topo, "plugin", 0UL, "metric_in", "startp_plugi", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
270 0 : /**/ fd_topob_tile_in( topo, "plugin", 0UL, "metric_in", "votel_plugin", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
271 0 : /**/ fd_topob_tile_in( topo, "plugin", 0UL, "metric_in", "valcfg_plugi", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
272 0 : }
273 :
274 0 : if( FD_LIKELY( config->tiles.gui.enabled ) ) {
275 0 : fd_topob_wksp( topo, "guih" );
276 0 : /**/ fd_topob_tile( topo, "guih", "guih", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 1, 0, 1 );
277 0 : /**/ fd_topob_tile_in( topo, "guih", 0UL, "metric_in", "plugin_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
278 0 : /**/ fd_topob_tile_in( topo, "guih", 0UL, "metric_in", "pohh_pack", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
279 0 : FOR(bank_tile_cnt) fd_topob_tile_in( topo, "guih", 0UL, "metric_in", "pack_bank", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
280 0 : /**/ fd_topob_tile_in( topo, "guih", 0UL, "metric_in", "pack_pohh", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
281 0 : FOR(bank_tile_cnt) fd_topob_tile_in( topo, "guih", 0UL, "metric_in", "bank_pohh", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
282 0 : }
283 :
284 0 : if( FD_UNLIKELY( config->tiles.bundle.enabled ) ) {
285 0 : fd_topob_wksp( topo, "bundle_verif" );
286 0 : fd_topob_wksp( topo, "bundle_sign" );
287 0 : fd_topob_wksp( topo, "sign_bundle" );
288 0 : fd_topob_wksp( topo, "pack_sign" );
289 0 : fd_topob_wksp( topo, "sign_pack" );
290 0 : fd_topob_wksp( topo, "bundle" );
291 :
292 0 : /**/ fd_topob_link( topo, "bundle_verif", "bundle_verif", config->tiles.verify.receive_buffer_size, FD_TPU_PARSED_MTU, 1UL );
293 0 : /**/ fd_topob_link( topo, "bundle_sign", "bundle_sign", 65536UL, 9UL, 1UL );
294 0 : /**/ fd_topob_link( topo, "sign_bundle", "sign_bundle", 128UL, 64UL, 1UL );
295 0 : /**/ fd_topob_link( topo, "pack_sign", "pack_sign", 65536UL, 1232UL, 1UL );
296 0 : /**/ fd_topob_link( topo, "sign_pack", "sign_pack", 128UL, 64UL, 1UL );
297 :
298 : /**/ fd_topob_tile( topo, "bundle", "bundle", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 1, 0, 1 );
299 :
300 : /**/ fd_topob_tile_out( topo, "bundle", 0UL, "bundle_verif", 0UL );
301 0 : FOR(verify_tile_cnt) fd_topob_tile_in( topo, "verify", i, "metric_in", "bundle_verif", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
302 :
303 0 : /**/ fd_topob_tile_in( topo, "sign", 0UL, "metric_in", "bundle_sign", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
304 0 : /**/ fd_topob_tile_out( topo, "bundle", 0UL, "bundle_sign", 0UL );
305 0 : /**/ fd_topob_tile_in( topo, "bundle", 0UL, "metric_in", "sign_bundle", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_UNPOLLED );
306 0 : /**/ fd_topob_tile_out( topo, "sign", 0UL, "sign_bundle", 0UL );
307 :
308 0 : /**/ fd_topob_tile_in( topo, "sign", 0UL, "metric_in", "pack_sign", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
309 0 : /**/ fd_topob_tile_out( topo, "pack", 0UL, "pack_sign", 0UL );
310 0 : /**/ fd_topob_tile_in( topo, "pack", 0UL, "metric_in", "sign_pack", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_UNPOLLED );
311 0 : /**/ fd_topob_tile_out( topo, "sign", 0UL, "sign_pack", 0UL );
312 :
313 0 : if( config->tiles.gui.enabled ) { /* GUI is the only consumer of bundle_status */
314 0 : fd_topob_wksp( topo, "bundle_status" );
315 : /* bundle_status must be kind of deep, to prevent exhausting
316 : shared flow control credits when publishing many packets at
317 : once. */
318 0 : fd_topob_link( topo, "bundle_status", "bundle_status", 65536UL, sizeof(fd_bundle_block_engine_update_t), 1UL );
319 0 : fd_topob_tile_in( topo, "guih", 0UL, "metric_in", "bundle_status", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
320 0 : fd_topob_tile_out( topo, "bundle", 0UL, "bundle_status", 0UL );
321 0 : }
322 0 : }
323 :
324 0 : if( FD_LIKELY( !is_auto_affinity ) ) {
325 0 : if( FD_UNLIKELY( affinity_tile_cnt<topo->tile_cnt ) )
326 0 : FD_LOG_ERR(( "The topology you are using has %lu tiles, but the CPU affinity specified in the config tile as [layout.affinity] only provides for %lu cores. "
327 0 : "You should either increase the number of cores dedicated to Firedancer in the affinity string, or decrease the number of cores needed by reducing "
328 0 : "the total tile count. You can reduce the tile count by decreasing individual tile counts in the [layout] section of the configuration file.",
329 0 : topo->tile_cnt, affinity_tile_cnt ));
330 0 : if( FD_UNLIKELY( affinity_tile_cnt>topo->tile_cnt ) )
331 0 : FD_LOG_WARNING(( "The topology you are using has %lu tiles, but the CPU affinity specified in the config tile as [layout.affinity] provides for %lu cores. "
332 0 : "Not all cores in the affinity will be used by Firedancer. You may wish to increase the number of tiles in the system by increasing "
333 0 : "individual tile counts in the [layout] section of the configuration file.",
334 0 : topo->tile_cnt, affinity_tile_cnt ));
335 :
336 0 : if( FD_LIKELY( strcmp( "", config->frankendancer.layout.agave_affinity ) ) ) {
337 0 : ushort agave_cpu[ FD_TILE_MAX ];
338 0 : ulong agave_cpu_cnt = fd_topob_parse_affinity_cstr( config->frankendancer.layout.agave_affinity, agave_cpu, 0, 0 );
339 :
340 0 : for( ulong i=0UL; i<agave_cpu_cnt; i++ ) {
341 0 : if( FD_UNLIKELY( agave_cpu[ i ]>=cpus->cpu_cnt ) )
342 0 : FD_LOG_ERR(( "The CPU affinity string in the configuration file under [layout.agave_affinity] specifies a CPU index of %hu, but the system "
343 0 : "only has %lu CPUs. You should either change the CPU allocations in the affinity string, or increase the number of CPUs "
344 0 : "in the system.",
345 0 : agave_cpu[ i ], cpus->cpu_cnt ));
346 :
347 0 : for( ulong j=0UL; j<topo->tile_cnt; j++ ) {
348 0 : fd_topo_tile_t * tile = &topo->tiles[ j ];
349 0 : if( tile->cpu_idx==agave_cpu[ i ] ) FD_LOG_WARNING(( "Tile `%s:%lu` is already assigned to CPU %hu, but the CPU is also assigned to Agave. "
350 0 : "This may cause contention between the two tiles.", tile->name, tile->kind_id, agave_cpu[ i ] ));
351 0 : }
352 :
353 0 : if( FD_UNLIKELY( topo->agave_affinity_cnt>FD_TILE_MAX ) ) {
354 0 : FD_LOG_ERR(( "The CPU affinity string in the configuration file under [layout.agave_affinity] specifies more CPUs than Firedancer can use. "
355 0 : "You should reduce the number of CPUs in the affinity string." ));
356 0 : }
357 0 : topo->agave_affinity_cpu_idx[ topo->agave_affinity_cnt++ ] = agave_cpu[ i ];
358 0 : }
359 0 : }
360 0 : } else {
361 0 : ushort blocklist_cores[ FD_TILE_MAX ];
362 0 : topo->blocklist_cores_cnt = fd_topob_parse_affinity_cstr( config->layout.blocklist_cores, blocklist_cores, 0, 0 );
363 0 : if( FD_UNLIKELY( topo->blocklist_cores_cnt>FD_TILE_MAX ) ) {
364 0 : FD_LOG_ERR(( "The CPU string in the configuration file under [layout.blocklist_cores] specifies more CPUs than Firedancer can use. "
365 0 : "You should reduce the number of CPUs in the excluded cores string." ));
366 0 : }
367 :
368 0 : for( ulong i=0UL; i<topo->blocklist_cores_cnt; i++ ) {
369 : /* Since we use fd_topob_parse_affinity_cstr() like for affinity, the user
370 : may input a string containing `f`. That's parsed correctly, but it's
371 : meaningless for blocklisted cores, so we reject it here. */
372 0 : if( FD_UNLIKELY( blocklist_cores[ i ]==USHORT_MAX ) ) {
373 0 : FD_LOG_ERR(( "The CPU string in the configuration file under [layout.blocklist_cores] contains invalid values: `f`. "
374 0 : "You should fix the excluded cores string." ));
375 0 : }
376 0 : topo->blocklist_cores_cpu_idx[ i ] = blocklist_cores[ i ];
377 0 : }
378 0 : }
379 :
380 : /* There is a special fseq that sits between the pack, bank, and poh
381 : tiles to indicate when the bank/poh tiles are done processing a
382 : microblock. Pack uses this to determine when to "unlock" accounts
383 : that it marked as locked because they were being used. */
384 :
385 0 : for( ulong i=0UL; i<bank_tile_cnt; i++ ) {
386 0 : fd_topo_obj_t * busy_obj = fd_topob_obj( topo, "fseq", "bank_busy" );
387 :
388 0 : fd_topo_tile_t * pohh_tile = &topo->tiles[ fd_topo_find_tile( topo, "pohh", 0UL ) ];
389 0 : fd_topo_tile_t * pack_tile = &topo->tiles[ fd_topo_find_tile( topo, "pack", 0UL ) ];
390 0 : fd_topob_tile_uses( topo, pohh_tile, busy_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
391 0 : fd_topob_tile_uses( topo, pack_tile, busy_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
392 0 : FD_TEST( fd_pod_insertf_ulong( topo->props, busy_obj->id, "execle_busy.%lu", i ) );
393 0 : }
394 :
395 : /* There's another special fseq that's used to communicate the shred
396 : version from the Agave boot path to the shred tile. */
397 0 : fd_topo_obj_t * pohh_shred_obj = fd_topob_obj( topo, "fseq", "pohh_shred" );
398 0 : fd_topo_tile_t * pohh_tile = &topo->tiles[ fd_topo_find_tile( topo, "pohh", 0UL ) ];
399 0 : fd_topob_tile_uses( topo, pohh_tile, pohh_shred_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
400 0 : for( ulong i=0UL; i<shred_tile_cnt; i++ ) {
401 0 : fd_topo_tile_t * shred_tile = &topo->tiles[ fd_topo_find_tile( topo, "shred", i ) ];
402 0 : fd_topob_tile_uses( topo, shred_tile, pohh_shred_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
403 0 : }
404 0 : FD_TEST( fd_pod_insertf_ulong( topo->props, pohh_shred_obj->id, "pohh_shred" ) );
405 :
406 0 : FOR(net_tile_cnt) fd_topos_net_tile_finish( topo, i );
407 :
408 0 : fd_topob_waker( topo );
409 :
410 0 : for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
411 0 : fd_topo_tile_t * tile = &topo->tiles[ i ];
412 0 : fd_topo_configure_tile( tile, config );
413 0 : if( FD_UNLIKELY( !strcmp( tile->name, "guih" ) ) ) tile->gui.tile_cnt = topo->tile_cnt;
414 0 : }
415 :
416 0 : if( FD_UNLIKELY( is_auto_affinity ) ) fd_topob_auto_layout( topo, 1 );
417 :
418 0 : fd_topob_finish( topo, CALLBACKS );
419 0 : config->topo = *topo;
420 0 : }
421 :
422 : void
423 : fd_topo_configure_tile( fd_topo_tile_t * tile,
424 : fd_config_t * config ) {
425 : int plugins_enabled = config->tiles.gui.enabled;
426 :
427 : if( FD_UNLIKELY( !strcmp( tile->name, "net" ) ||
428 : !strcmp( tile->name, "sock" ) ||
429 : !strcmp( tile->name, "mlx5" ) ) ) {
430 :
431 : tile->net.shred_listen_port = config->tiles.shred.shred_listen_port;
432 : tile->net.quic_transaction_listen_port = config->tiles.quic.quic_transaction_listen_port;
433 : tile->net.legacy_transaction_listen_port = config->tiles.quic.regular_transaction_listen_port;
434 :
435 : } else if( FD_UNLIKELY( !strcmp( tile->name, "netlnk" ) ) ) {
436 :
437 : /* already configured */
438 :
439 : } else if( FD_UNLIKELY( !strcmp( tile->name, "quic" ) ) ) {
440 :
441 : tile->quic.reasm_cnt = config->tiles.quic.txn_reassembly_count;
442 : tile->quic.out_depth = config->tiles.verify.receive_buffer_size;
443 : tile->quic.max_concurrent_connections = config->tiles.quic.max_concurrent_connections;
444 : tile->quic.max_concurrent_handshakes = config->tiles.quic.max_concurrent_handshakes;
445 : tile->quic.quic_transaction_listen_port = config->tiles.quic.quic_transaction_listen_port;
446 : tile->quic.idle_timeout_millis = config->tiles.quic.idle_timeout_millis;
447 : tile->quic.ack_delay_millis = config->tiles.quic.ack_delay_millis;
448 : tile->quic.retry = config->tiles.quic.retry;
449 : fd_cstr_fini( fd_cstr_append_cstr_safe( fd_cstr_init( tile->quic.key_log_path ), config->tiles.quic.ssl_key_log_file, sizeof(tile->quic.key_log_path) ) );
450 :
451 : } else if( FD_UNLIKELY( !strcmp( tile->name, "bundle" ) ) ) {
452 : fd_cstr_ncpy( tile->bundle.url, config->tiles.bundle.url, sizeof(tile->bundle.url) );
453 : tile->bundle.url_len = strnlen( tile->bundle.url, sizeof(tile->bundle.url)-1UL );
454 : fd_cstr_ncpy( tile->bundle.sni, config->tiles.bundle.tls_domain_name, sizeof(tile->bundle.sni) );
455 : tile->bundle.sni_len = strnlen( tile->bundle.sni, sizeof(tile->bundle.sni)-1UL );
456 : fd_cstr_ncpy( tile->bundle.identity_key_path, config->paths.identity_key, sizeof(tile->bundle.identity_key_path) );
457 : fd_cstr_ncpy( tile->bundle.key_log_path, config->development.bundle.ssl_key_log_file, sizeof(tile->bundle.key_log_path) );
458 : tile->bundle.buf_sz = config->development.bundle.buffer_size_kib<<10;
459 : tile->bundle.out_depth = config->tiles.verify.receive_buffer_size;
460 : tile->bundle.keepalive_interval_nanos = config->tiles.bundle.keepalive_interval_millis * (ulong)1e6;
461 : tile->bundle.tls_cert_verify = !!config->tiles.bundle.tls_cert_verify;
462 : } else if( FD_UNLIKELY( !strcmp( tile->name, "verify" ) ) ) {
463 : tile->verify.tcache_depth = config->tiles.verify.signature_cache_size;
464 :
465 : } else if( FD_UNLIKELY( !strcmp( tile->name, "dedup" ) ) ) {
466 : tile->dedup.tcache_depth = config->tiles.dedup.signature_cache_size;
467 :
468 : } else if( FD_UNLIKELY( !strcmp( tile->name, "resolh" ) ) ) {
469 :
470 : } else if( FD_UNLIKELY( !strcmp( tile->name, "pack" ) ) ) {
471 : tile->pack.max_pending_transactions = config->tiles.pack.max_pending_transactions;
472 : tile->pack.execle_tile_count = config->frankendancer.layout.bank_tile_count;
473 : tile->pack.max_cost_per_block = config->limits.max_cost_per_block;
474 : tile->pack.max_shreds_per_block = config->limits.max_shreds_per_block;
475 : tile->pack.bench_max_shreds_per_block = config->development.bench.max_shreds_per_block;
476 : tile->pack.use_consumed_cus = config->tiles.pack.use_consumed_cus;
477 : tile->pack.schedule_strategy = config->tiles.pack.schedule_strategy_enum;
478 : tile->pack.acct_blocklist_cnt = config->tiles.pack.account_blocklist_cnt;
479 :
480 : for( ulong i=0UL; i<tile->pack.acct_blocklist_cnt; i++ ) {
481 : if( FD_UNLIKELY( NULL==fd_base58_decode_32( config->tiles.pack.account_blocklist[i], tile->pack.acct_blocklist[i].uc ) ) ) {
482 : FD_LOG_ERR(( "could not parse account %s at index %lu in [tiles.pack.account_blocklist]", config->tiles.pack.account_blocklist[i], i ));
483 : }
484 : }
485 :
486 : if( FD_UNLIKELY( config->tiles.bundle.enabled ) ) {
487 : #define PARSE_BUNDLE_PUBKEY( _tile, f ) \
488 : if( FD_UNLIKELY( !fd_base58_decode_32( config->tiles.bundle.f, tile->_tile.bundle.f ) ) ) \
489 : FD_LOG_ERR(( "[tiles.bundle.enabled] set to true, but failed to parse [tiles.bundle."#f"] %s", config->tiles.bundle.f ));
490 : tile->pack.bundle.enabled = 1;
491 : PARSE_BUNDLE_PUBKEY( pack, tip_distribution_program_addr );
492 : PARSE_BUNDLE_PUBKEY( pack, tip_payment_program_addr );
493 : PARSE_BUNDLE_PUBKEY( pack, tip_distribution_authority );
494 : tile->pack.bundle.commission_bps = config->tiles.bundle.commission_bps;
495 : fd_cstr_ncpy( tile->pack.bundle.identity_key_path, config->paths.identity_key, sizeof(tile->pack.bundle.identity_key_path) );
496 : fd_cstr_ncpy( tile->pack.bundle.vote_account_path, config->paths.vote_account, sizeof(tile->pack.bundle.vote_account_path) );
497 : } else {
498 : fd_memset( &tile->pack.bundle, '\0', sizeof(tile->pack.bundle) );
499 : }
500 : } else if( FD_UNLIKELY( !strcmp( tile->name, "bank" ) ) ) {
501 :
502 : } else if( FD_UNLIKELY( !strcmp( tile->name, "pohh" ) ) ) {
503 : fd_cstr_ncpy( tile->pohh.identity_key_path, config->paths.identity_key, sizeof(tile->pohh.identity_key_path) );
504 :
505 : tile->pohh.plugins_enabled = plugins_enabled;
506 : tile->pohh.execle_cnt = config->frankendancer.layout.bank_tile_count;
507 : tile->pohh.lagged_consecutive_leader_start = config->tiles.pohh.lagged_consecutive_leader_start;
508 :
509 : if( FD_UNLIKELY( config->tiles.bundle.enabled ) ) {
510 : tile->pohh.bundle.enabled = 1;
511 : PARSE_BUNDLE_PUBKEY( pohh, tip_distribution_program_addr );
512 : PARSE_BUNDLE_PUBKEY( pohh, tip_payment_program_addr );
513 : fd_cstr_ncpy( tile->pohh.bundle.vote_account_path, config->paths.vote_account, sizeof(tile->pohh.bundle.vote_account_path) );
514 :
515 : } else {
516 : fd_memset( &tile->pohh.bundle, '\0', sizeof(tile->pohh.bundle) );
517 : }
518 :
519 : } else if( FD_UNLIKELY( !strcmp( tile->name, "shred" ) ) ) {
520 : fd_cstr_ncpy( tile->shred.identity_key_path, config->paths.identity_key, sizeof(tile->shred.identity_key_path) );
521 :
522 : tile->shred.fec_exposure = config->topo.links[ tile->out_link_id[ 0 ] ].depth;
523 : tile->shred.fec_resolver_depth = config->tiles.shred.max_pending_shred_sets;
524 : tile->shred.expected_shred_version = config->consensus.expected_shred_version;
525 : tile->shred.shred_listen_port = config->tiles.shred.shred_listen_port;
526 : tile->shred.max_shreds_per_block = config->limits.max_shreds_per_block;
527 : tile->shred.bench_max_shreds_per_block = config->development.bench.max_shreds_per_block;
528 : for( ulong i=0UL; i<config->tiles.shred.additional_shred_destinations_retransmit_cnt; i++ ) {
529 : parse_ip_port( "tiles.shred.additional_shred_destinations_retransmit",
530 : config->tiles.shred.additional_shred_destinations_retransmit[ i ],
531 : &tile->shred.adtl_dests_retransmit[ i ] );
532 : }
533 : tile->shred.adtl_dests_retransmit_cnt = config->tiles.shred.additional_shred_destinations_retransmit_cnt;
534 : for( ulong i=0UL; i<config->tiles.shred.additional_shred_destinations_leader_cnt; i++ ) {
535 : parse_ip_port( "tiles.shred.additional_shred_destinations_leader",
536 : config->tiles.shred.additional_shred_destinations_leader[ i ],
537 : &tile->shred.adtl_dests_leader[ i ] );
538 : }
539 : tile->shred.adtl_dests_leader_cnt = config->tiles.shred.additional_shred_destinations_leader_cnt;
540 :
541 : } else if( FD_UNLIKELY( !strcmp( tile->name, "store" ) ) ) {
542 : tile->store.disable_blockstore_from_slot = config->development.bench.disable_blockstore_from_slot;
543 :
544 : } else if( FD_UNLIKELY( !strcmp( tile->name, "sign" ) ) ) {
545 : fd_cstr_ncpy( tile->sign.identity_key_path, config->paths.identity_key, sizeof(tile->sign.identity_key_path) );
546 :
547 : /* Frankendancer does not use authorized voters in the sign tile. */
548 : tile->sign.authorized_voter_paths_cnt = 0UL;
549 : if( FD_UNLIKELY( config->tiles.bundle.enabled ) ) {
550 : PARSE_BUNDLE_PUBKEY( sign, tip_distribution_program_addr );
551 : PARSE_BUNDLE_PUBKEY( sign, tip_payment_program_addr );
552 : } else {
553 : /* 0xFF.. is not an invocable program */
554 : memset( tile->sign.bundle.tip_distribution_program_addr, '\xFF', 32UL );
555 : memset( tile->sign.bundle.tip_payment_program_addr, '\xFF', 32UL );
556 : }
557 : #undef PARSE_BUNDLE_PUBKEY
558 :
559 : } else if( FD_UNLIKELY( !strcmp( tile->name, "metric" ) ) ) {
560 : if( FD_UNLIKELY( !fd_cstr_to_ip4_addr( config->tiles.metric.prometheus_listen_address, &tile->metric.prometheus_listen_addr ) ) )
561 : FD_LOG_ERR(( "failed to parse prometheus listen address `%s`", config->tiles.metric.prometheus_listen_address ));
562 : tile->metric.prometheus_listen_port = config->tiles.metric.prometheus_listen_port;
563 :
564 : } else if( FD_UNLIKELY( !strcmp( tile->name, "diag" ) ) ) {
565 :
566 : } else if( FD_UNLIKELY( !strcmp( tile->name, "guih" ) ) ) {
567 : if( FD_UNLIKELY( !fd_cstr_to_ip4_addr( config->tiles.gui.gui_listen_address, &tile->gui.listen_addr ) ) )
568 : FD_LOG_ERR(( "failed to parse gui listen address `%s`", config->tiles.gui.gui_listen_address ));
569 : tile->gui.listen_port = config->tiles.gui.gui_listen_port;
570 : tile->gui.is_voting = strcmp( config->paths.vote_account, "" );
571 : fd_cstr_ncpy( tile->gui.cluster, config->cluster, sizeof(tile->gui.cluster) );
572 : fd_cstr_ncpy( tile->gui.identity_key_path, config->paths.identity_key, sizeof(tile->gui.identity_key_path) );
573 : fd_cstr_ncpy( tile->gui.vote_key_path, config->paths.vote_account, sizeof(tile->gui.vote_key_path) );
574 : tile->gui.max_http_connections = config->tiles.gui.max_http_connections;
575 : tile->gui.max_websocket_connections = config->tiles.gui.max_websocket_connections;
576 : tile->gui.max_http_request_length = config->tiles.gui.max_http_request_length;
577 : tile->gui.send_buffer_size_mb = config->tiles.gui.send_buffer_size_mb;
578 : tile->gui.schedule_strategy = config->tiles.pack.schedule_strategy_enum;
579 : tile->gui.websocket_compression = config->development.gui.websocket_compression;
580 : tile->gui.accdb_obj_id = ULONG_MAX;
581 :
582 : } else if( FD_UNLIKELY( !strcmp( tile->name, "plugin" ) ) ) {
583 :
584 : } else if( FD_UNLIKELY( !strcmp( tile->name, "waker" ) ) ) {
585 :
586 : } else {
587 : FD_LOG_ERR(( "unknown tile name %lu `%s`", tile->id, tile->name ));
588 : }
589 : }
|