LCOV - code coverage report
Current view: top level - ballet/shred - fd_shred.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 108 116 93.1 %
Date: 2026-09-17 04:28:31 Functions: 78 5400 1.4 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_shred_fd_shred_h
       2             : #define HEADER_fd_src_ballet_shred_fd_shred_h
       3             : 
       4             : #include "../bmtree/fd_bmtree.h"
       5             : 
       6             : /* Shreds form the on-wire representation of Solana block data
       7             :    optimized for transmission over unreliable links/WAN.
       8             : 
       9             :    ### Layout
      10             : 
      11             :    Each shred is 1228 bytes long.
      12             : 
      13             :       +------------------------+
      14             :       | Common Shred Header    | 83 bytes
      15             :       +------------------------+
      16             :       | Data Header            | 5 bytes
      17             :       | or Coding Header       | or 6 bytes
      18             :       +------------------------+
      19             :       |                        | variable
      20             :       | Payload                | length
      21             :       |                        |
      22             :       +------------------------+
      23             : 
      24             :        for Merkle shreds, followed by:
      25             : 
      26             :       +------------------------+
      27             :       | (Chained merkle root)  | 32 bytes
      28             :       +------------------------+
      29             :       +------------------------+
      30             :       | Merkle node #0 (root)  | 20 bytes
      31             :       +------------------------+
      32             :       | Merkle node #1         | 20 bytes
      33             :       ..........................
      34             : 
      35             :        for resigned shreds, followed by:
      36             : 
      37             :       +------------------------+
      38             :       | signature              | 64 bytes
      39             :       ..........................
      40             : 
      41             :    ### Shredding
      42             : 
      43             :    For a given input data blob (usually an entry batch),
      44             :    data shreds are derived by simply splitting up the blob into subslices.
      45             : 
      46             :    Each shred is sized such that it fits into a single UDP packet,
      47             :    i.e. currently bound by the generally accepted IPv6 MTU of 1280 bytes.
      48             : 
      49             :    ### Forward Error Correction
      50             : 
      51             :    Coding shreds implement Reed-Solomon error correction to provide tolerance against packet loss.
      52             : 
      53             :    Each data shred is first assigned an FEC set.
      54             :    For the vector of data shreds in each set, a corresponding vector of coding shreds contains parity data.
      55             : 
      56             :    FEC sets and entry batches do not necessarily align.
      57             : 
      58             :    ### Merkle Inclusion Proofs
      59             : 
      60             :    Data and coding shreds come in two variants respectively: legacy and merkle.
      61             :    Merkle shreds extend legacy shreds by adding FEC set inclusion proofs.
      62             : 
      63             :    It allows the block producer to commit to the vector of shreds that make up an FEC set.
      64             :    The inclusion proof is used to verify whether a shred is part of the FEC set commitment.
      65             : 
      66             :    The length of the inclusion proof is indicated by the variant field.
      67             : 
      68             :    ### resigned shreds
      69             : 
      70             :    Resigned shreds allow for an additional signature to be added on to lock down
      71             :    the retransmitter for turbine propagation
      72             : 
      73             :    ### Authentication
      74             : 
      75             :    Shreds are signed by the block producer.
      76             :    Consequently, only the block producer is able to create valid shreds for any given block. */
      77             : 
      78             : #include "../fd_ballet.h"
      79             : 
      80             : /* FD_SHRED_MAX_SZ: The max byte size of a shred.
      81             :    This limit derives from the IPv6 MTU of 1280 bytes, minus 48 bytes
      82             :    for the UDP/IPv6 headers and another 4 bytes for good measure.  Most
      83             :    shreds are this size, but Merkle data shreds may be smaller. */
      84    26841782 : #define FD_SHRED_MAX_SZ (1228UL)
      85             : /* FD_SHRED_MIN_SZ: The minimum byte size of a shred.
      86             :    A code shred of the max size covers a data shred of the minimum size
      87             :    with no padding. */
      88    26839046 : #define FD_SHRED_MIN_SZ (1203UL)
      89             : /* FD_SHRED_DATA_HEADER_SZ: size of all headers for data type shreds. */
      90    12218340 : #define FD_SHRED_DATA_HEADER_SZ (0x58UL)
      91             : /* FD_SHRED_CODE_HEADER_SZ: size of all headers for coding type shreds. */
      92     6219753 : #define FD_SHRED_CODE_HEADER_SZ (0x59UL)
      93             : /* This is a conservative bound.
      94             :    It's possible for a modified validator to create a data shred with
      95             :    this much payload.
      96             :    A validator that follows the default shredding policy should have
      97             :    payloads of no more than 1015 bytes.
      98             :    In general, shreds that are chained or resigned should have smaller
      99             :    payloads and a tigher bound. */
     100           3 : #define FD_SHRED_DATA_PAYLOAD_MAX (FD_SHRED_MIN_SZ-FD_SHRED_DATA_HEADER_SZ)
     101             : 
     102             : /* FD_SHRED_TYPE_* identifies the type of a shred.
     103             :    It is located at the four high bits of byte 0x40 (64) of the shred header
     104             :    and can be extracted using the fd_shred_type() function. */
     105             : /* FD_SHRED_TYPE_LEGACY_DATA: A shred carrying raw binary data. */
     106    14793752 : #define FD_SHRED_TYPE_LEGACY_DATA ((uchar)0xA0)
     107             : /* FD_SHRED_TYPE_LEGACY_CODE: A shred carrying Reed-Solomon ECC. */
     108           0 : #define FD_SHRED_TYPE_LEGACY_CODE ((uchar)0x50)
     109             : /* FD_SHRED_TYPE_MERKLE_DATA: A shred carrying raw binary data and a merkle inclusion proof. */
     110      197970 : #define FD_SHRED_TYPE_MERKLE_DATA ((uchar)0x80)
     111             : /* FD_SHRED_TYPE_MERKLE_CODE: A shred carrying Reed-Solomon ECC and a merkle inclusion proof. */
     112    27381197 : #define FD_SHRED_TYPE_MERKLE_CODE ((uchar)0x40)
     113             : /* FD_SHRED_TYPE_MERKLE_DATA_CHAINED: A shred carrying raw binary data and a chained merkle inclusion proof. */
     114      280680 : #define FD_SHRED_TYPE_MERKLE_DATA_CHAINED ((uchar)0x90)
     115             : /* FD_SHRED_TYPE_MERKLE_CODE_CHAINED: A shred carrying Reed-Solomon ECC and a chained merkle inclusion proof. */
     116      279816 : #define FD_SHRED_TYPE_MERKLE_CODE_CHAINED ((uchar)0x60)
     117             : 
     118             : /* FD_SHRED_TYPE_MERKLE_DATA_CHAINED_RESIGNED: A shred carrying raw binary data and a chained merkle inclusion proof and resigned. */
     119    24381129 : #define FD_SHRED_TYPE_MERKLE_DATA_CHAINED_RESIGNED ((uchar)0xB0)
     120             : /* FD_SHRED_TYPE_MERKLE_CODE_CHAINED_RESIGNED: A shred carrying Reed-Solomon ECC and a chained merkle inclusion proof and resigned. */
     121    24379497 : #define FD_SHRED_TYPE_MERKLE_CODE_CHAINED_RESIGNED ((uchar)0x70)
     122             : 
     123             : /* FD_SHRED_TYPEMASK_DATA: bitwise AND with type matches data shred */
     124             : #define FD_SHRED_TYPEMASK_DATA FD_SHRED_TYPE_MERKLE_DATA
     125             : /* FD_SHRED_TYPEMASK_CODE: bitwise AND with type matches code shred */
     126    26810678 : #define FD_SHRED_TYPEMASK_CODE FD_SHRED_TYPE_MERKLE_CODE
     127             : 
     128             : /* FD_SHRED_MERKLE_ROOT_SZ: the size of a merkle tree root in bytes. */
     129    24302538 : #define FD_SHRED_MERKLE_ROOT_SZ (32UL)
     130             : /* FD_SHRED_MERKLE_NODE_SZ: the size of a merkle inclusion proof node in bytes. */
     131    24322212 : #define FD_SHRED_MERKLE_NODE_SZ (20UL)
     132             : /* FD_SHRED_MERKLE_LAYER_CNT: the count of inclusion proof layers in the binary merkle tree. */
     133        6153 : #define FD_SHRED_MERKLE_LAYER_CNT (7UL)
     134             : /* FD_SHRED_SIGNATURE_SZ: the size of a signature in a shred. */
     135    27221877 : #define FD_SHRED_SIGNATURE_SZ (64UL)
     136             : /* A merkle inclusion proof node. */
     137             : typedef uchar fd_shred_merkle_t[FD_SHRED_MERKLE_NODE_SZ];
     138             : 
     139             : FD_STATIC_ASSERT( sizeof(fd_bmtree_node_t) == FD_SHRED_MERKLE_ROOT_SZ, update FD_SHRED_MERKLE_ROOT_SZ );
     140             : 
     141             : /* Constants relating to the data shred "flags" field. */
     142             : 
     143             : /* Mask of the "reference tick"    field in shred.data.flags */
     144           0 : #define FD_SHRED_DATA_REF_TICK_MASK      ((uchar)0x3f)
     145             : /* Mask of the "slot complete"       bit in shred.data.flags
     146             :    Indicates the last shred in a slot. */
     147        5631 : #define FD_SHRED_DATA_FLAG_SLOT_COMPLETE ((uchar)0x80)
     148             : /* Mask of the "data batch complete" bit in shred.data.flags */
     149        7260 : #define FD_SHRED_DATA_FLAG_DATA_COMPLETE ((uchar)0x40)
     150             : 
     151             : /* Maximum number of data shreds in a slot, also maximum number of parity shreds in a slot */
     152       13065 : #define FD_SHRED_BLK_MAX (1 << 15UL) /* 32,768 shreds */
     153             : 
     154             : /* Many static bounds are specified around the assumption that this is a
     155             :    protocol limit on the max number of shreds in a slot. If this limit
     156             :    changes, all the relevant usages in other areas of the Firedancer
     157             :    codebase should be updated before modifying this assertion. */
     158             : 
     159             : FD_STATIC_ASSERT( FD_SHRED_BLK_MAX == 32768, check all usages before changing this limit! );
     160             : 
     161             : /* Largest [development.bench.max_shreds_per_block] a benchmark cluster
     162             :    may raise the per-block shred limit to: the chainer's fec_set_idx is
     163             :    28 bits.  Sizes what must hold any configurable limit (repair proof
     164             :    depth). */
     165             : #define FD_SHRED_BLK_MAX_RAISED (1UL<<28)
     166             : 
     167             : /* 36,536,320 bytes per slot */
     168             : #define FD_SHRED_DATA_PAYLOAD_MAX_PER_SLOT (FD_SHRED_DATA_PAYLOAD_MAX * FD_SHRED_BLK_MAX)
     169             : 
     170             : /* Firedancer-specific internal error codes.
     171             : 
     172             :    These are not part of the Solana protocol. */
     173             : 
     174          21 : #define FD_SHRED_EBATCH  0x4000 /* End of batch reached (success)
     175             :                                    no more shreds and found FD_SHRED_DATA_FLAG_DATA_COMPLETE */
     176           9 : #define FD_SHRED_ESLOT   0x8000 /* End of slot reached (success)
     177             :                                    no more shreds and found FD_SHRED_DATA_FLAG_SLOT_COMPLETE */
     178           0 : #define FD_SHRED_ENOMEM      12 /* Error: Target buffer too small */
     179           0 : #define FD_SHRED_EINVAL      22 /* Error: Invalid shred data */
     180          27 : #define FD_SHRED_EPIPE       32 /* Error: Expected data in source buffer, got EOF */
     181             : 
     182             : /* Primary shred data structure.
     183             :    Relies heavily on packed fields and unaligned memory accesses. */
     184             : struct __attribute__((packed)) fd_shred {
     185             :   /* Ed25519 signature over the shred
     186             : 
     187             :      For legacy type shreds, signs over content of the shred structure past this signature field.
     188             :      For merkle type shreds, signs over the first node of the inclusion proof (merkle root). */
     189             :   /* 0x00 */ fd_ed25519_sig_t signature;
     190             : 
     191             :   /* Shred variant specifier
     192             :      Consists of two four bit fields. (Deliberately not using bit fields here)
     193             : 
     194             :      The high four bits indicate the shred type:
     195             :      - 0101: legacy code
     196             :      - 1010: legacy data
     197             :      - 0100: merkle code
     198             :      - 0110: merkle code (chained)
     199             :      - 0111: merkle code (chained resigned)
     200             :      - 1000: merkle data
     201             :      - 1001: merkle data (chained)
     202             :      - 1011: merkle data (chained resigned)
     203             : 
     204             :      For legacy type shreds, the low four bits are set to static patterns.
     205             :      For merkle type shreds, the low four bits are set to the number of non-root nodes in the inclusion proof.
     206             :      For merkle code type shreds, the 3rd highest bit represents if the merkle tree is chained.
     207             :      For merkle data type shreds, the 4th highest bit represents if the merkle tree is chained.
     208             :      For merkle code type shreds, the 4th highest bit represents if the shred is resigned.
     209             :      For merkle data type shreds, the 3th highest bit represents if the shred is resigned.
     210             : */
     211             :   /* 0x40 */ uchar  variant;
     212             : 
     213             :   /* Slot number that this shred is part of */
     214             :   /* 0x41 */ ulong  slot;
     215             : 
     216             :   /* Index of this shred within the slot */
     217             :   /* 0x49 */ uint   idx;
     218             : 
     219             :   /* Hash of the genesis version and historical hard forks of the current chain */
     220             :   /* 0x4d */ ushort version;
     221             : 
     222             :   /* Index into the vector of FEC sets for this slot. For data shreds, fec_set_idx<=idx. */
     223             :   /* 0x4f */ uint   fec_set_idx;
     224             : 
     225             :   union {
     226             :     /* Common data shred header */
     227             :     struct __attribute__((packed)) {
     228             :       /* Slot number difference between this block and the parent block.
     229             :          parent_off <= slot.
     230             :          Always greater than zero, except for slot 0, in which case the
     231             :          previous invariant forces this to be 0. */
     232             :       /* 0x53 */ ushort parent_off;
     233             : 
     234             :       /* Bit field (MSB first)
     235             :          See FD_SHRED_DATA_FLAG_*
     236             : 
     237             :           [XX.. ....] Block complete?       0b00=no 0b01=no 0b11=yes (implies Entry batch complete)
     238             :           [.X.. ....] Entry batch complete?  0b0=no  0b1=yes
     239             :           [..XX XXXX] Reference tick number */
     240             :       /* 0x55 */ uchar  flags;
     241             : 
     242             :       /* Shred size: size of data shred headers (88 bytes) + payload length */
     243             :       /* 0x56 */ ushort size;
     244             :     } data;
     245             : 
     246             :     /* Common coding shred header */
     247             :     struct __attribute__((packed)) {
     248             :       /* Total number of data shreds in FEC set. Must be positive <= FD_REEDSOL_DATA_SHREDS_MAX. */
     249             :       /* 0x53 */ ushort data_cnt;
     250             : 
     251             :       /* Total number of coding shreds in FEC set. Must be positive <= FD_REEDSOL_CODE_SHREDS_MAX. */
     252             :       /* 0x55 */ ushort code_cnt;
     253             : 
     254             :       /* Index within the vector of coding shreds in FEC set. In [0,
     255             :          code_cnt).  Also, shred.code.idx <= shred.idx. */
     256             :       /* 0x57 */ ushort idx;
     257             :     } code;
     258             :   };
     259             : };
     260             : typedef struct fd_shred fd_shred_t;
     261             : 
     262             : FD_PROTOTYPES_BEGIN
     263             : 
     264             : /* fd_shred_parse: Parses and validates an untrusted shred stored in
     265             :    bytes buf[i] for i in [0, sz).  sz must be at least FD_SHRED_MIN_SZ bytes.
     266             :    Allows trailing data.  max_shred_idx is the exclusive upper bound for
     267             :    data/parity shred indices within a slot, similar to max_shred_idx in
     268             :    fd_fec_resolver.
     269             : 
     270             :    The returned pointer either equals the input pointer or is NULL if
     271             :    the given shred is malformed or violates any invariants described
     272             :    above. */
     273             : FD_FN_PURE fd_shred_t const *
     274             : fd_shred_parse( uchar const * buf,
     275             :                 ulong         sz,
     276             :                 ulong         max_shred_idx );
     277             : 
     278             : /* fd_shred_type: Returns the value of the shred's type field. (FD_SHRED_TYPE_*) */
     279             : FD_FN_CONST static inline uchar
     280    64820578 : fd_shred_type( uchar variant ) {
     281    64820578 :   return variant & 0xf0;
     282    64820578 : }
     283             : 
     284             : /* fd_shred_variant: Returns the encoded variant field
     285             :    given the shred type and merkle proof length. */
     286             : FD_FN_CONST static inline uchar
     287             : fd_shred_variant( uchar type,
     288    12381819 :                   uchar merkle_cnt ) {
     289    12381819 :   if( FD_LIKELY( type==FD_SHRED_TYPE_LEGACY_DATA ) )
     290        1128 :     merkle_cnt = 0x05;
     291    12381819 :   if( FD_LIKELY( type==FD_SHRED_TYPE_LEGACY_CODE ) )
     292           3 :     merkle_cnt = 0x0a;
     293    12381819 :   return (uchar)(type | merkle_cnt);
     294    12381819 : }
     295             : 
     296             : FD_FN_PURE static inline ulong
     297    14779889 : fd_shred_sz( fd_shred_t const * shred ) {
     298    14779889 :   uchar type = fd_shred_type( shred->variant );
     299    14779889 :   return fd_ulong_if(
     300    14779889 :     type & FD_SHRED_TYPEMASK_CODE,
     301    14779889 :     FD_SHRED_MAX_SZ,
     302    14779889 :     fd_ulong_if( type==FD_SHRED_TYPE_LEGACY_DATA, shred->data.size, FD_SHRED_MIN_SZ)
     303    14779889 :   ); /* Legacy data */
     304    14779889 : }
     305             : 
     306             : /* fd_shred_header_sz: Returns the header size of a shred.
     307             :    Returns zero if the shred has an invalid variant.
     308             : 
     309             :    Accesses offsets up to FD_SHRED_HEADER_MIN_SZ. */
     310             : FD_FN_CONST static inline ulong
     311       26373 : fd_shred_header_sz( uchar variant ) {
     312       26373 :   uchar type = fd_shred_type( variant );
     313       26373 :   if( FD_LIKELY( type & FD_SHRED_TYPEMASK_DATA ) )
     314       12885 :     return FD_SHRED_DATA_HEADER_SZ;
     315       13488 :   if( FD_LIKELY( type & FD_SHRED_TYPEMASK_CODE ) )
     316       13488 :     return FD_SHRED_CODE_HEADER_SZ;
     317           0 :   return 0;
     318       13488 : }
     319             : 
     320             : /* fd_shred_merkle_cnt: Returns number of nodes in the merkle inclusion
     321             :    proof.  Note that this excludes the root.  Returns zero if the given
     322             :    shred is not a merkle variant. */
     323             : FD_FN_CONST static inline uint
     324    24108183 : fd_shred_merkle_cnt( uchar variant ) {
     325    24108183 :   uchar type = fd_shred_type( variant );
     326    24108183 :   if( FD_UNLIKELY( ( type == FD_SHRED_TYPE_LEGACY_DATA ) | ( type == FD_SHRED_TYPE_LEGACY_CODE ) ) )
     327          69 :     return 0;
     328    24108114 :   return (variant&0xfU);
     329    24108183 : }
     330             : 
     331             : /* fd_shred_merkle_sz: Returns the size in bytes of the merkle inclusion proof.
     332             :    Returns zero if the given shred is not a merkle variant.  */
     333             : FD_FN_CONST static inline ulong
     334    24073992 : fd_shred_merkle_sz( uchar variant ) {
     335    24073992 :   return fd_shred_merkle_cnt( variant ) * FD_SHRED_MERKLE_NODE_SZ;
     336    24073992 : }
     337             : 
     338             : 
     339             : /* fd_shred_is_chained: Returns true if the shred is a chained merkle data or code shred. */
     340             : FD_FN_CONST static inline uchar
     341       88773 : fd_shred_is_chained( ulong type ) {
     342       88773 :   return (uchar)(
     343       88773 :          ( type == FD_SHRED_TYPE_MERKLE_DATA_CHAINED )
     344       88773 :        | ( type == FD_SHRED_TYPE_MERKLE_CODE_CHAINED )
     345       88773 :        | ( type == FD_SHRED_TYPE_MERKLE_DATA_CHAINED_RESIGNED )
     346       88773 :        | ( type == FD_SHRED_TYPE_MERKLE_CODE_CHAINED_RESIGNED ) );
     347       88773 : }
     348             : 
     349             : /* fd_shred_is_resigned: Returns true if the shred is resigned by the retransmitter */
     350             : FD_FN_CONST static inline uchar
     351    24101370 : fd_shred_is_resigned( ulong type ) {
     352    24101370 :   return ( type == FD_SHRED_TYPE_MERKLE_DATA_CHAINED_RESIGNED )
     353    24101370 :        | ( type == FD_SHRED_TYPE_MERKLE_CODE_CHAINED_RESIGNED );
     354    24101370 : }
     355             : 
     356             : /* fd_shred_is_{data,code} return 1 if the provided shred type is one of
     357             :    the data (or code, respectively) types, and 0 if not.  The value
     358             :    provided for type must be a valid shred type (one of the
     359             :    FD_SHRED_TYPE_* values).  For the purposes of these functions,
     360             :    properties beyond data/code are ignored; e.g. a chained resigned
     361             :    Merkle data shred is considered a data shred. */
     362     1791477 : FD_FN_CONST static inline uchar fd_shred_is_data( ulong type ) { return (type & 0xC0UL)==0x80UL; }
     363        5598 : FD_FN_CONST static inline uchar fd_shred_is_code( ulong type ) { return (type & 0xC0UL)==0x40UL; }
     364             : 
     365             : /* fd_shred_swap_type: changes data into code or vice versa without
     366             :    affecting legacy, merkle, chained, or resigned status.  For example,
     367             :    fd_shred_swap_type( chained resigned data ) == chained resigned code.
     368             :    fd_shred_swap_type( merkle code ) == merkle data. */
     369             : FD_FN_CONST static inline uchar
     370        7560 : fd_shred_swap_type( ulong type ) {
     371             :   /* Swap bits 4 and 5. Swap bits 6 and 7. */
     372        7560 :   return (uchar)(((type & 0x50UL)<<1) | ((type&0xA0UL)>>1));
     373        7560 : }
     374             : 
     375             : /* fd_shred_payload_sz: Returns the payload size of a shred.
     376             :    Undefined behavior if the shred has not passed `fd_shred_parse`. */
     377             : FD_FN_PURE static inline ulong
     378         465 : fd_shred_payload_sz( fd_shred_t const * shred ) {
     379         465 :   ulong type = fd_shred_type( shred->variant );
     380         465 :   if( FD_LIKELY( type & FD_SHRED_TYPEMASK_DATA ) ) {
     381         318 :     return shred->data.size - FD_SHRED_DATA_HEADER_SZ;
     382         318 :   } else {
     383         147 :     return fd_shred_sz( shred ) - FD_SHRED_CODE_HEADER_SZ
     384         147 :       - fd_shred_merkle_sz( shred->variant )
     385         147 :       - fd_ulong_if( fd_shred_is_chained( type ), FD_SHRED_MERKLE_ROOT_SZ, 0 )
     386         147 :       - fd_ulong_if( fd_shred_is_resigned( type ), FD_SHRED_SIGNATURE_SZ, 0 );
     387         147 :   }
     388         465 : }
     389             : 
     390             : /* fd_shred_merkle_off: Returns the byte offset of the merkle inclusion proof of a shred.
     391             : 
     392             :    The provided shred must have passed validation in fd_shred_parse(). */
     393             : FD_FN_PURE static inline ulong
     394    12016683 : fd_shred_merkle_off( fd_shred_t const * shred ) {
     395    12016683 :   ulong type = fd_shred_type( shred->variant );
     396    12016683 :   return fd_shred_sz( shred )
     397    12016683 :     - fd_shred_merkle_sz( shred->variant )
     398    12016683 :     - fd_ulong_if( fd_shred_is_resigned( type ), FD_SHRED_SIGNATURE_SZ, 0 );
     399    12016683 : }
     400             : 
     401             : /* fd_shred_merkle_nodes: Returns a pointer to the shred's merkle proof data.
     402             : 
     403             :    The provided shred must have passed validation in fd_shred_parse(). */
     404             : FD_FN_PURE static inline fd_shred_merkle_t const *
     405       13707 : fd_shred_merkle_nodes( fd_shred_t const * shred ) {
     406       13707 :   uchar const * ptr = (uchar const *)shred;
     407       13707 :   ptr += fd_shred_merkle_off( shred );
     408       13707 :   return (fd_shred_merkle_t const *)ptr;
     409       13707 : }
     410             : 
     411             : /* fd_shred_merkle_root: Assuming that `shred` is a Merkle variant,
     412             :    reconstructs the merkle root from a shred and populates it in
     413             :    root_out.  Returns 1 on success, 0 on failure.  The output value must
     414             :    be ignored if a failure is returned.  U.B. if the shred is not a
     415             :    merkle variant. */
     416             : int
     417             : fd_shred_merkle_root( fd_shred_t const * shred, void * bmtree_mem, fd_bmtree_node_t * root_out );
     418             : 
     419             : /* fd_shred_data_payload: Returns a pointer to a data shred payload.
     420             : 
     421             :   The provided shred must have passed validation in fd_shred_parse(),
     422             :   and must satisfy `type&FD_SHRED_TYPEMASK_DATA`
     423             :   where `uchar type = fd_shred_type( shred->variant )`. */
     424             : FD_FN_CONST static inline uchar const *
     425         132 : fd_shred_data_payload( fd_shred_t const * shred ) {
     426         132 :   return (uchar const *)shred + FD_SHRED_DATA_HEADER_SZ;
     427         132 : }
     428             : 
     429             : /* fd_shred_code_payload: Returns a pointer to a coding shred payload.
     430             : 
     431             :   The provided shred must have passed validation in fd_shred_parse(),
     432             :   and must satisfy `type&FD_SHRED_TYPEMASK_CODE`
     433             :   where `uchar type = fd_shred_type( shred->variant )`. */
     434             : FD_FN_CONST static inline uchar const *
     435           0 : fd_shred_code_payload( fd_shred_t const * shred ) {
     436           0 :   return (uchar const *)shred + FD_SHRED_CODE_HEADER_SZ;
     437           0 : }
     438             : 
     439             : /* fd_shred_chain_offset: Assuming that `shred` is a chained Merkle
     440             :    variant, compute the offset from the start of the shred to the start
     441             :    of the chained Merkle root.  U.B. if the shred is not a chained
     442             :    variant. */
     443             : FD_FN_CONST static inline ulong
     444    12030789 : fd_shred_chain_off( uchar variant ) {
     445    12030789 :   ulong type = fd_shred_type( variant );
     446    12030789 :   return fd_ulong_if( type & FD_SHRED_TYPEMASK_CODE, FD_SHRED_MAX_SZ, FD_SHRED_MIN_SZ )
     447    12030789 :     - FD_SHRED_MERKLE_ROOT_SZ
     448    12030789 :     - fd_shred_merkle_sz( variant )
     449    12030789 :     - fd_ulong_if( fd_shred_is_resigned( type ), FD_SHRED_SIGNATURE_SZ, 0 );
     450    12030789 : }
     451             : 
     452             : /* fd_shred_retrasmitter_sig_off: Assuming that `shred` is a resigned
     453             :    variant, compute the offset from the start of the shred to the start
     454             :    of the retransmitter signature.  U.B if the shred is not a resigned
     455             :    chained type. */
     456             : FD_FN_PURE static inline ulong
     457     2745795 : fd_shred_retransmitter_sig_off( fd_shred_t const * shred ) {
     458     2745795 :   return fd_shred_sz( shred )-FD_SHRED_SIGNATURE_SZ;
     459     2745795 : }
     460             : 
     461             : FD_PROTOTYPES_END
     462             : 
     463             : #endif /* HEADER_fd_src_ballet_shred_fd_shred_h */

Generated by: LCOV version 1.14