LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_bank_hash_cmp.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 176 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "fd_bank_hash_cmp.h"
       2             : #include <unistd.h>
       3             : 
       4             : void *
       5           0 : fd_bank_hash_cmp_new( void * mem ) {
       6             : 
       7           0 :   if( FD_UNLIKELY( !mem ) ) {
       8           0 :     FD_LOG_WARNING( ( "NULL mem" ) );
       9           0 :     return NULL;
      10           0 :   }
      11             : 
      12           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_bank_hash_cmp_align() ) ) ) {
      13           0 :     FD_LOG_WARNING( ( "misaligned mem" ) );
      14           0 :     return NULL;
      15           0 :   }
      16             : 
      17           0 :   ulong footprint = fd_bank_hash_cmp_footprint();
      18             : 
      19           0 :   fd_memset( mem, 0, footprint );
      20             : 
      21           0 :   ulong laddr = (ulong)mem;
      22           0 :   laddr += sizeof( fd_bank_hash_cmp_t );
      23             : 
      24           0 :   laddr = fd_ulong_align_up( laddr, fd_bank_hash_cmp_map_align() );
      25           0 :   fd_bank_hash_cmp_map_new( (void *)laddr );
      26           0 :   laddr += fd_bank_hash_cmp_map_footprint();
      27             : 
      28           0 :   laddr = fd_ulong_align_up( laddr, fd_bank_hash_cmp_align() );
      29           0 :   FD_TEST( laddr == (ulong)mem + fd_bank_hash_cmp_footprint() );
      30             : 
      31           0 :   return mem;
      32           0 : }
      33             : 
      34             : fd_bank_hash_cmp_t *
      35           0 : fd_bank_hash_cmp_join( void * bank_hash_cmp ) {
      36           0 :   if( FD_UNLIKELY( !bank_hash_cmp ) ) {
      37           0 :     FD_LOG_WARNING( ( "NULL bank_hash_cmp" ) );
      38           0 :     return NULL;
      39           0 :   }
      40             : 
      41           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)bank_hash_cmp, fd_bank_hash_cmp_align() ) ) ) {
      42           0 :     FD_LOG_WARNING( ( "misaligned bank_hash_cmp" ) );
      43           0 :     return NULL;
      44           0 :   }
      45             : 
      46           0 :   ulong laddr = (ulong)bank_hash_cmp;
      47           0 :   laddr += sizeof( fd_bank_hash_cmp_t );
      48             : 
      49           0 :   fd_bank_hash_cmp_t * bank_hash_cmp_ = (fd_bank_hash_cmp_t *)bank_hash_cmp;
      50           0 :   bank_hash_cmp_->map                 = fd_bank_hash_cmp_map_join( (void *)laddr );
      51             : 
      52           0 :   return bank_hash_cmp;
      53           0 : }
      54             : 
      55             : void *
      56           0 : fd_bank_hash_cmp_leave( fd_bank_hash_cmp_t const * bank_hash_cmp ) {
      57             : 
      58           0 :   if( FD_UNLIKELY( !bank_hash_cmp ) ) {
      59           0 :     FD_LOG_WARNING( ( "NULL bank_hash_cmp" ) );
      60           0 :     return NULL;
      61           0 :   }
      62             : 
      63           0 :   return (void *)bank_hash_cmp;
      64           0 : }
      65             : 
      66             : void *
      67           0 : fd_bank_hash_cmp_delete( void * bank_hash_cmp ) {
      68             : 
      69           0 :   if( FD_UNLIKELY( !bank_hash_cmp ) ) {
      70           0 :     FD_LOG_WARNING( ( "NULL bank_hash_cmp" ) );
      71           0 :     return NULL;
      72           0 :   }
      73             : 
      74           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)bank_hash_cmp, fd_bank_hash_cmp_align() ) ) ) {
      75           0 :     FD_LOG_WARNING( ( "misaligned bank_hash_cmp" ) );
      76           0 :     return NULL;
      77           0 :   }
      78             : 
      79           0 :   return bank_hash_cmp;
      80           0 : }
      81             : 
      82             : void
      83           0 : fd_bank_hash_cmp_lock( fd_bank_hash_cmp_t * bank_hash_cmp ) {
      84           0 :   volatile int * lock = &bank_hash_cmp->lock;
      85           0 : # if FD_HAS_THREADS
      86           0 :   for( ;; ) {
      87           0 :     if( FD_LIKELY( !FD_ATOMIC_CAS( lock, 0UL, 1UL ) ) ) break;
      88           0 :     FD_SPIN_PAUSE();
      89           0 :   }
      90             : # else
      91             :   *lock = 1;
      92             : # endif
      93           0 :   FD_COMPILER_MFENCE();
      94           0 : }
      95             : 
      96             : void
      97           0 : fd_bank_hash_cmp_unlock( fd_bank_hash_cmp_t * bank_hash_cmp ) {
      98           0 :   volatile int * lock = &bank_hash_cmp->lock;
      99           0 :   FD_COMPILER_MFENCE();
     100           0 :   FD_VOLATILE( *lock ) = 0UL;
     101           0 : }
     102             : 
     103             : void
     104             : fd_bank_hash_cmp_insert( fd_bank_hash_cmp_t * bank_hash_cmp,
     105             :                          ulong                slot,
     106             :                          fd_hash_t const *    hash,
     107             :                          int                  ours,
     108           0 :                          ulong                stake ) {
     109           0 :   if( FD_UNLIKELY( slot <= bank_hash_cmp->watermark ) ) { return; }
     110           0 :   fd_bank_hash_cmp_entry_t * cmp = fd_bank_hash_cmp_map_query( bank_hash_cmp->map, slot, NULL );
     111             : 
     112           0 :   if( !cmp ) {
     113             : 
     114             :     /* If full, make room for new bank hashes */
     115             : 
     116           0 :     if( FD_UNLIKELY( bank_hash_cmp->cnt == fd_bank_hash_cmp_map_key_max() ) ) {
     117           0 :       FD_LOG_WARNING( ( "Bank matches unexpectedly full. Clearing. " ) );
     118           0 :       for( ulong i = 0; i < fd_bank_hash_cmp_map_slot_cnt(); i++ ) {
     119           0 :         fd_bank_hash_cmp_entry_t * entry = &bank_hash_cmp->map[i];
     120           0 :         if( FD_LIKELY( !fd_bank_hash_cmp_map_key_inval( entry->slot ) &&
     121           0 :                        entry->slot < bank_hash_cmp->watermark ) ) {
     122           0 :           fd_bank_hash_cmp_map_remove( bank_hash_cmp->map, entry );
     123           0 :           bank_hash_cmp->cnt--;
     124           0 :         }
     125           0 :       }
     126           0 :     }
     127             : 
     128           0 :     cmp      = fd_bank_hash_cmp_map_insert( bank_hash_cmp->map, slot );
     129           0 :     cmp->cnt = 0;
     130           0 :     bank_hash_cmp->cnt++;
     131           0 :   }
     132             : 
     133           0 :   if( FD_UNLIKELY( ours ) ) {
     134           0 :     cmp->ours = *hash;
     135           0 :     return;
     136           0 :   }
     137             : 
     138           0 :   for( ulong i = 0; i < cmp->cnt; i++ ) {
     139           0 :     if( FD_LIKELY( 0 == memcmp( &cmp->theirs[i], hash, sizeof( fd_hash_t ) ) ) ) {
     140           0 :       cmp->stakes[i] += stake;
     141           0 :       return;
     142           0 :     }
     143           0 :   }
     144             : 
     145           0 :   ulong max = sizeof( cmp->stakes ) / sizeof( ulong );
     146           0 :   if( FD_UNLIKELY( cmp->cnt == max ) ) {
     147           0 :     if( !cmp->overflow ) {
     148           0 :       FD_LOG_WARNING(( "[Bank Hash Comparison] more than %lu equivocating hashes for slot %lu. "
     149           0 :                        "new hash: %s. ignoring.",
     150           0 :                        max,
     151           0 :                        slot,
     152           0 :                        FD_BASE58_ENC_32_ALLOCA( hash ) ));
     153           0 :       cmp->overflow = 1;
     154           0 :     }
     155           0 :     return;
     156           0 :   }
     157           0 :   cmp->cnt++;
     158           0 :   cmp->theirs[cmp->cnt - 1] = *hash;
     159           0 :   cmp->stakes[cmp->cnt - 1] = stake;
     160           0 :   if( FD_UNLIKELY( cmp->cnt > 1 ) ) {
     161           0 :     for( ulong i = 0; i < cmp->cnt; i++ ) {
     162           0 :       FD_LOG_WARNING(( "slot: %lu. equivocating hash (#%lu): %s. stake: %lu",
     163           0 :                         cmp->slot,
     164           0 :                         i,
     165           0 :                         FD_BASE58_ENC_32_ALLOCA( cmp->theirs[i].hash ),
     166           0 :                         cmp->stakes[i] ));
     167           0 :     }
     168           0 :   }
     169           0 : }
     170             : 
     171             : int
     172           0 : fd_bank_hash_cmp_check( fd_bank_hash_cmp_t * bank_hash_cmp, ulong slot ) {
     173           0 :   fd_bank_hash_cmp_entry_t * cmp = fd_bank_hash_cmp_map_query( bank_hash_cmp->map, slot, NULL );
     174             : 
     175           0 :   if( FD_UNLIKELY( !cmp ) ) return 0;
     176             : 
     177           0 :   fd_hash_t null_hash = { 0 };
     178           0 :   if( FD_LIKELY( 0 == memcmp( &cmp->ours, &null_hash, sizeof( fd_hash_t ) ) ) ) return 0;
     179             : 
     180           0 :   if( FD_UNLIKELY( cmp->cnt == 0 ) ) return 0;
     181             : 
     182           0 :   fd_hash_t * theirs = &cmp->theirs[0];
     183           0 :   ulong       stake  = cmp->stakes[0];
     184           0 :   for( ulong i = 1; i < cmp->cnt; i++ ) {
     185           0 :     if( FD_UNLIKELY( cmp->stakes[i] > stake ) ) {
     186           0 :       theirs = &cmp->theirs[i];
     187           0 :       stake  = cmp->stakes[i];
     188           0 :     }
     189           0 :   }
     190             : 
     191           0 :   double pct = (double)stake / (double)bank_hash_cmp->total_stake;
     192           0 :   if( FD_LIKELY( pct > 0.52 ) ) {
     193           0 :     if( FD_UNLIKELY( 0 != memcmp( &cmp->ours, theirs, sizeof( fd_hash_t ) ) ) ) {
     194           0 :       FD_LOG_WARNING(( "\n\n[Bank Hash Comparison]\n"
     195           0 :                         "slot:   %lu\n"
     196           0 :                         "ours:   %s\n"
     197           0 :                         "theirs: %s\n"
     198           0 :                         "stake:  %.0lf%%\n"
     199           0 :                         "result: mismatch!\n",
     200           0 :                         cmp->slot,
     201           0 :                         FD_BASE58_ENC_32_ALLOCA( cmp->ours.hash ),
     202           0 :                         FD_BASE58_ENC_32_ALLOCA( theirs->hash ),
     203           0 :                         pct * 100 ));
     204           0 :       if( FD_UNLIKELY( cmp->cnt > 1 ) ) {
     205           0 :         for( ulong i = 0; i < cmp->cnt; i++ ) {
     206           0 :           FD_LOG_WARNING(( "slot: %lu. hash (#%lu): %s. stake: %lu",
     207           0 :                            cmp->slot,
     208           0 :                            i,
     209           0 :                            FD_BASE58_ENC_32_ALLOCA( cmp->theirs[i].hash ),
     210           0 :                            cmp->stakes[i] ));
     211           0 :         }
     212           0 :       }
     213           0 :       return 1;
     214           0 :     } else {
     215           0 :       FD_LOG_NOTICE(( "\n\n[Bank Hash Comparison]\n"
     216           0 :                       "slot:   %lu\n"
     217           0 :                       "ours:   %s\n"
     218           0 :                       "theirs: %s\n"
     219           0 :                       "stake:  %.0lf%%\n"
     220           0 :                       "result: match!\n",
     221           0 :                       cmp->slot,
     222           0 :                       FD_BASE58_ENC_32_ALLOCA( cmp->ours.hash ),
     223           0 :                       FD_BASE58_ENC_32_ALLOCA( theirs->hash ),
     224           0 :                       pct * 100 ));
     225           0 :     }
     226           0 :     fd_bank_hash_cmp_map_remove( bank_hash_cmp->map, cmp );
     227           0 :     bank_hash_cmp->cnt--;
     228           0 :     return 1;
     229           0 :   }
     230           0 :   return 0;
     231           0 : }

Generated by: LCOV version 1.14