Line data Source code
1 : #ifndef HEADER_fd_src_disco_shred_fd_shredder_h 2 : #define HEADER_fd_src_disco_shred_fd_shredder_h 3 : 4 : #include "../../ballet/sha256/fd_sha256.h" 5 : #include "../../disco/pack/fd_microblock.h" 6 : #include "../../ballet/reedsol/fd_reedsol.h" 7 : #include "../../ballet/bmtree/fd_bmtree.h" 8 : #include "fd_fec_set.h" 9 : 10 : #define FD_FEC_SET_MAX_BMTREE_DEPTH (7UL) /* 1+ceil(log2(DATA_SHREDS_MAX + PARITY_SHREDS_MAX)) */ 11 : 12 0 : #define FD_SHREDDER_ALIGN ( 128UL) 13 : /* FD_SHREDDER_FOOTPRINT is not provided because it depends on the footprint 14 : of fd_sha256_batch_t, which is not invariant (the latter depends on the 15 : underlying implementation). Instead, a static inline function is provided. */ 16 : 17 0 : #define FD_SHREDDER_MAGIC (0xF17EDA2547EDDE70UL) /* FIREDAN SHREDDER V0 */ 18 : 19 0 : #define FD_SHRED_FEATURES_ACTIVATION_SLOT_CNT (3UL) 20 0 : #define FD_SHRED_FEATURES_ACTIVATION_SLOT_DISABLED (ULONG_MAX) 21 : 22 : union fd_shred_features_activation_private { 23 : /* slots for features of interest - update cnt as needed in the future. */ 24 : ulong slots[ FD_SHRED_FEATURES_ACTIVATION_SLOT_CNT ]; 25 : struct { 26 : /* 0 */ ulong enforce_fixed_fec_set; 27 : /* 1 */ ulong switch_to_chacha8_turbine; 28 : /* 2 */ ulong discard_unexpected_data_complete_shreds; 29 : }; 30 : }; 31 : typedef union fd_shred_features_activation_private fd_shred_features_activation_t; 32 : 33 : 34 : struct __attribute__((aligned(FD_SHREDDER_ALIGN))) fd_shredder_private { 35 : ulong magic; 36 : ushort shred_version; 37 : 38 : fd_sha256_batch_t sha256 [ 1 ]; 39 : fd_reedsol_t reedsol[ 1 ]; 40 : union __attribute__((aligned(FD_BMTREE_COMMIT_ALIGN))) { 41 : fd_bmtree_commit_t bmtree; 42 : uchar _bmtree_footprint[ FD_BMTREE_COMMIT_FOOTPRINT( FD_FEC_SET_MAX_BMTREE_DEPTH ) ]; 43 : }; 44 : fd_bmtree_node_t bmtree_leaves[ FD_REEDSOL_DATA_SHREDS_MAX + FD_REEDSOL_PARITY_SHREDS_MAX ]; 45 : 46 : void const * entry_batch; 47 : ulong sz; 48 : ulong offset; 49 : 50 : fd_entry_batch_meta_t meta; 51 : ulong slot; 52 : ulong data_idx_offset; 53 : ulong parity_idx_offset; 54 : }; 55 : 56 : typedef struct fd_shredder_private fd_shredder_t; 57 : 58 0 : FD_FN_CONST static inline ulong fd_shredder_align ( void ) { return FD_SHREDDER_ALIGN; } 59 0 : FD_FN_CONST static inline ulong fd_shredder_footprint( void ) { return sizeof(fd_shredder_t); } 60 : 61 : /* fd_shredder_new formats a region of memory as a shredder object. 62 : The shredder does not sign: the caller writes the signature field 63 : of every shred it produces. */ 64 : void * fd_shredder_new( void * mem ); 65 : fd_shredder_t * fd_shredder_join( void * mem ); 66 : void * fd_shredder_leave( fd_shredder_t * shredder ); 67 : void * fd_shredder_delete( void * mem ); 68 : 69 0 : static inline void fd_shredder_set_shred_version( fd_shredder_t * shredder, ushort shred_version ) { shredder->shred_version = shred_version; } 70 : 71 : 72 : /* fd_shredder_count_{data_shreds, parity_shreds, fec_sets}: returns the 73 : number of data shreds, parity shreds, or FEC sets (respectively) 74 : required to send an entry batch of size `sz_bytes` bytes. It uses 75 : chained unsigned Merkle shreds. For data and parity shred counts, 76 : this is the total count across all FEC sets. 77 : 78 : We only produce FEC sets with 32 data and 32 parity shreds, so this 79 : form of counting is much simpler than before. */ 80 : 81 : #define FD_SHREDDER_NORMAL_FEC_SET_PAYLOAD_SZ (31840UL) 82 0 : #define FD_SHREDDER_CHAINED_FEC_SET_PAYLOAD_SZ (30816UL) /* -32 bytes * 32 shreds */ 83 : 84 : FD_FN_CONST static inline ulong 85 0 : fd_shredder_count_fec_sets( ulong sz_bytes ) { 86 0 : return (sz_bytes + FD_SHREDDER_CHAINED_FEC_SET_PAYLOAD_SZ - 1UL )/FD_SHREDDER_CHAINED_FEC_SET_PAYLOAD_SZ; 87 0 : } 88 : FD_FN_CONST static inline ulong 89 0 : fd_shredder_count_data_shreds( ulong sz_bytes ) { 90 0 : return 32UL*fd_shredder_count_fec_sets( sz_bytes ); 91 0 : } 92 : FD_FN_CONST static inline ulong 93 0 : fd_shredder_count_parity_shreds( ulong sz_bytes ) { 94 0 : return 32UL*fd_shredder_count_fec_sets( sz_bytes ); 95 0 : } 96 : 97 : /* fd_shredder_init_batch begins the computation of shreds for an entry 98 : batch. shredder must be a valid local join. entry_batch points to 99 : the first byte of a region of memory entry_batch_sz bytes long. 100 : entry_batch_sz must be strictly positive. The shredder object 101 : retains a read interest in the region of memory [entry_batch, 102 : entry_batch+entry_batch_sz) that lasts until fd_shredder_fini_batch 103 : is called. This region of memory should not be modified while in use 104 : by the shredder. meta contains the metadata for the batch that is 105 : necessary for shred production. The shredder object does not retain 106 : a read interest in the memory pointed to by meta. 107 : 108 : Returns shredder, which will be in a new batch when the function 109 : returns. */ 110 : fd_shredder_t * fd_shredder_init_batch( fd_shredder_t * shredder, 111 : void const * entry_batch, 112 : ulong entry_batch_sz, 113 : ulong slot, 114 : fd_entry_batch_meta_t const * meta ); 115 : 116 : /* fd_shredder_skip_batch updates the shredder state as necessary 117 : to skip processing this current batch. shredder must be a valid 118 : local join. entry_batch_sz must be strictly positive. 119 : 120 : Returns shredder, which will have data and parity shred indices 121 : updated as if the caller had called fd_shredder_init_batch with 122 : a batch of the specified size, followed by fd_shredder_next_fec_set 123 : exactly fd_shredder_count_fec_sets( entry_batch_sz ) times. */ 124 : fd_shredder_t * fd_shredder_skip_batch( fd_shredder_t * shredder, 125 : ulong entry_batch_sz, 126 : ulong slot ); 127 : 128 : /* fd_shredder_next_fec_set extracts the next FEC set from the in 129 : progress batch. Computes the entirety of both data and parity 130 : shreds, including the parity information and Merkle proofs; the 131 : signature field of each shred is clobbered (its tail holds the 132 : Merkle leaf prefix) and must be overwritten by the caller. Stores 133 : the generated shreds in result. The received-shred bitmaps 134 : data_shred_rcvd, parity_shred_rcvd, turbine_shred_rcvd and 135 : repair_shred_rcvd are left unchanged. 136 : 137 : shredder must be a valid local join. chained_merkle_root is a 138 : pointer to a 32-byte buffer containing the chained merkle root (the 139 : merkle root of the previous FEC set). Upon return, 140 : chained_merkle_root is updated with the new root. 141 : 142 : Returns result on success and NULL if all of the entry batch's data 143 : has been consumed already by previous calls to this function. On 144 : success, advances the position of the shredder within the batch 145 : without finishing the batch. */ 146 : fd_fec_set_t * 147 : fd_shredder_next_fec_set( fd_shredder_t * shredder, 148 : fd_fec_set_t * result, 149 : uchar * chained_merkle_root ); 150 : 151 : /* fd_shredder_fini_batch finishes the in process batch. shredder must 152 : be a valid local join that is currently in a batch. Upon return, 153 : shredder will no longer be in a batch and will be ready to begin a 154 : new batch with init_batch. Returns shredder. */ 155 : fd_shredder_t * fd_shredder_fini_batch( fd_shredder_t * shredder ); 156 : 157 : #endif /* HEADER_fd_src_disco_shred_fd_shredder_h */