LCOV - code coverage report
Current view: top level - choreo/forks - fd_forks.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 146 0.0 %
Date: 2025-07-01 05:00:49 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #include "fd_forks.h"
       2             : 
       3             : #include "../../flamenco/runtime/context/fd_exec_slot_ctx.h"
       4             : #include "../../flamenco/runtime/fd_acc_mgr.h"
       5             : #include "../../flamenco/runtime/fd_borrowed_account.h"
       6             : #include "../../flamenco/runtime/fd_runtime.h"
       7             : #include "../../flamenco/runtime/program/fd_program_util.h"
       8             : #include "../../flamenco/runtime/program/fd_vote_program.h"
       9             : 
      10             : void *
      11           0 : fd_forks_new( void * shmem, ulong max, ulong seed ) {
      12             : 
      13           0 :   if( FD_UNLIKELY( !shmem ) ) {
      14           0 :     FD_LOG_WARNING( ( "NULL mem" ) );
      15           0 :     return NULL;
      16           0 :   }
      17             : 
      18           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_forks_align() ) ) ) {
      19           0 :     FD_LOG_WARNING( ( "misaligned mem" ) );
      20           0 :     return NULL;
      21           0 :   }
      22             : 
      23           0 :   ulong footprint = fd_forks_footprint( max );
      24           0 :   if( FD_UNLIKELY( !footprint ) ) {
      25           0 :     FD_LOG_WARNING( ( "bad mem" ) );
      26           0 :     return NULL;
      27           0 :   }
      28             : 
      29           0 :   fd_memset( shmem, 0, footprint );
      30           0 :   ulong laddr = (ulong)shmem;
      31             : 
      32           0 :   laddr = fd_ulong_align_up( laddr, alignof( fd_forks_t ) );
      33           0 :   laddr += sizeof( fd_forks_t );
      34             : 
      35           0 :   laddr = fd_ulong_align_up( laddr, fd_fork_pool_align() );
      36           0 :   fd_fork_pool_new( (void *)laddr, max );
      37           0 :   laddr += fd_fork_pool_footprint( max );
      38             : 
      39           0 :   laddr = fd_ulong_align_up( laddr, fd_fork_frontier_align() );
      40           0 :   fd_fork_frontier_new( (void *)laddr, max, seed );
      41           0 :   laddr += fd_fork_frontier_footprint( max );
      42             : 
      43           0 :   return shmem;
      44           0 : }
      45             : 
      46             : fd_forks_t *
      47           0 : fd_forks_join( void * shforks ) {
      48             : 
      49           0 :   if( FD_UNLIKELY( !shforks ) ) {
      50           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
      51           0 :     return NULL;
      52           0 :   }
      53             : 
      54           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shforks, fd_forks_align() ) ) ) {
      55           0 :     FD_LOG_WARNING( ( "misaligned forks" ) );
      56           0 :     return NULL;
      57           0 :   }
      58             : 
      59           0 :   ulong        laddr = (ulong)shforks;
      60           0 :   fd_forks_t * forks = (void *)laddr;
      61             : 
      62           0 :   laddr = fd_ulong_align_up( laddr, alignof( fd_forks_t ) );
      63           0 :   laddr += sizeof( fd_forks_t );
      64             : 
      65           0 :   laddr       = fd_ulong_align_up( laddr, fd_fork_pool_align() );
      66           0 :   forks->pool = fd_fork_pool_join( (void *)laddr );
      67           0 :   ulong max   = fd_fork_pool_max( forks->pool );
      68           0 :   laddr += fd_fork_pool_footprint( max );
      69             : 
      70           0 :   laddr           = fd_ulong_align_up( laddr, fd_fork_frontier_align() );
      71           0 :   forks->frontier = fd_fork_frontier_join( (void *)laddr );
      72           0 :   laddr += fd_fork_frontier_footprint( max );
      73             : 
      74           0 :   return (fd_forks_t *)shforks;
      75           0 : }
      76             : 
      77             : void *
      78           0 : fd_forks_leave( fd_forks_t const * forks ) {
      79             : 
      80           0 :   if( FD_UNLIKELY( !forks ) ) {
      81           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
      82           0 :     return NULL;
      83           0 :   }
      84             : 
      85           0 :   return (void *)forks;
      86           0 : }
      87             : 
      88             : void *
      89           0 : fd_forks_delete( void * forks ) {
      90             : 
      91           0 :   if( FD_UNLIKELY( !forks ) ) {
      92           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
      93           0 :     return NULL;
      94           0 :   }
      95             : 
      96           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)forks, fd_forks_align() ) ) ) {
      97           0 :     FD_LOG_WARNING( ( "misaligned forks" ) );
      98           0 :     return NULL;
      99           0 :   }
     100             : 
     101           0 :   return forks;
     102           0 : }
     103             : 
     104             : fd_fork_t *
     105           0 : fd_forks_init( fd_forks_t * forks, ulong slot ) {
     106             : 
     107           0 :   if( FD_UNLIKELY( !forks ) ) {
     108           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
     109           0 :     return NULL;
     110           0 :   }
     111             : 
     112           0 :   fd_fork_t * fork = fd_fork_pool_ele_acquire( forks->pool );
     113           0 :   fork->slot       = slot;
     114           0 :   fork->prev       = fd_fork_pool_idx_null( forks->pool );
     115           0 :   fork->lock       = 0;
     116           0 :   fork->end_idx    = UINT_MAX;
     117           0 :   if( FD_UNLIKELY( !fd_fork_frontier_ele_insert( forks->frontier, fork, forks->pool ) ) ) {
     118           0 :     FD_LOG_WARNING( ( "Failed to insert fork into frontier" ) );
     119           0 :   }
     120             : 
     121           0 :   return fork;
     122           0 : }
     123             : 
     124             : fd_fork_t *
     125           0 : fd_forks_query( fd_forks_t * forks, ulong slot ) {
     126           0 :   return fd_fork_frontier_ele_query( forks->frontier, &slot, NULL, forks->pool );
     127           0 : }
     128             : 
     129             : fd_fork_t const *
     130           0 : fd_forks_query_const( fd_forks_t const * forks, ulong slot ) {
     131           0 :   return fd_fork_frontier_ele_query_const( forks->frontier, &slot, NULL, forks->pool );
     132           0 : }
     133             : 
     134             : // fd_fork_t *
     135             : // fd_forks_advance( fd_forks_t *          forks,
     136             : //                   fd_fork_t *           fork,
     137             : //                   ulong                 slot,
     138             : //                   fd_funk_t *           funk,
     139             : //                   fd_blockstore_t *     blockstore,
     140             : //                   fd_funk_t *           funk,
     141             : //                   fd_valloc_t           valloc ) {
     142             : //   // Remove slot ctx from frontier
     143             : //   fd_fork_t * child = fd_fork_frontier_ele_remove( forks->frontier,
     144             : //                                                    &fork->slot,
     145             : //                                                    NULL,
     146             : //                                                    forks->pool );
     147             : //   child->slot       = curr_slot;
     148             : //   if( FD_UNLIKELY( fd_fork_frontier_ele_query( forks->frontier,
     149             : //                                                &curr_slot,
     150             : //                                                NULL,
     151             : //                                                forks->pool ) ) ) {
     152             : //         FD_LOG_ERR( ( "invariant violation: child slot %lu was already in the
     153             : //         frontier", curr_slot ) );
     154             : //   }
     155             : //   fd_fork_frontier_ele_insert( forks->frontier, child, forks->pool );
     156             : //   FD_TEST( fork == child );
     157             : 
     158             : //   // fork is advancing
     159             : //   FD_LOG_DEBUG(( "new block execution - slot: %lu, parent_slot: %lu", curr_slot, parent_slot ));
     160             : 
     161             : //   fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot;
     162             : //   fork->slot_ctx->slot      = curr_slot;
     163             : 
     164             : //   fork->slot_ctx.status_cache = status_cache;
     165             : //   fd_funk_txn_xid_t xid;
     166             : 
     167             : //   fd_memcpy( xid.uc, blockhash.uc, sizeof( fd_funk_txn_xid_t));
     168             : //   xid.ul[0] = fork->slot_ctx.slot_bank.slot;
     169             : //   /* push a new transaction on the stack */
     170             : //   fd_funk_start_write( funk );
     171             : //   fork->slot_ctx.funk_txn = fd_funk_txn_prepare( funk, fork->slot_ctx.funk_txn, &xid, 1 );
     172             : //   fd_funk_end_write( funk );
     173             : 
     174             : //   int res = fd_runtime_publish_old_txns( &fork->slot_ctx, capture_ctx );
     175             : //   if( res != FD_RUNTIME_EXECUTE_SUCCESS ) {
     176             : //     FD_LOG_ERR(( "txn publishing failed" ));
     177             : //   }
     178             : // }
     179             : 
     180             : fd_fork_t *
     181             : fd_forks_prepare( fd_forks_t const *    forks,
     182             :                   ulong                 parent_slot,
     183             :                   fd_funk_t *           funk,
     184             :                   fd_blockstore_t *     blockstore,
     185           0 :                   fd_spad_t *           runtime_spad ) {
     186             : 
     187             :   /* Check the parent block is present in the blockstore and executed. */
     188             : 
     189           0 :   if( FD_UNLIKELY( !fd_blockstore_shreds_complete( blockstore, parent_slot ) ) ) {
     190           0 :     FD_LOG_WARNING( ( "fd_forks_prepare missing parent_slot %lu", parent_slot ) );
     191           0 :   }
     192             : 
     193             :   /* Query for parent_slot in the frontier. */
     194             : 
     195           0 :   fd_fork_t * fork = fd_fork_frontier_ele_query( forks->frontier, &parent_slot, NULL, forks->pool );
     196             : 
     197             :   /* If the parent block is both present and executed, but isn't in the
     198             :      frontier, that means this block is starting a new fork and needs to
     199             :      be added to the frontier. This requires recovering the slot_ctx
     200             :      as of that parent_slot by executing a funky rollback. */
     201             : 
     202           0 :   if( FD_UNLIKELY( !fork ) ) {
     203             : 
     204             :     /* Alloc a new slot_ctx */
     205             : 
     206           0 :     fork       = fd_fork_pool_ele_acquire( forks->pool );
     207           0 :     fork->prev = fd_fork_pool_idx_null( forks->pool );
     208           0 :     fork->slot = parent_slot;
     209           0 :     fork->lock = 1;
     210           0 :     fork->end_idx = UINT_MAX;
     211             : 
     212             :     /* Restore and decode w/ funk */
     213             : 
     214           0 :     (void)runtime_spad;
     215           0 :     (void)funk;
     216             :     // slot_ctx_restore( fork->slot, funk, blockstore, runtime_spad, slot_ctx );
     217             : 
     218             : 
     219             :     /* Add to frontier */
     220             : 
     221           0 :     fd_fork_frontier_ele_insert( forks->frontier, fork, forks->pool );
     222           0 :   }
     223             : 
     224           0 :   return fork;
     225           0 : }
     226             : 
     227             : void
     228           0 : fd_forks_publish( fd_forks_t * forks, ulong slot ) {
     229           0 :   fd_fork_t * tail = NULL;
     230           0 :   fd_fork_t * curr = NULL;
     231             : 
     232           0 :   for( fd_fork_frontier_iter_t iter = fd_fork_frontier_iter_init( forks->frontier, forks->pool );
     233           0 :        !fd_fork_frontier_iter_done( iter, forks->frontier, forks->pool );
     234           0 :        iter = fd_fork_frontier_iter_next( iter, forks->frontier, forks->pool ) ) {
     235           0 :     fd_fork_t * fork = fd_fork_frontier_iter_ele( iter, forks->frontier, forks->pool );
     236             : 
     237             :     /* Prune any forks not in the ancestry from root.
     238             : 
     239             :        Optimize for unlikely because there is usually just one fork. */
     240             : 
     241           0 :     if( FD_UNLIKELY( !fork->lock && fork->slot < slot ) ) {
     242           0 :       if( FD_LIKELY( !curr ) ) {
     243           0 :         tail = fork;
     244           0 :         curr = fork;
     245           0 :       } else {
     246           0 :         curr->prev = fd_fork_pool_idx( forks->pool, fork );
     247           0 :         curr       = fd_fork_pool_ele( forks->pool, curr->prev );
     248           0 :       }
     249           0 :     }
     250           0 :   }
     251             : 
     252           0 :   while( FD_UNLIKELY( tail ) ) {
     253           0 :     ulong remove = fd_fork_frontier_idx_remove( forks->frontier,
     254           0 :                                                 &tail->slot,
     255           0 :                                                 fd_fork_pool_idx_null( forks->pool ),
     256           0 :                                                 forks->pool );
     257           0 : #if FD_FORKS_USE_HANDHOLDING
     258           0 :     if( FD_UNLIKELY( remove == fd_fork_pool_idx_null( forks->pool ) ) ) {
     259           0 :       FD_LOG_ERR( ( "failed to remove fork we added to prune." ) );
     260           0 :     }
     261           0 : #endif
     262             : 
     263             :     /* pool_idx_release cannot fail given we just removed this from the
     264             :       frontier directly above. */
     265           0 :     fd_fork_pool_idx_release( forks->pool, remove );
     266           0 :     tail = fd_ptr_if( tail->prev != fd_fork_pool_idx_null( forks->pool ),
     267           0 :                       fd_fork_pool_ele( forks->pool, tail->prev ),
     268           0 :                       NULL );
     269           0 :   }
     270           0 : }
     271             : 
     272             : #include <stdio.h>
     273             : 
     274             : void
     275           0 : fd_forks_print( fd_forks_t const * forks ) {
     276           0 :   FD_LOG_NOTICE( ( "\n\n[Forks]" ) );
     277           0 :   for( fd_fork_frontier_iter_t iter = fd_fork_frontier_iter_init( forks->frontier, forks->pool );
     278           0 :        !fd_fork_frontier_iter_done( iter, forks->frontier, forks->pool );
     279           0 :        iter = fd_fork_frontier_iter_next( iter, forks->frontier, forks->pool ) ) {
     280           0 :     printf( "%lu\n", fd_fork_frontier_iter_ele_const( iter, forks->frontier, forks->pool )->slot );
     281           0 :   }
     282           0 :   printf( "\n" );
     283           0 : }

Generated by: LCOV version 1.14