Line data Source code
1 : #include "fd_snapin_tile_private.h"
2 : #include "utils/fd_ssparse.h"
3 : #include "utils/fd_vinyl_io_wd.h"
4 :
5 : /* bstream_push_account finishes processing a single account (pair).
6 : A single fd_stem_publish is issued, and the chunk always advances
7 : by mtu size. */
8 :
9 : static inline void
10 0 : bstream_push_account( fd_snapin_tile_t * ctx ) {
11 0 : FD_CRIT( !ctx->vinyl_op.data_rem, "incomplete account store" );
12 0 : FD_CRIT( ctx->vinyl_op.pair, "no store in progres" );
13 :
14 0 : fd_stem_publish( ctx->stem, ctx->hash_out.idx, FD_SNAPSHOT_MSG_DATA/*sig*/, ctx->hash_out.chunk, 1UL/*sz=acc_cnt*/, 0UL, 0UL/*tsorig*/, 0UL/*tspub*/ );
15 0 : ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, ctx->hash_out.mtu, ctx->hash_out.chunk0, ctx->hash_out.wmark );
16 :
17 0 : ctx->vinyl_op.pair = NULL;
18 0 : ctx->vinyl_op.pair_sz = 0UL;
19 0 : ctx->vinyl_op.dst = NULL;
20 0 : ctx->vinyl_op.dst_rem = 0UL;
21 0 : ctx->vinyl_op.meta_ele = NULL;
22 0 : }
23 :
24 : /* fd_snapin_process_account_header_vinyl starts processing a
25 : (possibly fragmented) account (slow). */
26 :
27 : int
28 : fd_snapin_process_account_header_vinyl( fd_snapin_tile_t * ctx,
29 0 : fd_ssparse_advance_result_t * result ) {
30 0 : FD_CRIT( !ctx->vinyl_op.dst_rem, "incomplete account store" );
31 0 : FD_CRIT( !ctx->vinyl_op.pair, "incomplete account store" );
32 :
33 0 : ulong val_sz = sizeof(fd_account_meta_t) + result->account_header.data_len;
34 0 : FD_CRIT( val_sz<=FD_VINYL_VAL_MAX, "corruption detected" );
35 :
36 0 : ulong pair_sz = fd_vinyl_bstream_pair_sz( val_sz );
37 0 : FD_TEST( pair_sz<=ctx->hash_out.mtu );
38 0 : uchar * pair = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
39 :
40 0 : uchar * dst = pair;
41 0 : ulong dst_rem = pair_sz;
42 :
43 0 : FD_CRIT( dst_rem >= sizeof(fd_vinyl_bstream_phdr_t), "corruption detected" );
44 0 : fd_vinyl_bstream_phdr_t * phdr = (fd_vinyl_bstream_phdr_t *)dst;
45 :
46 0 : phdr->ctl = fd_vinyl_bstream_ctl( FD_VINYL_BSTREAM_CTL_TYPE_PAIR, FD_VINYL_BSTREAM_CTL_STYLE_RAW, val_sz );
47 0 : fd_vinyl_key_init( &phdr->key, result->account_header.pubkey, 32UL );
48 0 : phdr->info.val_sz = (uint)val_sz; /* info.ui[ 0 ] */
49 0 : phdr->info.ui[ 1 ] = 0U;
50 0 : phdr->info.ul[ 1 ] = result->account_header.slot;
51 :
52 0 : dst += sizeof(fd_vinyl_bstream_phdr_t);
53 0 : dst_rem -= sizeof(fd_vinyl_bstream_phdr_t);
54 :
55 0 : FD_CRIT( dst_rem >= sizeof(fd_account_meta_t), "corruption detected" );
56 0 : fd_account_meta_t * meta = (fd_account_meta_t *)dst;
57 0 : memset( meta, 0, sizeof(fd_account_meta_t) ); /* bulk zero */
58 0 : memcpy( meta->owner, result->account_header.owner, sizeof(fd_pubkey_t) );
59 0 : meta->lamports = result->account_header.lamports;
60 0 : meta->slot = result->account_header.slot;
61 0 : meta->dlen = (uint)result->account_header.data_len;
62 0 : meta->executable = (uchar)result->account_header.executable;
63 :
64 0 : dst += sizeof(fd_account_meta_t);
65 0 : dst_rem -= sizeof(fd_account_meta_t);
66 :
67 0 : ctx->metrics.accounts_loaded++;
68 0 : FD_CRIT( dst_rem >= result->account_header.data_len, "corruption detected" );
69 :
70 0 : ctx->vinyl_op.pair = pair;
71 0 : ctx->vinyl_op.pair_sz = pair_sz;
72 0 : ctx->vinyl_op.dst = dst;
73 0 : ctx->vinyl_op.dst_rem = dst_rem;
74 0 : ctx->vinyl_op.data_rem = result->account_header.data_len;
75 :
76 0 : if( !ctx->vinyl_op.data_rem ) {
77 0 : bstream_push_account( ctx );
78 0 : return 1;
79 0 : }
80 0 : return 0;
81 0 : }
82 :
83 : /* fd_snapin_process_account_data_vinyl continues processing a
84 : fragmented account (slow). */
85 :
86 : int
87 : fd_snapin_process_account_data_vinyl( fd_snapin_tile_t * ctx,
88 0 : fd_ssparse_advance_result_t * result ) {
89 0 : if( FD_UNLIKELY( !ctx->vinyl_op.pair ) ) return 0; /* ignored account */
90 :
91 0 : ulong chunk_sz = result->account_data.data_sz;
92 0 : if( FD_LIKELY( chunk_sz ) ) {
93 0 : FD_CRIT( chunk_sz <= ctx->vinyl_op.dst_rem, "corruption detected" );
94 0 : FD_CRIT( chunk_sz <= ctx->vinyl_op.data_rem, "corruption detected" );
95 0 : fd_memcpy( ctx->vinyl_op.dst, result->account_data.data, chunk_sz );
96 0 : ctx->vinyl_op.dst += chunk_sz;
97 0 : ctx->vinyl_op.dst_rem -= chunk_sz;
98 0 : ctx->vinyl_op.data_rem -= chunk_sz;
99 0 : }
100 0 : if( !ctx->vinyl_op.data_rem ) { /* finish store */
101 0 : bstream_push_account( ctx );
102 0 : return 1;
103 0 : }
104 0 : return 0;
105 0 : }
106 :
107 : /* fd_snapin_process_account_batch_vinyl processes a batch of unfragmented
108 : accounts (fast path), converting them into vinyl bstream pairs.
109 : A single fd_stem_publish is issued for the complete batch, and the
110 : chunk always advances by mtu size. */
111 :
112 : int
113 : fd_snapin_process_account_batch_vinyl( fd_snapin_tile_t * ctx,
114 0 : fd_ssparse_advance_result_t * result ) {
115 :
116 0 : uchar * pair = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
117 :
118 0 : for( ulong i=0UL; i<FD_SSPARSE_ACC_BATCH_MAX; i++ ) {
119 :
120 0 : uchar const * frame = result->account_batch.batch[ i ];
121 0 : ulong const data_len = fd_ulong_load_8_fast( frame+0x08UL );
122 0 : uchar const * pubkey = frame+0x10UL;
123 0 : fd_vinyl_key_t key[1]; fd_vinyl_key_init( key, pubkey, 32UL );
124 0 : ulong lamports = fd_ulong_load_8_fast( frame+0x30UL );
125 0 : uchar owner[32]; memcpy( owner, frame+0x40UL, 32UL );
126 0 : _Bool executable = !!frame[ 0x60UL ];
127 :
128 0 : ulong val_sz = sizeof(fd_account_meta_t) + data_len;
129 0 : FD_CRIT( val_sz<=FD_VINYL_VAL_MAX, "corruption detected" );
130 :
131 0 : ulong pair_sz = fd_vinyl_bstream_pair_sz( val_sz );
132 0 : FD_TEST( pair_sz<=ctx->hash_out.mtu );
133 :
134 0 : uchar * dst = pair;
135 0 : ulong dst_rem = pair_sz;
136 :
137 0 : FD_CRIT( dst_rem >= sizeof(fd_vinyl_bstream_phdr_t), "corruption detected" );
138 0 : fd_vinyl_bstream_phdr_t * phdr = (fd_vinyl_bstream_phdr_t *)dst;
139 0 : memset( phdr, 0, sizeof(fd_vinyl_bstream_phdr_t) );
140 0 : phdr->ctl = fd_vinyl_bstream_ctl( FD_VINYL_BSTREAM_CTL_TYPE_PAIR, FD_VINYL_BSTREAM_CTL_STYLE_RAW, val_sz );
141 0 : phdr->key = *key;
142 0 : phdr->info.val_sz = (uint)val_sz; /* info.ui[ 0 ] */
143 0 : phdr->info.ui[ 1 ] = 0U;
144 0 : phdr->info.ul[ 1 ] = result->account_batch.slot;
145 :
146 0 : dst += sizeof(fd_vinyl_bstream_phdr_t);
147 0 : dst_rem -= sizeof(fd_vinyl_bstream_phdr_t);
148 :
149 0 : FD_CRIT( dst_rem >= sizeof(fd_account_meta_t), "corruption detected" );
150 0 : fd_account_meta_t * meta = (fd_account_meta_t *)dst;
151 0 : memset( meta, 0, sizeof(fd_account_meta_t) );
152 0 : memcpy( meta->owner, owner, sizeof(fd_pubkey_t) );
153 0 : meta->lamports = lamports;
154 0 : meta->slot = result->account_batch.slot;
155 0 : meta->dlen = (uint)data_len;
156 0 : meta->executable = !!executable;
157 :
158 0 : dst += sizeof(fd_account_meta_t);
159 0 : dst_rem -= sizeof(fd_account_meta_t);
160 :
161 0 : FD_CRIT( dst_rem >= data_len, "corruption detected" );
162 0 : fd_memcpy( dst, frame+0x88UL, data_len );
163 :
164 0 : dst += data_len;
165 0 : dst_rem -= data_len;
166 :
167 0 : pair += pair_sz;
168 :
169 0 : ctx->metrics.accounts_loaded++;
170 0 : }
171 0 : fd_stem_publish( ctx->stem, ctx->hash_out.idx, FD_SNAPSHOT_MSG_DATA/*sig*/, ctx->hash_out.chunk, FD_SSPARSE_ACC_BATCH_MAX/*sz=acc_cnt*/, 0UL, 0UL/*tsorig*/, 0UL/*tspub*/ );
172 0 : ctx->hash_out.chunk = fd_dcache_compact_next( ctx->hash_out.chunk, ctx->hash_out.mtu, ctx->hash_out.chunk0, ctx->hash_out.wmark );
173 0 : return 1;
174 0 : }
|