Line data Source code
1 : #include "fd_ssmanifest_writer.h" 2 : #include "../../flamenco/runtime/fd_system_ids.h" 3 : 4 12 : #define STATE_BLOCKHASH_QUEUE 1 5 12 : #define STATE_HASHES 2 6 12 : #define STATE_HARD_FORKS 3 7 12 : #define STATE_COUNTERS 4 8 12 : #define STATE_VOTE_ACCOUNTS 5 9 0 : #define STATE_STAKE_DELEGATION 6 10 0 : #define STATE_STAKE_EPOCH 7 11 12 : #define STATE_STAKE_HISTORY 8 12 12 : #define STATE_BANK_TRAILER 9 13 0 : #define STATE_ACCOUNT_STORAGE_ENTRY 10 14 12 : #define STATE_BANK_HASH_INFO 11 15 36 : #define STATE_EPOCH_STAKES 12 16 72 : #define STATE_EPOCH_STAKES_STAKES 13 17 54 : #define STATE_EPOCH_STAKES_EPOCH 14 18 0 : #define STATE_EPOCH_STAKE_HISTORY 15 19 36 : #define STATE_EPOCH_TOTAL_STAKE 16 20 36 : #define STATE_NODE_VOTE_ACCOUNTS 17 21 36 : #define STATE_AUTH_VOTER 18 22 30 : #define STATE_LTHASH 19 23 12 : #define STATE_BLOCK_ID 20 24 12 : #define STATE_DONE 21 25 : #define STATE_INIT STATE_BLOCKHASH_QUEUE 26 : 27 : fd_ssmanifest_writer_t * 28 : fd_ssmanifest_writer_init( fd_ssmanifest_writer_t * enc, 29 6 : fd_bank_t * bank ) { 30 6 : enc->state = STATE_BLOCKHASH_QUEUE; 31 6 : enc->bank = bank; 32 6 : enc->epoch_idx = 0; 33 6 : enc->epoch_cnt = 0; 34 6 : enc->vote_cnt = 0; 35 6 : enc->vote_idx = 0; 36 6 : enc->total_stake = 0UL; 37 6 : return enc; 38 6 : } 39 : 40 : static fd_epoch_credits_t const * 41 : find_epoch_credits( fd_bank_t * bank, 42 18 : fd_pubkey_t const * pubkey ) { 43 18 : ulong epoch_credits_len = *fd_bank_epoch_credits_len( bank ); 44 36 : for( ulong i=0UL; i<epoch_credits_len; i++ ) { 45 36 : fd_epoch_credits_t const * epoch_credits = &fd_bank_epoch_credits( bank )[ i ]; 46 36 : if( fd_memeq( epoch_credits->pubkey, pubkey, sizeof(fd_pubkey_t) ) ) return epoch_credits; 47 36 : } 48 0 : return NULL; 49 18 : } 50 : 51 : /* Size estimate */ 52 : 53 : #define ENCODE_FN static ulong manifest_estimate( fd_ssmanifest_writer_t * enc ) 54 105 : #define PREP ulong sz = 0UL; 55 1032 : #define PUSH_VAL(t,n) do { sz += sizeof(t); (void)(n); } while(0) 56 102 : #define RET_EXPR sz 57 : #include "fd_ssmanifest_encoder.c" 58 : 59 : ulong 60 3 : fd_snap_manifest_serialized_sz( fd_bank_t * bank ) { 61 3 : fd_ssmanifest_writer_t writer[1]; 62 3 : fd_ssmanifest_writer_init( writer, bank ); 63 3 : ulong sz = 0UL; 64 105 : for(;;) { 65 105 : ulong chunk = manifest_estimate( writer ); 66 105 : if( FD_UNLIKELY( !chunk ) ) break; 67 102 : sz += chunk; 68 102 : } 69 3 : return sz; 70 3 : } 71 : 72 : /* Actual encoder */ 73 : 74 : __attribute__((cold,noreturn)) 75 : static void fail( fd_ssmanifest_writer_t const * enc, 76 : ulong buf_sz, 77 0 : ulong line_nr ) { 78 0 : FD_LOG_ERR(( "buffer overflow (state=%u, buf_sz=%lu, line_nr=%lu)", enc->state, buf_sz, line_nr )); 79 0 : } 80 : 81 : #define ENCODE_FN \ 82 : ulong \ 83 : fd_snap_manifest_serialize( fd_ssmanifest_writer_t * enc, \ 84 : uchar out_buf[ FD_SSMANIFEST_BUF_MIN ], \ 85 : ulong buf_sz ) 86 : #define PREP \ 87 105 : uchar * p = out_buf; \ 88 105 : uchar * p1 = out_buf+buf_sz; 89 : #define PUSH_VAL( t, n ) \ 90 1032 : FD_STORE( t, __extension__({ \ 91 1032 : /* compile time bounds check elide */ \ 92 1032 : if( FD_UNLIKELY( p+sizeof(t) > p1 ) ) fail( enc, buf_sz, __LINE__ ); \ 93 1032 : uchar * ret = p; \ 94 1032 : p += sizeof(t); \ 95 1032 : ret; \ 96 1032 : }), (n) ) 97 102 : #define RET_EXPR (ulong)( p - out_buf ) 98 : #include "fd_ssmanifest_encoder.c"