LCOV - code coverage report
Current view: top level - disco - fd_disco_base.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 12 87 13.8 %
Date: 2026-02-26 05:45:35 Functions: 4 7812 0.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_fd_disco_base_h
       2             : #define HEADER_fd_src_disco_fd_disco_base_h
       3             : 
       4             : #include "../tango/fd_tango.h"
       5             : #include "../ballet/shred/fd_shred.h"
       6             : #include "../ballet/txn/fd_txn.h"
       7             : #include "../flamenco/types/fd_types_custom.h"
       8             : #include "../util/wksp/fd_wksp_private.h"
       9             : 
      10          18 : #define DST_PROTO_OUTGOING (0UL)
      11           0 : #define DST_PROTO_TPU_UDP  (1UL)
      12           0 : #define DST_PROTO_TPU_QUIC (2UL)
      13          18 : #define DST_PROTO_SHRED    (3UL)
      14           0 : #define DST_PROTO_REPAIR   (4UL)
      15           0 : #define DST_PROTO_GOSSIP   (5UL)
      16           0 : #define DST_PROTO_SEND     (6UL)
      17             : 
      18           0 : #define POH_PKT_TYPE_MICROBLOCK    (0UL)
      19           0 : #define POH_PKT_TYPE_BECAME_LEADER (1UL)
      20           0 : #define POH_PKT_TYPE_FEAT_ACT_SLOT (2UL)
      21             : 
      22             : /* FD_NET_MTU is the max full packet size, with ethernet, IP, and UDP
      23             :    headers that can go in or out of the net tile.  2048 is the maximum
      24             :    XSK entry size, so this value follows naturally. */
      25             : 
      26          39 : #define FD_NET_MTU (2048UL)
      27             : 
      28             : /* FD_TPU_MTU is the max serialized byte size of a txn sent over TPU.
      29             : 
      30             :    This is minimum MTU of IPv6 packet - IPv6 header - UDP header
      31             :                                  1280 -          40 -          8 */
      32             : 
      33           0 : #define FD_TPU_MTU (1232UL)
      34             : 
      35             : /* FD_GOSSIP_MTU is the max sz of a gossip packet which is the same as
      36             :    above. */
      37             : 
      38           0 : #define FD_GOSSIP_MTU (FD_TPU_MTU)
      39             : 
      40             : /* FD_SHRED_STORE_MTU is the size of an fd_fec_set (statically
      41             :    asserted in fd_shred_tile.c). */
      42             : 
      43           0 : #define FD_SHRED_STORE_MTU (78656UL)
      44             : 
      45             : /* FD_SHRED_OUT_MTU is the maximum size of a frag on the shred_out
      46             :    link.  This is the size of a data shred header + merkle root
      47             :    + chained merkle root + nonce/is_leader. */
      48             : 
      49           0 : #define FD_SHRED_OUT_MTU (FD_SHRED_CODE_HEADER_SZ + 2*FD_SHRED_MERKLE_ROOT_SZ + sizeof(int))
      50             : FD_STATIC_ASSERT( FD_SHRED_OUT_MTU == 157UL , update FD_SHRED_OUT_MTU );
      51             : 
      52           0 : #define FD_NETMUX_SIG_MIN_HDR_SZ    ( 42UL) /* The default header size, which means no vlan tags and no IP options. */
      53             : #define FD_NETMUX_SIG_IGNORE_HDR_SZ (102UL) /* Outside the allowable range, but still fits in 4 bits when compressed */
      54             : 
      55             : /* These limits are defined here to prevent circular dependencies, and
      56             :    statically asserted they are calculated correctly in the relevant
      57             :    places.  We get one bound using transactions that consume the minimum
      58             :    number of CUs and another bound using the minimum size transactions.
      59             :    The overall bound is the lower of the two. */
      60             : #define FD_MAX_TXN_PER_SLOT_CU    98039UL
      61             : #define FD_MAX_TXN_PER_SLOT_SHRED 272635UL
      62          18 : #define FD_MAX_TXN_PER_SLOT       98039UL
      63             : FD_STATIC_ASSERT( FD_MAX_TXN_PER_SLOT<=FD_MAX_TXN_PER_SLOT_CU&&FD_MAX_TXN_PER_SLOT<=FD_MAX_TXN_PER_SLOT_SHRED, max_txn_per_slot );
      64             : FD_STATIC_ASSERT( FD_MAX_TXN_PER_SLOT>=FD_MAX_TXN_PER_SLOT_CU||FD_MAX_TXN_PER_SLOT>=FD_MAX_TXN_PER_SLOT_SHRED, max_txn_per_slot );
      65             : 
      66             : 
      67             : FD_PROTOTYPES_BEGIN
      68             : 
      69             :  /* hdr_sz is the total size of network headers, including eth, ip, udp.
      70             :     Ignored for outgoing packets.
      71             :     For incoming packets, hash_{ip_addr,port} are the source IP and port,
      72             :     for outgoing packets, they are the destination IP and port. */
      73             : FD_FN_CONST static inline ulong
      74             : fd_disco_netmux_sig( uint   hash_ip_addr,
      75             :                      ushort hash_port,
      76             :                      uint   ip_addr,
      77             :                      ulong  proto,
      78          36 :                      ulong  hdr_sz ) {
      79             :   /* The size of an Ethernet header is 14+4k bytes, where 0<=k<=3 (?) is
      80             :      the number of vlan tags.  The size of an IP header is 4j, where
      81             :      5<=j<=15 is the size given in the header.  The size of a UDP header
      82             :      is 8B.  Thus, the total sum of these is 42+4i, where i=k+j-5,
      83             :      0<=i<=13.  Since bits are at a premium here, we compress the header
      84             :      size by just storing i. */
      85          36 :   ulong hdr_sz_i = ((hdr_sz - 42UL)>>2)&0xFUL;
      86          36 :   ulong hash     = 0xfffffUL & fd_ulong_hash( (ulong)hash_ip_addr | ((ulong)hash_port<<32) );
      87          36 :   return (hash<<44) | ((hdr_sz_i&0xFUL)<<40UL) | ((proto&0xFFUL)<<32UL) | ((ulong)ip_addr);
      88          36 : }
      89             : 
      90          18 : FD_FN_CONST static inline ulong fd_disco_netmux_sig_hash ( ulong sig ) { return (sig>>44UL); }
      91          18 : FD_FN_CONST static inline ulong fd_disco_netmux_sig_proto( ulong sig ) { return (sig>>32UL) & 0xFFUL; }
      92          18 : FD_FN_CONST static inline uint  fd_disco_netmux_sig_ip   ( ulong sig ) { return (uint)(sig & 0xFFFFFFFFUL); }
      93             : 
      94             : /* fd_disco_netmux_sig_hdr_sz extracts the total size of the Ethernet,
      95             :    IP, and UDP headers from the netmux signature field.  The UDP payload
      96             :    of the packet stored in the corresponding frag begins at the returned
      97             :    offset. */
      98           0 : FD_FN_CONST static inline ulong  fd_disco_netmux_sig_hdr_sz( ulong sig ) { return 4UL*((sig>>40UL) & 0xFUL) + 42UL; }
      99             : 
     100             : FD_FN_CONST static inline ulong
     101             : fd_disco_poh_sig( ulong slot,
     102             :                   ulong pkt_type,
     103           0 :                   ulong execle_tile ) {
     104             :    /* The high 6 bits of the low byte of the signature field is the
     105             :       execle idx.  Execles will filter to only handle frags with their
     106             :       own idx.  The higher 7 bytes are the slot number.  Technically,
     107             :       the slot number is a ulong, but it won't hit 256^7 for about 10^9
     108             :       years at the current rate.  The lowest bits of the low byte is the
     109             :       packet type. */
     110           0 :   return (slot << 8) | ((execle_tile & 0x3FUL) << 2) | (pkt_type & 0x3UL);
     111           0 : }
     112             : 
     113           0 : FD_FN_CONST static inline ulong fd_disco_poh_sig_pkt_type( ulong sig ) { return (sig & 0x3UL); }
     114           0 : FD_FN_CONST static inline ulong fd_disco_poh_sig_slot( ulong sig ) { return (sig >> 8); }
     115           0 : FD_FN_CONST static inline ulong fd_disco_poh_sig_execle_tile( ulong sig ) { return (sig >> 2) & 0x3FUL; }
     116             : 
     117             : FD_FN_CONST static inline ulong
     118             : fd_disco_execle_sig( ulong slot,
     119           0 :                      ulong pack_idx ) {
     120           0 :   return (slot << 32) | pack_idx;
     121           0 : }
     122             : 
     123           0 : FD_FN_CONST static inline ulong fd_disco_execle_sig_slot( ulong sig ) { return (sig >> 32); }
     124           0 : FD_FN_CONST static inline ulong fd_disco_execle_sig_pack_idx( ulong sig ) { return sig & 0xFFFFFFFFUL; }
     125             : 
     126             : /* fd_disco_shred_out_shred_sig constructs a sig for the shred_out link.
     127             :    The encoded fields vary depending on the type of the sig.  The
     128             :    diagram below describes the encoding.
     129             : 
     130             :    for sz==FD_SHRED_OUT_MTU
     131             : 
     132             :    msg_type (1)   | slot (32) | fec_set_idx (15) | is_turbine (1) | shred_idx (15) |
     133             :    MSG_TYPE_SHRED | [31, 62]  | [16, 30]         | [15]           | [0, 14]        |
     134             : 
     135             :    in the above case, the last 4 bytes of the dcache entry are the nonce.
     136             : 
     137             :    msg_type (1)   | slot (32) | fec_set_idx (15)| is_slot_complete (1) | data_cnt (15) |
     138             :    MSG_TYPE_FEC   | [31, 62]  | [16, 30]        | [15]                 | [0, 14]       | => should soon always be 32
     139             : 
     140             :    in the above case, the last 4 bytes of the dcache entry are the is_leader flag..
     141             : 
     142             :    for sz==0:
     143             :    these are FEC_CLEAR messages and look like MSG_TYPE_SHRED but with some unpopulated fields:
     144             :    ...   | slot (32) | fec_set_idx (15) | ...  | max_shred_idx (15) |
     145             :    ...   | [31, 62]  | [16, 30]         | ...  | [0, 14]            |
     146             : 
     147             :    is_turbine describes whether this shred source was turbine or repair.
     148             :    If the source is repair, then the nonce value in the dcache will
     149             :    have meaning.
     150             : 
     151             :    Note: if the slot number is >= UINT_MAX, the sender will store the
     152             :    value UINT_MAX in this field. If the receiver sees a value of
     153             :    UINT_MAX in the field, it must read the actual slot number from the
     154             :    dcache entry.
     155             : 
     156             :    The following 15 bits describe the fec_set_idx.  This is a
     157             :    15-bit value because shreds are bounded to 2^15 per slot, so in the
     158             :    worst case there is an independent FEC set for every shred, which
     159             :    results in at most 2^15 FEC sets per slot. */
     160             : 
     161           0 : #define FD_SHRED_OUT_MSG_TYPE_SHRED (0)
     162           0 : #define FD_SHRED_OUT_MSG_TYPE_FEC   (1)
     163             : 
     164           0 : FD_FN_CONST static inline int fd_disco_shred_out_msg_type( ulong sig ) { return fd_ulong_extract_bit( sig, 63 ); }
     165             : 
     166             : FD_FN_CONST static inline ulong
     167             : fd_disco_shred_out_shred_sig( int   is_turbine,
     168             :                               ulong slot,
     169             :                               uint  fec_set_idx,
     170           0 :                               uint  shred_idx ) {
     171           0 :    ulong slot_ul        = fd_ulong_min( slot, (ulong)UINT_MAX );
     172           0 :    ulong shred_idx_ul   = fd_ulong_min( (ulong)shred_idx,   (ulong)FD_SHRED_BLK_MAX );
     173           0 :    ulong fec_set_idx_ul = fd_ulong_min( (ulong)fec_set_idx, (ulong)FD_SHRED_BLK_MAX );
     174           0 :    ulong is_turbine_ul  = !!is_turbine;
     175           0 :    ulong msg_type_ul    = FD_SHRED_OUT_MSG_TYPE_SHRED;
     176             : 
     177           0 :   return msg_type_ul << 63 | slot_ul << 31 | fec_set_idx_ul << 16 | is_turbine_ul << 15 | shred_idx_ul;
     178           0 : }
     179             : 
     180             : /* fd_disco_shred_out_shred_sig_{...} are accessors for the fields encoded
     181             :    in the sig described above. */
     182             : 
     183           0 : FD_FN_CONST static inline ulong fd_disco_shred_out_shred_sig_slot       ( ulong sig ) { return       fd_ulong_extract    ( sig, 31, 62 ); }
     184           0 : FD_FN_CONST static inline uint  fd_disco_shred_out_shred_sig_fec_set_idx( ulong sig ) { return (uint)fd_ulong_extract    ( sig, 16, 30 ); }
     185           0 : FD_FN_CONST static inline int   fd_disco_shred_out_shred_sig_is_turbine ( ulong sig ) { return       fd_ulong_extract_bit( sig, 15     ); }
     186           0 : FD_FN_CONST static inline uint  fd_disco_shred_out_shred_sig_shred_idx  ( ulong sig ) { return (uint)fd_ulong_extract    ( sig, 0, 14  ); }
     187             : 
     188             : FD_FN_CONST static inline ulong
     189           0 : fd_disco_shred_out_fec_sig( ulong slot, uint fec_set_idx, uint data_cnt, int is_slot_complete ) {
     190           0 :   ulong slot_ul          = fd_ulong_min( slot, (ulong)UINT_MAX );
     191           0 :   ulong fec_set_idx_ul   = fd_ulong_min( (ulong)fec_set_idx, (ulong)FD_SHRED_BLK_MAX );
     192           0 :   ulong data_cnt_ul      = fd_ulong_min( (ulong)data_cnt, (ulong)FD_SHRED_BLK_MAX );
     193           0 :   ulong is_slot_complete_ul = !!is_slot_complete;
     194           0 :   ulong msg_type_ul         = FD_SHRED_OUT_MSG_TYPE_FEC;
     195           0 :   return msg_type_ul << 63 | slot_ul << 31 | fec_set_idx_ul << 16 | is_slot_complete_ul << 15 | data_cnt_ul;
     196           0 : }
     197             : 
     198           0 : FD_FN_CONST static inline ulong fd_disco_shred_out_fec_sig_slot            ( ulong sig ) { return         fd_ulong_extract    ( sig, 31, 62 ); }
     199           0 : FD_FN_CONST static inline uint  fd_disco_shred_out_fec_sig_fec_set_idx     ( ulong sig ) { return (uint)  fd_ulong_extract    ( sig, 16, 30 ); }
     200           0 : FD_FN_CONST static inline int   fd_disco_shred_out_fec_sig_is_slot_complete( ulong sig ) { return         fd_ulong_extract_bit( sig, 15     ); }
     201           0 : FD_FN_CONST static inline uint  fd_disco_shred_out_fec_sig_data_cnt        ( ulong sig ) { return (uint)  fd_ulong_extract    ( sig, 0, 14  ); }
     202             : 
     203             : /* Exclusively used for force completion messages */
     204             : 
     205             : FD_FN_CONST static inline ulong
     206           0 : fd_disco_repair_shred_sig( uint last_shred_idx ){
     207           0 :    return (ulong) last_shred_idx;
     208           0 : }
     209             : 
     210           0 : FD_FN_CONST static inline uint fd_disco_repair_shred_sig_last_shred_idx( ulong sig ) { return (uint) sig; }
     211             : 
     212             : 
     213             : FD_FN_CONST static inline ulong
     214           0 : fd_disco_repair_replay_sig( ulong slot, ushort parent_off, uint data_cnt, int slot_complete ) {
     215           0 :   /*
     216           0 :    | slot (32) | parent_off (16) | data_cnt (15) | slot_complete(1)
     217           0 :    | [32, 63]  | [16, 31]        | [1, 15]       | [0]
     218           0 :   */
     219           0 :   ulong slot_ul          = fd_ulong_min( slot, (ulong)UINT_MAX );
     220           0 :   ulong parent_off_ul    = (ulong)parent_off;
     221           0 :   ulong data_cnt_ul      = fd_ulong_min( (ulong)data_cnt, (ulong)FD_SHRED_BLK_MAX );
     222           0 :   ulong slot_complete_ul = !!slot_complete;
     223           0 :   return slot_ul << 32 | parent_off_ul << 16 | data_cnt_ul << 1 | slot_complete_ul;
     224           0 : }
     225             : 
     226             : FD_FN_PURE static inline ulong
     227           0 : fd_disco_compact_chunk0( void * wksp ) {
     228           0 :   return (((struct fd_wksp_private *)wksp)->gaddr_lo) >> FD_CHUNK_LG_SZ;
     229           0 : }
     230             : 
     231             : FD_FN_PURE static inline ulong
     232           0 : fd_disco_compact_wmark( void * wksp, ulong mtu ) {
     233           0 :   ulong chunk_mtu  = ((mtu + 2UL*FD_CHUNK_SZ-1UL) >> (1+FD_CHUNK_LG_SZ)) << 1;
     234           0 :   ulong wksp_hi = ((struct fd_wksp_private *)wksp)->gaddr_hi;
     235           0 :   return (wksp_hi >> FD_CHUNK_LG_SZ) - chunk_mtu;
     236           0 : }
     237             : 
     238             : FD_PROTOTYPES_END
     239             : 
     240             : #endif /* HEADER_fd_src_disco_fd_disco_base_h */

Generated by: LCOV version 1.14