Skip to content

Commit c0d78f8

Browse files
batch lthash
1 parent 3b1b286 commit c0d78f8

File tree

2 files changed

+172
-30
lines changed

2 files changed

+172
-30
lines changed

src/ballet/lthash/fd_lthash_adder.h

Lines changed: 145 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ struct __attribute__((aligned(FD_LTHASH_ADDER_ALIGN))) fd_lthash_adder {
2929

3030
uint batch_cnt;
3131

32+
struct {
33+
uchar pubkey[ 32UL ];
34+
uchar owner[ 32UL ];
35+
uchar executable;
36+
ulong data_len;
37+
int valid;
38+
} buffered_account;
39+
40+
struct {
41+
uchar * data;
42+
ulong data_sz;
43+
ulong data_max;
44+
} buffered_data;
45+
46+
fd_blake3_t blake[1];
47+
3248
#if FD_LTHASH_ADDER_PARA_MAX>1
3349

3450
uchar batch_data[ FD_LTHASH_ADDER_PARA_MAX*FD_BLAKE3_CHUNK_SZ ]
@@ -66,10 +82,9 @@ fd_lthash_adder_push( fd_lthash_adder_t * adder,
6682
ulong const batch_threshold = 512UL;
6783
fd_lthash_value_t value[1];
6884
if( FD_UNLIKELY( input_sz>batch_threshold ) ) {
69-
fd_blake3_t blake[1];
70-
fd_blake3_init( blake );
71-
fd_blake3_append( blake, input, input_sz );
72-
fd_blake3_fini_2048( blake, value->bytes );
85+
fd_blake3_init( adder->blake );
86+
fd_blake3_append( adder->blake, input, input_sz );
87+
fd_blake3_fini_2048( adder->blake, value->bytes );
7388
fd_lthash_add( sum, value );
7489
return;
7590
}
@@ -99,15 +114,136 @@ fd_lthash_adder_flush( fd_lthash_adder_t * adder,
99114
uint batch_cnt = adder->batch_cnt;
100115
for( uint i=0U; i<batch_cnt; i++ ) {
101116
fd_lthash_value_t value[1];
102-
fd_blake3_t blake[1];
103-
fd_blake3_init( blake );
104-
fd_blake3_append( blake, (void const *)adder->batch_ptrs[ i ], adder->batch_sz[ i ] );
105-
fd_blake3_fini_2048( blake, value->bytes );
117+
fd_blake3_init( adder->blake );
118+
fd_blake3_append( adder->blake, (void const *)adder->batch_ptrs[ i ], adder->batch_sz[ i ] );
119+
fd_blake3_fini_2048( adder->blake, value->bytes );
106120
fd_lthash_add( sum, value );
107121
}
108122
adder->batch_cnt = 0U;
109123
}
110124

125+
/* fd_lthash_adder_stream_account_hdr buffers account metadata into
126+
the lthash adder. */
127+
static inline int
128+
fd_lthash_adder_stream_account_hdr(
129+
fd_lthash_adder_t * adder,
130+
fd_lthash_value_t * sum,
131+
void const * pubkey,
132+
ulong data_sz,
133+
ulong lamports,
134+
uchar executable,
135+
void const * owner
136+
) {
137+
fd_lthash_value_t value[1];
138+
139+
ulong const static_sz = 0UL;
140+
ulong const batch_threshold = 0UL;
141+
142+
adder->buffered_data.data_sz = 0UL;
143+
adder->buffered_data.data_max = 0UL;
144+
145+
if( FD_UNLIKELY( data_sz > batch_threshold-static_sz || /* optimize for small appends */
146+
FD_BLAKE3_PARA_MAX==0 ) ) {
147+
adder->buffered_account.valid = 1;
148+
adder->buffered_account.executable = executable;
149+
adder->buffered_account.data_len = data_sz;
150+
memcpy( adder->buffered_account.pubkey, pubkey, 32UL );
151+
memcpy( adder->buffered_account.owner, owner, 32UL );
152+
adder->buffered_data.data_max = data_sz;
153+
154+
fd_blake3_init( adder->blake );
155+
fd_blake3_append( adder->blake, &lamports, sizeof(ulong) );
156+
157+
if( FD_UNLIKELY( data_sz==0UL ) ) {
158+
uchar footer[ 65 ];
159+
footer[ 0 ] = executable;
160+
memcpy( footer+1, owner, 32 );
161+
memcpy( footer+33, pubkey, 32 );
162+
fd_blake3_append( adder->blake, footer, sizeof(footer) );
163+
fd_blake3_fini_2048( adder->blake, value->bytes );
164+
fd_lthash_add( sum, value );
165+
return 1;
166+
}
167+
} else {
168+
uint batch_idx = adder->batch_cnt++;
169+
uchar * slot = (uchar *)adder->batch_ptrs[ batch_idx ];
170+
uchar * p = slot;
171+
172+
/* Fixed size header */
173+
FD_STORE( ulong, p, lamports );
174+
p += sizeof(ulong);
175+
/* Variable size content */
176+
adder->buffered_data.data = p;
177+
adder->buffered_data.data_max = data_sz;
178+
p += data_sz;
179+
/* Fixed size footer */
180+
p[0] = executable; p += 1;
181+
fd_memcpy( p, owner, 32 ); p += 32;
182+
fd_memcpy( p, pubkey, 32 ); p += 32;
183+
184+
adder->batch_sz[ batch_idx ] = (uint)( p-slot );
185+
186+
if( batch_idx+1>=FD_BLAKE3_PARA_MAX && data_sz==0UL ) {
187+
# if FD_HAS_AVX512
188+
fd_blake3_lthash_batch16( (void const **)fd_type_pun_const( adder->batch_ptrs ), adder->batch_sz, value->words );
189+
# elif FD_HAS_AVX
190+
fd_blake3_lthash_batch8 ( (void const **)fd_type_pun_const( adder->batch_ptrs ), adder->batch_sz, value->words );
191+
# endif
192+
adder->batch_cnt = 0;
193+
fd_lthash_add( sum, value );
194+
}
195+
}
196+
return 0;
197+
}
198+
199+
/* fd_lthash_adder_stream_account_data buffers account data
200+
into the lthash adder. */
201+
202+
static inline int
203+
fd_lthash_adder_stream_account_data(
204+
fd_lthash_adder_t * adder,
205+
fd_lthash_value_t * sum,
206+
uchar const * data,
207+
ulong data_sz
208+
) {
209+
fd_lthash_value_t value[1];
210+
fd_lthash_zero( value );
211+
/* FIXME opportunities for memcpy hax here */
212+
213+
if( FD_UNLIKELY( adder->buffered_account.valid ) ) {
214+
fd_blake3_append( adder->blake, data, data_sz );
215+
} else {
216+
fd_memcpy( adder->buffered_data.data+adder->buffered_data.data_sz, data, data_sz );
217+
}
218+
adder->buffered_data.data_sz += data_sz;
219+
220+
if( FD_LIKELY( adder->buffered_data.data_sz==adder->buffered_data.data_max ) ) {
221+
if( adder->buffered_account.valid ) {
222+
uchar footer[ 65 ];
223+
footer[ 0 ] = adder->buffered_account.executable;
224+
memcpy( footer+1, adder->buffered_account.owner, 32 );
225+
memcpy( footer+33, adder->buffered_account.pubkey, 32 );
226+
fd_blake3_append( adder->blake, footer, sizeof(footer) );
227+
fd_blake3_fini_2048( adder->blake, value->bytes );
228+
fd_lthash_add( sum, value );
229+
adder->buffered_account.valid = 0;
230+
return 1;
231+
} else {
232+
uint batch_idx = adder->batch_cnt;
233+
if( batch_idx+1>=FD_BLAKE3_PARA_MAX ) {
234+
# if FD_HAS_AVX512
235+
fd_blake3_lthash_batch16( (void const **)fd_type_pun_const( adder->batch_ptrs ), adder->batch_sz, value->words );
236+
# elif FD_HAS_AVX
237+
fd_blake3_lthash_batch8 ( (void const **)fd_type_pun_const( adder->batch_ptrs ), adder->batch_sz, value->words );
238+
# endif
239+
adder->batch_cnt = 0;
240+
fd_lthash_add( sum, value );
241+
}
242+
}
243+
}
244+
return 0;
245+
}
246+
111247
/* fd_lthash_adder_push_solana_account wraps fd_lthash_adder_push for
112248
Solana account inputs. */
113249

@@ -171,6 +307,7 @@ fd_lthash_adder_push_solana_account(
171307
}
172308
}
173309

310+
174311
FD_PROTOTYPES_END
175312

176313
#endif /* HEADER_fd_src_ballet_lthash_fd_lthash_adder_h */

src/discof/restore/fd_snaplt_tile.c

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "../../ballet/lthash/fd_lthash.h"
44
#include "../../flamenco/runtime/fd_hashes.h"
55
#include "../../flamenco/runtime/fd_acc_mgr.h"
6+
#include "../../ballet/lthash/fd_lthash_adder.h"
67

78
#include "utils/fd_ssctrl.h"
89

@@ -25,7 +26,8 @@
2526
struct fd_snaplt_tile {
2627
int state;
2728

28-
fd_lthash_value_t running_lthash;
29+
fd_lthash_value_t running_lthash;
30+
fd_lthash_adder_t * adder;
2931

3032
fd_snapshot_account_t account;
3133
ulong acc_data_sz;
@@ -80,6 +82,7 @@ scratch_footprint( fd_topo_tile_t const * tile ) {
8082
(void)tile;
8183
ulong l = FD_LAYOUT_INIT;
8284
l = FD_LAYOUT_APPEND( l, alignof(fd_snaplt_tile_t), sizeof(fd_snaplt_tile_t) );
85+
l = FD_LAYOUT_APPEND( l, FD_LTHASH_ADDER_ALIGN, sizeof(fd_lthash_adder_t) );
8386
return FD_LAYOUT_FINI( l, alignof(fd_snaplt_tile_t) );
8487
}
8588

@@ -130,17 +133,31 @@ during_frag( fd_snaplt_tile_t * ctx,
130133

131134
if( FD_LIKELY( account->lamports!=0UL ) ) {
132135
ctx->hash_account = 1;
133-
fd_blake3_init( ctx->b3 );
134-
fd_blake3_append( ctx->b3, &account->lamports, sizeof( ulong ) );
135-
fd_memcpy( &ctx->account, account, sizeof(fd_snapshot_account_t) );
136+
int hashed = fd_lthash_adder_stream_account_hdr( ctx->adder,
137+
&ctx->running_lthash,
138+
account->pubkey,
139+
account->data_len,
140+
account->lamports,
141+
account->executable,
142+
account->owner );
143+
if( hashed ) {
144+
ctx->metrics.accounts_hashed++;
145+
ctx->hash_account = 0;
146+
}
136147
}
137148
break;
138149
}
139150
case FD_SNAPSHOT_HASH_MSG_ACCOUNT_DATA: {
140151
FD_TEST( ctx->state==FD_SNAPLT_STATE_HASHING );
141152
if( FD_LIKELY( ctx->hash_account ) ) {
142-
fd_blake3_append( ctx->b3, fd_chunk_to_laddr_const( ctx->in.wksp, chunk ), sz );
143-
ctx->acc_data_sz += sz;
153+
int hashed = fd_lthash_adder_stream_account_data( ctx->adder,
154+
&ctx->running_lthash,
155+
(uchar const *)fd_chunk_to_laddr_const( ctx->in.wksp, chunk ),
156+
sz );
157+
if( hashed ) {
158+
ctx->metrics.accounts_hashed++;
159+
ctx->hash_account = 0;
160+
}
144161
}
145162
break;
146163
}
@@ -174,26 +191,11 @@ after_frag( fd_snaplt_tile_t * ctx,
174191
case FD_SNAPSHOT_HASH_MSG_ACCOUNT_HDR:
175192
case FD_SNAPSHOT_HASH_MSG_ACCOUNT_DATA: {
176193
FD_TEST( ctx->state==FD_SNAPLT_STATE_HASHING );
177-
if( FD_LIKELY( ctx->acc_data_sz==ctx->account.data_len && ctx->hash_account ) ) {
178-
/* hash account here */
179-
fd_lthash_value_t account_lthash[1];
180-
fd_lthash_zero( account_lthash );
181-
182-
uchar executable_flag = ctx->account.executable & 0x1;
183-
fd_blake3_append( ctx->b3, &executable_flag, sizeof( uchar ) );
184-
fd_blake3_append( ctx->b3, ctx->account.owner, FD_HASH_FOOTPRINT );
185-
fd_blake3_append( ctx->b3, ctx->account.pubkey, FD_HASH_FOOTPRINT );
186-
fd_blake3_fini_2048( ctx->b3, account_lthash->bytes );
187-
188-
fd_lthash_add( &ctx->running_lthash, account_lthash );
189-
ctx->acc_data_sz = 0UL;
190-
ctx->hash_account = 0;
191-
ctx->metrics.accounts_hashed++;
192-
}
193194
break;
194195
}
195196
case FD_SNAPSHOT_HASH_MSG_FINI: {
196197
FD_TEST( ctx->state==FD_SNAPLT_STATE_HASHING );
198+
fd_lthash_adder_flush( ctx->adder, &ctx->running_lthash );
197199
uchar * lthash_out = fd_chunk_to_laddr( ctx->out.wksp, ctx->out.chunk );
198200
fd_memcpy( lthash_out, &ctx->running_lthash, sizeof(fd_lthash_value_t) );
199201
fd_stem_publish( stem, 0UL, FD_SNAPSHOT_HASH_MSG_RESULT, ctx->out.chunk, FD_LTHASH_LEN_BYTES, 0UL, 0UL, 0UL );
@@ -229,6 +231,9 @@ unprivileged_init( fd_topo_t * topo,
229231

230232
FD_SCRATCH_ALLOC_INIT( l, scratch );
231233
fd_snaplt_tile_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_snaplt_tile_t), sizeof(fd_snaplt_tile_t) );
234+
void * _adder = FD_SCRATCH_ALLOC_APPEND( l, FD_LTHASH_ADDER_ALIGN, sizeof(fd_lthash_adder_t) );
235+
236+
ctx->adder = fd_lthash_adder_new( _adder );
232237

233238
if( FD_UNLIKELY( tile->in_cnt!=1UL ) ) FD_LOG_ERR(( "tile `" NAME "` has %lu ins, expected 1", tile->in_cnt ));
234239
if( FD_UNLIKELY( tile->out_cnt!=1UL ) ) FD_LOG_ERR(( "tile `" NAME "` has %lu outs, expected 1", tile->out_cnt ));

0 commit comments

Comments
 (0)