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 */