Line data Source code
1 : #include "fd_hashes.h"
2 : #include "fd_acc_mgr.h"
3 : #include "fd_bank.h"
4 : #include "context/fd_capture_ctx.h"
5 : #include "../capture/fd_solcap_writer.h"
6 : #include "../../ballet/blake3/fd_blake3.h"
7 : #include "../../ballet/lthash/fd_lthash.h"
8 : #include "../../ballet/sha256/fd_sha256.h"
9 : #include "fd_txn_account.h"
10 :
11 : void
12 : fd_hashes_account_lthash( fd_pubkey_t const * pubkey,
13 : fd_account_meta_t const * account,
14 : uchar const * data,
15 924 : fd_lthash_value_t * lthash_out ) {
16 924 : fd_lthash_zero( lthash_out );
17 :
18 : /* Accounts with zero lamports are not included in the hash, so they should always be treated as zero */
19 924 : if( FD_UNLIKELY( account->lamports == 0 ) ) {
20 9 : return;
21 9 : }
22 :
23 915 : uchar executable = account->executable & 0x1;
24 :
25 915 : fd_blake3_t b3[1];
26 915 : fd_blake3_init( b3 );
27 915 : fd_blake3_append( b3, &account->lamports, sizeof( ulong ) );
28 915 : fd_blake3_append( b3, data, account->dlen );
29 915 : fd_blake3_append( b3, &executable, sizeof( uchar ) );
30 915 : fd_blake3_append( b3, account->owner, FD_PUBKEY_FOOTPRINT );
31 915 : fd_blake3_append( b3, pubkey, FD_PUBKEY_FOOTPRINT );
32 915 : fd_blake3_fini_2048( b3, lthash_out->bytes );
33 915 : }
34 :
35 : void
36 : fd_hashes_hash_bank( fd_lthash_value_t const * lthash,
37 : fd_hash_t const * prev_bank_hash,
38 : fd_hash_t const * last_blockhash,
39 : ulong signature_count,
40 0 : fd_hash_t * hash_out ) {
41 :
42 : /* The bank hash for a slot is a sha256 of two sub-hashes:
43 : sha256(
44 : sha256( previous bank hash, signature count, last PoH blockhash ),
45 : lthash of the accounts modified in this slot
46 : )
47 : */
48 0 : fd_sha256_t sha;
49 0 : fd_sha256_init( &sha );
50 0 : fd_sha256_append( &sha, prev_bank_hash, sizeof( fd_hash_t ) );
51 0 : fd_sha256_append( &sha, (uchar const *) &signature_count, sizeof( ulong ) );
52 0 : fd_sha256_append( &sha, (uchar const *) last_blockhash, sizeof( fd_hash_t ) );
53 0 : fd_sha256_fini( &sha, hash_out->hash );
54 :
55 0 : fd_sha256_init( &sha );
56 0 : fd_sha256_append( &sha, (uchar const *) hash_out->hash, sizeof(fd_hash_t) );
57 0 : fd_sha256_append( &sha, (uchar const *) lthash->bytes, sizeof(fd_lthash_value_t) );
58 0 : fd_sha256_fini( &sha, hash_out->hash );
59 0 : }
60 :
61 : void
62 : fd_hashes_update_lthash( fd_txn_account_t const * account,
63 : fd_lthash_value_t const * prev_account_hash,
64 : fd_bank_t * bank,
65 462 : fd_capture_ctx_t * capture_ctx ) {
66 :
67 : /* Subtract the old hash of the account from the bank lthash */
68 462 : fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) );
69 462 : fd_lthash_sub( bank_lthash, prev_account_hash );
70 :
71 : /* Hash the new version of the account */
72 462 : fd_lthash_value_t new_hash[1];
73 462 : fd_account_meta_t const * meta = fd_txn_account_get_meta( account );
74 462 : fd_hashes_account_lthash( account->pubkey, meta, fd_txn_account_get_data( account ), new_hash );
75 :
76 : /* Add the new hash of the account to the bank lthash */
77 462 : fd_lthash_add( bank_lthash, new_hash );
78 :
79 462 : fd_bank_lthash_end_locking_modify( bank );
80 :
81 : /* Write the new account state to the capture file */
82 462 : if( capture_ctx && capture_ctx->capture && fd_bank_slot_get( bank )>=capture_ctx->solcap_start_slot ) {
83 0 : fd_solana_account_meta_t meta = fd_txn_account_get_solana_meta( account );
84 0 : int err = fd_solcap_write_account(
85 0 : capture_ctx->capture,
86 0 : account->pubkey,
87 0 : &meta,
88 0 : fd_txn_account_get_data( account ),
89 0 : fd_txn_account_get_data_len( account ) );
90 0 : if( FD_UNLIKELY( err ) ) {
91 0 : FD_LOG_ERR(( "Failed to write account to capture file" ));
92 0 : }
93 0 : }
94 462 : }
|