Line data Source code
1 : #include "fd_hashes.h"
2 : #include "fd_acc_mgr.h"
3 : #include "fd_bank.h"
4 : #include "../capture/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 1098 : fd_lthash_value_t * lthash_out ) {
16 1098 : fd_hashes_account_lthash_simple( pubkey->uc,
17 1098 : account->owner,
18 1098 : account->lamports,
19 1098 : account->executable,
20 1098 : data,
21 1098 : account->dlen,
22 1098 : lthash_out );
23 1098 : }
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 : uchar executable,
30 : uchar const * data,
31 : ulong data_len,
32 1098 : fd_lthash_value_t * lthash_out ) {
33 1098 : fd_lthash_zero( lthash_out );
34 :
35 : /* Accounts with zero lamports are not included in the hash, so they should always be treated as zero */
36 1098 : if( FD_UNLIKELY( lamports == 0 ) ) {
37 27 : return;
38 27 : }
39 :
40 1071 : uchar executable_flag = executable & 0x1;
41 :
42 1071 : fd_blake3_t b3[1];
43 1071 : fd_blake3_init( b3 );
44 1071 : fd_blake3_append( b3, &lamports, sizeof( ulong ) );
45 1071 : fd_blake3_append( b3, data, data_len );
46 1071 : fd_blake3_append( b3, &executable_flag, sizeof( uchar ) );
47 1071 : fd_blake3_append( b3, owner, FD_HASH_FOOTPRINT );
48 1071 : fd_blake3_append( b3, pubkey, FD_HASH_FOOTPRINT );
49 1071 : fd_blake3_fini_2048( b3, lthash_out->bytes );
50 1071 : }
51 :
52 : void
53 : fd_hashes_hash_bank( fd_lthash_value_t const * lthash,
54 : fd_hash_t const * prev_bank_hash,
55 : fd_hash_t const * last_blockhash,
56 : ulong signature_count,
57 0 : fd_hash_t * hash_out ) {
58 :
59 : /* The bank hash for a slot is a sha256 of two sub-hashes:
60 : sha256(
61 : sha256( previous bank hash, signature count, last PoH blockhash ),
62 : lthash of the accounts modified in this slot
63 : )
64 : */
65 0 : fd_sha256_t sha;
66 0 : fd_sha256_init( &sha );
67 0 : fd_sha256_append( &sha, prev_bank_hash, sizeof( fd_hash_t ) );
68 0 : fd_sha256_append( &sha, (uchar const *) &signature_count, sizeof( ulong ) );
69 0 : fd_sha256_append( &sha, (uchar const *) last_blockhash, sizeof( fd_hash_t ) );
70 0 : fd_sha256_fini( &sha, hash_out->hash );
71 :
72 0 : fd_sha256_init( &sha );
73 0 : fd_sha256_append( &sha, (uchar const *) hash_out->hash, sizeof(fd_hash_t) );
74 0 : fd_sha256_append( &sha, (uchar const *) lthash->bytes, sizeof(fd_lthash_value_t) );
75 0 : fd_sha256_fini( &sha, hash_out->hash );
76 0 : }
77 :
78 : void
79 : fd_hashes_update_lthash( fd_pubkey_t const * pubkey,
80 : fd_account_meta_t const * meta,
81 : fd_lthash_value_t const * prev_account_hash,
82 : fd_bank_t * bank,
83 549 : fd_capture_ctx_t * capture_ctx ) {
84 :
85 : /* Hash the new version of the account */
86 549 : fd_lthash_value_t new_hash[1];
87 549 : fd_hashes_account_lthash( pubkey, meta, fd_account_data( meta ), new_hash );
88 :
89 : /* Subtract the old hash of the account from the bank lthash */
90 549 : fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) );
91 549 : fd_lthash_sub( bank_lthash, prev_account_hash );
92 :
93 : /* Add the new hash of the account to the bank lthash */
94 549 : fd_lthash_add( bank_lthash, new_hash );
95 :
96 549 : fd_bank_lthash_end_locking_modify( bank );
97 :
98 549 : if( capture_ctx && capture_ctx->capture &&
99 549 : fd_bank_slot_get( bank )>=capture_ctx->solcap_start_slot ) {
100 0 : fd_solana_account_meta_t solana_meta[1];
101 0 : fd_solana_account_meta_init(
102 0 : solana_meta,
103 0 : meta->lamports,
104 0 : meta->owner,
105 0 : meta->executable
106 0 : );
107 0 : fd_capture_link_write_account_update(
108 0 : capture_ctx,
109 0 : capture_ctx->current_txn_idx,
110 0 : pubkey,
111 0 : solana_meta,
112 0 : fd_bank_slot_get( bank ),
113 0 : fd_account_data( meta ),
114 0 : meta->dlen );
115 0 : }
116 549 : }
|