Line data Source code
1 : #ifndef HEADER_fd_src_disco_pack_fd_pack_rebate_sum_h 2 : #define HEADER_fd_src_disco_pack_fd_pack_rebate_sum_h 3 : 4 : #include "../fd_disco_base.h" 5 : #include "fd_microblock.h" 6 : 7 : 8 : /* Pack schedules transactions assuming they consume all the CUs they 9 : request in order to accommodate the worst case. However, 10 : transactions frequently consume fewer CUs than they request. If the 11 : bank tiles notify pack of how many CUs can be rebated, pack can use 12 : that information to schedule additional transactions. 13 : 14 : fd_pack_rebate_sum_t digests microblocks and produces 0-3 15 : fd_pack_rebate_t messages which summarizes what rebates are needed. 16 : From the bank tiles's perspective, fd_pack_rebate_t is an opaque 17 : type, but pack reads its internals. */ 18 : 19 : FD_STATIC_ASSERT( MAX_TXN_PER_MICROBLOCK*FD_TXN_ACCT_ADDR_MAX<4096UL, map_size ); 20 : 21 36 : #define FD_PACK_REBATE_SUM_CAPACITY (5UL*1024UL) 22 : 23 : typedef struct { 24 : fd_acct_addr_t key; /* account address */ 25 : ulong rebate_cus; 26 : } fd_pack_rebate_entry_t; 27 : 28 : 29 : struct fd_pack_rebate_sum_private { 30 : ulong total_cost_rebate; 31 : ulong vote_cost_rebate; 32 : ulong data_bytes_rebate; 33 : ulong microblock_cnt_rebate; 34 : ulong alloc_rebate; 35 : int ib_result; /* -1: IB failed, 0: not an IB, 1: IB success */ 36 : uint writer_cnt; 37 : 38 : fd_pack_rebate_entry_t map[ 8192UL ]; 39 : fd_pack_rebate_entry_t * inserted[ FD_PACK_REBATE_SUM_CAPACITY ]; 40 : }; 41 : typedef struct fd_pack_rebate_sum_private fd_pack_rebate_sum_t; 42 : 43 : 44 : struct fd_pack_rebate { 45 : ulong total_cost_rebate; 46 : ulong vote_cost_rebate; 47 : ulong data_bytes_rebate; 48 : ulong microblock_cnt_rebate; 49 : ulong alloc_rebate; 50 : int ib_result; /* -1: IB failed, 0: not an IB, 1: IB success */ 51 : uint writer_cnt; 52 : 53 : fd_pack_rebate_entry_t writer_rebates[ 1UL ]; /* Actually writer_cnt, up to FD_PACK_REBATE_MAX_ENTRIES */ 54 : }; 55 : typedef struct fd_pack_rebate fd_pack_rebate_t; 56 : 57 : /* Entries per report capped so a max-size report is exactly 65408 58 : bytes (64 KiB - 128, one dcache slot), which keeps a deep 59 : execle_pack link under a gigantic page boundary. */ 60 102 : #define FD_PACK_REBATE_MAX_ENTRIES (1634UL) 61 : 62 : #define FD_PACK_REBATE_MIN_SZ (sizeof(fd_pack_rebate_t)-sizeof(fd_pack_rebate_entry_t)) 63 0 : #define FD_PACK_REBATE_MAX_SZ (sizeof(fd_pack_rebate_t)+(FD_PACK_REBATE_MAX_ENTRIES-1UL)*sizeof(fd_pack_rebate_entry_t)) 64 : 65 : FD_STATIC_ASSERT( sizeof(fd_pack_rebate_t)+(FD_PACK_REBATE_MAX_ENTRIES-1UL)*sizeof(fd_pack_rebate_entry_t)==65408UL, rebate_depth ); 66 : 67 : 68 0 : FD_FN_PURE static inline ulong fd_pack_rebate_sum_align ( void ) { return alignof(fd_pack_rebate_sum_t); } 69 0 : FD_FN_PURE static inline ulong fd_pack_rebate_sum_footprint( void ) { return sizeof (fd_pack_rebate_sum_t); } 70 : 71 6 : FD_FN_PURE static inline fd_pack_rebate_sum_t * fd_pack_rebate_sum_join( void * mem ) { return (fd_pack_rebate_sum_t *)mem; } 72 : 73 : void * fd_pack_rebate_sum_new( void * mem ); 74 : 75 : /* fd_pack_rebate_sum_add_txn adds rebate information from a bundle or 76 : microblock to the pending summary. This reads the EXECUTE_SUCCESS 77 : flag and the execle_cu field, so those must be populated in the 78 : transactions before this is called. 79 : 80 : s must be a valid local join. txn will be indexed txn[i] for i in [0, 81 : txn_cnt), and each transaction must have the previously mentioned 82 : fields set. 83 : 84 : Additionally, if the transaction txn[i] loads writable accounts 85 : from one or more address lookup tables, addtl_writable[i] must 86 : either be NULL or point to the first writable account address that 87 : it loaded. When not NULL, adtl_writable is indexed 88 : addtl_writable[i][j] for j in [0, TXN(txn[i])->addr_table_adtl_writable_cnt ). 89 : If adtl_writable[i] is NULL, ALT account rebates are skipped (this can 90 : happen if the transaction doesn't load any writable accounts from address 91 : lookup tables or if the resolved addresses are not available). 92 : txn_cnt must be in [0, MAX_TXN_PER_MICROBLOCK], where txn_cnt==0 is 93 : a no-op. txn and adtl_writable can be NULL if txn_cnt==0. 94 : 95 : This function does not retain any read interest in txn or 96 : adtl_writable after returning. 97 : 98 : Returns the number of times fd_pack_rebate_sum_report must be called 99 : before the next call to add_txn with a non-zero txn_cnt. */ 100 : ulong 101 : fd_pack_rebate_sum_add_txn( fd_pack_rebate_sum_t * s, 102 : fd_txn_p_t const * txn, 103 : fd_acct_addr_t const * const * adtl_writable, 104 : ulong txn_cnt ); 105 : 106 : /* fd_pack_rebate_sum_report generates a rebate report from the state of 107 : the current rebate information. s must point to a valid local join. 108 : out must point to a region of memory with at least 109 : FD_PACK_REBATE_MAX_SZ bytes of capacity. Returns the number of bytes 110 : that were written, which will be in [0, FD_PACK_REBATE_MAX_SZ]. 111 : Updates the state of s so that subsequent calls to this function will 112 : write new information. */ 113 : ulong 114 : fd_pack_rebate_sum_report( fd_pack_rebate_sum_t * s, 115 : fd_pack_rebate_t * out ); 116 : 117 : /* fd_pack_rebate_sum_clear clears the state of any pending rebates. 118 : Requires that s is a valid local join. Given that, it's faster but 119 : equivalent to calling leave, delete, new, then join. */ 120 : void 121 : fd_pack_rebate_sum_clear( fd_pack_rebate_sum_t * s ); 122 : 123 : #endif /* HEADER_fd_src_disco_pack_fd_pack_rebate_sum_h */