LCOV - code coverage report
Current view: top level - disco/keyguard - fd_sign_tile.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 284 0.0 %
Date: 2026-09-17 04:28:31 Functions: 0 16 0.0 %

          Line data    Source code
       1             : #define _GNU_SOURCE
       2             : #include "../tiles.h"
       3             : 
       4             : #include "generated/fd_sign_tile_seccomp.h"
       5             : 
       6             : #include "../keyguard/fd_keyguard.h"
       7             : #include "../keyguard/fd_keyload.h"
       8             : #include "../keyguard/fd_keyswitch.h"
       9             : #include "../../discof/admin/fd_adminctl.h"
      10             : #include "../../ballet/base58/fd_base58.h"
      11             : #include "../metrics/fd_metrics.h"
      12             : #include "../../ballet/bls/fd_bls.h"
      13             : 
      14             : #include "../../util/hist/fd_histf.h"
      15             : 
      16             : #include <errno.h>
      17             : #include <sys/mman.h>
      18             : 
      19           0 : #define MAX_IN (32UL)
      20             : 
      21             : /* fd_sign_in_ctx_t is a context object for each in (producer) mcache
      22             :    connected to the sign tile. */
      23             : 
      24             : struct fd_sign_out_ctx {
      25             :   fd_wksp_t * out_mem;
      26             :   ulong       out_chunk0;
      27             :   ulong       out_wmark;
      28             :   ulong       out_chunk;
      29             : };
      30             : typedef struct fd_sign_out_ctx fd_sign_out_ctx_t;
      31             : 
      32             : struct fd_sign_in_ctx {
      33             :   int              role;
      34             :   fd_wksp_t *      mem;
      35             :   ulong            chunk0;
      36             :   ulong            wmark;
      37             :   ulong            mtu;
      38             : };
      39             : typedef struct fd_sign_in_ctx fd_sign_in_ctx_t;
      40             : 
      41             : typedef struct {
      42             :   uchar             _data[ FD_KEYGUARD_SIGN_REQ_MTU ];
      43             : 
      44             :   /* Pre-staged with the public key base58 encoded, followed by "-" in the first bytes */
      45             :   ulong public_key_base58_sz;
      46             :   uchar concat[ FD_BASE58_ENCODED_32_SZ+1UL+9UL ];
      47             : 
      48             :   fd_sign_in_ctx_t  in[ MAX_IN ];
      49             :   fd_sign_out_ctx_t out[ MAX_IN ];
      50             : 
      51             :   fd_sha512_t       sha512 [ 1 ];
      52             : 
      53             :   fd_keyswitch_t *  keyswitch;
      54             : 
      55             :   fd_keyswitch_t *  av_keyswitch; /* authorized voters */
      56             : 
      57             :   uchar *           public_key;
      58             :   uchar *           private_key;
      59             : 
      60             :   uchar *           bls_private_key; /* alpenglow BLS voting key */
      61             : 
      62             :   uchar tip_payment_program     [32];
      63             :   uchar tip_distribution_program[32];
      64             : 
      65             :   ulong             authorized_voters_cnt;
      66             :   uchar             authorized_voter_pubkeys[ 16UL ][ 32UL ];
      67             :   uchar             authorized_voter_private_keys[ 16UL ][ 32UL ];
      68             : 
      69             :   fd_histf_t        sign_duration[1];
      70             : } fd_sign_ctx_t;
      71             : 
      72             : FD_FN_CONST static inline ulong
      73           0 : scratch_align( void ) {
      74           0 :   return alignof( fd_sign_ctx_t );
      75           0 : }
      76             : 
      77             : FD_FN_PURE static inline ulong
      78           0 : scratch_footprint( fd_topo_tile_t const * tile ) {
      79           0 :   (void)tile;
      80           0 :   ulong l = FD_LAYOUT_INIT;
      81           0 :   l = FD_LAYOUT_APPEND( l, alignof( fd_sign_ctx_t ), sizeof( fd_sign_ctx_t ) );
      82           0 :   return FD_LAYOUT_FINI( l, scratch_align() );
      83           0 : }
      84             : 
      85             : static void FD_FN_SENSITIVE
      86           0 : derive_fields( fd_sign_ctx_t * ctx ) {
      87           0 :   uchar check_public_key[ 32 ];
      88           0 :   fd_ed25519_public_from_private( check_public_key, ctx->private_key, ctx->sha512 );
      89           0 :   if( FD_UNLIKELY( memcmp( check_public_key, ctx->public_key, 32UL ) ) )
      90           0 :     FD_LOG_EMERG(( "The public key in the identity key file does not match the public key derived from the private key. "
      91           0 :                    "Firedancer will not use the key pair to sign as it might leak the private key." ));
      92             : 
      93           0 :   fd_base58_encode_32( ctx->public_key, &ctx->public_key_base58_sz, (char *)ctx->concat );
      94           0 :   ctx->concat[ ctx->public_key_base58_sz ] = '-';
      95             : 
      96             :   /* Alpenglow BLS key derivation, matching
      97             :      solana_bls_signatures::SecretKey::derive_from_signer: the BLS IKM
      98             :      is the identity's ed25519 signature over a fixed message. */
      99           0 :   static char const derive_msg[] = "bls-key-derive-alpenglow";
     100           0 :   uchar ikm[ 64 ];
     101           0 :   fd_ed25519_sign( ikm, (uchar const *)derive_msg, sizeof(derive_msg)-1UL, ctx->public_key, ctx->private_key, ctx->sha512 );
     102           0 :   fd_bls_sec_derive( (fd_bls_sec_t *)fd_type_pun( ctx->bls_private_key ), ikm, sizeof(ikm) );
     103           0 :   fd_memzero_explicit( ikm, sizeof(ikm) );
     104           0 : }
     105             : 
     106             : static void FD_FN_SENSITIVE
     107           0 : during_housekeeping_sensitive( fd_sign_ctx_t * ctx ) {
     108           0 :   if( FD_UNLIKELY( fd_keyswitch_state_query( ctx->keyswitch )==FD_KEYSWITCH_STATE_SWITCH_PENDING ) ) {
     109           0 :     memcpy( ctx->private_key, ctx->keyswitch->bytes, 32UL );
     110           0 :     fd_memzero_explicit( ctx->keyswitch->bytes, 32UL );
     111           0 :     FD_COMPILER_MFENCE();
     112           0 :     memcpy( ctx->public_key, ctx->keyswitch->bytes+32UL, 32UL );
     113             : 
     114           0 :     derive_fields( ctx );
     115           0 :     fd_keyswitch_state( ctx->keyswitch, FD_KEYSWITCH_STATE_COMPLETED );
     116           0 :   }
     117             : 
     118             :   /* firedancer only */
     119             : 
     120           0 :   if( FD_UNLIKELY( ctx->av_keyswitch && fd_keyswitch_state_query( ctx->av_keyswitch )==FD_KEYSWITCH_STATE_SWITCH_PENDING ) ) {
     121           0 :     ulong param = fd_keyswitch_param_query( ctx->av_keyswitch );
     122           0 :     if( FD_LIKELY( param==FD_KEYSWITCH_PARAM_AV_ADD ) ) {
     123           0 :       if( FD_UNLIKELY( ctx->authorized_voters_cnt==16UL ) ) {
     124           0 :         FD_LOG_WARNING(( "keyswitch failed: maximum number of authorized voters reached" ));
     125           0 :         fd_memzero_explicit( ctx->av_keyswitch->bytes, 64UL );
     126           0 :         ctx->av_keyswitch->result = FD_ADD_AUTHORIZED_VOTER_RESULT_MAX_AUTH_VOTERS;
     127           0 :         fd_keyswitch_state( ctx->av_keyswitch, FD_KEYSWITCH_STATE_FAILED );
     128           0 :         return;
     129           0 :       }
     130           0 :       for( ulong i=0UL; i<ctx->authorized_voters_cnt; i++ ) {
     131           0 :         if( FD_UNLIKELY( !memcmp( ctx->authorized_voter_pubkeys[ i ], ctx->av_keyswitch->bytes+32UL, 32UL ) ) ) {
     132           0 :           FD_BASE58_ENCODE_32_BYTES( ctx->authorized_voter_pubkeys[ i ], pubkey_b58 );
     133           0 :           FD_LOG_WARNING(( "keyswitch failed: authorized voter key duplicate (%s)", pubkey_b58 ));
     134           0 :           fd_memzero_explicit( ctx->av_keyswitch->bytes, 64UL );
     135           0 :           ctx->av_keyswitch->result = FD_ADD_AUTHORIZED_VOTER_RESULT_DUPLICATE_AUTH_VOTER;
     136           0 :           fd_keyswitch_state( ctx->av_keyswitch, FD_KEYSWITCH_STATE_FAILED );
     137           0 :           return;
     138           0 :         }
     139           0 :       }
     140             : 
     141           0 :       memcpy( ctx->authorized_voter_private_keys[ ctx->authorized_voters_cnt ], ctx->av_keyswitch->bytes, 32UL );
     142           0 :       fd_memzero_explicit( ctx->av_keyswitch->bytes, 32UL );
     143           0 :       FD_COMPILER_MFENCE();
     144           0 :       memcpy( ctx->authorized_voter_pubkeys[ ctx->authorized_voters_cnt ], ctx->av_keyswitch->bytes + 32UL, 32UL );
     145           0 :       ctx->authorized_voters_cnt++;
     146           0 :     } else if( FD_LIKELY( param==FD_KEYSWITCH_PARAM_AV_CLEAR ) ) {
     147           0 :       fd_memzero_explicit( ctx->authorized_voter_private_keys, sizeof( ctx->authorized_voter_private_keys ) );
     148           0 :       fd_memzero_explicit( ctx->authorized_voter_pubkeys,      sizeof( ctx->authorized_voter_pubkeys      ) );
     149           0 :       ctx->authorized_voters_cnt = 0UL;
     150           0 :     } else {
     151           0 :       FD_LOG_CRIT(( "keyswitch: unexpected authorized voter operation %lu", param ));
     152           0 :     }
     153           0 :     fd_keyswitch_state( ctx->av_keyswitch, FD_KEYSWITCH_STATE_COMPLETED );
     154           0 :   }
     155           0 : }
     156             : 
     157             : static inline void
     158           0 : during_housekeeping( fd_sign_ctx_t * ctx ) {
     159           0 :   during_housekeeping_sensitive( ctx );
     160           0 : }
     161             : 
     162             : static inline void
     163           0 : metrics_write( fd_sign_ctx_t * ctx ) {
     164           0 :   FD_MHIST_COPY( SIGN, SIGN_DURATION_SECONDS, ctx->sign_duration );
     165           0 : }
     166             : 
     167             : /* during_frag is called between pairs for sequence number checks, as
     168             :    we are reading incoming frags.  We don't actually need to copy the
     169             :    fragment here, see fd_dedup.c for why we do this.*/
     170             : 
     171             : static void FD_FN_SENSITIVE
     172             : during_frag_sensitive( void * _ctx,
     173             :                        ulong  in_idx,
     174             :                        ulong  seq,
     175             :                        ulong  sig,
     176             :                        ulong  chunk,
     177           0 :                        ulong  sz ) {
     178           0 :   (void)seq;
     179           0 :   (void)sig;
     180             : 
     181           0 :   fd_sign_ctx_t * ctx = (fd_sign_ctx_t *)_ctx;
     182           0 :   FD_TEST( in_idx<MAX_IN );
     183             : 
     184           0 :   int   role = ctx->in[ in_idx ].role;
     185           0 :   ulong mtu  = ctx->in[ in_idx ].mtu;
     186             : 
     187           0 :   if( chunk<ctx->in[ in_idx ].chunk0 || chunk>ctx->in[ in_idx ].wmark || sz>mtu ) {
     188           0 :     FD_LOG_EMERG(( "oversz or out of bounds signing request (role=%d chunk=%lu sz=%lu mtu=%lu, chunk0=%lu, wmark=%lu)", role, chunk, sz, mtu, ctx->in[ in_idx ].chunk0, ctx->in[ in_idx ].wmark ));
     189           0 :   }
     190             : 
     191           0 :   void * src = fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk );
     192           0 :   fd_memcpy( ctx->_data, src, sz );
     193           0 : }
     194             : 
     195             : 
     196             : static void
     197             : during_frag( void * _ctx,
     198             :              ulong  in_idx,
     199             :              ulong  seq,
     200             :              ulong  sig,
     201             :              ulong  chunk,
     202             :              ulong  sz,
     203           0 :              ulong  ctl FD_PARAM_UNUSED ) {
     204           0 :   during_frag_sensitive( _ctx, in_idx, seq, sig, chunk, sz );
     205           0 : }
     206             : 
     207             : static void FD_FN_SENSITIVE
     208             : after_frag_sensitive( void *              _ctx,
     209             :                       ulong               in_idx,
     210             :                       ulong               seq,
     211             :                       ulong               sig,
     212             :                       ulong               sz,
     213             :                       ulong               tsorig,
     214             :                       ulong               tspub,
     215           0 :                       fd_stem_context_t * stem ) {
     216           0 :   (void)seq;
     217           0 :   (void)tspub;
     218             : 
     219           0 :   fd_sign_ctx_t * ctx = (fd_sign_ctx_t *)_ctx;
     220             : 
     221             :   /* The lower 32 bits are used to specify the sign type.
     222             : 
     223             :      If the frag is coming from the repair tile, then the upper 32 bits
     224             :      contain the repair tile nonce to identify the request.
     225             : 
     226             :      If the frag is coming from the send tile, then the upper 32 bits
     227             :      contain the index of the authorized voter that needs to sign the
     228             :      vote transaction.  The least significant bit of the upper 32 is
     229             :      used to indicate if a second signature is needed.  The next 4 least
     230             :      significant bits are used to encode the index of the authorized
     231             :      voter that a signature is needed from. */
     232           0 :   int sign_type         = (int)(uint)(sig);
     233           0 :   int needs_second_sign = ctx->in[ in_idx ].role==FD_KEYGUARD_ROLE_TXSEND && ((sig>>32) & 1UL);
     234             : 
     235           0 :   FD_TEST( in_idx<MAX_IN );
     236             : 
     237           0 :   int role = ctx->in[ in_idx ].role;
     238             : 
     239           0 :   fd_keyguard_authority_t authority = {0};
     240           0 :   memcpy( authority.identity_pubkey,          ctx->public_key,               32UL );
     241           0 :   memcpy( authority.tip_payment_program,      ctx->tip_payment_program,      32UL );
     242           0 :   memcpy( authority.tip_distribution_program, ctx->tip_distribution_program, 32UL );
     243             : 
     244           0 :   if( FD_UNLIKELY( !fd_keyguard_payload_authorize( &authority, ctx->_data, sz, role, sign_type ) ) ) {
     245           0 :     FD_LOG_EMERG(( "fd_keyguard_payload_authorize failed (role=%d sign_type=%d)", role, sign_type ));
     246           0 :   }
     247             : 
     248           0 :   long sign_duration = -fd_tickcount();
     249             : 
     250           0 :   uchar * dst    = fd_chunk_to_laddr( ctx->out[ in_idx ].out_mem, ctx->out[ in_idx ].out_chunk );
     251           0 :   ulong   out_sz = 64UL;
     252             : 
     253           0 :   switch( sign_type ) {
     254           0 :   case FD_KEYGUARD_SIGN_TYPE_ED25519: {
     255           0 :     fd_ed25519_sign( dst, ctx->_data, sz, ctx->public_key, ctx->private_key, ctx->sha512 );
     256           0 :     if( needs_second_sign ) {
     257           0 :       ulong authority_idx = (sig >> 33) & 0xFUL;
     258           0 :       if( FD_UNLIKELY( authority_idx>=ctx->authorized_voters_cnt ) )
     259           0 :         FD_LOG_CRIT(( "invalid sign request from in_idx=%lu: authority_idx=%lu out of range (authorized_voters_cnt=%lu)", in_idx, authority_idx, ctx->authorized_voters_cnt ));
     260           0 :       fd_ed25519_sign( dst+64UL, ctx->_data, sz, ctx->authorized_voter_pubkeys[ authority_idx ], ctx->authorized_voter_private_keys[ authority_idx ], ctx->sha512 );
     261           0 :       out_sz = 128UL;
     262           0 :     }
     263           0 :     break;
     264           0 :   }
     265           0 :   case FD_KEYGUARD_SIGN_TYPE_SHA256_ED25519: {
     266           0 :     uchar hash[ 32 ];
     267           0 :     fd_sha256_hash( ctx->_data, sz, hash );
     268           0 :     fd_ed25519_sign( dst, hash, 32UL, ctx->public_key, ctx->private_key, ctx->sha512 );
     269           0 :     break;
     270           0 :   }
     271           0 :   case FD_KEYGUARD_SIGN_TYPE_PUBKEY_CONCAT_ED25519: {
     272           0 :     memcpy( ctx->concat+ctx->public_key_base58_sz+1UL, ctx->_data, 9UL );
     273           0 :     fd_ed25519_sign( dst, ctx->concat, ctx->public_key_base58_sz+1UL+9UL, ctx->public_key, ctx->private_key, ctx->sha512 );
     274           0 :     break;
     275           0 :   }
     276           0 :   case FD_KEYGUARD_SIGN_TYPE_BLS: {
     277           0 :     fd_bls_sig_t bls_sig[1];
     278           0 :     fd_bls_sec_sign( (fd_bls_sec_t const *)fd_type_pun_const( ctx->bls_private_key ), ctx->_data, sz, bls_sig );
     279           0 :     fd_bls_sig_ser( bls_sig, dst );
     280           0 :     out_sz = FD_KEYGUARD_BLS_SIG_SZ;
     281           0 :     break;
     282           0 :   }
     283           0 :   default:
     284           0 :     FD_LOG_EMERG(( "invalid sign type: %d", sign_type ));
     285           0 :   }
     286             : 
     287           0 :   sign_duration += fd_tickcount();
     288           0 :   fd_histf_sample( ctx->sign_duration, (ulong)sign_duration );
     289             : 
     290           0 :   fd_stem_publish( stem, in_idx, sig, ctx->out[ in_idx ].out_chunk, out_sz, 0UL, tsorig, 0UL );
     291           0 :   ctx->out[ in_idx ].out_chunk = fd_dcache_compact_next( ctx->out[ in_idx ].out_chunk, out_sz, ctx->out[ in_idx ].out_chunk0, ctx->out[ in_idx ].out_wmark );
     292           0 : }
     293             : 
     294             : static void
     295             : after_frag( void *              _ctx,
     296             :             ulong               in_idx,
     297             :             ulong               seq,
     298             :             ulong               sig,
     299             :             ulong               sz,
     300             :             ulong               tsorig,
     301             :             ulong               tspub,
     302           0 :             fd_stem_context_t * stem ) {
     303           0 :   after_frag_sensitive( _ctx, in_idx, seq, sig, sz, tsorig, tspub, stem );
     304           0 : }
     305             : 
     306             : static void FD_FN_SENSITIVE
     307             : privileged_init_sensitive( fd_topo_t const *      topo,
     308           0 :                            fd_topo_tile_t const * tile ) {
     309           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     310           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     311           0 :   fd_sign_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof( fd_sign_ctx_t ), sizeof( fd_sign_ctx_t ) );
     312             : 
     313           0 :   uchar * identity_key = fd_keyload_mprotect_wr( fd_keyload_load( tile->sign.identity_key_path, /* pubkey only: */ 0 ), /* public_key_only: */ 0 );
     314           0 :   ctx->private_key = identity_key;
     315           0 :   ctx->public_key  = identity_key + 32UL;
     316             : 
     317           0 :   ctx->bls_private_key = fd_keyload_alloc_protected_pages( 1UL, 2UL );
     318             : 
     319           0 :   ctx->authorized_voters_cnt = tile->sign.authorized_voter_paths_cnt;
     320           0 :   for( ulong i=0UL; i<tile->sign.authorized_voter_paths_cnt; i++ ) {
     321           0 :     uchar const * authorized_voter_key = fd_keyload_load( tile->sign.authorized_voter_paths[ i ], /* pubkey only: */ 0 );
     322           0 :     memcpy( ctx->authorized_voter_private_keys[ i ], authorized_voter_key, 32UL );
     323           0 :     memcpy( ctx->authorized_voter_pubkeys[ i ], authorized_voter_key + 32UL, 32UL );
     324           0 :   }
     325             : 
     326             :   /* The stack can be taken over and reorganized by under AddressSanitizer,
     327             :      which causes this code to fail.  */
     328             : #if FD_HAS_ASAN
     329             :   FD_LOG_WARNING(( "!!! SECURITY WARNING !!! YOU ARE RUNNING THE SIGNING TILE "
     330             :                    "WITH ADDRESS SANITIZER ENABLED. THIS CAN LEAK SENSITIVE "
     331             :                    "DATA INCLUDING YOUR PRIVATE KEYS INTO CORE DUMPS IF THIS "
     332             :                    "PROCESS ABORTS. IT IS HIGHLY ADVISED TO NOT TO RUN IN THIS "
     333             :                    "MODE IN PRODUCTION!" ));
     334             : #else
     335             :   /* Prevent the stack from showing up in core dumps just in case the
     336             :      private key somehow ends up in there. */
     337           0 :   FD_TEST( fd_tile_stack0() );
     338           0 :   FD_TEST( fd_tile_stack_sz() );
     339           0 :   if( FD_UNLIKELY( madvise( (void*)fd_tile_stack0(), fd_tile_stack_sz(), MADV_DONTDUMP ) ) )
     340           0 :     FD_LOG_ERR(( "madvise failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     341           0 : #endif
     342           0 : }
     343             : 
     344             : static void
     345             : privileged_init( fd_topo_t const *      topo,
     346           0 :                  fd_topo_tile_t const * tile ) {
     347           0 :   privileged_init_sensitive( topo, tile );
     348           0 : }
     349             : 
     350             : static void FD_FN_SENSITIVE
     351             : unprivileged_init_sensitive( fd_topo_t const *      topo,
     352           0 :                              fd_topo_tile_t const * tile ) {
     353           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     354             : 
     355           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     356           0 :   fd_sign_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof( fd_sign_ctx_t ), sizeof( fd_sign_ctx_t ) );
     357           0 :   FD_TEST( fd_sha512_join( fd_sha512_new( ctx->sha512 ) ) );
     358             : 
     359           0 :   FD_TEST( tile->in_cnt<=MAX_IN );
     360           0 :   FD_TEST( tile->in_cnt==tile->out_cnt );
     361             : 
     362           0 :   fd_histf_join( fd_histf_new( ctx->sign_duration, FD_MHIST_SECONDS_MIN( SIGN, SIGN_DURATION_SECONDS ),
     363           0 :                                                    FD_MHIST_SECONDS_MAX( SIGN, SIGN_DURATION_SECONDS ) ) );
     364             : 
     365           0 :   ctx->keyswitch = fd_keyswitch_join( fd_topo_obj_laddr( topo, tile->id_keyswitch_obj_id ) );
     366           0 :   derive_fields( ctx );
     367             : 
     368           0 :   if( FD_LIKELY( tile->av_keyswitch_obj_id!=ULONG_MAX ) ) {
     369           0 :     ctx->av_keyswitch = fd_keyswitch_join( fd_topo_obj_laddr( topo, tile->av_keyswitch_obj_id ) );
     370           0 :     FD_TEST( ctx->av_keyswitch );
     371           0 :   } else {
     372           0 :     ctx->av_keyswitch = NULL;
     373           0 :   }
     374             : 
     375           0 :   memcpy( ctx->tip_payment_program,      tile->sign.bundle.tip_payment_program_addr,      32UL );
     376           0 :   memcpy( ctx->tip_distribution_program, tile->sign.bundle.tip_distribution_program_addr, 32UL );
     377             : 
     378           0 :   for( ulong i=0UL; i<MAX_IN; i++ ) ctx->in[ i ].role = -1;
     379             : 
     380           0 :   for( ulong i=0UL; i<tile->in_cnt; i++ ) {
     381           0 :     fd_topo_link_t const * in_link = &topo->links[ tile->in_link_id[ i ] ];
     382           0 :     fd_topo_link_t const * out_link = &topo->links[ tile->out_link_id[ i ] ];
     383             : 
     384           0 :     if( in_link->mtu > FD_KEYGUARD_SIGN_REQ_MTU ) FD_LOG_CRIT(( "oversz link[%lu].mtu=%lu", i, in_link->mtu ));
     385           0 :     ctx->in[ i ].mem    = fd_wksp_containing( in_link->dcache );
     386           0 :     ctx->in[ i ].mtu    = in_link->mtu;
     387           0 :     ctx->in[ i ].chunk0 = fd_dcache_compact_chunk0( ctx->in[ i ].mem, in_link->dcache );
     388           0 :     ctx->in[ i ].wmark  = fd_dcache_compact_wmark( ctx->in[ i ].mem, in_link->dcache, in_link->mtu );
     389             : 
     390           0 :     ctx->out[ i ].out_mem    = fd_wksp_containing( out_link->dcache );
     391           0 :     ctx->out[ i ].out_chunk0 = fd_dcache_compact_chunk0( ctx->out[ i ].out_mem, out_link->dcache );
     392           0 :     ctx->out[ i ].out_wmark  = fd_dcache_compact_wmark( ctx->out[ i ].out_mem, out_link->dcache, out_link->mtu );
     393           0 :     ctx->out[ i ].out_chunk  = ctx->out[ i ].out_chunk0;
     394             : 
     395           0 :     if( !strcmp( in_link->name, "shred_sign" ) ) {
     396           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_LEADER;
     397           0 :       FD_TEST( !strcmp( out_link->name, "sign_shred" ) );
     398           0 :       FD_TEST( in_link->mtu==32UL );
     399           0 :       FD_TEST( out_link->mtu==64UL );
     400           0 :     } else if ( !strcmp( in_link->name, "gossip_sign" ) ) {
     401           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_GOSSIP;
     402           0 :       FD_TEST( !strcmp( out_link->name, "sign_gossip" ) );
     403           0 :       FD_TEST( in_link->mtu==2048UL );
     404           0 :       FD_TEST( out_link->mtu==64UL );
     405           0 :     } else if ( !strcmp( in_link->name, "repair_sign" ) ) {
     406           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_REPAIR;
     407           0 :       FD_TEST( !strcmp( out_link->name, "sign_repair" ) );
     408           0 :       FD_TEST( in_link->mtu==124UL ); // FD_REPAIR_MAX_PREIMAGE_SZ
     409           0 :       FD_TEST( out_link->mtu==64UL );
     410           0 :     } else if ( !strcmp(in_link->name, "txsend_sign" ) ) {
     411           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_TXSEND;
     412           0 :       FD_TEST( !strcmp( out_link->name, "sign_txsend" ) );
     413           0 :       FD_TEST( in_link->mtu==FD_TXN_MTU_V0  );
     414           0 :       FD_TEST( out_link->mtu==64UL*2UL );
     415           0 :     } else if( !strcmp(in_link->name, "bundle_sign" ) ) {
     416           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_BUNDLE;
     417           0 :       FD_TEST( !strcmp( out_link->name, "sign_bundle" ) );
     418           0 :       FD_TEST( in_link->mtu==9UL );
     419           0 :       FD_TEST( out_link->mtu==64UL );
     420           0 :     } else if( !strcmp(in_link->name, "event_sign" ) ) {
     421           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_EVENT;
     422           0 :       FD_TEST( !strcmp( out_link->name, "sign_event" ) );
     423           0 :       FD_TEST( in_link->mtu==317UL );
     424           0 :       FD_TEST( out_link->mtu==64UL );
     425           0 :     } else if( !strcmp(in_link->name, "pack_sign" ) ) {
     426           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_BUNDLE_CRANK;
     427           0 :       FD_TEST( !strcmp( out_link->name, "sign_pack" ) );
     428           0 :       FD_TEST( in_link->mtu==1232UL );
     429           0 :       FD_TEST( out_link->mtu==64UL );
     430           0 :     } else if( !strcmp(in_link->name, "rserve_sign" ) ) {
     431           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_RSERVE;
     432           0 :       FD_TEST( !strcmp( out_link->name, "sign_rserve" ) );
     433           0 :       FD_TEST( in_link->mtu==32UL );
     434           0 :       FD_TEST( out_link->mtu==64UL );
     435           0 :     } else if( !strcmp(in_link->name, "votor_sign" ) ) {
     436           0 :       ctx->in[ i ].role = FD_KEYGUARD_ROLE_VOTOR;
     437           0 :       FD_TEST( !strcmp( out_link->name, "sign_votor" ) );
     438           0 :       FD_TEST( in_link->mtu==130UL );
     439           0 :       FD_TEST( out_link->mtu==FD_KEYGUARD_BLS_SIG_SZ );
     440           0 :     } else {
     441           0 :       FD_LOG_CRIT(( "unexpected link %s", in_link->name ));
     442           0 :     }
     443           0 :   }
     444             : 
     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             : 
     450             : static void
     451             : unprivileged_init( fd_topo_t const *      topo,
     452           0 :                    fd_topo_tile_t const * tile ) {
     453           0 :   unprivileged_init_sensitive( topo, tile );
     454           0 : }
     455             : 
     456             : static ulong
     457             : populate_allowed_seccomp( fd_topo_t const *      topo,
     458             :                           fd_topo_tile_t const * tile,
     459             :                           ulong                  out_cnt,
     460           0 :                           struct sock_filter *   out ) {
     461           0 :   (void)topo;
     462           0 :   (void)tile;
     463             : 
     464           0 :   populate_sock_filter_policy_fd_sign_tile( out_cnt, out, (uint)fd_log_private_logfile_fd() );
     465           0 :   return sock_filter_policy_fd_sign_tile_instr_cnt;
     466           0 : }
     467             : 
     468             : static ulong
     469             : populate_allowed_fds( fd_topo_t const *      topo,
     470             :                       fd_topo_tile_t const * tile,
     471             :                       ulong                  out_fds_cnt,
     472           0 :                       int *                  out_fds ) {
     473           0 :   (void)topo;
     474           0 :   (void)tile;
     475             : 
     476           0 :   if( FD_UNLIKELY( out_fds_cnt<2UL ) ) FD_LOG_ERR(( "out_fds_cnt %lu", out_fds_cnt ));
     477             : 
     478           0 :   ulong out_cnt = 0;
     479           0 :   out_fds[ out_cnt++ ] = 2; /* stderr */
     480           0 :   if( FD_LIKELY( -1!=fd_log_private_logfile_fd() ) )
     481           0 :     out_fds[ out_cnt++ ] = fd_log_private_logfile_fd(); /* logfile */
     482           0 :   return out_cnt;
     483           0 : }
     484             : 
     485           0 : #define STEM_BURST (1UL)
     486             : 
     487             : /* See explanation in fd_pack */
     488           0 : #define STEM_LAZY  (128L*3000L)
     489             : 
     490           0 : #define STEM_CALLBACK_CONTEXT_TYPE  fd_sign_ctx_t
     491           0 : #define STEM_CALLBACK_CONTEXT_ALIGN alignof(fd_sign_ctx_t)
     492             : 
     493           0 : #define STEM_CALLBACK_DURING_HOUSEKEEPING during_housekeeping
     494           0 : #define STEM_CALLBACK_METRICS_WRITE       metrics_write
     495           0 : #define STEM_CALLBACK_DURING_FRAG         during_frag
     496           0 : #define STEM_CALLBACK_AFTER_FRAG          after_frag
     497             : 
     498             : #include "../../disco/stem/fd_stem.c"
     499             : 
     500             : fd_topo_run_tile_t fd_tile_sign = {
     501             :   .name                     = "sign",
     502             :   .populate_allowed_seccomp = populate_allowed_seccomp,
     503             :   .populate_allowed_fds     = populate_allowed_fds,
     504             :   .scratch_align            = scratch_align,
     505             :   .scratch_footprint        = scratch_footprint,
     506             :   .privileged_init          = privileged_init,
     507             :   .unprivileged_init        = unprivileged_init,
     508             :   .run                      = stem_run,
     509             : };

Generated by: LCOV version 1.14