LCOV - code coverage report
Current view: top level - disco/pack - fd_pack_rebate_sum.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 87 100 87.0 %
Date: 2025-07-01 05:00:49 Functions: 3 4 75.0 %

          Line data    Source code
       1             : #include "fd_pack_rebate_sum.h"
       2             : #include "fd_pack.h"
       3             : #if FD_HAS_AVX
       4             : #include "../../util/simd/fd_avx.h"
       5             : #endif
       6             : 
       7             : static const fd_acct_addr_t null_addr = { 0 };
       8             : 
       9             : #define MAP_NAME        rmap
      10       24003 : #define MAP_T           fd_pack_rebate_entry_t
      11      105999 : #define MAP_LG_SLOT_CNT 13
      12       52536 : #define MAP_KEY_T       fd_acct_addr_t
      13       61134 : #define MAP_KEY_NULL    null_addr
      14             : #if FD_HAS_AVX
      15       52536 : # define MAP_KEY_INVAL(k)     _mm256_testz_si256( wb_ldu( (k).b ), wb_ldu( (k).b ) )
      16             : #else
      17             : # define MAP_KEY_INVAL(k)     MAP_KEY_EQUAL(k, null_addr)
      18             : #endif
      19       24273 : #define MAP_KEY_EQUAL(k0,k1)  (!memcmp((k0).b,(k1).b, FD_TXN_ACCT_ADDR_SZ))
      20             : #define MAP_KEY_EQUAL_IS_SLOW 1
      21             : #define MAP_MEMOIZE           0
      22       28296 : #define MAP_KEY_HASH(key)     ((uint)fd_hash( 132132, (key).b, 32UL ))
      23           0 : #define MAP_MOVE(d,s)         (__extension__({ FD_LOG_CRIT(( "Tried to move a map value" )); (d)=(s); }))
      24             : 
      25             : #include "../../util/tmpl/fd_map.c"
      26             : 
      27             : 
      28             : void *
      29           6 : fd_pack_rebate_sum_new( void * mem ) {
      30           6 :   fd_pack_rebate_sum_t * s = (fd_pack_rebate_sum_t *)mem;
      31             : 
      32           6 :   s->total_cost_rebate        = 0UL;
      33           6 :   s->vote_cost_rebate         = 0UL;
      34           6 :   s->data_bytes_rebate        = 0UL;
      35           6 :   s->microblock_cnt_rebate    = 0UL;
      36           6 :   s->ib_result                = 0;
      37           6 :   s->writer_cnt               = 0U;
      38             : 
      39           6 :   rmap_new( s->map );
      40             : 
      41             :   /* Not a good place to put this, but there's not really a better place
      42             :      for it either.  The compiler should eliminate it. */
      43           6 :   FD_TEST( rmap_footprint()==sizeof(s->map) );
      44           6 :   return mem;
      45           6 : }
      46             : 
      47          42 : #define HEADROOM (FD_PACK_REBATE_SUM_CAPACITY-MAX_TXN_PER_MICROBLOCK*FD_TXN_ACCT_ADDR_MAX)
      48             : 
      49             : ulong
      50             : fd_pack_rebate_sum_add_txn( fd_pack_rebate_sum_t         * s,
      51             :                             fd_txn_p_t     const         * txns,
      52             :                             fd_acct_addr_t const * const * adtl_writable,
      53          42 :                             ulong                          txn_cnt ) {
      54             :   /* See end of function for this equation */
      55          42 :   if( FD_UNLIKELY( txn_cnt==0UL ) ) return (ulong)((fd_int_max( 0, (int)s->writer_cnt - (int)HEADROOM ) + 1636) / 1637);
      56             : 
      57          33 :   int is_initializer_bundle = 1;
      58          33 :   int ib_success            = 1;
      59          33 :   int any_in_block          = 0;
      60             : 
      61         204 :   for( ulong i=0UL; i<txn_cnt; i++ ) {
      62         171 :     fd_txn_p_t const * txn = txns+i;
      63         171 :     ulong rebated_cus   = txn->bank_cu.rebated_cus;
      64         171 :     int   in_block      = !!(txn->flags & FD_TXN_P_FLAGS_EXECUTE_SUCCESS);
      65             : 
      66             :     /* For IB purposes, treat AlreadyProcessed (7) as success.  If one
      67             :        transaction is an initializer bundle, they all must be, so it's
      68             :        unclear if the first line should be an |= or an &=, but &= seems
      69             :        more right. */
      70         171 :     is_initializer_bundle &= !!(txn->flags & FD_TXN_P_FLAGS_INITIALIZER_BUNDLE);
      71         171 :     ib_success            &= in_block | ((txn->flags&FD_TXN_P_FLAGS_RESULT_MASK)==(7U<<24));
      72         171 :     any_in_block          |= in_block;
      73             : 
      74         171 :     s->total_cost_rebate += rebated_cus;
      75         171 :     s->vote_cost_rebate  += fd_ulong_if( txn->flags & FD_TXN_P_FLAGS_IS_SIMPLE_VOTE, rebated_cus,     0UL );
      76         171 :     s->data_bytes_rebate += fd_ulong_if( !in_block,                                  txn->payload_sz, 0UL );
      77             : 
      78         171 :     if( FD_UNLIKELY( rebated_cus==0UL ) ) continue;
      79             : 
      80         171 :     fd_acct_addr_t const * accts = fd_txn_get_acct_addrs( TXN(txn), txn->payload );
      81         171 :     for( fd_txn_acct_iter_t iter=fd_txn_acct_iter_init( TXN(txn), FD_TXN_ACCT_CAT_WRITABLE & FD_TXN_ACCT_CAT_IMM );
      82         264 :         iter!=fd_txn_acct_iter_end(); iter=fd_txn_acct_iter_next( iter ) ) {
      83             : 
      84          93 :       ulong j=fd_txn_acct_iter_idx( iter );
      85             : 
      86          93 :       fd_pack_rebate_entry_t * in_table = rmap_query( s->map, accts[j], NULL );
      87          93 :       if( FD_UNLIKELY( !in_table ) ) {
      88          66 :         in_table = rmap_insert( s->map, accts[j] );
      89          66 :         in_table->rebate_cus = 0UL;
      90          66 :         s->inserted[ s->writer_cnt++ ] = in_table;
      91          66 :       }
      92          93 :       in_table->rebate_cus += rebated_cus;
      93          93 :     }
      94         171 :     accts = adtl_writable[i];
      95         171 :     if( FD_LIKELY( txn->flags & FD_TXN_P_FLAGS_SANITIZE_SUCCESS ) ) {
      96       12063 :       for( ulong j=0UL; j<(ulong)TXN(txn)->addr_table_adtl_writable_cnt; j++ ) {
      97       11922 :         fd_pack_rebate_entry_t * in_table = rmap_query( s->map, accts[j], NULL );
      98       11922 :         if( FD_UNLIKELY( !in_table ) ) {
      99       11916 :           in_table = rmap_insert( s->map, accts[j] );
     100       11916 :           in_table->rebate_cus = 0UL;
     101       11916 :           s->inserted[ s->writer_cnt++ ] = in_table;
     102       11916 :         }
     103       11922 :         in_table->rebate_cus += rebated_cus;
     104       11922 :       }
     105         141 :     }
     106         171 :     FD_TEST( s->writer_cnt<=FD_PACK_REBATE_SUM_CAPACITY );
     107         171 :   }
     108             : 
     109          33 :   int is_bundle = txns->flags & FD_TXN_P_FLAGS_BUNDLE; /* can't mix bundle and non-bundle */
     110          33 :   ulong microblock_cnt_rebate = fd_ulong_if( any_in_block, 0UL, fd_ulong_if( is_bundle, txn_cnt, 1UL ) );
     111          33 :   s->microblock_cnt_rebate += microblock_cnt_rebate;
     112          33 :   s->data_bytes_rebate     += microblock_cnt_rebate*48UL; /* microblock headers */
     113             : 
     114          33 :   if( FD_UNLIKELY( is_initializer_bundle & (s->ib_result!=-1) ) ) { /* if in -1 state, stay. Shouldn't be possible */
     115           6 :     s->ib_result = fd_int_if( ib_success, 1, -1 );
     116           6 :   }
     117             : 
     118             :   /* We want to make sure that we have enough capacity to insert 31*128
     119             :      addresses without hitting 5k.  Thus, if x is the current value of
     120             :      writer_cnt, we need to call report at least y times to ensure
     121             :                         x-y*1637 <= 5*1024-31*128
     122             :                                y >= (x-1152)/1637
     123             :      but y is an integer, so y >= ceiling( (x-1152)/1637 ) */
     124          33 :   return (ulong)((fd_int_max( 0, (int)s->writer_cnt - (int)HEADROOM ) + 1636) / 1637);
     125          33 : }
     126             : 
     127             : 
     128             : ulong
     129             : fd_pack_rebate_sum_report( fd_pack_rebate_sum_t * s,
     130          45 :                            fd_pack_rebate_t     * out ) {
     131          45 :   if( FD_UNLIKELY( (s->ib_result==0) & (s->total_cost_rebate==0UL) & (s->writer_cnt==0U) ) ) return 0UL;
     132          36 :   out->total_cost_rebate       = s->total_cost_rebate;          s->total_cost_rebate       = 0UL;
     133          36 :   out->vote_cost_rebate        = s->vote_cost_rebate;           s->vote_cost_rebate        = 0UL;
     134          36 :   out->data_bytes_rebate       = s->data_bytes_rebate;          s->data_bytes_rebate       = 0UL;
     135          36 :   out->microblock_cnt_rebate   = s->microblock_cnt_rebate;      s->microblock_cnt_rebate   = 0UL;
     136          36 :   out->ib_result               = s->ib_result;                  s->ib_result               = 0;
     137             : 
     138          36 :   out->writer_cnt = 0U;
     139          36 :   ulong writer_cnt = fd_ulong_min( s->writer_cnt, 1637UL );
     140       12018 :   for( ulong i=0UL; i<writer_cnt; i++ ) {
     141       11982 :     fd_pack_rebate_entry_t * e = s->inserted[ --(s->writer_cnt) ];
     142       11982 :     out->writer_rebates[ out->writer_cnt++ ] = *e;
     143       11982 :     rmap_remove( s->map, e );
     144       11982 :   }
     145             : 
     146          36 :   return sizeof(*out)-sizeof(fd_pack_rebate_entry_t)+(out->writer_cnt)*sizeof(fd_pack_rebate_entry_t);
     147          45 : }
     148             : 
     149             : void
     150           0 : fd_pack_rebate_sum_clear( fd_pack_rebate_sum_t * s ) {
     151           0 :   s->total_cost_rebate       = 0UL;
     152           0 :   s->vote_cost_rebate        = 0UL;
     153           0 :   s->data_bytes_rebate       = 0UL;
     154           0 :   s->microblock_cnt_rebate   = 0UL;
     155           0 :   s->ib_result               = 0;
     156             : 
     157           0 :   ulong writer_cnt = s->writer_cnt;
     158           0 :   for( ulong i=0UL; i<writer_cnt; i++ ) {
     159           0 :     fd_pack_rebate_entry_t * e = s->inserted[ --(s->writer_cnt) ];
     160           0 :     rmap_remove( s->map, e );
     161           0 :   }
     162           0 : }

Generated by: LCOV version 1.14