LCOV - code coverage report
Current view: top level - discof/sender - fd_sender_tile.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 252 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 13 0.0 %

          Line data    Source code
       1             : /* Sender tile signs and sends transactions to the current leader. Currently
       2             :    only supports transactions which require one signature. */
       3             : #define _GNU_SOURCE
       4             : 
       5             : #include "../../disco/topo/fd_topo.h"
       6             : #include "generated/fd_sender_tile_seccomp.h"
       7             : 
       8             : #include "../store/fd_store.h"
       9             : #include "../../flamenco/repair/fd_repair.h"
      10             : #include "../../flamenco/runtime/fd_blockstore.h"
      11             : #include "../../flamenco/leaders/fd_leaders.h"
      12             : #include "../../flamenco/fd_flamenco.h"
      13             : #include "../../util/fd_util.h"
      14             : #include "../../choreo/fd_choreo.h"
      15             : #include "../../util/net/fd_eth.h"
      16             : #include "../../util/net/fd_ip4.h"
      17             : #include "../../util/net/fd_udp.h"
      18             : #include "../../disco/shred/fd_stake_ci.h"
      19             : #include "../../disco/topo/fd_pod_format.h"
      20             : #include "../../disco/keyguard/fd_keyload.h"
      21             : #include "../../disco/keyguard/fd_keyguard_client.h"
      22             : #include "../../disco/keyguard/fd_keyguard.h"
      23             : #include "../../flamenco/leaders/fd_leaders.h"
      24             : #include "../../flamenco/runtime/fd_runtime.h"
      25             : #include "../../disco/fd_disco.h"
      26             : #include "../../util/net/fd_net_headers.h"
      27             : 
      28             : #include <unistd.h>
      29             : #include <arpa/inet.h>
      30             : #include <linux/unistd.h>
      31             : #include <sys/random.h>
      32             : #include <netdb.h>
      33             : #include <netinet/in.h>
      34             : #include <sys/socket.h>
      35             : 
      36           0 : #define SCRATCH_MAX    (4UL /*KiB*/ << 10)
      37           0 : #define SCRATCH_DEPTH  (4UL) /* 4 scratch frames */
      38             : 
      39             : struct fd_sender_tile_ctx {
      40             :   fd_pubkey_t identity_key[ 1 ];
      41             :   fd_pubkey_t vote_acct_addr[ 1 ];
      42             : 
      43             :   fd_stake_ci_t * stake_ci;
      44             :   ulong *         poh_slot;
      45             :   fd_shred_dest_weighted_t * new_dest_ptr;
      46             :   ulong                      new_dest_cnt;
      47             : 
      48             :   uchar txn_buf[ sizeof(fd_txn_p_t) ] __attribute__((aligned(alignof(fd_txn_p_t))));
      49             : 
      50             :   fd_gossip_peer_addr_t tpu_serve_addr;
      51             :   fd_ip4_udp_hdrs_t     packet_hdr[1];
      52             :   ushort                net_id;
      53             : 
      54             :   ulong       stake_in_idx;
      55             :   fd_wksp_t * stake_in_mem;
      56             :   ulong       stake_in_chunk0;
      57             :   ulong       stake_in_wmark;
      58             : 
      59             :   ulong       contact_in_idx;
      60             :   fd_wksp_t * contact_in_mem;
      61             :   ulong       contact_in_chunk0;
      62             :   ulong       contact_in_wmark;
      63             : 
      64             :   ulong       replay_in_idx;
      65             :   fd_wksp_t * replay_in_mem;
      66             :   ulong       replay_in_chunk0;
      67             :   ulong       replay_in_wmark;
      68             : 
      69             :   ulong       poh_in_idx;
      70             :   fd_wksp_t * poh_in_mem;
      71             :   ulong       poh_in_chunk0;
      72             :   ulong       poh_in_wmark;
      73             : 
      74             :   ulong            gossip_out_idx;
      75             :   fd_frag_meta_t * gossip_out_mcache;
      76             :   ulong *          gossip_out_sync;
      77             :   ulong            gossip_out_depth;
      78             :   ulong            gossip_out_seq;
      79             : 
      80             :   fd_wksp_t * gossip_out_mem;
      81             :   ulong       gossip_out_chunk0;
      82             :   ulong       gossip_out_wmark;
      83             :   ulong       gossip_out_chunk;
      84             : 
      85             :   ulong            dedup_out_idx;
      86             :   fd_frag_meta_t * dedup_out_mcache;
      87             :   ulong *          dedup_out_sync;
      88             :   ulong            dedup_out_depth;
      89             :   ulong            dedup_out_seq;
      90             : 
      91             :   fd_wksp_t * dedup_out_mem;
      92             :   ulong       dedup_out_chunk0;
      93             :   ulong       dedup_out_wmark;
      94             :   ulong       dedup_out_chunk;
      95             : 
      96             :   ulong            net_out_idx;
      97             :   fd_frag_meta_t * net_out_mcache;
      98             :   ulong *          net_out_sync;
      99             :   ulong            net_out_depth;
     100             :   ulong            net_out_seq;
     101             : 
     102             :   fd_wksp_t * net_out_mem;
     103             :   ulong       net_out_chunk0;
     104             :   ulong       net_out_wmark;
     105             :   ulong       net_out_chunk;
     106             : 
     107             :   ulong                sign_in_idx;
     108             :   ulong                sign_out_idx;
     109             :   fd_keyguard_client_t keyguard_client[ 1 ];
     110             : 
     111             : };
     112             : typedef struct fd_sender_tile_ctx fd_sender_tile_ctx_t;
     113             : 
     114             : 
     115             : FD_FN_CONST static inline ulong
     116           0 : scratch_align( void ) {
     117           0 :   return 128UL;
     118           0 : }
     119             : 
     120             : FD_FN_PURE static inline ulong
     121           0 : loose_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED ) {
     122           0 :   return 0UL;
     123           0 : }
     124             : 
     125             : FD_FN_PURE static inline ulong
     126           0 : scratch_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED) {
     127           0 :   ulong l = FD_LAYOUT_INIT;
     128           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_sender_tile_ctx_t), sizeof(fd_sender_tile_ctx_t) );
     129           0 :   l = FD_LAYOUT_APPEND( l, fd_stake_ci_align(), fd_stake_ci_footprint() );
     130           0 :   l = FD_LAYOUT_APPEND( l, fd_scratch_smem_align(), fd_scratch_smem_footprint( SCRATCH_MAX   ) );
     131           0 :   l = FD_LAYOUT_APPEND( l, fd_scratch_fmem_align(), fd_scratch_fmem_footprint( SCRATCH_DEPTH ) );
     132           0 :   return FD_LAYOUT_FINI( l, scratch_align() );
     133           0 : }
     134             : 
     135             : static void
     136             : send_packet( fd_sender_tile_ctx_t * ctx,
     137             :              uint                   dst_ip_addr,
     138             :              ushort                 dst_port,
     139             :              uchar const *          payload,
     140             :              ulong                  payload_sz,
     141           0 :              ulong                  tsorig ) {
     142           0 :   uchar * packet = fd_chunk_to_laddr( ctx->net_out_mem, ctx->net_out_chunk );
     143             : 
     144           0 :   fd_ip4_udp_hdrs_t * hdr = (fd_ip4_udp_hdrs_t *)packet;
     145           0 :   *hdr = *ctx->packet_hdr;
     146             : 
     147           0 :   fd_ip4_hdr_t * ip4 = hdr->ip4;
     148           0 :   ip4->daddr  = dst_ip_addr;
     149           0 :   ip4->net_id = fd_ushort_bswap( ctx->net_id++ );
     150           0 :   ip4->check  = 0U;
     151           0 :   ip4->net_tot_len = fd_ushort_bswap( (ushort)(payload_sz + sizeof(fd_ip4_hdr_t)+sizeof(fd_udp_hdr_t)) );
     152           0 :   ip4->check  = fd_ip4_hdr_check_fast( ip4 );
     153             : 
     154           0 :   fd_udp_hdr_t * udp = hdr->udp;
     155           0 :   udp->net_dport = fd_ushort_bswap( dst_port );
     156           0 :   udp->net_len   = fd_ushort_bswap( (ushort)(payload_sz + sizeof(fd_udp_hdr_t)) );
     157           0 :   fd_memcpy( packet+sizeof(fd_ip4_udp_hdrs_t), payload, payload_sz );
     158           0 :   udp->check     = 0U;
     159             : 
     160           0 :   ulong tspub     = fd_frag_meta_ts_comp( fd_tickcount() );
     161           0 :   ulong sig       = fd_disco_netmux_sig( dst_ip_addr, dst_port, dst_ip_addr, DST_PROTO_OUTGOING, sizeof(fd_ip4_udp_hdrs_t) );
     162           0 :   ulong packet_sz = payload_sz + sizeof(fd_ip4_udp_hdrs_t);
     163           0 :   fd_mcache_publish( ctx->net_out_mcache, ctx->net_out_depth, ctx->net_out_seq, sig, ctx->net_out_chunk, packet_sz, 0UL, tsorig, tspub );
     164           0 :   ctx->net_out_seq   = fd_seq_inc( ctx->net_out_seq, 1UL );
     165           0 :   ctx->net_out_chunk = fd_dcache_compact_next( ctx->net_out_chunk, packet_sz, ctx->net_out_chunk0, ctx->net_out_wmark );
     166           0 : }
     167             : 
     168             : static int
     169             : get_current_leader_tpu_vote_contact( fd_sender_tile_ctx_t *      ctx,
     170           0 :                                      fd_shred_dest_weighted_t ** out_dest ) {
     171           0 :   ulong poh_slot = fd_fseq_query( ctx->poh_slot );
     172           0 :   if( poh_slot==ULONG_MAX ) { return -1; }
     173             : 
     174           0 :   fd_epoch_leaders_t const * lsched = fd_stake_ci_get_lsched_for_slot( ctx->stake_ci, poh_slot );
     175           0 :   if( FD_UNLIKELY( !lsched      ) ) { return -1; }
     176             : 
     177           0 :   fd_pubkey_t const * slot_leader = fd_epoch_leaders_get( lsched, poh_slot );
     178           0 :   if( FD_UNLIKELY( !slot_leader ) ) { return -1 ; } /* Count this as bad slot too */
     179             : 
     180           0 :   fd_shred_dest_t * sdest = fd_stake_ci_get_sdest_for_slot( ctx->stake_ci, poh_slot );
     181           0 :   fd_shred_dest_idx_t sdest_idx = fd_shred_dest_pubkey_to_idx( sdest, slot_leader );
     182           0 :   if( FD_UNLIKELY( sdest_idx==FD_SHRED_DEST_NO_DEST ) ) {
     183           0 :     return -1;
     184           0 :   }
     185             : 
     186           0 :   *out_dest = fd_shred_dest_idx_to_dest( sdest, sdest_idx );
     187             : 
     188           0 :   return 0;
     189           0 : }
     190             : 
     191             : static inline void
     192             : handle_new_cluster_contact_info( fd_sender_tile_ctx_t * ctx,
     193             :                                  uchar const *         buf,
     194           0 :                                  ulong                 buf_sz ) {
     195           0 :   ulong const * header = (ulong const *)fd_type_pun_const( buf );
     196             : 
     197           0 :   ulong dest_cnt = buf_sz;
     198             : 
     199           0 :   if( dest_cnt >= MAX_SHRED_DESTS )
     200           0 :     FD_LOG_ERR(( "Cluster nodes had %lu destinations, which was more than the max of %lu", dest_cnt, MAX_SHRED_DESTS ));
     201             : 
     202           0 :   fd_shred_dest_wire_t const * in_dests = fd_type_pun_const( header );
     203           0 :   fd_shred_dest_weighted_t * dests = fd_stake_ci_dest_add_init( ctx->stake_ci );
     204             : 
     205           0 :   ctx->new_dest_ptr = dests;
     206           0 :   ctx->new_dest_cnt = dest_cnt;
     207             : 
     208           0 :   for( ulong i=0UL; i<dest_cnt; i++ ) {
     209           0 :     memcpy( dests[i].pubkey.uc, in_dests[i].pubkey, 32UL );
     210           0 :     dests[i].ip4  = in_dests[i].ip4_addr;
     211           0 :     dests[i].port = in_dests[i].udp_port;
     212           0 :   }
     213           0 : }
     214             : 
     215             : static inline void
     216           0 : finalize_new_cluster_contact_info( fd_sender_tile_ctx_t * ctx ) {
     217           0 :   fd_stake_ci_dest_add_fini( ctx->stake_ci, ctx->new_dest_cnt );
     218           0 : }
     219             : 
     220             : static void
     221             : during_frag( fd_sender_tile_ctx_t * ctx,
     222             :              ulong                  in_idx,
     223             :              ulong                  seq FD_PARAM_UNUSED,
     224             :              ulong                  sig FD_PARAM_UNUSED,
     225             :              ulong                  chunk,
     226             :              ulong                  sz,
     227           0 :              ulong                  ctl FD_PARAM_UNUSED ) {
     228             : 
     229           0 :   if( FD_UNLIKELY( in_idx==ctx->sign_in_idx ) ) {
     230           0 :     FD_LOG_CRIT(( "signing tile send out of band fragment" ));
     231           0 :   }
     232             : 
     233           0 :   if( FD_UNLIKELY( in_idx==ctx->stake_in_idx ) ) {
     234           0 :     if( FD_UNLIKELY( chunk<ctx->stake_in_chunk0 || chunk>ctx->stake_in_wmark ) )
     235           0 :       FD_LOG_ERR(( "chunk %lu %lu corrupt, not in range [%lu,%lu]", chunk, sz,
     236           0 :             ctx->stake_in_chunk0, ctx->stake_in_wmark ));
     237           0 :     uchar const * dcache_entry = fd_chunk_to_laddr_const( ctx->stake_in_mem, chunk );
     238           0 :     fd_stake_ci_stake_msg_init( ctx->stake_ci, dcache_entry );
     239           0 :   }
     240             : 
     241           0 :   if( FD_UNLIKELY( in_idx==ctx->contact_in_idx ) ) {
     242           0 :     if( FD_UNLIKELY( chunk<ctx->contact_in_chunk0 || chunk>ctx->contact_in_wmark ) ) {
     243           0 :       FD_LOG_ERR(( "chunk %lu %lu corrupt, not in range [%lu,%lu]", chunk, sz, ctx->contact_in_chunk0, ctx->contact_in_wmark ));
     244           0 :     }
     245             : 
     246           0 :     uchar const * dcache_entry = fd_chunk_to_laddr_const( ctx->contact_in_mem, chunk );
     247           0 :     handle_new_cluster_contact_info( ctx, dcache_entry, sz );
     248           0 :   }
     249             : 
     250           0 :   if( FD_UNLIKELY( in_idx==ctx->replay_in_idx ) ) {
     251           0 :     if( FD_UNLIKELY( chunk<ctx->replay_in_chunk0 || chunk>ctx->replay_in_wmark || sz!=sizeof(fd_txn_p_t) ) ) {
     252           0 :       FD_LOG_ERR(( "chunk %lu %lu corrupt, not in range [%lu,%lu]", chunk, sz, ctx->replay_in_chunk0, ctx->replay_in_wmark ));
     253           0 :     }
     254             : 
     255           0 :     uchar const * dcache_entry = fd_chunk_to_laddr_const( ctx->replay_in_mem, chunk );
     256           0 :     memcpy( ctx->txn_buf, dcache_entry, sz );
     257           0 :   }
     258           0 : }
     259             : 
     260             : static void
     261             : after_frag( fd_sender_tile_ctx_t * ctx,
     262             :             ulong                  in_idx,
     263             :             ulong                  seq,
     264             :             ulong                  sig,
     265             :             ulong                  sz,
     266             :             ulong                  tsorig,
     267             :             ulong                  tspub,
     268           0 :             fd_stem_context_t *    stem ) {
     269           0 :   (void)seq;
     270           0 :   (void)sig;
     271           0 :   (void)sz;
     272           0 :   (void)tsorig;
     273           0 :   (void)tspub;
     274           0 :   (void)stem;
     275             : 
     276           0 :   if( FD_UNLIKELY( in_idx==ctx->contact_in_idx ) ) {
     277           0 :     finalize_new_cluster_contact_info( ctx );
     278           0 :     return;
     279           0 :   }
     280             : 
     281           0 :   if( FD_UNLIKELY( in_idx==ctx->stake_in_idx ) ) {
     282           0 :     fd_stake_ci_stake_msg_fini( ctx->stake_ci );
     283           0 :     return;
     284           0 :   }
     285             : 
     286           0 :   if( FD_UNLIKELY( in_idx==ctx->replay_in_idx ) ) {
     287           0 :     fd_txn_p_t * txn = (fd_txn_p_t *)fd_type_pun(ctx->txn_buf);
     288             : 
     289             :     /* sign the txn */
     290           0 :     uchar * signature = txn->payload + TXN(txn)->signature_off;
     291           0 :     uchar * message   = txn->payload + TXN(txn)->message_off;
     292           0 :     ulong message_sz  = txn->payload_sz - TXN(txn)->message_off;
     293           0 :     fd_keyguard_client_sign( ctx->keyguard_client, signature, message, message_sz, FD_KEYGUARD_SIGN_TYPE_ED25519 );
     294             : 
     295           0 :     uchar * msg_to_gossip = fd_chunk_to_laddr( ctx->gossip_out_mem, ctx->gossip_out_chunk );
     296           0 :     memcpy( msg_to_gossip, txn->payload, txn->payload_sz );
     297             : 
     298             :     /* send to leader */
     299           0 :     fd_shred_dest_weighted_t * leader_dest = NULL;
     300           0 :     int res = get_current_leader_tpu_vote_contact( ctx, &leader_dest );
     301             :     /* TODO: add metrics for successful votes sent and failed votes */
     302           0 :     if( res==0 ) {
     303           0 :       send_packet( ctx, leader_dest->ip4, leader_dest->port, msg_to_gossip, txn->payload_sz, 0UL );
     304           0 :     }
     305             : 
     306             :     /* send to gossip */
     307           0 :     fd_mcache_publish( ctx->gossip_out_mcache, ctx->gossip_out_depth, ctx->gossip_out_seq, 1UL, ctx->gossip_out_chunk,
     308           0 :       txn->payload_sz, 0UL, 0, 0 );
     309           0 :     ctx->gossip_out_seq   = fd_seq_inc( ctx->gossip_out_seq, 1UL );
     310           0 :     ctx->gossip_out_chunk = fd_dcache_compact_next( ctx->gossip_out_chunk, txn->payload_sz,
     311           0 :                                                     ctx->gossip_out_chunk0, ctx->gossip_out_wmark );
     312             :     /* send to dedup */
     313           0 :     uchar * msg_to_pack = fd_chunk_to_laddr( ctx->dedup_out_mem, ctx->dedup_out_chunk );
     314           0 :     memcpy( msg_to_pack, msg_to_gossip, txn->payload_sz );
     315           0 :     fd_mcache_publish( ctx->dedup_out_mcache, ctx->dedup_out_depth, ctx->dedup_out_seq, 1UL, ctx->dedup_out_chunk,
     316           0 :       txn->payload_sz, 0UL, 0, 0 );
     317           0 :     ctx->dedup_out_seq    = fd_seq_inc( ctx->dedup_out_seq, 1UL );
     318           0 :     ctx->dedup_out_chunk = fd_dcache_compact_next( ctx->dedup_out_chunk, txn->payload_sz, ctx->dedup_out_chunk0,
     319           0 :         ctx->dedup_out_wmark );
     320           0 :   }
     321           0 : }
     322             : 
     323             : static void
     324             : privileged_init( fd_topo_t *      topo,
     325           0 :                  fd_topo_tile_t * tile ) {
     326           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     327             : 
     328           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     329           0 :   fd_sender_tile_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_sender_tile_ctx_t), sizeof(fd_sender_tile_ctx_t) );
     330             : 
     331           0 :   if( FD_UNLIKELY( !strcmp( tile->sender.identity_key_path, "" ) ) )
     332           0 :     FD_LOG_ERR(( "identity_key_path not set" ));
     333             : 
     334           0 :   ctx->identity_key[ 0 ] = *(fd_pubkey_t const *)fd_type_pun_const( fd_keyload_load( tile->sender.identity_key_path, /* pubkey only: */ 1 ) );
     335           0 : }
     336             : 
     337             : static void
     338             : unprivileged_init( fd_topo_t *      topo,
     339           0 :                    fd_topo_tile_t * tile ) {
     340           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     341             : 
     342           0 :   if( FD_UNLIKELY( !tile->out_cnt ) ) FD_LOG_ERR(( "sender has no primary output link" ));
     343             : 
     344             :   /* Scratch mem setup */
     345             : 
     346           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     347           0 :   fd_sender_tile_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_sender_tile_ctx_t), sizeof(fd_sender_tile_ctx_t) );
     348             :   // TODO: set the lo_mark_slot to the actual snapshot slot!
     349           0 :   ctx->stake_ci = fd_stake_ci_join( fd_stake_ci_new( FD_SCRATCH_ALLOC_APPEND( l, fd_stake_ci_align(), fd_stake_ci_footprint() ), ctx->identity_key ) );
     350           0 :   void * scratch_smem        = FD_SCRATCH_ALLOC_APPEND( l, fd_scratch_smem_align(), fd_scratch_smem_footprint( SCRATCH_MAX   ) );
     351           0 :   void * scratch_fmem        = FD_SCRATCH_ALLOC_APPEND( l, fd_scratch_fmem_align(), fd_scratch_fmem_footprint( SCRATCH_DEPTH ) );
     352             : 
     353             :   /* scratch space attach */
     354           0 :   fd_scratch_attach( scratch_smem, scratch_fmem, SCRATCH_MAX, SCRATCH_DEPTH );
     355             : 
     356           0 :   ctx->net_id = (ushort)0;
     357             : 
     358           0 :   ctx->tpu_serve_addr.addr = tile->sender.ip_addr;
     359           0 :   ctx->tpu_serve_addr.port = fd_ushort_bswap( tile->sender.tpu_listen_port );
     360           0 :   fd_ip4_udp_hdr_init( ctx->packet_hdr, FD_TXN_MTU, ctx->tpu_serve_addr.addr, ctx->tpu_serve_addr.port );
     361             : 
     362           0 :   ulong poh_slot_obj_id = fd_pod_query_ulong( topo->props, "poh_slot", ULONG_MAX );
     363           0 :   FD_TEST( poh_slot_obj_id!=ULONG_MAX );
     364           0 :   ctx->poh_slot = fd_fseq_join( fd_topo_obj_laddr( topo, poh_slot_obj_id ) );
     365             : 
     366             :   /* Set up stake input */
     367           0 :   ctx->stake_in_idx = fd_topo_find_tile_in_link( topo, tile, "stake_out", 0 );
     368           0 :   FD_TEST( ctx->stake_in_idx!=ULONG_MAX );
     369           0 :   fd_topo_link_t * stake_in_link = &topo->links[ tile->in_link_id[ ctx->stake_in_idx ] ];
     370           0 :   ctx->stake_in_mem    = topo->workspaces[ topo->objs[ stake_in_link->dcache_obj_id ].wksp_id ].wksp;
     371           0 :   ctx->stake_in_chunk0 = fd_dcache_compact_chunk0( ctx->stake_in_mem, stake_in_link->dcache );
     372           0 :   ctx->stake_in_wmark  = fd_dcache_compact_wmark( ctx->stake_in_mem, stake_in_link->dcache, stake_in_link->mtu );
     373             : 
     374             :   /* Set up contact input */
     375           0 :   ctx->contact_in_idx = fd_topo_find_tile_in_link( topo, tile, "gossip_voter", 0 );
     376           0 :   FD_TEST( ctx->contact_in_idx!=ULONG_MAX );
     377           0 :   fd_topo_link_t * contact_in_link = &topo->links[ tile->in_link_id[ ctx->contact_in_idx ] ];
     378           0 :   ctx->contact_in_mem    = topo->workspaces[ topo->objs[ contact_in_link->dcache_obj_id ].wksp_id ].wksp;
     379           0 :   ctx->contact_in_chunk0 = fd_dcache_compact_chunk0( ctx->contact_in_mem, contact_in_link->dcache );
     380           0 :   ctx->contact_in_wmark  = fd_dcache_compact_wmark( ctx->contact_in_mem, contact_in_link->dcache, contact_in_link->mtu );
     381             : 
     382             :   /* Set up replay tile input */
     383           0 :   ctx->replay_in_idx = fd_topo_find_tile_in_link( topo, tile, "replay_voter", 0 );
     384           0 :   FD_TEST( ctx->replay_in_idx!=ULONG_MAX );
     385           0 :   fd_topo_link_t * replay_in_link = &topo->links[ tile->in_link_id[ ctx->replay_in_idx ] ];
     386           0 :   ctx->replay_in_mem    = topo->workspaces[ topo->objs[ replay_in_link->dcache_obj_id ].wksp_id ].wksp;
     387           0 :   ctx->replay_in_chunk0 = fd_dcache_compact_chunk0( ctx->replay_in_mem, replay_in_link->dcache );
     388           0 :   ctx->replay_in_wmark  = fd_dcache_compact_wmark( ctx->replay_in_mem, replay_in_link->dcache, replay_in_link->mtu );
     389             : 
     390             :   /* Set up repair request output */
     391           0 :   ctx->gossip_out_idx = fd_topo_find_tile_out_link( topo, tile, "voter_gossip", 0 );
     392           0 :   FD_TEST( ctx->gossip_out_idx!=ULONG_MAX );
     393           0 :   fd_topo_link_t * gossip_out_link = &topo->links[ tile->out_link_id[ ctx->gossip_out_idx ] ];
     394           0 :   ctx->gossip_out_mcache = gossip_out_link->mcache;
     395           0 :   ctx->gossip_out_sync   = fd_mcache_seq_laddr( ctx->gossip_out_mcache );
     396           0 :   ctx->gossip_out_depth  = fd_mcache_depth( ctx->gossip_out_mcache );
     397           0 :   ctx->gossip_out_seq    = fd_mcache_seq_query( ctx->gossip_out_sync );
     398           0 :   ctx->gossip_out_mem    = topo->workspaces[ topo->objs[ gossip_out_link->dcache_obj_id ].wksp_id ].wksp;
     399           0 :   ctx->gossip_out_chunk0 = fd_dcache_compact_chunk0( ctx->gossip_out_mem, gossip_out_link->dcache );
     400           0 :   ctx->gossip_out_wmark  = fd_dcache_compact_wmark ( ctx->gossip_out_mem, gossip_out_link->dcache, gossip_out_link->mtu );
     401           0 :   ctx->gossip_out_chunk  = ctx->gossip_out_chunk0;
     402             : 
     403             :   /* Set up dedup output */
     404           0 :   ctx->dedup_out_idx = fd_topo_find_tile_out_link( topo, tile, "voter_dedup", 0 );
     405           0 :   FD_TEST( ctx->dedup_out_idx!=ULONG_MAX );
     406           0 :   fd_topo_link_t * dedup_out_link = &topo->links[ tile->out_link_id[ ctx->dedup_out_idx ] ];
     407           0 :   ctx->dedup_out_mcache = dedup_out_link->mcache;
     408           0 :   ctx->dedup_out_sync   = fd_mcache_seq_laddr( ctx->dedup_out_mcache );
     409           0 :   ctx->dedup_out_depth  = fd_mcache_depth( ctx->dedup_out_mcache );
     410           0 :   ctx->dedup_out_seq    = fd_mcache_seq_query( ctx->dedup_out_sync );
     411           0 :   ctx->dedup_out_mem    = topo->workspaces[ topo->objs[ dedup_out_link->dcache_obj_id ].wksp_id ].wksp;
     412           0 :   ctx->dedup_out_chunk0 = fd_dcache_compact_chunk0( ctx->dedup_out_mem, dedup_out_link->dcache );
     413           0 :   ctx->dedup_out_wmark  = fd_dcache_compact_wmark ( ctx->dedup_out_mem, dedup_out_link->dcache, dedup_out_link->mtu );
     414           0 :   ctx->dedup_out_chunk  = ctx->dedup_out_chunk0;
     415             : 
     416             :   /* Set up net output */
     417           0 :   ctx->net_out_idx = fd_topo_find_tile_out_link( topo, tile, "voter_net", 0 );
     418           0 :   FD_TEST( ctx->net_out_idx!=ULONG_MAX );
     419           0 :   fd_topo_link_t * net_out_link = &topo->links[ tile->out_link_id[ ctx->net_out_idx ] ];
     420           0 :   ctx->net_out_mcache = net_out_link->mcache;
     421           0 :   ctx->net_out_sync   = fd_mcache_seq_laddr( ctx->net_out_mcache );
     422           0 :   ctx->net_out_depth  = fd_mcache_depth( ctx->net_out_mcache );
     423           0 :   ctx->net_out_seq    = fd_mcache_seq_query( ctx->net_out_sync );
     424           0 :   ctx->net_out_mem    = topo->workspaces[ topo->objs[ net_out_link->dcache_obj_id ].wksp_id ].wksp;
     425           0 :   ctx->net_out_chunk0 = fd_dcache_compact_chunk0( ctx->net_out_mem, net_out_link->dcache );
     426           0 :   ctx->net_out_wmark  = fd_dcache_compact_wmark ( ctx->net_out_mem, net_out_link->dcache, net_out_link->mtu );
     427           0 :   ctx->net_out_chunk  = ctx->net_out_chunk0;
     428             : 
     429             : 
     430             :   /* Set up keyguard(s) */
     431           0 :   ctx->sign_in_idx  = fd_topo_find_tile_in_link( topo, tile, "sign_voter", 0 );
     432           0 :   ctx->sign_out_idx = fd_topo_find_tile_out_link( topo, tile, "voter_sign", 0 );
     433           0 :   FD_TEST( ctx->sign_in_idx==( tile->in_cnt-1 ) );
     434             : 
     435           0 :   fd_topo_link_t * sign_in  = &topo->links[ tile->in_link_id[ ctx->sign_in_idx ] ];
     436           0 :   fd_topo_link_t * sign_out = &topo->links[ tile->out_link_id[ ctx->sign_out_idx ] ];
     437             : 
     438           0 :   if ( fd_keyguard_client_join( fd_keyguard_client_new( ctx->keyguard_client,
     439           0 :                                                             sign_out->mcache,
     440           0 :                                                             sign_out->dcache,
     441           0 :                                                             sign_in->mcache,
     442           0 :                                                             sign_in->dcache ) )==NULL ) {
     443           0 :     FD_LOG_ERR(( "Keyguard join failed" ));
     444           0 :   }
     445           0 :   ulong scratch_top = FD_SCRATCH_ALLOC_FINI( l, scratch_align() );
     446           0 :   if( FD_UNLIKELY( scratch_top != (ulong)scratch + scratch_footprint( tile ) ) ) {
     447           0 :     FD_LOG_ERR(( "scratch overflow %lu %lu %lu", scratch_top - (ulong)scratch - scratch_footprint( tile ), scratch_top, (ulong)scratch + scratch_footprint( tile ) ));
     448           0 :   }
     449           0 : }
     450             : 
     451             : 
     452             : static ulong
     453             : populate_allowed_seccomp( fd_topo_t const *      topo,
     454             :                           fd_topo_tile_t const * tile,
     455             :                           ulong                  out_cnt,
     456           0 :                           struct sock_filter *   out ) {
     457           0 :   (void)topo;
     458           0 :   (void)tile;
     459             : 
     460           0 :   populate_sock_filter_policy_fd_sender_tile( out_cnt, out, (uint)fd_log_private_logfile_fd() );
     461           0 :   return sock_filter_policy_fd_sender_tile_instr_cnt;
     462           0 : }
     463             : 
     464             : static ulong
     465             : populate_allowed_fds( fd_topo_t const *      topo,
     466             :                       fd_topo_tile_t const * tile,
     467             :                       ulong                  out_fds_cnt,
     468           0 :                       int *                  out_fds ) {
     469           0 :   (void)topo;
     470           0 :   (void)tile;
     471             : 
     472           0 :   if( FD_UNLIKELY( out_fds_cnt<2UL ) ) FD_LOG_ERR(( "out_fds_cnt %lu", out_fds_cnt ));
     473             : 
     474           0 :   ulong out_cnt = 0;
     475           0 :   out_fds[ out_cnt++ ] = 2UL; /* stderr */
     476           0 :   if( FD_LIKELY( -1!=fd_log_private_logfile_fd() ) )
     477           0 :     out_fds[ out_cnt++ ] = fd_log_private_logfile_fd(); /* logfile */
     478           0 :   return out_cnt;
     479           0 : }
     480             : 
     481           0 : #define STEM_BURST (1UL)
     482             : 
     483           0 : #define STEM_CALLBACK_CONTEXT_TYPE  fd_sender_tile_ctx_t
     484           0 : #define STEM_CALLBACK_CONTEXT_ALIGN alignof(fd_sender_tile_ctx_t)
     485             : 
     486           0 : #define STEM_CALLBACK_DURING_FRAG during_frag
     487           0 : #define STEM_CALLBACK_AFTER_FRAG  after_frag
     488             : 
     489             : #include "../../disco/stem/fd_stem.c"
     490             : 
     491             : fd_topo_run_tile_t fd_tile_sender = {
     492             :   .name                     = "sender",
     493             :   .loose_footprint          = loose_footprint,
     494             :   .populate_allowed_seccomp = populate_allowed_seccomp,
     495             :   .populate_allowed_fds     = populate_allowed_fds,
     496             :   .scratch_align            = scratch_align,
     497             :   .scratch_footprint        = scratch_footprint,
     498             :   .privileged_init          = privileged_init,
     499             :   .unprivileged_init        = unprivileged_init,
     500             :   .run                      = stem_run,
     501             : };

Generated by: LCOV version 1.14