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;
60 0 : phdr->info.ul[1] = result->account_header.slot;
61 :
62 0 : dst += sizeof(fd_vinyl_bstream_phdr_t);
63 0 : dst_rem -= sizeof(fd_vinyl_bstream_phdr_t);
64 :
65 0 : FD_CRIT( dst_rem >= sizeof(fd_account_meta_t), "corruption detected" );
66 0 : fd_account_meta_t * meta = (fd_account_meta_t *)dst;
67 0 : memset( meta, 0, sizeof(fd_account_meta_t) ); /* bulk zero */
68 0 : memcpy( meta->owner, result->account_header.owner, sizeof(fd_pubkey_t) );
69 0 : meta->lamports = result->account_header.lamports;
70 0 : meta->slot = result->account_header.slot;
71 0 : meta->dlen = (uint)result->account_header.data_len;
72 0 : meta->executable = (uchar)result->account_header.executable;
73 :
74 0 : dst += sizeof(fd_account_meta_t);
75 0 : dst_rem -= sizeof(fd_account_meta_t);
76 :
77 0 : ctx->metrics.accounts_loaded++;
78 0 : FD_CRIT( dst_rem >= result->account_header.data_len, "corruption detected" );
79 :
80 0 : ctx->vinyl_op.pair = pair;
81 0 : ctx->vinyl_op.pair_sz = pair_sz;
82 0 : ctx->vinyl_op.dst = dst;
83 0 : ctx->vinyl_op.dst_rem = dst_rem;
84 0 : ctx->vinyl_op.data_rem = result->account_header.data_len;
85 :
86 0 : if( !ctx->vinyl_op.data_rem ) {
87 0 : bstream_push_account( ctx );
88 0 : return 1;
89 0 : }
90 0 : return 0;
91 0 : }
92 :
93 : /* fd_snapin_process_account_data_vinyl continues processing a
94 : fragmented account (slow). */
95 :
96 : int
97 : fd_snapin_process_account_data_vinyl( fd_snapin_tile_t * ctx,
98 0 : fd_ssparse_advance_result_t * result ) {
99 0 : if( FD_UNLIKELY( !ctx->vinyl_op.pair ) ) return 0; /* ignored account */
100 :
101 0 : ulong chunk_sz = result->account_data.data_sz;
102 0 : if( FD_LIKELY( chunk_sz ) ) {
103 0 : FD_CRIT( chunk_sz <= ctx->vinyl_op.dst_rem, "corruption detected" );
104 0 : FD_CRIT( chunk_sz <= ctx->vinyl_op.data_rem, "corruption detected" );
105 0 : fd_memcpy( ctx->vinyl_op.dst, result->account_data.data, chunk_sz );
106 0 : ctx->vinyl_op.dst += chunk_sz;
107 0 : ctx->vinyl_op.dst_rem -= chunk_sz;
108 0 : ctx->vinyl_op.data_rem -= chunk_sz;
109 0 : }
110 0 : if( !ctx->vinyl_op.data_rem ) { /* finish store */
111 0 : bstream_push_account( ctx );
112 0 : return 1;
113 0 : }
114 0 : return 0;
115 0 : }
116 :
117 : /* fd_snapin_process_account_batch_vinyl processes a batch of unfragmented
118 : accounts (fast path), converting them into vinyl bstream pairs.
119 : A single fd_stem_publish is issued for the complete batch, and the
120 : chunk always advances by mtu size. */
121 :
122 : int
123 : fd_snapin_process_account_batch_vinyl( fd_snapin_tile_t * ctx,
124 0 : fd_ssparse_advance_result_t * result ) {
125 :
126 0 : uchar * pair = fd_chunk_to_laddr( ctx->hash_out.mem, ctx->hash_out.chunk );
127 :
128 0 : for( ulong i=0UL; i<FD_SSPARSE_ACC_BATCH_MAX; i++ ) {
129 :
130 0 : uchar const * frame = result->account_batch.batch[ i ];
131 0 : ulong const data_len = fd_ulong_load_8_fast( frame+0x08UL );
132 0 : uchar const * pubkey = frame+0x10UL;
133 0 : fd_vinyl_key_t key[1]; fd_vinyl_key_init( key, pubkey, 32UL );
134 0 : ulong lamports = fd_ulong_load_8_fast( frame+0x30UL );
135 0 : uchar owner[32]; memcpy( owner, frame+0x40UL, 32UL );
136 0 : _Bool executable = !!frame[ 0x60UL ];
137 :
138 0 : ulong val_sz = sizeof(fd_account_meta_t) + data_len;
139 0 : FD_CRIT( val_sz<=FD_VINYL_VAL_MAX, "corruption detected" );
140 :
141 0 : ulong pair_sz = fd_vinyl_bstream_pair_sz( val_sz );
142 0 : FD_TEST( pair_sz<=ctx->hash_out.mtu );
143 :
144 0 : uchar * dst = pair;
145 0 : ulong dst_rem = pair_sz;
146 :
147 0 : FD_CRIT( dst_rem >= sizeof(fd_vinyl_bstream_phdr_t), "corruption detected" );
148 0 : fd_vinyl_bstream_phdr_t * phdr = (fd_vinyl_bstream_phdr_t *)dst;
149 0 : phdr->ctl = fd_vinyl_bstream_ctl( FD_VINYL_BSTREAM_CTL_TYPE_PAIR, FD_VINYL_BSTREAM_CTL_STYLE_RAW, val_sz );
150 0 : phdr->key = *key;
151 0 : phdr->info.val_sz = (uint)val_sz;
152 0 : phdr->info.ul[1] = result->account_batch.slot;
153 :
154 0 : dst += sizeof(fd_vinyl_bstream_phdr_t);
155 0 : dst_rem -= sizeof(fd_vinyl_bstream_phdr_t);
156 :
157 0 : FD_CRIT( dst_rem >= sizeof(fd_account_meta_t), "corruption detected" );
158 0 : fd_account_meta_t * meta = (fd_account_meta_t *)dst;
159 0 : memset( meta, 0, sizeof(fd_account_meta_t) ); /* bulk zero */
160 0 : memcpy( meta->owner, owner, sizeof(fd_pubkey_t) );
161 0 : meta->lamports = lamports;
162 0 : meta->slot = result->account_batch.slot;
163 0 : meta->dlen = (uint)data_len;
164 0 : meta->executable = !!executable;
165 :
166 0 : dst += sizeof(fd_account_meta_t);
167 0 : dst_rem -= sizeof(fd_account_meta_t);
168 :
169 0 : FD_CRIT( dst_rem >= data_len, "corruption detected" );
170 0 : fd_memcpy( dst, frame+0x88UL, data_len );
171 :
172 0 : dst += data_len;
173 0 : dst_rem -= data_len;
174 :
175 0 : pair += pair_sz;
176 :
177 0 : ctx->metrics.accounts_loaded++;
178 0 : }
179 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*/ );
180 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 );
181 0 : return 1;
182 0 : }
183 :
184 : void
185 0 : fd_snapin_vinyl_shutdown( fd_snapin_tile_t * ctx ) {
186 0 : (void)ctx;
187 0 : }
|