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 : /* Pack schedules transactions assuming they consume all the CUs they 8 : request in order to accommodate the worst case. However, 9 : transactions frequently consume fewer CUs than they request. If the 10 : bank tiles notify pack of how many CUs can be rebated, pack can use 11 : that information to schedule additional transactions. 12 : 13 : fd_pack_rebate_sum_t digests microblocks and produces 14 : fd_pack_rebate_t messages summarizing what rebates are needed. 15 : From the bank tiles's perspective, fd_pack_rebate_t is an opaque 16 : type, but pack reads its internals. */ 17 : 18 : FD_STATIC_ASSERT( MAX_TXN_PER_MICROBLOCK*FD_TXN_ACCT_ADDR_MAX<4096UL, map_size ); 19 : 20 0 : #define FD_PACK_REBATE_SUM_CAPACITY (5UL*1024UL) 21 : 22 : typedef struct { 23 : fd_acct_addr_t key; /* account address */ 24 : ulong rebate_cus; 25 : } fd_pack_rebate_entry_t; 26 : 27 : #define FD_PACK_REBATE_SUM_MAP_FOOTPRINT (4UL*sizeof(ulong) + 8192UL*sizeof(fd_pack_rebate_entry_t)) 28 : #define FD_PACK_REBATE_SUM_MAP_ALIGN (8UL) 29 : 30 : struct fd_pack_rebate_sum_private { 31 : ulong total_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 : uchar map_mem[ FD_PACK_REBATE_SUM_MAP_FOOTPRINT ] __attribute__((aligned(FD_PACK_REBATE_SUM_MAP_ALIGN))); 39 : fd_pack_rebate_entry_t * map; 40 : fd_pack_rebate_entry_t * inserted[ FD_PACK_REBATE_SUM_CAPACITY ]; 41 : }; 42 : typedef struct fd_pack_rebate_sum_private fd_pack_rebate_sum_t; 43 : 44 : 45 : struct fd_pack_rebate { 46 : ulong total_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 : /* At most one bundle's worth of writable accounts can be added between 58 : reports. */ 59 0 : #define FD_PACK_REBATE_MAX_ENTRIES (MAX_TXN_PER_MICROBLOCK*MAX_TX_ACCOUNT_LOCKS) 60 : 61 : #define FD_PACK_REBATE_MIN_SZ (sizeof(fd_pack_rebate_t)-sizeof(fd_pack_rebate_entry_t)) 62 0 : #define FD_PACK_REBATE_MAX_SZ (sizeof(fd_pack_rebate_t)+(FD_PACK_REBATE_MAX_ENTRIES-1UL)*sizeof(fd_pack_rebate_entry_t)) 63 : 64 : FD_STATIC_ASSERT( FD_PACK_REBATE_MAX_SZ<USHORT_MAX, rebate_depth ); 65 : 66 : 67 0 : FD_FN_PURE static inline ulong fd_pack_rebate_sum_align ( void ) { return alignof(fd_pack_rebate_sum_t); } 68 0 : FD_FN_PURE static inline ulong fd_pack_rebate_sum_footprint( void ) { return sizeof (fd_pack_rebate_sum_t); } 69 : 70 0 : FD_FN_PURE static inline fd_pack_rebate_sum_t * fd_pack_rebate_sum_join( void * mem ) { return (fd_pack_rebate_sum_t *)mem; } 71 : 72 : /* fd_pack_rebate_sum_new creates a new rebate sum object. `mem` must 73 : point to a region of memory with at least 74 : fd_pack_rebate_sum_footprint() bytes of capacity and an alignment of 75 : at least fd_pack_rebate_sum_align(). `seed` is the hash seed used by 76 : the writer rebate map and should be randomly generated. */ 77 : void * 78 : fd_pack_rebate_sum_new( void * mem, 79 : ulong seed ); 80 : 81 : /* fd_pack_rebate_sum_add_txn adds rebate information from a bundle or 82 : microblock to the pending summary. This reads the EXECUTE_SUCCESS 83 : flag and the execle_cu field, so those must be populated in the 84 : transactions before this is called. 85 : 86 : s must be a valid local join. txn will be indexed txn[i] for i in [0, 87 : txn_cnt), and each transaction must have the previously mentioned 88 : fields set. 89 : 90 : Additionally, if the transaction txn[i] loads writable accounts 91 : from one or more address lookup tables, addtl_writable[i] must 92 : either be NULL or point to the first writable account address that 93 : it loaded. When not NULL, adtl_writable is indexed 94 : addtl_writable[i][j] for j in [0, TXN(txn[i])->addr_table_adtl_writable_cnt ). 95 : If adtl_writable[i] is NULL, ALT account rebates are skipped (this can 96 : happen if the transaction doesn't load any writable accounts from address 97 : lookup tables or if the resolved addresses are not available). 98 : txn_cnt must be in [0, MAX_TXN_PER_MICROBLOCK], where txn_cnt==0 is 99 : a no-op. txn and adtl_writable can be NULL if txn_cnt==0. 100 : 101 : This function does not retain any read interest in txn or 102 : adtl_writable after returning. 103 : 104 : Returns the number of times fd_pack_rebate_sum_report must be called 105 : before the next call to add_txn with a non-zero txn_cnt. */ 106 : ulong 107 : fd_pack_rebate_sum_add_txn( fd_pack_rebate_sum_t * s, 108 : fd_txn_p_t const * txn, 109 : fd_acct_addr_t const * const * adtl_writable, 110 : ulong txn_cnt ); 111 : 112 : /* fd_pack_rebate_sum_report generates a rebate report from the state of 113 : the current rebate information. s must point to a valid local join. 114 : out must point to a region of memory with at least 115 : FD_PACK_REBATE_MAX_SZ bytes of capacity. Returns the number of bytes 116 : that were written, which will be in [0, FD_PACK_REBATE_MAX_SZ]. 117 : Updates the state of s so that subsequent calls to this function will 118 : write new information. */ 119 : ulong 120 : fd_pack_rebate_sum_report( fd_pack_rebate_sum_t * s, 121 : fd_pack_rebate_t * out ); 122 : 123 : /* fd_pack_rebate_sum_clear clears the state of any pending rebates. 124 : Requires that s is a valid local join. Given that, it's faster but 125 : equivalent to calling leave, delete, new, then join. */ 126 : void 127 : fd_pack_rebate_sum_clear( fd_pack_rebate_sum_t * s ); 128 : 129 : #endif /* HEADER_fd_src_disco_pack_fd_pack_rebate_sum_h */