LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_hashes.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 4 4 100.0 %
Date: 2026-05-27 08:23:31 Functions: 2 78 2.6 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_fd_hashes_h
       2             : #define HEADER_fd_src_flamenco_runtime_fd_hashes_h
       3             : 
       4             : #include "../fd_flamenco_base.h"
       5             : #include "../../ballet/lthash/fd_lthash.h"
       6             : 
       7             : /* fd_hashes.h provides functions for computing and updating the bank hash
       8             :    for a completed slot.  The bank hash is a cryptographic hash of the
       9             :    slot's state including all account modifications and transaction
      10             :    signatures.
      11             : 
      12             :    The bank hash is computed as:
      13             :      sha256( sha256( prev_bank_hash || signature_count || last_blockhash ) || lthash )
      14             : 
      15             :    Where:
      16             :    - lthash is the cumulative lattice hash of all accounts
      17             :    - prev_bank_hash is the bank hash of the parent slot
      18             :    - last_blockhash is the last proof-of-history blockhash
      19             :    - signature_count is the number of signatures processed in the slot
      20             : 
      21             :    To compute the lthash, whenever any account is modified during transaction
      22             :    execution, we must remove the old version of the account hash from the
      23             :    cumulative lthash, hash the account, and add the new hash to the lthash.
      24             : */
      25             : 
      26             : 
      27             : FD_PROTOTYPES_BEGIN
      28             : 
      29             : /* fd_hashes_account_lthash computes the lattice hash (lthash) of a
      30             :    single account for use in the bank hash calculation.  The lthash is a
      31             :    cryptographic hash that supports incremental updates via addition and
      32             :    subtraction operations.
      33             : 
      34             :    For accounts with non-zero lamports, the hash is computed as:
      35             :      blake3( lamports || data || executable || owner || pubkey )
      36             : 
      37             :    For accounts with zero lamports, the hash is zero (these accounts are
      38             :    excluded from the bank hash).
      39             : 
      40             :    pubkey points to the account's public key (32 bytes).  account points
      41             :    to the account metadata containing lamports, data length, executable
      42             :    flag, and owner.  data points to the account data of size
      43             :    account->dlen bytes.  lthash_out points to where the computed lthash
      44             :    value will be written (FD_LTHASH_LEN_BYTES).
      45             : 
      46             :    On return, lthash_out contains the computed lthash.  For zero-lamport
      47             :    accounts, lthash_out will be zeroed via fd_lthash_zero.
      48             : 
      49             :    This function assumes all pointers are valid and properly aligned.
      50             :    The account data pointer must be readable for account->dlen bytes. */
      51             : 
      52             : void
      53             : fd_hashes_account_lthash( fd_pubkey_t const       * pubkey,
      54             :                           fd_account_meta_t const * account,
      55             :                           uchar const             * data,
      56             :                           fd_lthash_value_t *       lthash_out );
      57             : 
      58             : /* fd_hashes_account_lthash_simple is functionally the same as
      59             :    fd_hashes_account_lthash, but with simpler arguments that detail
      60             :    the exact parameters that go into the lthash.
      61             : 
      62             :    pubkey points to the account's public key (32 bytes).  owner points
      63             :    to the account's owner (32 bytes).  lamports is the account's
      64             :    lamports.  executable is the account's executable flag.  data points
      65             :    to the account data.  data_len is the length of the account data.
      66             :    lthash_out points to where the computed lthash value will be written
      67             :    (2048 bytes).
      68             : 
      69             :    On return, lthash_out contains the computed lthash.  This function
      70             :    assumes all pointers are valid and properly aligned.  The account
      71             :    data pointer must be readable for data_len bytes. */
      72             : void
      73             : fd_hashes_account_lthash_simple( uchar const         pubkey[ static FD_HASH_FOOTPRINT ],
      74             :                                  uchar const         owner[ static FD_HASH_FOOTPRINT ],
      75             :                                  ulong               lamports,
      76             :                                  uchar               executable,
      77             :                                  uchar const *       data,
      78             :                                  ulong               data_len,
      79             :                                  fd_lthash_value_t * lthash_out );
      80             : 
      81             : /* fd_hashes_update_lthash updates the bank's incremental lthash when an
      82             :    account is modified during transaction execution.  The bank lthash is
      83             :    maintained incrementally by subtracting the old account hash and
      84             :    adding the new account hash.
      85             : 
      86             :    meta is a pointer to the modified account's metadata and data.
      87             :    prev_hash contains the lthash of the account before modification (or
      88             :    zero for newly created accounts).  bank is the bank whose lthash
      89             :    should be updated.  capture_ctx is an optional capture context for
      90             :    recording account changes (can be NULL).
      91             : 
      92             :    This function:
      93             :    - Acquires a write lock on the bank's lthash
      94             :    - Subtracts prev_hash from the bank lthash
      95             :    - Computes the new account hash
      96             :    - Adds the new hash to the bank lthash
      97             :    - Releases the lock
      98             :    - If capture_ctx is provided, writes the account state to the capture
      99             : 
     100             :    On capture write failure, the function will FD_LOG_ERR and terminate.
     101             :    The function assumes all non-optional pointers are valid.
     102             : 
     103             :    IMPORTANT: fd_hashes_update_lthash, or fd_hashes_update_lthash_from_funk,
     104             :    must be called whenever an account is modified during transaction
     105             :    execution. This includes sysvar accounts. */
     106             : 
     107             : void
     108             : fd_hashes_update_lthash1( fd_lthash_value_t *       lthash_post, /* out */
     109             :                           fd_lthash_value_t const * lthash_prev, /* in */
     110             :                           fd_pubkey_t const *       pubkey,
     111             :                           fd_account_meta_t const * meta,
     112             :                           fd_bank_t               * bank,
     113             :                           fd_capture_ctx_t        * capture_ctx );
     114             : 
     115             : FD_FN_UNUSED static void
     116             : fd_hashes_update_lthash( fd_pubkey_t const *       pubkey,
     117             :                          fd_account_meta_t const * meta,
     118             :                          fd_lthash_value_t const * prev_account_hash,
     119             :                          fd_bank_t               * bank,
     120        4719 :                          fd_capture_ctx_t        * capture_ctx ) {
     121        4719 :   fd_lthash_value_t post[1];
     122        4719 :   fd_hashes_update_lthash1( post, prev_account_hash, pubkey, meta, bank, capture_ctx );
     123        4719 : }
     124             : 
     125             : /* fd_hashes_hash_bank computes the bank hash for a completed slot.  The
     126             :    bank hash is a deterministic hash of the slot's state including all
     127             :    account modifications and transaction signatures.
     128             : 
     129             :    The hash is computed as:
     130             :      sha256( sha256( prev_bank_hash || signature_count || last_blockhash ) || lthash )
     131             : 
     132             :    Where:
     133             :    - lthash is the cumulative lattice hash of all accounts
     134             :    - prev_bank_hash is the bank hash of the parent slot
     135             :    - last_blockhash is the last proof-of-history blockhash
     136             :    - signature_count is the number of signatures processed in the slot
     137             : 
     138             :    The resulting bank hash is written to hash_out.
     139             : */
     140             : 
     141             : void
     142             : fd_hashes_hash_bank( fd_lthash_value_t const * lthash,
     143             :                      fd_hash_t const *        prev_bank_hash,
     144             :                      fd_hash_t const *        last_blockhash,
     145             :                      ulong                    signature_count,
     146             :                      fd_hash_t *              hash_out );
     147             : 
     148             : /* fd_hashes_apply_hard_forks mixes hard-fork data into an existing bank
     149             :    hash in place, matching Agave's bank hash computation.
     150             : 
     151             :    For each registered hard fork i where
     152             :      parent_slot < hard_forks[i].slot <= slot,
     153             :    the fork's count is summed.  If the sum is non-zero, the hash is updated:
     154             :      hash = sha256( hash || sum_as_u64_le )
     155             : 
     156             :    hash is mutated in place.  slot and parent_slot are the slot and parent
     157             :    slot of the bank being finalized.  If hard_fork_cnt is zero or no
     158             :    forks are in range, hash is unchanged. */
     159             : 
     160             : void
     161             : fd_hashes_apply_hard_forks( fd_hash_t *            hash,
     162             :                             ulong                  slot,
     163             :                             ulong                  parent_slot,
     164             :                             fd_hard_fork_t const * hard_forks,
     165             :                             ulong                  hard_fork_cnt );
     166             : 
     167             : FD_PROTOTYPES_END
     168             : 
     169             : #endif /* HEADER_fd_src_flamenco_runtime_fd_hashes_h */

Generated by: LCOV version 1.14