LCOV - code coverage report
Current view: top level - disco/poh - fd_poh_tile.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 2 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_poh_fd_poh_tile_h
       2             : #define HEADER_fd_src_disco_poh_fd_poh_tile_h
       3             : 
       4             : #include "../tiles.h"
       5             : #include "../shred/fd_stake_ci.h"
       6             : 
       7             : /* Common library functions for the Proof of History tile. */
       8             : 
       9             : /* When we are becoming leader, and we think the prior leader might have
      10             :    skipped their slot, we give them a grace period to finish.  In the
      11             :    Agave client this is called grace ticks.  This is a courtesy to
      12             :    maintain network health, and is not strictly necessary.  It is
      13             :    actually advantageous to us as new leader to take over right away and
      14             :    give no grace period, since we could generate more fees.
      15             : 
      16             :    Here we define the grace period to be two slots, which is taken from
      17             :    Agave directly. */
      18             : #define GRACE_SLOTS (2UL)
      19             : 
      20             : /* The maximum number of microblocks that pack is allowed to pack into a
      21             :    single slot.  This is not consensus critical, and pack could, if we
      22             :    let it, produce as many microblocks as it wants, and the slot would
      23             :    still be valid.
      24             : 
      25             :    We have this here instead so that PoH can estimate slot completion,
      26             :    and keep the hashcnt up to date as pack progresses through packing
      27             :    the slot.  If this upper bound was not enforced, PoH could tick to
      28             :    the last hash of the slot and have no hashes left to mixin incoming
      29             :    microblocks from pack, so this upper bound is a coordination
      30             :    mechanism so that PoH can progress hashcnts while the slot is active,
      31             :    and know that pack will not need those hashcnts later to do mixins. */
      32           0 : #define MAX_MICROBLOCKS_PER_SLOT (16384UL)
      33             : 
      34             : /* When we are hashing in the background in case a prior leader skips
      35             :    their slot, we need to store the result of each tick hash so we can
      36             :    publish them when we become leader.  The network requires at least
      37             :    one leader slot to publish in each epoch for the leader schedule to
      38             :    generate, so in the worst case we might need two full epochs of slots
      39             :    to store the hashes.  (Eg, if epoch T only had a published slot in
      40             :    position 0 and epoch T+1 only had a published slot right at the end).
      41             : 
      42             :    There is a tighter bound: the block data limit of mainnet-beta is
      43             :    currently FD_PACK_MAX_DATA_PER_BLOCK, or 27,332,342 bytes per slot.
      44             :    At 48 bytes per tick, it is not possible to publish a slot that skips
      45             :    569,424 or more prior slots. */
      46           0 : #define MAX_SKIPPED_TICKS (1UL+(FD_PACK_MAX_DATA_PER_BLOCK/48UL))
      47             : 
      48             : struct fd_poh_tile_in_ctx {
      49             :   fd_wksp_t * mem;
      50             :   ulong       chunk0;
      51             :   ulong       wmark;
      52             : };
      53             : typedef struct fd_poh_tile_in_ctx fd_poh_tile_in_ctx_t;
      54             : 
      55             : typedef void * (*fd_poh_tile_get_micoblock_buffer_func_t)( void * arg );
      56             : typedef void   (*fd_poh_tile_publish_microblock_func_t)( void * arg, ulong tspub, ulong sig, ulong sz );
      57             : typedef void * (*fd_poh_tile_get_pack_buffer_func_t)( void * arg );
      58             : typedef void   (*fd_poh_tile_publish_pack_func_t)( void * arg, ulong tspub, ulong sig, ulong sz );
      59             : typedef void   (*fd_poh_tile_register_tick_func_t)( void * arg, ulong slot, uchar hash[ static 32 ] );
      60             : typedef void   (*fd_poh_tile_signal_leader_change_func_t)( void * arg );
      61             : 
      62             : struct fd_poh_tile_ctx {
      63             :   /* Static configuration determined at genesis creation time.  See
      64             :      long comment above for more information. */
      65             :   double hashcnt_duration_ns;
      66             :   double slot_duration_ns;
      67             :   ulong  tick_duration_ns;
      68             :   ulong  hashcnt_per_tick;
      69             :   ulong  ticks_per_slot;
      70             : 
      71             :   /* Derived from the above configuration, but we precompute it. */
      72             :   ulong hashcnt_per_slot;
      73             : 
      74             :   /* The current slot and hashcnt within that slot of the proof of
      75             :      history, including hashes we have been producing in the background
      76             :      while waiting for our next leader slot. */
      77             :   ulong slot;
      78             :   ulong hashcnt;
      79             : 
      80             :   /* When we send a microblock on to the shred tile, we need to tell
      81             :      it how many hashes there have been since the last microblock, so
      82             :      this tracks the hashcnt of the last published microblock.
      83             : 
      84             :      As well, the next leader slot that we can transition into will
      85             :      always be strictly more than the slot this hashcnt is in, otherwise
      86             :      we could potentially become leader for a slot twice. */   
      87             :   ulong last_slot;
      88             :   ulong last_hashcnt;
      89             : 
      90             :   /* See how this field is used below.  If we have sequential leader
      91             :      slots, we don't reset the expected slot end time between the two,
      92             :      to prevent clock drift.  If we didn't do this, our 2nd slot would
      93             :      end 400ms + `time_for_replay_to_move_slot_and_reset_poh` after
      94             :      our 1st, rather than just strictly 400ms. */
      95             :   ulong expect_sequential_leader_slot;
      96             : 
      97             :   /* The PoH tile must never drop microblocks that get committed by the
      98             :      bank, so it needs to always be able to mixin a microblock hash.
      99             :      Mixing in requires incrementing the hashcnt, so we need to ensure
     100             :      at all times that there is enough hascnts left in the slot to
     101             :      mixin whatever future microblocks pack might produce for it.
     102             : 
     103             :      This value tracks that.  At any time, max_microblocks_per_slot
     104             :      - microblocks_lower_bound is an upper bound on the maximum number
     105             :      of microblocks that might still be received in this slot. */
     106             :   ulong microblocks_lower_bound;
     107             : 
     108             :   /* Constant, fixed at initialization.  The maximum number of
     109             :      microblocks that the pack tile can publish in each slot. */
     110             :   ulong max_microblocks_per_slot;
     111             : 
     112             :   uchar __attribute__((aligned(32UL))) hash[ 32 ];
     113             : 
     114             :   /* When we are not leader, we need to save the hashes that were
     115             :      produced in case the prior leader skips.  If they skip, we will
     116             :      replay these skipped hashes into our next leader bank so that
     117             :      the slot hashes sysvar can be updated correctly.  We only need 150
     118             :      of these, because that's what's required for consensus in the
     119             :      sysvar. */
     120             :   uchar skipped_tick_hashes[ MAX_SKIPPED_TICKS ][ 32 ];
     121             : 
     122             :   /* The timestamp in nanoseconds of when the reset slot was received.
     123             :      This is the timestamp we are building on top of to determine when
     124             :      our next leader slot starts. */
     125             :   long reset_slot_start_ns;
     126             : 
     127             :   /* The hashcnt corresponding to the start of the current reset slot. */
     128             :   ulong reset_slot;
     129             : 
     130             :   /* The hashcnt at which our next leader slot begins, or ULONG max if
     131             :      we have no known next leader slot. */
     132             :   ulong next_leader_slot;
     133             : 
     134             :   /* The current slot where we are leader. If it is set to FD_SLOT_NULL, we are
     135             :      not leader. */
     136             :   ulong current_leader_slot;
     137             : 
     138             : 
     139             :   /* If we have published a tick or a microblock for a particular slot
     140             :      to the shred tile, we should never become leader for that slot
     141             :      again, otherwise we could publish a duplicate block.
     142             : 
     143             :      This value tracks the max slot that we have published a tick or
     144             :      microblock for so we can prevent this. */
     145             :   ulong highwater_leader_slot;
     146             : 
     147             :   fd_sha256_t * sha256;
     148             : 
     149             :   fd_stake_ci_t * stake_ci;
     150             : 
     151             :   fd_pubkey_t identity_key;
     152             : 
     153             :   fd_wksp_t * shred_out_mem;
     154             :   ulong       shred_out_chunk0;
     155             :   ulong       shred_out_wmark;
     156             :   ulong       shred_out_chunk;
     157             : 
     158             :   fd_frag_meta_t * pack_out_mcache;
     159             :   ulong            pack_out_depth;
     160             :   ulong            pack_out_seq;
     161             :   fd_wksp_t *      pack_out_mem;
     162             :   ulong            pack_out_chunk0;
     163             :   ulong            pack_out_wmark;
     164             :   ulong            pack_out_chunk;
     165             : 
     166             :   fd_histf_t begin_leader_delay[ 1 ];
     167             :   fd_histf_t first_microblock_delay[ 1 ];
     168             :   fd_histf_t slot_done_delay[ 1 ];
     169             : 
     170             :   /* Callbacks */
     171             :   void * arg;
     172             : 
     173             :   fd_poh_tile_get_micoblock_buffer_func_t get_microblock_buffer_func;
     174             :   fd_poh_tile_publish_microblock_func_t   publish_microblock_func;
     175             :   fd_poh_tile_get_micoblock_buffer_func_t get_pack_buffer_func;
     176             :   fd_poh_tile_publish_microblock_func_t   publish_pack_func;
     177             :   fd_poh_tile_register_tick_func_t        register_tick_func;
     178             :   fd_poh_tile_signal_leader_change_func_t signal_leader_change_func;
     179             : };
     180             : typedef struct fd_poh_tile_ctx fd_poh_tile_ctx_t;
     181             : 
     182             : FD_PROTOTYPES_BEGIN
     183             : 
     184             : ulong
     185             : fd_poh_tile_align( void );
     186             : 
     187             : ulong
     188             : fd_poh_tile_footprint( void );
     189             : 
     190             : void
     191             : fd_poh_tile_publish_microblock( fd_poh_tile_ctx_t * ctx,
     192             :                                 ulong               sig,
     193             :                                 ulong               slot,
     194             :                                 ulong               hashcnt_delta,
     195             :                                 fd_txn_p_t *        txns,
     196             :                                 ulong               txn_cnt );
     197             :                               
     198             : void
     199             : fd_poh_tile_initialize( fd_poh_tile_ctx_t * ctx,
     200             :                         ulong               tick_duration_ns, /* See clock comments above, will be 500ns for mainnet-beta. */
     201             :                         ulong               hashcnt_per_tick,    /* See clock comments above, will be 12,500 for mainnet-beta. */
     202             :                         ulong               ticks_per_slot,      /* See clock comments above, will almost always be 64. */
     203             :                         ulong               tick_height,         /* The counter (height) of the tick to start hashing on top of. */
     204             :                         uchar const *       last_entry_hash      /* Points to start of a 32 byte region of memory, the hash itself at the tick height. */ );
     205             : 
     206             : int
     207             : fd_poh_tile_reached_leader_slot( fd_poh_tile_ctx_t * ctx,
     208             :                                  ulong *             out_leader_slot,
     209             :                                  ulong *             out_reset_slot );
     210             : 
     211             : void
     212             : fd_poh_tile_publish_became_leader( fd_poh_tile_ctx_t * ctx,
     213             :                                    void const *        current_leader_data,
     214             :                                    ulong               slot );
     215             : 
     216             : void
     217             : fd_poh_tile_no_longer_leader( fd_poh_tile_ctx_t * ctx );
     218             : 
     219             : void
     220             : fd_poh_tile_reset( fd_poh_tile_ctx_t * ctx,
     221             :                    ulong               completed_bank_slot, /* The slot that successfully produced a block */
     222             :                    uchar const *       reset_blockhash,     /* The hash of the last tick in the produced block */
     223             :                    ulong               hashcnt_per_tick     /* The hashcnt per tick of the bank that completed */);
     224             : int
     225             : fd_poh_tile_get_leader_after_n_slots( fd_poh_tile_ctx_t * ctx,
     226             :                                       ulong               n,
     227             :                                       uchar               out_pubkey[ static 32 ] );
     228             : int
     229             : fd_poh_tile_after_credit( fd_poh_tile_ctx_t * ctx,
     230             :                           int *               opt_poll_in );
     231             : 
     232             : void
     233             : fd_poh_tile_init_stakes( fd_poh_tile_ctx_t * ctx, uchar const * stakes_msg );
     234             : 
     235             : void
     236             : fd_poh_tile_fini_stakes( fd_poh_tile_ctx_t * ctx );
     237             : 
     238             : void
     239             : fd_poh_tile_during_housekeeping( fd_poh_tile_ctx_t * ctx );
     240             : 
     241             : void
     242             : fd_poh_tile_begin_leader( fd_poh_tile_ctx_t * ctx,
     243             :                           ulong               slot,
     244             :                           ulong               hashcnt_per_tick );
     245             : 
     246             : void
     247             : fd_poh_tile_process_packed_microblock( fd_poh_tile_ctx_t * ctx,
     248             :                                        ulong               target_slot,
     249             :                                        ulong               sig,
     250             :                                        fd_txn_p_t *        txns,
     251             :                                        ulong               txn_cnt,
     252             :                                        uchar               mixin_hash[ static 32 ] );
     253             : 
     254             : void
     255             : fd_poh_tile_done_packing( fd_poh_tile_ctx_t * ctx,
     256             :                           ulong microblocks_in_slot );
     257             : 
     258             : fd_poh_tile_ctx_t *
     259             : fd_poh_tile_new( void * scratch,
     260             :                  void * arg,
     261             :                  fd_poh_tile_get_micoblock_buffer_func_t get_microblock_buffer_func,
     262             :                  fd_poh_tile_publish_microblock_func_t   publish_microblock_func,
     263             :                  fd_poh_tile_get_pack_buffer_func_t      get_pack_buffer_func,
     264             :                  fd_poh_tile_publish_pack_func_t         publish_pack_func,
     265             :                  fd_poh_tile_register_tick_func_t        register_tick_func,
     266             :                  fd_poh_tile_signal_leader_change_func_t signal_leader_change_func );
     267             : 
     268             : FD_PROTOTYPES_END
     269             : 
     270             : #endif /* HEADER_fd_src_disco_poh_fd_poh_tile_h */

Generated by: LCOV version 1.14