7
7
#include "../../flamenco/runtime/fd_acc_mgr.h"
8
8
#include "../../flamenco/types/fd_types.h"
9
9
#include "../../funk/fd_funk.h"
10
+ #include "../../ballet/lthash/fd_lthash.h"
11
+ #include "../../flamenco/runtime/fd_hashes.h"
10
12
11
13
#define NAME "snapin"
12
14
@@ -31,9 +33,23 @@ struct fd_snapin_tile {
31
33
fd_funk_txn_t * funk_txn ;
32
34
uchar * acc_data ;
33
35
34
- fd_stem_context_t * stem ;
36
+ fd_stem_context_t * stem ;
35
37
fd_snapshot_parser_t * ssparse ;
36
38
39
+ struct {
40
+
41
+ struct {
42
+ fd_lthash_value_t lthash ;
43
+ fd_lthash_value_t manifest_lthash ;
44
+ } full ;
45
+
46
+ struct {
47
+ fd_lthash_value_t lthash ;
48
+ fd_lthash_value_t manifest_lthash ;
49
+ } incremental ;
50
+
51
+ } lthash_info ;
52
+
37
53
struct {
38
54
ulong full_bytes_read ;
39
55
ulong incremental_bytes_read ;
@@ -95,6 +111,11 @@ manifest_cb( void * _ctx,
95
111
fd_snapin_tile_t * ctx = (fd_snapin_tile_t * )_ctx ;
96
112
97
113
ulong sz = sizeof (fd_snapshot_manifest_t )+ manifest_sz ;
114
+
115
+ fd_snapshot_manifest_t * manifest = (fd_snapshot_manifest_t * )fd_chunk_to_laddr_const ( ctx -> manifest_out .wksp , ctx -> manifest_out .chunk );
116
+ uchar * manifest_lthash = ctx -> full ? ctx -> lthash_info .full .manifest_lthash .bytes : ctx -> lthash_info .incremental .manifest_lthash .bytes ;
117
+ fd_memcpy ( manifest_lthash , manifest -> accounts_lthash , sizeof (fd_lthash_value_t ) );
118
+
98
119
FD_TEST ( sz <=ctx -> manifest_out .mtu );
99
120
ulong sig = ctx -> full ? fd_ssmsg_sig ( FD_SSMSG_MANIFEST_FULL , manifest_sz ) :
100
121
fd_ssmsg_sig ( FD_SSMSG_MANIFEST_INCREMENTAL , manifest_sz );
@@ -117,6 +138,19 @@ is_duplicate_account( fd_snapin_tile_t * ctx,
117
138
/* TODO: Reaching here means the existing value is a duplicate
118
139
account. We need to hash the existing account and subtract that
119
140
hash from the running lthash. */
141
+ fd_lthash_value_t old_account_lthash [1 ];
142
+ fd_lthash_value_t * lthash = ctx -> full ? & ctx -> lthash_info .full .lthash : & ctx -> lthash_info .incremental .lthash ;
143
+ fd_hashes_account_lthash ( (fd_pubkey_t * )account_pubkey ,
144
+ rec_meta ,
145
+ fd_account_meta_get_data_const ( rec_meta ),
146
+ old_account_lthash );
147
+ FD_LOG_WARNING (("subtracting old account hash %s for pubkey %s from lthash %s" ,
148
+ FD_LTHASH_ENC_32_ALLOCA ( old_account_lthash ),
149
+ FD_BASE58_ENC_32_ALLOCA ( (fd_pubkey_t * )account_pubkey ),
150
+ FD_LTHASH_ENC_32_ALLOCA ( lthash )));
151
+ fd_lthash_sub ( lthash , old_account_lthash );
152
+ FD_LOG_WARNING (("resulting lthash %s" ,
153
+ FD_LTHASH_ENC_32_ALLOCA ( lthash )));
120
154
}
121
155
122
156
return 0 ;
@@ -151,6 +185,21 @@ account_cb( void * _ctx,
151
185
ctx -> acc_data = fd_txn_account_get_data_mut ( rec );
152
186
ctx -> metrics .accounts_inserted ++ ;
153
187
fd_txn_account_mutable_fini ( rec , ctx -> funk , ctx -> funk_txn , & prepare );
188
+
189
+ fd_lthash_value_t new_account_lthash [1 ];
190
+ fd_lthash_value_t * lthash = ctx -> full ? & ctx -> lthash_info .full .lthash : & ctx -> lthash_info .incremental .lthash ;
191
+ fd_hashes_account_lthash ( (fd_pubkey_t * )hdr -> meta .pubkey ,
192
+ fd_txn_account_get_meta ( rec ),
193
+ fd_txn_account_get_data ( rec ),
194
+ new_account_lthash );
195
+ FD_LOG_WARNING (("adding new account hash %s for pubkey %s from lthash %s" ,
196
+ FD_LTHASH_ENC_32_ALLOCA ( new_account_lthash ),
197
+ FD_BASE58_ENC_32_ALLOCA ( (fd_pubkey_t * )hdr -> meta .pubkey ),
198
+ FD_LTHASH_ENC_32_ALLOCA ( lthash )));
199
+ fd_lthash_add ( lthash , new_account_lthash );
200
+ FD_LOG_WARNING (("resulting lthash %s" ,
201
+ FD_LTHASH_ENC_32_ALLOCA ( lthash )));
202
+
154
203
}
155
204
156
205
static void
@@ -220,13 +269,19 @@ handle_control_frag( fd_snapin_tile_t * ctx,
220
269
ctx -> full = 1 ;
221
270
fd_snapshot_parser_reset ( ctx -> ssparse , fd_chunk_to_laddr ( ctx -> manifest_out .wksp , ctx -> manifest_out .chunk ), ctx -> manifest_out .mtu );
222
271
fd_funk_txn_cancel_root ( ctx -> funk );
272
+ fd_lthash_zero ( & ctx -> lthash_info .full .lthash );
273
+ fd_lthash_zero ( & ctx -> lthash_info .incremental .lthash );
274
+ fd_lthash_zero ( & ctx -> lthash_info .full .manifest_lthash );
275
+ fd_lthash_zero ( & ctx -> lthash_info .incremental .manifest_lthash );
223
276
ctx -> state = FD_SNAPIN_STATE_LOADING ;
224
277
break ;
225
278
case FD_SNAPSHOT_MSG_CTRL_RESET_INCREMENTAL :
226
279
ctx -> full = 0 ;
227
280
fd_snapshot_parser_reset ( ctx -> ssparse , fd_chunk_to_laddr ( ctx -> manifest_out .wksp , ctx -> manifest_out .chunk ), ctx -> manifest_out .mtu );
228
281
if ( FD_UNLIKELY ( !ctx -> funk_txn ) ) fd_funk_txn_cancel_root ( ctx -> funk );
229
282
else fd_funk_txn_cancel ( ctx -> funk , ctx -> funk_txn , 0 );
283
+ fd_lthash_zero ( & ctx -> lthash_info .incremental .lthash );
284
+ fd_lthash_zero ( & ctx -> lthash_info .incremental .manifest_lthash );
230
285
ctx -> state = FD_SNAPIN_STATE_LOADING ;
231
286
break ;
232
287
case FD_SNAPSHOT_MSG_CTRL_EOF_FULL :
@@ -237,6 +292,14 @@ handle_control_frag( fd_snapin_tile_t * ctx,
237
292
break ;
238
293
}
239
294
295
+ if ( FD_UNLIKELY ( memcmp ( ctx -> lthash_info .full .lthash .bytes , ctx -> lthash_info .full .manifest_lthash .bytes , sizeof (fd_lthash_value_t ) ) ) ) {
296
+ FD_LOG_WARNING (( "calculated accounts lthash %s does not match accounts lthash %s in snapshot manifest" ,
297
+ FD_LTHASH_ENC_32_ALLOCA ( & ctx -> lthash_info .full .lthash ),
298
+ FD_LTHASH_ENC_32_ALLOCA ( & ctx -> lthash_info .full .manifest_lthash ) ));
299
+ transition_malformed ( ctx , stem );
300
+ break ;
301
+ }
302
+
240
303
fd_snapshot_parser_reset ( ctx -> ssparse , fd_chunk_to_laddr ( ctx -> manifest_out .wksp , ctx -> manifest_out .chunk ), ctx -> manifest_out .mtu );
241
304
242
305
fd_funk_txn_xid_t incremental_xid = fd_funk_generate_xid ();
@@ -251,6 +314,15 @@ handle_control_frag( fd_snapin_tile_t * ctx,
251
314
break ;
252
315
}
253
316
317
+ if ( FD_UNLIKELY ( memcmp ( ctx -> lthash_info .full .lthash .bytes , ctx -> lthash_info .full .manifest_lthash .bytes , sizeof (fd_lthash_value_t ) ) ||
318
+ memcmp ( ctx -> lthash_info .incremental .lthash .bytes , ctx -> lthash_info .incremental .manifest_lthash .bytes , sizeof (fd_lthash_value_t ) ) ) ) {
319
+ FD_LOG_WARNING (( "calculated accounts lthash %s does not match accounts lthash %s in snapshot manifest" ,
320
+ FD_LTHASH_ENC_32_ALLOCA ( & ctx -> lthash_info .full .lthash ),
321
+ FD_LTHASH_ENC_32_ALLOCA ( & ctx -> lthash_info .full .manifest_lthash ) ));
322
+ transition_malformed ( ctx , stem );
323
+ break ;
324
+ }
325
+
254
326
if ( FD_LIKELY ( ctx -> funk_txn ) ) fd_funk_txn_publish_into_parent ( ctx -> funk , ctx -> funk_txn , 0 );
255
327
fd_stem_publish ( stem , 0UL , fd_ssmsg_sig ( FD_SSMSG_DONE , 0UL ), 0UL , 0UL , 0UL , 0UL , 0UL );
256
328
break ;
@@ -346,6 +418,11 @@ unprivileged_init( fd_topo_t * topo,
346
418
ctx -> in .chunk0 = fd_dcache_compact_chunk0 ( ctx -> in .wksp , in_link -> dcache );
347
419
ctx -> in .wmark = fd_dcache_compact_wmark ( ctx -> in .wksp , in_link -> dcache , in_link -> mtu );
348
420
ctx -> in .mtu = in_link -> mtu ;
421
+
422
+ fd_lthash_zero ( & ctx -> lthash_info .full .lthash );
423
+ fd_lthash_zero ( & ctx -> lthash_info .incremental .lthash );
424
+ fd_lthash_zero ( & ctx -> lthash_info .full .manifest_lthash );
425
+ fd_lthash_zero ( & ctx -> lthash_info .incremental .manifest_lthash );
349
426
}
350
427
351
428
#define STEM_BURST 2UL /* For control fragments, one acknowledgement, and one malformed message */
0 commit comments