Skip to content

Commit 3b2dd1f

Browse files
committed
gui: remove memcpy for reliable links
1 parent b842208 commit 3b2dd1f

File tree

1 file changed

+67
-42
lines changed

1 file changed

+67
-42
lines changed

src/disco/gui/fd_gui_tile.c

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,15 @@ typedef struct {
116116

117117
uchar __attribute__((aligned(FD_CLOCK_ALIGN))) clock_mem[ FD_CLOCK_FOOTPRINT ];
118118

119-
/* This needs to be max(sz) across all kinds of messages.
120-
Currently this is just figured out manually, it's a gossip update
121-
message assuming the table is completely full (40200) of peers.
119+
ulong chunk;
120+
union {
121+
struct {
122+
ulong slot;
123+
} repair_net;
122124

123-
We also require an alignment of 64 to hold fd_txn_p_t structs. */
124-
uchar buf[ 8UL+FD_GUI_MAX_PEER_CNT*(58UL+12UL*34UL) ] __attribute__((aligned(64)));
125+
uchar net_gossvf[ 1232UL ];
126+
uchar gossip_net[ 1232UL ];
127+
} parsed;
125128

126129
fd_http_server_t * gui_server;
127130

@@ -278,7 +281,40 @@ during_frag( fd_gui_ctx_t * ctx,
278281
if( FD_UNLIKELY( chunk<ctx->in[ in_idx ].chunk0 || chunk>ctx->in[ in_idx ].wmark || sz>ctx->in[ in_idx ].mtu ) )
279282
FD_LOG_ERR(( "chunk %lu %lu corrupt, not in range [%lu,%lu] or too large (%lu)", chunk, sz, ctx->in[ in_idx ].chunk0, ctx->in[ in_idx ].wmark, ctx->in[ in_idx ].mtu ));
280283

281-
fd_memcpy( ctx->buf, src, sz );
284+
switch( ctx->in_kind[ in_idx ] ) {
285+
case IN_KIND_REPAIR_NET: {
286+
FD_TEST( ctx->is_full_client );
287+
ctx->parsed.repair_net.slot = ULONG_MAX;
288+
uchar * payload;
289+
ulong payload_sz;
290+
if( FD_LIKELY( fd_ip4_udp_hdr_strip( src, sz, &payload, &payload_sz, NULL, NULL, NULL ) ) ) {
291+
fd_repair_msg_t const * msg = (fd_repair_msg_t const *)payload;
292+
switch ( msg->kind ) {
293+
case FD_REPAIR_KIND_PING:
294+
case FD_REPAIR_KIND_PONG:
295+
case FD_REPAIR_KIND_ORPHAN: break;
296+
case FD_REPAIR_KIND_SHRED: { if( FD_UNLIKELY( msg->shred.slot==0 ) ) { break; } ctx->parsed.repair_net.slot = msg->shred.slot; break; }
297+
case FD_REPAIR_KIND_HIGHEST_SHRED: { if( FD_UNLIKELY( msg->highest_shred.slot==0 ) ) { break; } ctx->parsed.repair_net.slot = msg->highest_shred.slot; break; }
298+
default: FD_LOG_ERR(( "unexpected repair msg kind %u", msg->kind ));
299+
}
300+
}
301+
break;
302+
}
303+
case IN_KIND_NET_GOSSVF: {
304+
FD_TEST( ctx->is_full_client );
305+
FD_TEST( sz<=sizeof(ctx->parsed.net_gossvf) );
306+
fd_memcpy( ctx->parsed.net_gossvf, src, sz );
307+
break;
308+
}
309+
case IN_KIND_GOSSIP_NET: {
310+
FD_TEST( ctx->is_full_client );
311+
FD_TEST( sz<=sizeof(ctx->parsed.gossip_net) );
312+
fd_memcpy( ctx->parsed.gossip_net, src, sz );
313+
break;
314+
}
315+
}
316+
317+
ctx->chunk = chunk;
282318
}
283319

