Line data Source code
1 : /* Serialize status_cache (Vec<SlotDelta>) for a Solana snapshot. 2 : Included twice: once for size estimation, once for actual encoding. 3 : See fd_ssmanifest_encoder.c for the pattern. */ 4 : 5 54 : ENCODE_FN { 6 : 7 54 : PREP 8 : 9 54 : fd_txncache_writer_tc_t const * tc = (fd_txncache_writer_tc_t const *)enc->tc; 10 : 11 54 : switch( enc->state ) { 12 : 13 6 : case STATE_HEADER: { 14 3 : ulong root_cnt = 0UL; 15 3 : for( ulong it = root_slist_iter_init( tc->shmem->root_ll, tc->blockcache_shmem_pool ); 16 30 : !root_slist_iter_done( it, tc->shmem->root_ll, tc->blockcache_shmem_pool ); 17 24 : it = root_slist_iter_next( it, tc->shmem->root_ll, tc->blockcache_shmem_pool ) ) { 18 24 : root_cnt++; 19 24 : } 20 6 : PUSH_VAL( ulong, 1UL ); /* slot_deltas_len = 1 */ 21 6 : PUSH_VAL( ulong, enc->slot ); /* slot */ 22 6 : PUSH_VAL( uchar, 1 ); /* is_root = true */ 23 6 : PUSH_VAL( ulong, root_cnt ); /* status_len */ 24 3 : enc->root_iter = root_slist_iter_init( tc->shmem->root_ll, tc->blockcache_shmem_pool ); 25 6 : if( root_slist_iter_done( enc->root_iter, tc->shmem->root_ll, tc->blockcache_shmem_pool ) ) { 26 0 : enc->state = STATE_DONE; 27 6 : } else { 28 6 : enc->state = STATE_BLOCKHASH; 29 6 : } 30 3 : break; 31 3 : } 32 : 33 24 : case STATE_BLOCKHASH: { 34 12 : ulong bc_idx = root_slist_iter_idx( enc->root_iter, tc->shmem->root_ll, tc->blockcache_shmem_pool ); 35 12 : fd_txncache_blockcache_shmem_t const * bc_shmem = &tc->blockcache_shmem_pool[ bc_idx ]; 36 : 37 24 : PUSH_VAL( fd_hash_t, bc_shmem->blockhash ); 38 24 : PUSH_VAL( ulong, bc_shmem->txnhash_offset ); 39 : 40 12 : ulong txn_cnt = txncache_count_txns( tc, enc->snapshot_root_idx, bc_idx ); 41 24 : PUSH_VAL( ulong, txn_cnt ); 42 : 43 24 : if( txn_cnt ) { 44 18 : fd_txncache_writer_blockcache_t const * bc = &tc->blockcache_pool[ bc_idx ]; 45 18 : enc->page_idx = 0UL; 46 18 : enc->txn_idx = 0UL; 47 18 : enc->txns_in_page = FD_TXNCACHE_TXNS_PER_PAGE - (ulong)tc->txnpages[ bc->pages[ 0 ] ].free; 48 18 : enc->state = STATE_TXNS; 49 18 : } else { 50 6 : enc->root_iter = root_slist_iter_next( enc->root_iter, tc->shmem->root_ll, tc->blockcache_shmem_pool ); 51 6 : if( root_slist_iter_done( enc->root_iter, tc->shmem->root_ll, tc->blockcache_shmem_pool ) ) { 52 6 : enc->state = STATE_DONE; 53 6 : } 54 6 : } 55 12 : break; 56 12 : } 57 : 58 18 : case STATE_TXNS: { 59 9 : ulong bc_idx = root_slist_iter_idx( enc->root_iter, tc->shmem->root_ll, tc->blockcache_shmem_pool ); 60 9 : fd_txncache_blockcache_shmem_t const * bc_shmem = &tc->blockcache_shmem_pool[ bc_idx ]; 61 9 : fd_txncache_writer_blockcache_t const * bc = &tc->blockcache_pool[ bc_idx ]; 62 : 63 36 : while( enc->page_idx < (ulong)bc_shmem->pages_cnt ) { 64 18 : fd_txncache_txnpage_t const * page = &tc->txnpages[ bc->pages[ enc->page_idx ] ]; 65 60 : while( enc->txn_idx < enc->txns_in_page ) { 66 42 : fd_txncache_single_txn_t const * txn = page->txns[ enc->txn_idx ]; 67 42 : if( FD_UNLIKELY( !txncache_txn_on_snapshot_root( tc, enc->snapshot_root_idx, txn ) ) ) { 68 6 : enc->txn_idx++; 69 6 : continue; 70 6 : } 71 36 : fd_txnhash_20_t h; 72 36 : __builtin_memcpy( h.b, txn->txnhash, 20UL ); 73 36 : PUSH_VAL( fd_txnhash_20_t, h ); 74 36 : PUSH_VAL( uint, 0U ); /* result = Ok */ 75 18 : enc->txn_idx++; 76 18 : } 77 9 : enc->page_idx++; 78 9 : enc->txn_idx = 0UL; 79 18 : if( enc->page_idx < (ulong)bc_shmem->pages_cnt ) { 80 0 : enc->txns_in_page = FD_TXNCACHE_TXNS_PER_PAGE - (ulong)tc->txnpages[ bc->pages[ enc->page_idx ] ].free; 81 0 : } 82 9 : } 83 : 84 9 : enc->root_iter = root_slist_iter_next( enc->root_iter, tc->shmem->root_ll, tc->blockcache_shmem_pool ); 85 18 : if( root_slist_iter_done( enc->root_iter, tc->shmem->root_ll, tc->blockcache_shmem_pool ) ) { 86 0 : enc->state = STATE_DONE; 87 18 : } else { 88 18 : enc->state = STATE_BLOCKHASH; 89 18 : } 90 9 : break; 91 9 : } 92 : 93 6 : case STATE_DONE: 94 6 : return 0UL; 95 : 96 0 : default: 97 0 : FD_LOG_CRIT(( "invalid state reached (%u)", enc->state )); 98 54 : } 99 : 100 48 : return RET_EXPR; 101 54 : } 102 : 103 : #undef PREP 104 : #undef ENCODE_FN 105 : #undef PUSH_VAL 106 : #undef RET_EXPR