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 0 : static void write_slot_hashes( fd_exec_slot_ctx_t * slot_ctx, fd_slot_hashes_t * slot_hashes ) { 17 0 : ulong sz = fd_slot_hashes_size( slot_hashes ); 18 0 : if (sz < slot_hashes_min_account_size) 19 0 : sz = slot_hashes_min_account_size; 20 0 : uchar enc[sz]; 21 0 : fd_memset( enc, 0, sz ); 22 0 : fd_bincode_encode_ctx_t ctx; 23 0 : ctx.data = enc; 24 0 : ctx.dataend = enc + sz; 25 0 : if( fd_slot_hashes_encode( slot_hashes, &ctx ) ) 26 0 : FD_LOG_ERR(("fd_slot_hashes_encode failed")); 27 : 28 0 : fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_slot_hashes_id, enc, sz, slot_ctx->slot_bank.slot ); 29 0 : } 30 : 31 0 : void fd_sysvar_slot_hashes_init( fd_exec_slot_ctx_t * slot_ctx, fd_slot_hashes_t * slot_hashes ) { 32 0 : write_slot_hashes( slot_ctx, slot_hashes ); 33 0 : } 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, fd_spad_t * runtime_spad ) { 38 0 : fd_slot_hashes_t * slot_hashes = fd_sysvar_slot_hashes_read( slot_ctx, runtime_spad ); 39 0 : if( !slot_hashes ) { 40 0 : FD_LOG_WARNING(("NEVER CREATED THIS MF BEFORE")); 41 0 : uchar * deque_mem = fd_spad_alloc( runtime_spad, 42 0 : deq_fd_slot_hash_t_align(), 43 0 : deq_fd_slot_hash_t_footprint( FD_SYSVAR_SLOT_HASHES_CAP ) ); 44 0 : slot_hashes->hashes = deq_fd_slot_hash_t_join( deq_fd_slot_hash_t_new( deque_mem, FD_SYSVAR_SLOT_HASHES_CAP ) ); 45 0 : if( FD_UNLIKELY( !slot_hashes->hashes ) ) { 46 0 : FD_LOG_ERR(( "Unable to allocate memory for slot hashes" )); 47 0 : } 48 0 : } 49 : 50 0 : fd_slot_hash_t * hashes = slot_hashes->hashes; 51 : 52 0 : uchar found = 0; 53 0 : for( deq_fd_slot_hash_t_iter_t iter = deq_fd_slot_hash_t_iter_init( hashes ); 54 0 : !deq_fd_slot_hash_t_iter_done( hashes, iter ); 55 0 : iter = deq_fd_slot_hash_t_iter_next( hashes, iter ) ) { 56 0 : fd_slot_hash_t * ele = deq_fd_slot_hash_t_iter_ele( hashes, iter ); 57 0 : if( ele->slot == slot_ctx->slot_bank.slot ) { 58 0 : memcpy( &ele->hash, &slot_ctx->slot_bank.banks_hash, sizeof(fd_hash_t) ); 59 0 : found = 1; 60 0 : } 61 0 : } 62 : 63 0 : if ( !found ) { 64 : // https://github.com/firedancer-io/solana/blob/08a1ef5d785fe58af442b791df6c4e83fe2e7c74/runtime/src/bank.rs#L2371 65 0 : fd_slot_hash_t slot_hash = { 66 0 : .hash = slot_ctx->slot_bank.banks_hash, // parent hash? 67 0 : .slot = slot_ctx->slot_bank.prev_slot, // parent_slot 68 0 : }; 69 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 ) )); 70 : 71 0 : if (deq_fd_slot_hash_t_full( hashes ) ) 72 0 : fd_slot_hash_destroy( deq_fd_slot_hash_t_pop_tail_nocopy( hashes ) ); 73 : 74 0 : deq_fd_slot_hash_t_push_head( hashes, slot_hash ); 75 0 : } 76 : 77 0 : write_slot_hashes( slot_ctx, slot_hashes ); 78 0 : } 79 : 80 : fd_slot_hashes_t * 81 : fd_sysvar_slot_hashes_read( fd_exec_slot_ctx_t * slot_ctx, 82 0 : fd_spad_t * runtime_spad ) { 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_TXN_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 : }; 95 : 96 0 : ulong total_sz = 0UL; 97 0 : err = fd_slot_hashes_decode_footprint( &decode, &total_sz ); 98 0 : if( FD_UNLIKELY( err ) ) { 99 0 : return NULL; 100 0 : } 101 : 102 0 : uchar * mem = fd_spad_alloc( runtime_spad, fd_slot_hashes_align(), total_sz ); 103 0 : if( FD_UNLIKELY( !mem ) ) { 104 0 : FD_LOG_ERR(( "Unable to allocate memory for slot hashes" )); 105 0 : } 106 : 107 0 : return fd_slot_hashes_decode( mem, &decode ); 108 0 : }