Skip to content

Commit a43c913

Browse files
committed
batch of fixes for rpc service
1 parent 3c8a2a9 commit a43c913

File tree

5 files changed

+160
-87
lines changed

5 files changed

+160
-87
lines changed

src/discof/replay/fd_replay_notif.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ struct __attribute__((aligned(64UL))) fd_replay_notif_msg {
1414
ulong parent;
1515
ulong root;
1616
ulong slot;
17+
ulong slot_in_epoch;
18+
ulong epoch;
1719
ulong height;
1820
fd_hash_t bank_hash;
1921
fd_hash_t block_hash;
2022
ulong transaction_count;
2123
ulong shred_cnt;
22-
ulong ts;
24+
long ts;
2325
} slot_exec;
2426
};
2527
uint type;

src/discof/replay/fd_replay_tile.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,19 +644,25 @@ publish_slot_notifications( fd_replay_tile_ctx_t * ctx,
644644
#define NOTIFY_START msg = fd_chunk_to_laddr( ctx->notif_out->mem, ctx->notif_out->chunk )
645645
#define NOTIFY_END \
646646
fd_mcache_publish( ctx->notif_out->mcache, ctx->notif_out->depth, ctx->notif_out->seq, \
647-
0UL, ctx->notif_out->chunk, sizeof(fd_replay_notif_msg_t), 0UL, tsorig, tsorig ); \
647+
0UL, ctx->notif_out->chunk, sizeof(fd_replay_notif_msg_t), 0UL, \
648+
fd_frag_meta_ts_comp(tsorig), fd_frag_meta_ts_comp(tsorig) ); \
648649
ctx->notif_out->seq = fd_seq_inc( ctx->notif_out->seq, 1UL ); \
649650
ctx->notif_out->chunk = fd_dcache_compact_next( ctx->notif_out->chunk, sizeof(fd_replay_notif_msg_t), \
650651
ctx->notif_out->chunk0, ctx->notif_out->wmark ); \
651652
msg = NULL
652653

653-
ulong tsorig = fd_frag_meta_ts_comp( fd_tickcount() );
654+
long tsorig = fd_log_wallclock();
654655
fd_replay_notif_msg_t * msg = NULL;
656+
fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( ctx->slot_ctx->bank );
657+
ulong slot_idx;
658+
ulong epoch = fd_slot_to_epoch( epoch_schedule, curr_slot, &slot_idx );
655659

