Line data Source code
1 : #include "fd_sysvar_slot_hashes.h" 2 : #include "fd_sysvar.h" 3 : #include "../fd_acc_mgr.h" 4 : #include "../fd_borrowed_account.h" 5 : #include "../fd_system_ids.h" 6 : #include "../context/fd_exec_slot_ctx.h" 7 : 8 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_hashes.rs#L11 */ 9 : const ulong slot_hashes_max_entries = 512; 10 : 11 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/sysvar/slot_hashes.rs#L12 */ 12 : const ulong slot_hashes_min_account_size = 20488; 13 : 14 10368 : void write_slot_hashes( fd_exec_slot_ctx_t * slot_ctx, fd_slot_hashes_t* slot_hashes ) { 15 10368 : ulong sz = fd_slot_hashes_size( slot_hashes ); 16 10368 : if (sz < slot_hashes_min_account_size) 17 10368 : sz = slot_hashes_min_account_size; 18 10368 : uchar enc[sz]; 19 10368 : fd_memset( enc, 0, sz ); 20 10368 : fd_bincode_encode_ctx_t ctx; 21 10368 : ctx.data = enc; 22 10368 : ctx.dataend = enc + sz; 23 10368 : if ( fd_slot_hashes_encode( slot_hashes, &ctx ) ) 24 0 : FD_LOG_ERR(("fd_slot_hashes_encode failed")); 25 : 26 10368 : fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_slot_hashes_id, enc, sz, slot_ctx->slot_bank.slot ); 27 10368 : } 28 : 29 10368 : void fd_sysvar_slot_hashes_init( fd_exec_slot_ctx_t * slot_ctx, fd_slot_hashes_t * slot_hashes ) { 30 10368 : write_slot_hashes( slot_ctx, slot_hashes ); 31 10368 : } 32 : 33 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_hashes.rs#L34 */ 34 : void 35 0 : fd_sysvar_slot_hashes_update( fd_exec_slot_ctx_t * slot_ctx ) { 36 0 : FD_SCRATCH_SCOPE_BEGIN { 37 : 38 0 : fd_slot_hashes_t slot_hashes; 39 0 : if( !fd_sysvar_slot_hashes_read( &slot_hashes, slot_ctx ) ) { 40 0 : slot_hashes.hashes = deq_fd_slot_hash_t_alloc( slot_ctx->valloc, FD_SYSVAR_SLOT_HASHES_CAP ); 41 0 : FD_TEST( slot_hashes.hashes ); 42 0 : } 43 : 44 0 : fd_slot_hash_t * hashes = slot_hashes.hashes; 45 : 46 0 : uchar found = 0; 47 0 : for ( deq_fd_slot_hash_t_iter_t iter = deq_fd_slot_hash_t_iter_init( hashes ); 48 0 : !deq_fd_slot_hash_t_iter_done( hashes, iter ); 49 0 : iter = deq_fd_slot_hash_t_iter_next( hashes, iter ) ) { 50 0 : fd_slot_hash_t * ele = deq_fd_slot_hash_t_iter_ele( hashes, iter ); 51 0 : if ( ele->slot == slot_ctx->slot_bank.slot ) { 52 0 : memcpy( &ele->hash, &slot_ctx->slot_bank.banks_hash, sizeof(fd_hash_t) ); 53 0 : found = 1; 54 0 : } 55 0 : } 56 : 57 0 : if ( !found ) { 58 : // https://github.com/firedancer-io/solana/blob/08a1ef5d785fe58af442b791df6c4e83fe2e7c74/runtime/src/bank.rs#L2371 59 0 : fd_slot_hash_t slot_hash = { 60 0 : .hash = slot_ctx->slot_bank.banks_hash, // parent hash? 61 0 : .slot = slot_ctx->slot_bank.prev_slot, // parent_slot 62 0 : }; 63 0 : FD_LOG_DEBUG(( "fd_sysvar_slot_hash_update: slot %lu, hash %s", slot_hash.slot, FD_BASE58_ENC_32_ALLOCA( slot_hash.hash.key ) )); 64 0 : fd_bincode_destroy_ctx_t ctx2 = { .valloc = slot_ctx->valloc }; 65 : 66 0 : if (deq_fd_slot_hash_t_full( hashes ) ) 67 0 : fd_slot_hash_destroy( deq_fd_slot_hash_t_pop_tail_nocopy( hashes ), &ctx2 ); 68 : 69 0 : deq_fd_slot_hash_t_push_head( hashes, slot_hash ); 70 0 : } 71 : 72 0 : write_slot_hashes( slot_ctx, &slot_hashes ); 73 0 : fd_bincode_destroy_ctx_t ctx = { .valloc = slot_ctx->valloc }; 74 0 : fd_slot_hashes_destroy( &slot_hashes, &ctx ); 75 0 : } FD_SCRATCH_SCOPE_END; 76 0 : } 77 : 78 : fd_slot_hashes_t * 79 : fd_sysvar_slot_hashes_read( fd_slot_hashes_t * result, 80 0 : fd_exec_slot_ctx_t * slot_ctx ) { 81 : 82 : // FD_LOG_INFO(( "SysvarS1otHashes111111111111111111111111111 at slot %lu: " FD_LOG_HEX16_FMT, slot_ctx->slot_bank.slot, FD_LOG_HEX16_FMT_ARGS( metadata.hash ) )); 83 : 84 0 : FD_BORROWED_ACCOUNT_DECL(rec); 85 0 : int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, (fd_pubkey_t const *)&fd_sysvar_slot_hashes_id, rec ); 86 0 : if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) 87 0 : return NULL; 88 : 89 0 : fd_bincode_decode_ctx_t decode = { 90 0 : .data = rec->const_data, 91 0 : .dataend = rec->const_data + rec->const_meta->dlen, 92 0 : .valloc = slot_ctx->valloc /* !!! There is no reason to place this on the slot_ctx heap. Use scratch instead. */ 93 0 : }; 94 : 95 0 : if( FD_UNLIKELY( fd_slot_hashes_decode( result, &decode )!=FD_BINCODE_SUCCESS ) ) 96 0 : return NULL; 97 0 : return result; 98 0 : }