Line data Source code
1 : #include "fd_sysvar_slot_hashes.h"
2 : #include "fd_sysvar.h"
3 : #include "../fd_system_ids.h"
4 : #include "../fd_accdb_svm.h"
5 :
6 : void
7 : fd_sysvar_slot_hashes_init( fd_bank_t * bank,
8 : fd_accdb_t * accdb,
9 0 : fd_capture_ctx_t * capture_ctx ) {
10 0 : uchar data[ FD_SYSVAR_SLOT_HASHES_BINCODE_SZ ] = {0};
11 0 : fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_slot_hashes_id, data, FD_SYSVAR_SLOT_HASHES_BINCODE_SZ );
12 0 : }
13 :
14 : void
15 : fd_sysvar_slot_hashes_update( fd_bank_t * bank,
16 : fd_accdb_t * accdb,
17 613 : fd_capture_ctx_t * capture_ctx ) {
18 613 : fd_accdb_svm_update_t update[1];
19 613 : fd_acc_t acc = fd_accdb_svm_open_rw( bank, accdb, update, &fd_sysvar_slot_hashes_id, 0 );
20 613 : if( FD_UNLIKELY( !acc.lamports ) ) {
21 : /* Agave initializes a new empty slot_hashes if it doesn't exist */
22 0 : fd_sysvar_slot_hashes_init( bank, accdb, capture_ctx );
23 0 : acc = fd_accdb_svm_open_rw( bank, accdb, update, &fd_sysvar_slot_hashes_id, 0 );
24 0 : if( FD_UNLIKELY( !acc.lamports ) ) {
25 0 : FD_LOG_ERR(( "state is missing slot hashes sysvar" ));
26 0 : }
27 0 : }
28 613 : if( FD_UNLIKELY( 0!=memcmp( acc.owner, &fd_sysvar_owner_id, sizeof(fd_pubkey_t) ) ) ) {
29 0 : FD_LOG_ERR(( "slot hashes sysvar not owned by sysvar owner" ));
30 0 : }
31 613 : uchar * data = acc.data;
32 613 : ulong data_sz = acc.data_len;
33 613 : if( FD_UNLIKELY( data_sz < FD_SYSVAR_SLOT_HASHES_BINCODE_SZ ) ) {
34 0 : FD_LOG_HEXDUMP_ERR(( "invalid slot hashes sysvar", data, data_sz ));
35 0 : }
36 :
37 613 : ulong cnt = FD_LOAD( ulong, data );
38 613 : if( FD_UNLIKELY( cnt > FD_SYSVAR_SLOT_HASHES_CAP ) ) {
39 0 : FD_LOG_HEXDUMP_ERR(( "corrupt slot hashes sysvar", data, data_sz ));
40 0 : }
41 :
42 : /* Search for existing entry with parent_slot */
43 613 : fd_slot_hash_t * entries = (fd_slot_hash_t *)(data + sizeof(ulong));
44 613 : int found = 0;
45 302246 : for( ulong i=0UL; i<cnt; i++ ) {
46 301633 : if( entries[i].slot == bank->f.parent_slot ) {
47 0 : fd_memcpy( &entries[i].hash, &bank->f.bank_hash, sizeof(fd_hash_t) );
48 0 : found = 1;
49 0 : break;
50 0 : }
51 301633 : }
52 :
53 615 : if( !found ) {
54 615 : ulong keep = fd_ulong_min( cnt, FD_SYSVAR_SLOT_HASHES_CAP - 1UL );
55 615 : memmove( &entries[1], &entries[0], keep * sizeof(fd_slot_hash_t) );
56 615 : entries[0].slot = bank->f.parent_slot;
57 615 : fd_memcpy( &entries[0].hash, &bank->f.bank_hash, sizeof(fd_hash_t) );
58 615 : FD_STORE( ulong, data, keep + 1UL );
59 615 : }
60 :
61 613 : fd_sysvar_adjust_balance_for_rent( bank, &acc );
62 613 : fd_accdb_svm_close_rw( bank, accdb, capture_ctx, &acc, update );
63 613 : }
64 :
65 : int
66 : fd_sysvar_slot_hashes_validate( uchar const * data,
67 36922 : ulong sz ) {
68 36922 : if( FD_UNLIKELY( sz < sizeof(ulong) ) ) return 0;
69 36922 : ulong cnt = FD_LOAD( ulong, data );
70 36922 : if( FD_UNLIKELY( cnt > FD_SYSVAR_SLOT_HASHES_CAP ) ) return 0;
71 36892 : if( FD_UNLIKELY( sz < sizeof(ulong) + cnt*sizeof(fd_slot_hash_t) ) ) return 0;
72 36892 : return 1;
73 36892 : }
74 :
75 : fd_slot_hashes_t *
76 : fd_sysvar_slot_hashes_view( fd_slot_hashes_t * view,
77 : uchar const * data,
78 9393 : ulong sz ) {
79 9393 : if( FD_UNLIKELY( !fd_sysvar_slot_hashes_validate( data, sz ) ) ) return NULL;
80 9393 : ulong cnt = FD_LOAD( ulong, data );
81 9393 : view->elems = (fd_slot_hash_t const *)( data + sizeof(ulong) );
82 9393 : view->cnt = cnt;
83 9393 : return view;
84 9393 : }
|