Line data Source code
1 : #include "ag_vote_serde.h" 2 : 3 0 : #define FAIL( cond, err ) do { if( FD_UNLIKELY( cond ) ) return AG_VOTE_DE_ERR_##err; } while( 0 ) 4 : 5 : ulong 6 : ag_vote_ser( ag_vote_t const * self, 7 0 : uchar buf[ static AG_VOTE_SER_MAX ] ) { 8 0 : ag_vote_serde_t vote = { 9 0 : .version = (uchar)1, 10 0 : .tag = (uchar)( self->kind+AG_VOTE_SERDE_TAG_NOTAR ), 11 0 : .slot = ag_vote_slot( self ), 12 0 : .block_id = ag_vote_block_hash( self ), 13 0 : .shred_version = ag_vote_shred_version( self ), 14 0 : }; 15 : 16 0 : ulong off = 0UL; 17 0 : buf[ off ] = vote.version; off += sizeof(uchar); 18 0 : buf[ off ] = vote.tag; off += sizeof(uchar); 19 0 : FD_STORE( ulong, buf+off, vote.slot ); off += sizeof(ulong); 20 0 : if( FD_LIKELY( vote.block_id ) ) { memcpy( buf+off, vote.block_id, sizeof(ag_block_hash_t) ); off += sizeof(ag_block_hash_t); } 21 0 : blst_p2_affine_serialize( buf+off, ag_vote_sig( self ) ); off += FD_BLS_SIG_SZ; 22 0 : FD_STORE( ushort, buf+off, vote.shred_version ); off += sizeof(ushort); 23 : 24 0 : return off; 25 0 : } 26 : 27 : int 28 : ag_vote_de( ag_vote_t * self, 29 : uchar const * buf, 30 0 : ulong buf_sz ) { 31 0 : FAIL( buf_sz<2 /* version + tag */, SZ ); 32 : 33 0 : ulong off = 0UL; 34 0 : ag_vote_serde_t vote; 35 0 : vote.version = buf[ off ]; off += sizeof(uchar); 36 0 : vote.tag = buf[ off ]; off += sizeof(uchar); 37 0 : FAIL( vote.version!=1, INVAL ); 38 : 39 0 : uint kind = (uint)vote.tag - AG_VOTE_SERDE_TAG_NOTAR; 40 : 41 0 : int has_block_id = kind==AG_VOTE_KIND_NOTAR || kind==AG_VOTE_KIND_NOTAR_FALLBACK; 42 0 : FAIL( buf_sz<AG_VOTE_SER_SZ( has_block_id ), SZ ); /* too few, trailing bytes are ignored */ 43 : 44 0 : vote.slot = FD_LOAD( ulong, buf+off ); off += sizeof(ulong); 45 0 : vote.block_id = NULL; 46 0 : if( FD_LIKELY( has_block_id ) ) { 47 0 : vote.block_id = buf+off; off += sizeof(ag_block_hash_t); 48 0 : } 49 0 : vote.signature = buf+off; off += FD_BLS_SIG_SZ; 50 : 51 0 : fd_bls_sig_t sig[1]; 52 0 : FAIL( blst_p2_deserialize( sig, vote.signature )!=BLST_SUCCESS, INVAL ); 53 0 : FAIL( blst_p2_affine_is_inf( sig ), SIG ); 54 0 : vote.shred_version = FD_LOAD( ushort, buf+off ); off += sizeof(ushort); 55 : 56 0 : fd_memset( self, 0, sizeof(ag_vote_t) ); 57 0 : self->kind = kind; 58 : 59 0 : switch( kind ) { 60 0 : case AG_VOTE_KIND_NOTAR: 61 0 : self->notar.slot = vote.slot; 62 0 : self->notar.shred_version = vote.shred_version; 63 0 : memcpy( self->notar.block_hash, vote.block_id, sizeof(ag_block_hash_t) ); 64 0 : self->notar.sig = *sig; 65 0 : break; 66 0 : case AG_VOTE_KIND_FINAL: 67 0 : self->final.slot = vote.slot; 68 0 : self->final.shred_version = vote.shred_version; 69 0 : self->final.sig = *sig; 70 0 : break; 71 0 : case AG_VOTE_KIND_SKIP: 72 0 : self->skip.slot = vote.slot; 73 0 : self->skip.shred_version = vote.shred_version; 74 0 : self->skip.sig = *sig; 75 0 : break; 76 0 : case AG_VOTE_KIND_NOTAR_FALLBACK: 77 0 : self->notar_fallback.slot = vote.slot; 78 0 : self->notar_fallback.shred_version = vote.shred_version; 79 0 : memcpy( self->notar_fallback.block_hash, vote.block_id, sizeof(ag_block_hash_t) ); 80 0 : self->notar_fallback.sig = *sig; 81 0 : break; 82 0 : case AG_VOTE_KIND_SKIP_FALLBACK: 83 0 : self->skip_fallback.slot = vote.slot; 84 0 : self->skip_fallback.shred_version = vote.shred_version; 85 0 : self->skip_fallback.sig = *sig; 86 0 : break; 87 0 : default: 88 0 : return AG_VOTE_DE_ERR_INVAL; 89 0 : } 90 : 91 0 : return AG_VOTE_DE_SUCCESS; 92 0 : } 93 : 94 : ulong 95 : ag_vote_signing_ser( uint kind, 96 : ulong slot, 97 : uchar const * block_hash, 98 : ushort shred_version, 99 0 : uchar buf[ static AG_VOTE_SIGNING_SER_MAX ] ) { 100 0 : ulong off = 0UL; 101 0 : buf[ off ] = (uchar)( kind+AG_VOTE_SERDE_TAG_NOTAR ); off += sizeof(uchar); 102 0 : FD_STORE( ulong, buf+off, slot ); off += sizeof(ulong); 103 0 : if( FD_LIKELY( block_hash ) ) { memcpy( buf+off, block_hash, sizeof(ag_block_hash_t) ); off += sizeof(ag_block_hash_t); } 104 0 : FD_STORE( ushort, buf+off, shred_version ); off += sizeof(ushort); 105 0 : return off; 106 0 : }