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