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 42 : #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 vote_cost_rebate; 33 : ulong data_bytes_rebate; 34 : ulong microblock_cnt_rebate; 35 : ulong alloc_rebate; 36 : int ib_result; /* -1: IB failed, 0: not an IB, 1: IB success */ 37 : uint writer_cnt; 38 : 39 : uchar map_mem[ FD_PACK_REBATE_SUM_MAP_FOOTPRINT ] __attribute__((aligned(FD_PACK_REBATE_SUM_MAP_ALIGN))); 40 : fd_pack_rebate_entry_t * map; 41 : fd_pack_rebate_entry_t * inserted[ FD_PACK_REBATE_SUM_CAPACITY ]; 42 : }; 43 : typedef struct fd_pack_rebate_sum_private fd_pack_rebate_sum_t; 44 : 45 : 46 : struct fd_pack_rebate { 47 : ulong total_cost_rebate; 48 : ulong vote_cost_rebate; 49 : ulong data_bytes_rebate; 50 : ulong microblock_cnt_rebate; 51 : ulong alloc_rebate; 52 : int ib_result; /* -1: IB failed, 0: not an IB, 1: IB success */ 53 : uint writer_cnt; 54 : 55 : fd_pack_rebate_entry_t writer_rebates[ 1UL ]; /* Actually writer_cnt, up to FD_PACK_REBATE_MAX_ENTRIES */ 56 : }; 57 : typedef struct fd_pack_rebate fd_pack_rebate_t; 58 : 59 : /* At most one bundle's worth of writable accounts can be added between 60 : reports. */ 61 159 : #define FD_PACK_REBATE_MAX_ENTRIES (MAX_TXN_PER_MICROBLOCK*MAX_TX_ACCOUNT_LOCKS) 62 : 63 : #define FD_PACK_REBATE_MIN_SZ (sizeof(fd_pack_rebate_t)-sizeof(fd_pack_rebate_entry_t)) 64 0 : #define FD_PACK_REBATE_MAX_SZ (sizeof(fd_pack_rebate_t)+(FD_PACK_REBATE_MAX_ENTRIES-1UL)*sizeof(fd_pack_rebate_entry_t)) 65 : 66 : FD_STATIC_ASSERT( FD_PACK_REBATE_MAX_SZ<USHORT_MAX, rebate_depth ); 67 : 68 : 69 0 : FD_FN_PURE static inline ulong fd_pack_rebate_sum_align ( void ) { return alignof(fd_pack_rebate_sum_t); } 70 0 : FD_FN_PURE static inline ulong fd_pack_rebate_sum_footprint( void ) { return sizeof (fd_pack_rebate_sum_t); } 71 : 72 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; } 73 : 74 : /* fd_pack_rebate_sum_new creates a new rebate sum object. `mem` must 75 : point to a region of memory with at least 76 : fd_pack_rebate_sum_footprint() bytes of capacity and an alignment of 77 : at least fd_pack_rebate_sum_align(). `seed` is the hash seed used by 78 : the writer rebate map and should be randomly generated. */ 79 : void * 80 : fd_pack_rebate_sum_new( void * mem, 81 : ulong seed ); 82 : 83 : /* fd_pack_rebate_sum_add_txn adds rebate information from a bundle or 84 : microblock to the pending summary. This reads the EXECUTE_SUCCESS 85 : flag and the execle_cu field, so those must be populated in the 86 : transactions before this is called. 87 : 88 : s must be a valid local join. txn will be indexed txn[i] for i in [0, 89 : txn_cnt), and each transaction must have the previously mentioned 90 : fields set. 91 : 92 : Additionally, if the transaction txn[i] loads writable accounts 93 : from one or more address lookup tables, addtl_writable[i] must 94 : either be NULL or point to the first writable account address that 95 : it loaded. When not NULL, adtl_writable is indexed 96 : addtl_writable[i][j] for j in [0, TXN(txn[i])->addr_table_adtl_writable_cnt ). 97 : If adtl_writable[i] is NULL, ALT account rebates are skipped (this can 98 : happen if the transaction doesn't load any writable accounts from address 99 : lookup tables or if the resolved addresses are not available). 100 : txn_cnt must be in [0, MAX_TXN_PER_MICROBLOCK], where txn_cnt==0 is 101 : a no-op. txn and adtl_writable can be NULL if txn_cnt==0. 102 : 103 : This function does not retain any read interest in txn or 104 : adtl_writable after returning. 105 : 106 : Returns the number of times fd_pack_rebate_sum_report must be called 107 : before the next call to add_txn with a non-zero txn_cnt. */ 108 : ulong 109 : fd_pack_rebate_sum_add_txn( fd_pack_rebate_sum_t * s, 110 : fd_txn_p_t const * txn, 111 : fd_acct_addr_t const * const * adtl_writable, 112 : ulong txn_cnt ); 113 : 114 : /* fd_pack_rebate_sum_report generates a rebate report from the state of 115 : the current rebate information. s must point to a valid local join. 116 : out must point to a region of memory with at least 117 : FD_PACK_REBATE_MAX_SZ bytes of capacity. Returns the number of bytes 118 : that were written, which will be in [0, FD_PACK_REBATE_MAX_SZ]. 119 : Updates the state of s so that subsequent calls to this function will 120 : write new information. */ 121 : ulong 122 : fd_pack_rebate_sum_report( fd_pack_rebate_sum_t * s, 123 : fd_pack_rebate_t * out ); 124 : 125 : /* fd_pack_rebate_sum_clear clears the state of any pending rebates. 126 : Requires that s is a valid local join. Given that, it's faster but 127 : equivalent to calling leave, delete, new, then join. */ 128 : void 129 : fd_pack_rebate_sum_clear( fd_pack_rebate_sum_t * s ); 130 : 131 : #endif /* HEADER_fd_src_disco_pack_fd_pack_rebate_sum_h */