Line data Source code
1 : #include "fd_tower_serde.h" 2 : #include "fd_tower.h" 3 : 4 : #define SHORTVEC 0 5 : 6 108 : #define DE( T, name ) do { \ 7 108 : if( FD_UNLIKELY( off+sizeof(T)>buf_sz ) ) return -1; \ 8 108 : serde->name = *(T const *)fd_type_pun_const( buf+off ); \ 9 108 : off += sizeof(T); \ 10 108 : } while(0) 11 : 12 108 : #define SER( T, name ) do { \ 13 108 : if( FD_UNLIKELY( off+sizeof(T)>buf_sz ) ) return -1; \ 14 108 : FD_STORE( T, buf+off, serde->name ); \ 15 108 : off += sizeof(T); \ 16 108 : } while(0) 17 : 18 : static ulong 19 3 : de_short_u16( ushort * dst, uchar const * src ) { 20 3 : if ( FD_LIKELY( !(0x80U & src[0]) ) ) { *dst = (ushort)src[0]; return 1; } 21 0 : else if( FD_LIKELY( !(0x80U & src[1]) ) ) { *dst = (ushort)((ulong)(src[0]&0x7FUL) + (((ulong)src[1])<<7)); return 2; } 22 0 : else { *dst = (ushort)((ulong)(src[0]&0x7FUL) + (((ulong)(src[1]&0x7FUL))<<7) + (((ulong)src[2])<<14)); return 3; } 23 3 : } 24 : 25 : static ulong 26 93 : de_var_int( ulong * dst, uchar const * src ) { 27 93 : *dst = 0; 28 93 : ulong off = 0; 29 93 : ulong bit = 0; 30 93 : while( FD_LIKELY( bit < 64 ) ) { 31 93 : uchar byte = *(uchar const *)(src+off); 32 93 : off += 1; 33 93 : *dst |= (byte & 0x7FUL) << bit; 34 93 : if( FD_LIKELY( (byte & 0x80U) == 0U ) ) { 35 93 : if( FD_UNLIKELY( (*dst>>bit) != byte ) ) FD_LOG_CRIT(( "de_varint" )); 36 93 : if( FD_UNLIKELY( byte==0U && (bit!=0U || *dst!=0UL) ) ) FD_LOG_CRIT(( "de_varint" )); 37 93 : return off; 38 93 : } 39 0 : bit += 7; 40 0 : } 41 0 : FD_LOG_CRIT(( "de_varint" )); 42 0 : } 43 : 44 : static ulong 45 3 : ser_short_u16( uchar * dst, ushort val ) { 46 3 : if ( FD_LIKELY( val < 0x80U ) ) { 47 3 : dst[0] = (uchar)val; 48 3 : return 1; 49 3 : } 50 0 : else if( FD_LIKELY( val < 0x4000U ) ) { 51 0 : dst[0] = (uchar)((val & 0x7FUL) | 0x80U); 52 0 : dst[1] = (uchar)(val >> 7); 53 0 : return 2; 54 0 : } 55 0 : else { 56 0 : dst[0] = (uchar)((val & 0x7FUL) | 0x80U); 57 0 : dst[1] = (uchar)(((val >> 7) & 0x7FUL) | 0x80U); 58 0 : dst[2] = (uchar)(val >> 14); 59 0 : return 3; 60 0 : } 61 3 : } 62 : 63 : static ulong 64 93 : ser_var_int( uchar * dst, ulong val ) { 65 93 : ulong off = 0; 66 93 : while( FD_LIKELY( val >= 0x80UL ) ) { 67 0 : dst[off] = (uchar)((val & 0x7FUL) | 0x80U); 68 0 : val >>= 7; 69 0 : off += 1; 70 0 : } 71 93 : dst[off] = (uchar)val; 72 93 : return off + 1; 73 93 : } 74 : 75 : int 76 : fd_compact_tower_sync_deserialize( fd_compact_tower_sync_serde_t * serde, 77 : uchar const * buf, 78 3 : ulong buf_sz ) { 79 3 : ulong off = 0; 80 3 : DE( ulong, root ); 81 3 : off += de_short_u16( &serde->lockouts_cnt, buf+off ); 82 3 : if( FD_UNLIKELY( serde->lockouts_cnt > FD_TOWER_VOTE_MAX ) ) return -1; 83 96 : for( ulong i = 0; i < serde->lockouts_cnt; i++ ) { 84 93 : off += de_var_int( &serde->lockouts[i].offset, buf+off ); 85 93 : DE( uchar, lockouts[i].confirmation_count ); 86 93 : } 87 3 : DE( fd_hash_t, hash ); 88 3 : DE( uchar, timestamp_option ); 89 3 : if( FD_LIKELY( serde->timestamp_option ) ) { 90 3 : DE( long, timestamp ); 91 3 : } 92 3 : DE( fd_hash_t, block_id ); 93 3 : return 0; 94 3 : } 95 : 96 : int 97 : fd_compact_tower_sync_serialize( fd_compact_tower_sync_serde_t const * serde, 98 : uchar * buf, 99 : ulong buf_sz, 100 3 : ulong * out_sz ) { 101 3 : ulong off = 0; 102 3 : SER( ulong, root ); 103 3 : off += ser_short_u16( buf+off, serde->lockouts_cnt ); 104 3 : if( FD_UNLIKELY( serde->lockouts_cnt > FD_TOWER_VOTE_MAX ) ) return -1; 105 96 : for( ulong i = 0; i < serde->lockouts_cnt; i++ ) { 106 93 : off += ser_var_int( buf+off, serde->lockouts[i].offset ); 107 93 : SER( uchar, lockouts[i].confirmation_count ); 108 93 : } 109 3 : SER( fd_hash_t, hash ); 110 3 : SER( uchar, timestamp_option ); 111 3 : if( FD_LIKELY( serde->timestamp_option ) ) { 112 3 : SER( long, timestamp ); 113 3 : } 114 3 : SER( fd_hash_t, block_id ); 115 3 : if( FD_LIKELY( out_sz ) ) *out_sz = off; 116 3 : return 0; 117 3 : }