LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_hashes.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 91 102 89.2 %
Date: 2026-10-22 04:28:21 Functions: 9 9 100.0 %

          Line data    Source code
       1             : #include "fd_hashes.h"
       2             : #include "fd_bank.h"
       3             : #include "../../ballet/sha256/fd_sha256.h"
       4             : #include "../capture/fd_capture_ctx.h"
       5             : 
       6             : static fd_blake3_t *
       7             : account_lthash_init( fd_blake3_t * b3,
       8             :                      uchar const   pubkey[ static FD_HASH_FOOTPRINT ],
       9             :                      uchar const   owner[ static FD_HASH_FOOTPRINT ],
      10             :                      ulong         lamports,
      11             :                      int           executable,
      12             :                      uchar const * data,
      13      127215 :                      ulong         data_len ) {
      14      127215 :   uchar executable_flag = !!executable;
      15             : 
      16      127215 :   fd_blake3_init( b3 );
      17      127215 :   fd_blake3_append( b3, &lamports, sizeof( ulong ) );
      18      127215 :   fd_blake3_append( b3, data, data_len );
      19      127215 :   fd_blake3_append( b3, &executable_flag, sizeof( uchar ) );
      20      127215 :   fd_blake3_append( b3, owner, FD_HASH_FOOTPRINT );
      21      127215 :   fd_blake3_append( b3, pubkey, FD_HASH_FOOTPRINT );
      22      127215 :   return b3;
      23      127215 : }
      24             : 
      25             : void
      26             : fd_hashes_account_lthash_simple( uchar const         pubkey[ static FD_HASH_FOOTPRINT ],
      27             :                                  uchar const         owner[ static FD_HASH_FOOTPRINT ],
      28             :                                  ulong               lamports,
      29             :                                  int                 executable,
      30             :                                  uchar const *       data,
      31             :                                  ulong               data_len,
      32       35490 :                                  fd_lthash_value_t * lthash_out ) {
      33       35490 :   if( FD_UNLIKELY( !lamports ) ) {
      34        2007 :     fd_lthash_zero( lthash_out );
      35        2007 :     return;
      36        2007 :   }
      37             : 
      38       33483 :   fd_blake3_t b3[1];
      39       33483 :   fd_blake3_fini_2048( account_lthash_init( b3, pubkey, owner, lamports, executable, data, data_len ), lthash_out->bytes );
      40       33483 : }
      41             : 
      42             : void
      43             : fd_hashes_account_lthash_xn( ulong                 n,
      44             :                              uchar const * const * pubkey,
      45             :                              uchar const * const * owner,
      46             :                              ulong const *         lamports,
      47             :                              int const *           executable,
      48             :                              uchar const * const * data,
      49             :                              ulong const *         data_len,
      50       45300 :                              fd_lthash_value_t **  lthash_out ) {
      51       45300 :   fd_blake3_t   b3  [ FD_BLAKE3_XN_MAX ];
      52       45300 :   fd_blake3_t * sha [ FD_BLAKE3_XN_MAX ];
      53       45300 :   void *        hash[ FD_BLAKE3_XN_MAX ];
      54       45300 :   ulong         m = 0UL;
      55             : 
      56      142317 :   for( ulong i=0UL; i<n; i++ ) {
      57       97017 :     if( FD_UNLIKELY( !lamports[ i ] ) ) {
      58        3285 :       fd_lthash_zero( lthash_out[ i ] );
      59        3285 :       continue;
      60        3285 :     }
      61             : 
      62       93732 :     sha [ m ] = account_lthash_init( b3+m, pubkey[ i ], owner[ i ], lamports[ i ], executable[ i ], data[ i ], data_len[ i ] );
      63       93732 :     hash[ m ] = lthash_out[ i ]->bytes;
      64       93732 :     m++;
      65       93732 :   }
      66             : 
      67       45300 :   if( FD_LIKELY( m ) ) fd_blake3_fini_2048_xn( m, sha, hash );
      68       45300 : }
      69             : 
      70             : void
      71             : fd_hashes_hash_bank( fd_lthash_value_t const * lthash,
      72             :                      fd_hash_t const *         prev_bank_hash,
      73             :                      fd_hash_t const *         last_blockhash,
      74             :                      ulong                     signature_count,
      75         423 :                      fd_hash_t *               hash_out ) {
      76             : 
      77             :   /* The bank hash for a slot is a sha256 of two sub-hashes:
      78             :      sha256(
      79             :         sha256( previous bank hash, signature count, last PoH blockhash ),
      80             :         lthash of the accounts modified in this slot
      81             :      )
      82             :   */
      83         423 :   fd_sha256_t sha;
      84         423 :   fd_sha256_init( &sha );
      85         423 :   fd_sha256_append( &sha, prev_bank_hash, sizeof( fd_hash_t ) );
      86         423 :   fd_sha256_append( &sha, (uchar const *) &signature_count, sizeof( ulong ) );
      87         423 :   fd_sha256_append( &sha, (uchar const *) last_blockhash, sizeof( fd_hash_t ) );
      88         423 :   fd_sha256_fini( &sha, hash_out->hash );
      89             : 
      90         423 :   fd_sha256_init( &sha );
      91         423 :   fd_sha256_append( &sha, (uchar const *) hash_out->hash, sizeof(fd_hash_t) );
      92         423 :   fd_sha256_append( &sha, (uchar const *) lthash->bytes,  sizeof(fd_lthash_value_t) );
      93         423 :   fd_sha256_fini( &sha, hash_out->hash );
      94         423 : }
      95             : 
      96             : static void
      97             : update_bank_lthash( fd_bank_t *               bank,
      98             :                     fd_lthash_value_t const * lthash_prev,
      99        9321 :                     fd_lthash_value_t const * lthash_post ) {
     100        9321 :   fd_lthash_value_t delta[1];
     101        9321 :   fd_memcpy( delta, lthash_post, sizeof(fd_lthash_value_t) );
     102        9321 :   fd_lthash_sub( delta, lthash_prev );
     103             : 
     104        9321 :   fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
     105        9321 :   fd_lthash_add( bank_lthash, delta );
     106        9321 :   fd_bank_lthash_end_locking_modify( bank );
     107        9321 : }
     108             : 
     109             : void
     110             : fd_hashes_update_simple( fd_lthash_value_t *       lthash_post, /* out */
     111             :                          fd_lthash_value_t const * lthash_prev, /* in */
     112             :                          uchar const               pubkey[ static FD_HASH_FOOTPRINT ],
     113             :                          uchar const               owner[ static FD_HASH_FOOTPRINT ],
     114             :                          ulong                     lamports,
     115             :                          int                       executable,
     116             :                          uchar const *             data,
     117             :                          ulong                     data_len,
     118             :                          fd_bank_t               * bank,
     119          30 :                          fd_capture_ctx_t        * capture_ctx ) {
     120             :   /* Compute the new hash of the account */
     121          30 :   fd_hashes_account_lthash_simple( pubkey, owner, lamports, executable, data, data_len, lthash_post );
     122             : 
     123          30 :   update_bank_lthash( bank, lthash_prev, lthash_post );
     124          30 :   fd_hashes_capture_account( pubkey, owner, lamports, executable, data, data_len, bank, capture_ctx );
     125          30 : }
     126             : 
     127             : void
     128             : fd_hashes_update_pair( uchar const        pubkey[ static FD_HASH_FOOTPRINT ],
     129             :                        uchar const        prev_owner[ static FD_HASH_FOOTPRINT ],
     130             :                        ulong              prev_lamports,
     131             :                        int                prev_executable,
     132             :                        uchar const *      prev_data,
     133             :                        ulong              prev_data_len,
     134             :                        uchar const        owner[ static FD_HASH_FOOTPRINT ],
     135             :                        ulong              lamports,
     136             :                        int                executable,
     137             :                        uchar const *      data,
     138             :                        ulong              data_len,
     139             :                        fd_bank_t *        bank,
     140        9291 :                        fd_capture_ctx_t * capture_ctx ) {
     141        9291 :   fd_lthash_value_t   lthash_prev[1];
     142        9291 :   fd_lthash_value_t   lthash_post[1];
     143        9291 :   uchar const *       pk [2] = { pubkey,          pubkey     };
     144        9291 :   uchar const *       ow [2] = { prev_owner,      owner      };
     145        9291 :   ulong               la [2] = { prev_lamports,   lamports   };
     146        9291 :   int                 ex [2] = { prev_executable, executable };
     147        9291 :   uchar const *       da [2] = { prev_data,       data       };
     148        9291 :   ulong               dl [2] = { prev_data_len,   data_len   };
     149        9291 :   fd_lthash_value_t * out[2] = { lthash_prev,     lthash_post };
     150        9291 :   fd_hashes_account_lthash_xn( 2UL, pk, ow, la, ex, da, dl, out );
     151             : 
     152        9291 :   update_bank_lthash( bank, lthash_prev, lthash_post );
     153        9291 :   fd_hashes_capture_account( pubkey, owner, lamports, executable, data, data_len, bank, capture_ctx );
     154        9291 : }
     155             : 
     156             : void
     157             : fd_hashes_capture_account( uchar const        pubkey[ static FD_HASH_FOOTPRINT ],
     158             :                            uchar const        owner[ static FD_HASH_FOOTPRINT ],
     159             :                            ulong              lamports,
     160             :                            int                executable,
     161             :                            uchar const *      data,
     162             :                            ulong              data_len,
     163             :                            fd_bank_t *        bank,
     164       37872 :                            fd_capture_ctx_t * capture_ctx ) {
     165       37872 :   if( FD_LIKELY( !capture_ctx ||
     166       37872 :                  !capture_ctx->capture_solcap ||
     167       37872 :                  bank->f.slot<capture_ctx->solcap_start_slot ) ) return;
     168             : 
     169           0 :   fd_solana_account_meta_t solana_meta[1];
     170           0 :   fd_solana_account_meta_init( solana_meta, lamports, owner, executable );
     171           0 :   fd_capture_link_write_account_update(
     172           0 :     capture_ctx,
     173           0 :     capture_ctx->current_txn_idx,
     174           0 :     (fd_pubkey_t const *)pubkey,
     175           0 :     solana_meta,
     176           0 :     bank->f.slot,
     177           0 :     data,
     178           0 :     data_len );
     179           0 : }
     180             : 
     181             : void
     182             : fd_hashes_apply_hard_forks( fd_hash_t *            hash,
     183             :                             ulong                  slot,
     184             :                             ulong                  parent_slot,
     185             :                             fd_hard_fork_t const * hard_forks,
     186         432 :                             ulong                  hard_fork_cnt ) {
     187         432 :   ulong sum = 0UL;
     188         456 :   for( ulong i=0UL; i<hard_fork_cnt; i++ ) {
     189          24 :     if( FD_UNLIKELY( parent_slot<hard_forks[ i ].slot && hard_forks[ i ].slot<=slot ) ) sum += hard_forks[ i ].cnt;
     190          24 :   }
     191             : 
     192         432 :   if( FD_UNLIKELY( !sum ) ) return;
     193             : 
     194           9 :   ulong sum_le[ 1 ];
     195           9 :   FD_STORE( ulong, sum_le, sum );
     196             : 
     197           9 :   fd_sha256_t sha;
     198           9 :   fd_sha256_init( &sha );
     199           9 :   fd_sha256_append( &sha, hash->hash, sizeof(fd_hash_t) );
     200           9 :   fd_sha256_append( &sha, sum_le,     sizeof(ulong)     );
     201           9 :   fd_sha256_fini( &sha, hash->hash );
     202           9 : }

Generated by: LCOV version 1.14