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