656660
{
657661
NOTIFY_START;
658662
msg->type = FD_REPLAY_SLOT_TYPE;
659663
msg->slot_exec.slot = curr_slot;
664+
msg->slot_exec.epoch = epoch;
665+
msg->slot_exec.slot_in_epoch = slot_idx;
660666
msg->slot_exec.parent = fd_bank_parent_slot_get( ctx->slot_ctx->bank );
661667
msg->slot_exec.root = ctx->consensus_root;
662668
msg->slot_exec.height = block_entry_block_height;

src/discof/rpcserver/fd_block_to_json.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ generic_program_to_json( fd_webserver_t * ws,
286286
fd_web_reply_encode_base58(ws, raw + instr->data_off, instr->data_sz);
287287
char buf32[FD_BASE58_ENCODED_32_SZ];
288288
fd_base58_encode_32((const uchar*)(accts + instr->program_id), NULL, buf32);
289-
fd_web_reply_sprintf(ws, "\",\"program\":\"unknown\",\"programId\":\"%s\",\"stackHeight\":null}", buf32);
289+
fd_web_reply_sprintf(ws, "\",\"program\":\"unknown\",\"programId\":\"%s\",\"stackHeight\":1}", buf32);
290290
*need_comma = 1;
291291
} FD_SPAD_FRAME_END;
292292
return NULL;
@@ -320,7 +320,7 @@ vote_program_to_json( fd_webserver_t * ws,
320320
fd_rpc_json_t * json = fd_rpc_json_init( fd_rpc_json_new( fd_spad_alloc( spad, fd_rpc_json_align(), fd_rpc_json_footprint() ) ), ws );
321321
fd_vote_instruction_walk( json, instruction, fd_rpc_json_walk, NULL, 0, 0 );
322322

323-
EMIT_SIMPLE(",\"program\":\"vote\",\"programId\":\"Vote111111111111111111111111111111111111111\",\"stackHeight\":null}");
323+
EMIT_SIMPLE(",\"program\":\"vote\",\"programId\":\"Vote111111111111111111111111111111111111111\",\"stackHeight\":1}");
324324
*need_comma = 1;
325325
} FD_SPAD_FRAME_END;
326326
return NULL;
@@ -354,7 +354,7 @@ system_program_to_json( fd_webserver_t * ws,
354354
fd_rpc_json_t * json = fd_rpc_json_init( fd_rpc_json_new( fd_spad_alloc( spad, fd_rpc_json_align(), fd_rpc_json_footprint() ) ), ws );
355355
fd_system_program_instruction_walk( json, instruction, fd_rpc_json_walk, NULL, 0, 0 );
356356

357-
EMIT_SIMPLE(",\"program\":\"system\",\"programId\":\"11111111111111111111111111111111\",\"stackHeight\":null}");
357+
EMIT_SIMPLE(",\"program\":\"system\",\"programId\":\"11111111111111111111111111111111\",\"stackHeight\":1}");
358358
*need_comma = 1;
359359
} FD_SPAD_FRAME_END;
360360
return NULL;
@@ -412,7 +412,7 @@ compute_budget_program_to_json( fd_webserver_t * ws,
412412
fd_rpc_json_t * json = fd_rpc_json_init( fd_rpc_json_new( fd_spad_alloc( spad, fd_rpc_json_align(), fd_rpc_json_footprint() ) ), ws );
413413
fd_compute_budget_program_instruction_walk( json, instruction, fd_rpc_json_walk, NULL, 0, 0 );
414414

415-
EMIT_SIMPLE(",\"program\":\"compute_budget\",\"programId\":\"ComputeBudget111111111111111111111111111111\",\"stackHeight\":null}");
415+
EMIT_SIMPLE(",\"program\":\"compute_budget\",\"programId\":\"ComputeBudget111111111111111111111111111111\",\"stackHeight\":1}");
416416
*need_comma = 1;
417417
} FD_SPAD_FRAME_END;
418418
return NULL;
@@ -471,7 +471,7 @@ fd_instr_to_json( fd_webserver_t * ws,
471471
}
472472
EMIT_SIMPLE("],\"data\":\"");
473473
fd_web_reply_encode_base58(ws, raw + instr->data_off, instr->data_sz);
474-
fd_web_reply_sprintf(ws, "\",\"programIdIndex\":%u,\"stackHeight\":null}", (uint)instr->program_id);
474+
fd_web_reply_sprintf(ws, "\",\"programIdIndex\":%u,\"stackHeight\":%u}", (uint)instr->program_id, (uint)1);
475475
*need_comma = 1;
476476

477477
} else if( encoding == FD_ENC_JSON_PARSED ) {
@@ -588,9 +588,12 @@ fd_txn_to_json_full( fd_webserver_t * ws,
588588
EMIT_SIMPLE("],");
589589
}
590590

591-
fd_web_reply_sprintf(ws, "\"header\":{\"numReadonlySignedAccounts\":%u,\"numReadonlyUnsignedAccounts\":%u,\"numRequiredSignatures\":%u},\"instructions\":[",
592-
(uint)txn->readonly_signed_cnt, (uint)txn->readonly_unsigned_cnt, (uint)txn->signature_cnt);
591+
if( encoding == FD_ENC_JSON ) {
592+
fd_web_reply_sprintf(ws, "\"header\":{\"numReadonlySignedAccounts\":%u,\"numReadonlyUnsignedAccounts\":%u,\"numRequiredSignatures\":%u},",
593+
(uint)txn->readonly_signed_cnt, (uint)txn->readonly_unsigned_cnt, (uint)txn->signature_cnt);
594+
}
593595

596+
EMIT_SIMPLE("\"instructions\":[");
594597
ushort instr_cnt = txn->instr_cnt;
595598
int need_comma = 0;
596599
for (ushort idx = 0; idx < instr_cnt; idx++) {
@@ -694,8 +697,8 @@ fd_block_to_json( fd_webserver_t * ws,
694697
} else {
695698
phash[0] = '\0';
696699
}
697-
fd_web_reply_sprintf(ws, "\"blockHeight\":%lu,\"blockTime\":%lu,\"parentSlot\":%lu,\"blockhash\":\"%s\",\"previousBlockhash\":\"%s\"",
698-
info->slot_exec.height, info->slot_exec.ts/(ulong)1e9, info->slot_exec.parent, hash, phash);
700+
fd_web_reply_sprintf(ws, "\"blockHeight\":%lu,\"blockTime\":%ld,\"parentSlot\":%lu,\"blockhash\":\"%s\",\"previousBlockhash\":\"%s\"",
701+
info->slot_exec.height, info->slot_exec.ts/(long)1e9, info->slot_exec.parent, hash, phash);
699702

700703
if( rewards ) {
701704
fd_base58_encode_32(rewards->leader.uc, 0, hash);

src/discof/rpcserver/fd_rpc_history.c

Lines changed: 106 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct fd_rpc_txn {
3232
ulong slot;
3333
ulong file_offset;
3434
ulong file_size;
35+
struct fd_rpc_txn * next_lru;
3536
};
3637
typedef struct fd_rpc_txn fd_rpc_txn_t;
3738

@@ -62,8 +63,8 @@ struct fd_rpc_acct_map_elem {
6263
fd_pubkey_t key;
6364
ulong next;
6465
ulong slot;
65-
ulong age;
6666
fd_rpc_txn_key_t sig; /* Transaction signature */
67+
struct fd_rpc_acct_map_elem * next_lru;
6768
};
6869
typedef struct fd_rpc_acct_map_elem fd_rpc_acct_map_elem_t;
6970
#define MAP_NAME fd_rpc_acct_map
@@ -94,8 +95,12 @@ struct fd_rpc_history {
9495
fd_rpc_block_t * block_map;
9596
ulong block_cnt;
9697
fd_rpc_txn_t * txn_map;
98+
fd_rpc_txn_t * txn_oldest_lru;
99+
fd_rpc_txn_t * txn_newest_lru;
97100
fd_rpc_acct_map_t * acct_map;
98101
fd_rpc_acct_map_elem_t * acct_pool;
102+
fd_rpc_acct_map_elem_t * acct_oldest_lru;
103+
fd_rpc_acct_map_elem_t * acct_newest_lru;
99104
fd_rpc_reasm_map_t * reasm_map;
100105
ulong first_slot;
101106
ulong latest_slot;
@@ -179,19 +184,22 @@ fd_rpc_history_save_info(fd_rpc_history_t * hist, fd_replay_notif_msg_t * info)
179184
blk->info = *info;
180185
}
181186

182-
static void
187+
static ulong
183188
fd_rpc_history_scan_block(fd_rpc_history_t * hist, ulong slot, ulong file_offset, uchar * blk_data, ulong blk_sz) {
184189
ulong blockoff = 0;
190+
ulong ret = 0;
185191
while (blockoff < blk_sz) {
186192
if ( blockoff + sizeof(ulong) > blk_sz )
187-
return;
193+
return ret;
188194
ulong mcount = *(const ulong *)(blk_data + blockoff);
189195
blockoff += sizeof(ulong);
190196

191197
/* Loop across microblocks */
192198
for (ulong mblk = 0; mblk < mcount; ++mblk) {
193-
if ( blockoff + sizeof(fd_microblock_hdr_t) > blk_sz )
199+
if ( blockoff + sizeof(fd_microblock_hdr_t) > blk_sz ) {
194200
FD_LOG_ERR(("premature end of block"));
201+
return ret;
202+
}
195203
fd_microblock_hdr_t * hdr = (fd_microblock_hdr_t *)((const uchar *)blk_data + blockoff);
196204
blockoff += sizeof(fd_microblock_hdr_t);
197205

@@ -202,21 +210,38 @@ fd_rpc_history_scan_block(fd_rpc_history_t * hist, ulong slot, ulong file_offset
202210
const uchar* raw = (const uchar *)blk_data + blockoff;
203211
ulong txn_sz = fd_txn_parse_core(raw, fd_ulong_min(blk_sz - blockoff, FD_TXN_MTU), txn_out, NULL, &pay_sz);
204212
if ( txn_sz == 0 || txn_sz > FD_TXN_MAX_SZ ) {
205-
FD_LOG_WARNING( ( "failed to parse transaction %lu in microblock %lu at offset %lu", txn_idx, mblk, blockoff ) );
206-
return;
213+
FD_LOG_ERR( ( "failed to parse transaction %lu in microblock %lu (%lu) at offset %lu", txn_idx, mblk, ret,blockoff ) );
214+
return ret;
207215
}
208216
fd_txn_t * txn = (fd_txn_t *)txn_out;
209217

210218
/* Loop across signatures */
211219
fd_ed25519_sig_t const * sigs = (fd_ed25519_sig_t const *)(raw + txn->signature_off);
212220
for ( uchar j = 0; j < txn->signature_cnt; j++ ) {
213-
if( fd_rpc_txn_map_is_full( hist->txn_map ) ) break; /* Out of space */
221+
while( fd_rpc_txn_map_is_full( hist->txn_map ) ) {
222+
/* Remove the oldest entry from the map */
223+
fd_rpc_txn_t * ent = hist->txn_oldest_lru;
224+
hist->txn_oldest_lru = ent->next_lru;
225+
fd_rpc_txn_map_remove( hist->txn_map, &ent->sig );
226+
}
227+
228+
/* Insert the new entry into the map */
214229
fd_rpc_txn_key_t key;
215230
memcpy(&key, (const uchar*)&sigs[j], sizeof(key));
216231
fd_rpc_txn_t * ent = fd_rpc_txn_map_insert( hist->txn_map, &key );
217232
ent->file_offset = file_offset + blockoff;
218233
ent->file_size = pay_sz;
219234
ent->slot = slot;
235+
236+
/* Update the LRU chain*/
237+
ent->next_lru = NULL;
238+
if( hist->txn_newest_lru ) {
239+
hist->txn_newest_lru->next_lru = ent;
240+
hist->txn_newest_lru = ent;
241+
} else {
242+
hist->txn_newest_lru = ent;
243+
hist->txn_oldest_lru = ent;
244+
}
220245
}
221246

222247
/* Loop across accounts */
@@ -225,66 +250,102 @@ fd_rpc_history_scan_block(fd_rpc_history_t * hist, ulong slot, ulong file_offset
225250
fd_pubkey_t * accs = (fd_pubkey_t *)((uchar *)raw + txn->acct_addr_off);
226251
for( ulong i = 0UL; i < txn->acct_addr_cnt; i++ ) {
227252
if( !memcmp(&accs[i], fd_solana_vote_program_id.key, sizeof(fd_pubkey_t)) ) continue; /* Ignore votes */
228-
if( !fd_rpc_acct_map_pool_free( hist->acct_pool ) ) break;
253+
254+
while( !fd_rpc_acct_map_pool_free( hist->acct_pool ) ) {
255+
/* Remove the oldest entry from the map */
256+
fd_rpc_acct_map_elem_t * ent = hist->acct_oldest_lru;
257+
hist->acct_oldest_lru = ent->next_lru;
258+
ent = fd_rpc_acct_map_ele_remove( hist->acct_map, &ent->key, NULL, hist->acct_pool );
259+
if( ent ) fd_rpc_acct_map_pool_ele_release( hist->acct_pool, ent );
260+
}
261+
262+
/* Insert the new entry into the map */
229263
fd_rpc_acct_map_elem_t * ele = fd_rpc_acct_map_pool_ele_acquire( hist->acct_pool );
230264
ele->key = accs[i];
231265
ele->slot = slot;
232266
ele->sig = sig0;
233267
fd_rpc_acct_map_ele_insert( hist->acct_map, ele, hist->acct_pool );
268+
269+
/* Update the LRU chain */
270+
ele->next_lru = NULL;
271+
if( hist->acct_newest_lru ) {
272+
hist->acct_newest_lru->next_lru = ele;
273+
hist->acct_newest_lru = ele;
274+
} else {
275+
hist->acct_newest_lru = ele;
276+
hist->acct_oldest_lru = ele;
277+
}
234278
}
235279

236280
blockoff += pay_sz;
237281
}
238282
}
283+
ret = blockoff;
239284
}
240-
if ( blockoff != blk_sz )
241-
FD_LOG_ERR(("garbage at end of block"));
285+
return ret;
242286
}
243287

244288
void
245289
fd_rpc_history_process_column(fd_rpc_history_t * hist, struct fd_rpc_reasm_map_column * col, fd_store_t * store, fd_reasm_fec_t * fec) {
246-
FD_SPAD_FRAME_BEGIN( hist->spad ) {
247-
248-
FD_LOG_NOTICE(( "assembling slot %lu block", fec->slot ));
290+
ulong slot = fec->slot;
291+
FD_LOG_NOTICE(( "assembling slot %lu block", slot ));
249292

250-
/* Assemble the block */
251-
fd_store_fec_t * list[FD_REASM_MAP_COL_HEIGHT];
252-
ulong slot = fec->slot;
253-
ulong blk_sz = 0;
254-
for( ulong i = 0; i < col->ele_cnt; i++ ) {
293+
/* Get a block from the map */
294+
fd_rpc_block_t * blk = fd_rpc_history_alloc_block( hist, slot );
295+
if( blk == NULL ) return;
296+
ulong file_offset = blk->file_offset = hist->file_totsz;
297+
blk->file_size = 0;
298+
299+
/* Look up all the store_fec_t elements for this column */
300+
fd_store_fec_t * list[FD_REASM_MAP_COL_HEIGHT];
301+
for( ulong idx = 0; idx < col->ele_cnt; ) {
302+
ulong end_idx = ULONG_MAX;
303+
/* Query the next batch */
304+
fd_store_shacq( store );
305+
ulong batch_sz = 0;
306+
for( ulong i = idx; i < col->ele_cnt; i++ ) {
255307
fd_reasm_fec_t * ele = &col->ele[i];
256-
fd_store_fec_t * fec_p = list[i] = fd_store_query( store, &ele->key );
308+
fd_store_fec_t * fec_p = list[i-idx] = fd_store_query( store, &ele->key );
257309
if( !fec_p ) {
258-
FD_LOG_WARNING(( "missing fec" ));
310+
FD_LOG_ERR(( "missing fec" ));
311+
fd_store_shrel( store );
259312
return;
260313
}
261-
blk_sz += fec_p->data_sz;
262-
}
263-
uchar * blk_data = fd_spad_alloc( hist->spad, alignof(ulong), blk_sz );
264-
ulong blk_off = 0;
265-
for( ulong i = 0; i < col->ele_cnt; i++ ) {
266-
fd_store_fec_t * fec_p = list[i];
267-
fd_memcpy( blk_data + blk_off, fec_p->data, fec_p->data_sz );
268-
blk_off += fec_p->data_sz;
314+
batch_sz += fec_p->data_sz;
315+
if( col->ele[i].data_complete ) {
316+
end_idx = i;
317+
break;
318+
}
269319
}
270-
FD_TEST( blk_off == blk_sz );
271-
272-
/* Get a block from the map */
273-
fd_rpc_block_t * blk = fd_rpc_history_alloc_block( hist, slot );
274-
if( blk == NULL ) return;
275-
276-
/* Write the block to the file */
277-
if( pwrite( hist->file_fd, blk_data, blk_sz, (long)hist->file_totsz ) != (ssize_t)blk_sz ) {
278-
FD_LOG_ERR(( "unable to write to rpc history file" ));
320+
if( end_idx == ULONG_MAX ) {
321+
FD_LOG_ERR(( "missing data complete flag" ));
322+
fd_store_shrel( store );
323+
return;
279324
}
280-
ulong file_offset = blk->file_offset = hist->file_totsz;
281-
blk->file_size = blk_sz;
282-
hist->file_totsz += blk_sz;
283-
284-
/* Scan the block */
285-
fd_rpc_history_scan_block( hist, slot, file_offset, blk_data, blk_sz );
286-
287-
} FD_SPAD_FRAME_END;
325+
FD_SPAD_FRAME_BEGIN( hist->spad ) {
326+
uchar * blk_data = fd_spad_alloc( hist->spad, alignof(ulong), batch_sz );
327+
ulong batch_off = 0;
328+
for( ulong i = idx; i <= end_idx; i++ ) {
329+
fd_store_fec_t * fec_p = list[i-idx];
330+
fd_memcpy( blk_data + batch_off, fec_p->data, fec_p->data_sz );
331+
batch_off += fec_p->data_sz;
332+
}
333+
FD_TEST( batch_off == batch_sz );
334+
/* Scan the block. Trim the padding. */
335+
batch_sz = fd_rpc_history_scan_block( hist, slot, file_offset, blk_data, batch_sz );
336+
/* Write the trimmed batch to the file */
337+
if( pwrite( hist->file_fd, blk_data, batch_sz, (long)file_offset ) != (ssize_t)batch_sz ) {
338+
FD_LOG_ERR(( "unable to write to rpc history file" ));
339+
fd_store_shrel( store );
340+
return;
341+
}
342+
file_offset += batch_sz;
343+
blk->file_size += batch_sz;
344+
hist->file_totsz = file_offset;
345+
} FD_SPAD_FRAME_END;
346+
fd_store_shrel( store );
347+
idx = end_idx + 1;
348+
}
288349
}
289350

290351
static void

0 commit comments

Comments
 (0)