284320
static inline void
@@ -290,19 +326,20 @@ after_frag( fd_gui_ctx_t * ctx,
290326
ulong tsorig,
291327
ulong tspub,
292328
fd_stem_context_t * stem ) {
293-
(void)seq;
294-
(void)stem;
329+
(void)seq; (void)stem;
330+
331+
uchar * src = (uchar *)fd_chunk_to_laddr( ctx->in[ in_idx ].mem, ctx->chunk );
295332

296333
switch ( ctx->in_kind[ in_idx ] ) {
297334
case IN_KIND_PLUGIN: {
298335
FD_TEST( !ctx->is_full_client );
299-
fd_gui_plugin_message( ctx->gui, sig, ctx->buf, fd_clock_now( ctx->clock ) );
336+
fd_gui_plugin_message( ctx->gui, sig, src, fd_clock_now( ctx->clock ) );
300337
break;
301338
}
302339
case IN_KIND_EXEC_REPLAY: {
303340
FD_TEST( ctx->is_full_client );
304341
if( FD_LIKELY( sig>>32==FD_EXEC_TT_TXN_EXEC ) ) {
305-
fd_exec_task_done_msg_t * msg = (fd_exec_task_done_msg_t *)ctx->buf;
342+
fd_exec_task_done_msg_t * msg = (fd_exec_task_done_msg_t *)src;
306343

307344
long tickcount = fd_tickcount();
308345
long tsorig_ns = ctx->ref_wallclock + (long)((double)(fd_frag_meta_ts_decomp( tsorig, tickcount ) - ctx->ref_tickcount) / ctx->tick_per_ns);
@@ -315,7 +352,7 @@ after_frag( fd_gui_ctx_t * ctx,
315352
case IN_KIND_REPLAY_OUT: {
316353
FD_TEST( ctx->is_full_client );
317354
if( FD_UNLIKELY( sig==REPLAY_SIG_SLOT_COMPLETED ) ) {
318-
fd_replay_slot_completed_t const * replay = (fd_replay_slot_completed_t const *)ctx->buf;
355+
fd_replay_slot_completed_t const * replay = (fd_replay_slot_completed_t const *)src;
319356

320357
fd_bank_t * bank = fd_banks_bank_query( ctx->banks, replay->bank_idx );
321358
/* bank should already have positive refcnt */
@@ -383,7 +420,7 @@ after_frag( fd_gui_ctx_t * ctx,
383420
fd_gui_handle_replay_update( ctx->gui, &slot_completed, fd_clock_now( ctx->clock ) );
384421

385422
} else if( FD_UNLIKELY( sig==REPLAY_SIG_BECAME_LEADER ) ) {
386-
fd_became_leader_t * became_leader = (fd_became_leader_t *)ctx->buf;
423+
fd_became_leader_t * became_leader = (fd_became_leader_t *)src;
387424
fd_gui_became_leader( ctx->gui, became_leader->slot, became_leader->slot_start_ns, became_leader->slot_end_ns, became_leader->limits.slot_max_cost, became_leader->max_microblocks_in_slot );
388425
} else {
389426
return;
@@ -393,29 +430,29 @@ after_frag( fd_gui_ctx_t * ctx,
393430
case IN_KIND_REPLAY_STAKE: {
394431
FD_TEST( ctx->is_full_client );
395432

396-
fd_stake_weight_msg_t * leader_schedule = (fd_stake_weight_msg_t *)ctx->buf;
433+
fd_stake_weight_msg_t * leader_schedule = (fd_stake_weight_msg_t *)src;
397434
fd_gui_handle_leader_schedule( ctx->gui, leader_schedule, fd_clock_now( ctx->clock ) );
398435
break;
399436
}
400437
case IN_KIND_SNAPIN: {
401438
FD_TEST( ctx->is_full_client );
402-
fd_gui_peers_handle_config_account( ctx->peers, ctx->buf, sz );
439+
fd_gui_peers_handle_config_account( ctx->peers, src, sz );
403440
break;
404441
}
405442
case IN_KIND_GENESI_OUT: {
406443
FD_TEST( ctx->is_full_client );
407444

408445
if( FD_LIKELY( sig==GENESI_SIG_BOOTSTRAP_COMPLETED ) ) {
409-
fd_gui_handle_genesis_hash( ctx->gui, ctx->buf+sizeof(fd_lthash_value_t) );
446+
fd_gui_handle_genesis_hash( ctx->gui, src+sizeof(fd_lthash_value_t) );
410447
} else {
411-
fd_gui_handle_genesis_hash( ctx->gui, ctx->buf );
448+
fd_gui_handle_genesis_hash( ctx->gui, src );
412449
}
413450
break;
414451
}
415452
case IN_KIND_TOWER_OUT: {
416453
FD_TEST( ctx->is_full_client );
417454
if( FD_LIKELY( sig==FD_TOWER_SIG_SLOT_DONE )) {
418-
fd_tower_slot_done_t const * tower = (fd_tower_slot_done_t const *)ctx->buf;
455+
fd_tower_slot_done_t const * tower = (fd_tower_slot_done_t const *)src;
419456
fd_gui_handle_tower_update( ctx->gui, tower, fd_clock_now( ctx->clock ) );
420457
}
421458
break;
@@ -434,25 +471,13 @@ after_frag( fd_gui_ctx_t * ctx,
434471
}
435472
case IN_KIND_SNAPCT: {
436473
FD_TEST( ctx->is_full_client );
437-
fd_gui_handle_snapshot_update( ctx->gui, (fd_snapct_update_t *)ctx->buf );
474+
fd_gui_handle_snapshot_update( ctx->gui, (fd_snapct_update_t *)src );
438475
break;
439476
}
440477
case IN_KIND_REPAIR_NET: {
441-
FD_TEST( ctx->is_full_client );
442-
uchar * payload;
443-
ulong payload_sz;
444-
if( FD_LIKELY( fd_ip4_udp_hdr_strip( ctx->buf, sz, &payload, &payload_sz, NULL, NULL, NULL ) ) ) {
445-
fd_repair_msg_t const * msg = (fd_repair_msg_t const *)payload;
446-
long tsorig_ns = ctx->ref_wallclock + (long)((double)(fd_frag_meta_ts_decomp( tsorig, fd_tickcount() ) - ctx->ref_tickcount) / ctx->tick_per_ns);
447-
switch ( msg->kind ) {
448-
case FD_REPAIR_KIND_PING:
449-
case FD_REPAIR_KIND_PONG:
450-
case FD_REPAIR_KIND_ORPHAN: break;
451-
case FD_REPAIR_KIND_SHRED: { if( FD_UNLIKELY( msg->shred.slot==0 ) ) { break; } fd_gui_handle_repair_slot( ctx->gui, msg->shred.slot, tsorig_ns ); break; }
452-
case FD_REPAIR_KIND_HIGHEST_SHRED: { if( FD_UNLIKELY( msg->highest_shred.slot==0 ) ) { break; } fd_gui_handle_repair_slot( ctx->gui, msg->highest_shred.slot, tsorig_ns ); break; }
453-
default: FD_LOG_ERR(( "unexpected repair msg kind %u", msg->kind ));
454-
}
455-
}
478+
if( FD_UNLIKELY( ctx->parsed.repair_net.slot==ULONG_MAX ) ) break;
479+
long tsorig_ns = ctx->ref_wallclock + (long)((double)(fd_frag_meta_ts_decomp( tsorig, fd_tickcount() ) - ctx->ref_tickcount) / ctx->tick_per_ns);
480+
fd_gui_handle_repair_slot( ctx->gui, ctx->parsed.repair_net.slot, tsorig_ns );
456481
break;
457482
}
458483
case IN_KIND_NET_GOSSVF: {
@@ -461,7 +486,7 @@ after_frag( fd_gui_ctx_t * ctx,
461486
ulong payload_sz;
462487
fd_ip4_hdr_t * ip4_hdr;
463488
fd_udp_hdr_t * udp_hdr;
464-
if( FD_LIKELY( fd_ip4_udp_hdr_strip( ctx->buf, sz, &payload, &payload_sz, NULL, &ip4_hdr, &udp_hdr ) ) ) {
489+
if( FD_LIKELY( fd_ip4_udp_hdr_strip( ctx->parsed.net_gossvf, sz, &payload, &payload_sz, NULL, &ip4_hdr, &udp_hdr ) ) ) {
465490
fd_gui_peers_handle_gossip_message( ctx->peers, payload, payload_sz, &(fd_ip4_port_t){ .addr = ip4_hdr->saddr, .port = udp_hdr->net_sport }, 1 );
466491
}
467492
break;
@@ -472,13 +497,13 @@ after_frag( fd_gui_ctx_t * ctx,
472497
ulong payload_sz;
473498
fd_ip4_hdr_t * ip4_hdr;
474499
fd_udp_hdr_t * udp_hdr;
475-
FD_TEST( fd_ip4_udp_hdr_strip( ctx->buf, sz, &payload, &payload_sz, NULL, &ip4_hdr, &udp_hdr ) );
500+
FD_TEST( fd_ip4_udp_hdr_strip( ctx->parsed.gossip_net, sz, &payload, &payload_sz, NULL, &ip4_hdr, &udp_hdr ) );
476501
fd_gui_peers_handle_gossip_message( ctx->peers, payload, payload_sz, &(fd_ip4_port_t){ .addr = ip4_hdr->daddr, .port = udp_hdr->net_dport }, 0 );
477502
break;
478503
}
479504
case IN_KIND_GOSSIP_OUT: {
480505
FD_TEST( ctx->is_full_client );
481-
fd_gossip_update_message_t * update = (fd_gossip_update_message_t *)ctx->buf;
506+
fd_gossip_update_message_t * update = (fd_gossip_update_message_t *)src;
482507
switch( update->tag ) {
483508
case FD_GOSSIP_UPDATE_TAG_CONTACT_INFO_REMOVE: FD_TEST( sz == FD_GOSSIP_UPDATE_SZ_CONTACT_INFO_REMOVE ); break;
484509
case FD_GOSSIP_UPDATE_TAG_CONTACT_INFO: FD_TEST( sz == FD_GOSSIP_UPDATE_SZ_CONTACT_INFO ); break;
@@ -490,22 +515,22 @@ after_frag( fd_gui_ctx_t * ctx,
490515
case IN_KIND_POH_PACK: {
491516
FD_TEST( !ctx->is_full_client );
492517
FD_TEST( fd_disco_poh_sig_pkt_type( sig )==POH_PKT_TYPE_BECAME_LEADER );
493-
fd_became_leader_t * became_leader = (fd_became_leader_t *)ctx->buf;
518+
fd_became_leader_t * became_leader = (fd_became_leader_t *)src;
494519
fd_gui_became_leader( ctx->gui, fd_disco_poh_sig_slot( sig ), became_leader->slot_start_ns, became_leader->slot_end_ns, became_leader->limits.slot_max_cost, became_leader->max_microblocks_in_slot );
495520
break;
496521
}
497522
case IN_KIND_PACK_POH: {
498-
fd_gui_unbecame_leader( ctx->gui, fd_disco_bank_sig_slot( sig ), (fd_done_packing_t const *)ctx->buf, fd_clock_now( ctx->clock ) );
523+
fd_gui_unbecame_leader( ctx->gui, fd_disco_bank_sig_slot( sig ), (fd_done_packing_t const *)src, fd_clock_now( ctx->clock ) );
499524
break;
500525
}
501526
case IN_KIND_PACK_BANK: {
502527
if( FD_LIKELY( fd_disco_poh_sig_pkt_type( sig )==POH_PKT_TYPE_MICROBLOCK ) ) {
503-
fd_microblock_bank_trailer_t * trailer = (fd_microblock_bank_trailer_t *)( ctx->buf+sz-sizeof(fd_microblock_bank_trailer_t) );
528+
fd_microblock_bank_trailer_t * trailer = (fd_microblock_bank_trailer_t *)( src+sz-sizeof(fd_microblock_bank_trailer_t) );
504529
long now = ctx->ref_wallclock + (long)((double)(fd_frag_meta_ts_decomp( tspub, fd_tickcount() ) - ctx->ref_tickcount) / ctx->tick_per_ns);
505530
fd_gui_microblock_execution_begin( ctx->gui,
506531
now,
507532
fd_disco_poh_sig_slot( sig ),
508-
(fd_txn_p_t *)ctx->buf,
533+
(fd_txn_p_t *)src,
509534
(sz-sizeof( fd_microblock_bank_trailer_t ))/sizeof( fd_txn_p_t ),
510535
(uint)trailer->microblock_idx,
511536
trailer->pack_txn_idx );
@@ -515,14 +540,14 @@ after_frag( fd_gui_ctx_t * ctx,
515540
break;
516541
}
517542
case IN_KIND_BANK_POH: {
518-
fd_microblock_trailer_t * trailer = (fd_microblock_trailer_t *)( ctx->buf+sz-sizeof( fd_microblock_trailer_t ) );
543+
fd_microblock_trailer_t * trailer = (fd_microblock_trailer_t *)( src+sz-sizeof( fd_microblock_trailer_t ) );
519544
long now = ctx->ref_wallclock + (long)((double)(fd_frag_meta_ts_decomp( tspub, fd_tickcount() ) - ctx->ref_tickcount) / ctx->tick_per_ns);
520545
fd_gui_microblock_execution_end( ctx->gui,
521546
now,
522547
ctx->in_bank_idx[ in_idx ],
523548
fd_disco_bank_sig_slot( sig ),
524549
(sz-sizeof( fd_microblock_trailer_t ))/sizeof( fd_txn_p_t ),
525-
(fd_txn_p_t *)ctx->buf,
550+
(fd_txn_p_t *)src,
526551
trailer->pack_txn_idx,
527552
trailer->txn_start_pct,
528553
trailer->txn_load_end_pct,

0 commit comments

Comments
 (0)