Skip to content

Commit 13a65bf

Browse files
committed
shred: keep track of parent block_id when we are leader
1 parent 3037f95 commit 13a65bf

File tree

5 files changed

+52
-12
lines changed

5 files changed

+52
-12
lines changed

agave

src/disco/shred/fd_shred_tile.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ FD_STATIC_ASSERT( sizeof(fd_entry_batch_meta_t)==56UL, poh_shred_mtu );
104104

105105
#define FD_SHRED_ADD_SHRED_EXTRA_RETVAL_CNT 2
106106

107+
/* Number of entries in the block_ids table. Each entry is 32 byte.
108+
This table is used to keep track of block ids that we create
109+
when we're leader, so that we can access them whenever we need
110+
a *parent* block id for a new block. Larger table allows to
111+
retrieve older parent block ids. Currently it's set for worst
112+
case parent offset of USHORT_MAX (max allowed in a shred),
113+
making the total table 2MiB.
114+
See also comment on chained_merkle_root. */
115+
#define BLOCK_IDS_TABLE_CNT USHORT_MAX
116+
107117
/* See note on parallelization above. Currently we process all batches in tile 0. */
108118
#if 1
109119
#define SHOULD_PROCESS_THESE_SHREDS ( ctx->round_robin_id==0 )
@@ -236,7 +246,8 @@ typedef struct {
236246
/* too large to be left in the stack */
237247
fd_shred_dest_idx_t scratchpad_dests[ FD_SHRED_DEST_MAX_FANOUT*(FD_REEDSOL_DATA_SHREDS_MAX+FD_REEDSOL_PARITY_SHREDS_MAX) ];
238248

239-
uchar chained_merkle_root[ FD_SHRED_MERKLE_ROOT_SZ ];
249+
uchar * chained_merkle_root;
250+
uchar block_ids[ BLOCK_IDS_TABLE_CNT ][ FD_SHRED_MERKLE_ROOT_SZ ];
240251
} fd_shred_ctx_t;
241252

242253
FD_FN_CONST static inline ulong
@@ -449,16 +460,46 @@ during_frag( fd_shred_ctx_t * ctx,
449460
ctx->batch_cnt = 0UL;
450461
ctx->slot = target_slot;
451462

452-
/* Only copy parent_block_id to chained_merkle_root at the beginning
453-
of a new slot*/
463+
/* At the beginning of a new slot, prepare chained_merkle_root.
464+
chained_merkle_root is initialized at the block_id of the parent
465+
block, there's two cases:
466+
467+
1. block_id is passed in by the poh tile:
468+
- it's always passed when parent block had a different leader
469+
- it may be passed when we were leader for parent block (there
470+
are race conditions when it's not passed)
471+
472+
2. block_id is taken from block_ids table if we were the leader
473+
for the parent block (when we were NOT the leader, because of
474+
equivocation, we can't store block_id in the table)
475+
476+
chained_merkle_root is stored in block_ids table at target_slot
477+
and it's progressively updated as more microblocks are received.
478+
As a result, when we move to a new slot, the block_ids table at
479+
the old slot will contain the block_id.
480+
481+
The block_ids table is designed to protect against the race condition
482+
case in 1., therefore the table may not be set in some cases, e.g. if
483+
a validator (re)starts, but in those cases we don't expect the race
484+
condition to apply. */
485+
ctx->chained_merkle_root = ctx->block_ids[ target_slot % BLOCK_IDS_TABLE_CNT ];
454486
if( FD_UNLIKELY( SHOULD_PROCESS_THESE_SHREDS ) ) {
455-
/* chained_merkle_root is set as the merkle root of the last FEC set
456-
of the parent block (and passed in by POH tile) */
457487
if( FD_LIKELY( entry_meta->parent_block_id_valid ) ) {
488+
/* 1. Initialize chained_merkle_root sent from poh tile */
458489
memcpy( ctx->chained_merkle_root, entry_meta->parent_block_id, FD_SHRED_MERKLE_ROOT_SZ );
459490
} else {
460-
ctx->metrics->invalid_block_id_cnt++;
461-
memset( ctx->chained_merkle_root, 0, FD_SHRED_MERKLE_ROOT_SZ );
491+
ulong parent_slot = target_slot - entry_meta->parent_offset;
492+
fd_epoch_leaders_t const * lsched = fd_stake_ci_get_lsched_for_slot( ctx->stake_ci, parent_slot );
493+
fd_pubkey_t const * slot_leader = fd_epoch_leaders_get( lsched, parent_slot );
494+
495+
if( lsched && slot_leader && fd_memeq( slot_leader, ctx->identity_key, sizeof(fd_pubkey_t) ) ) {
496+
/* 2. Initialize chained_merkle_root from block_ids table, if we were the leader */
497+
memcpy( ctx->chained_merkle_root, ctx->block_ids[ parent_slot % BLOCK_IDS_TABLE_CNT ], FD_SHRED_MERKLE_ROOT_SZ );
498+
} else {
499+
/* This should never happen, log a metric and set chained_merkle_root to 0 */
500+
ctx->metrics->invalid_block_id_cnt++;
501+
memset( ctx->chained_merkle_root, 0, FD_SHRED_MERKLE_ROOT_SZ );
502+
}
462503
}
463504
}
464505
}
@@ -1303,6 +1344,8 @@ unprivileged_init( fd_topo_t * topo,
13031344
ulong scratch_top = FD_SCRATCH_ALLOC_FINI( l, 1UL );
13041345
if( FD_UNLIKELY( scratch_top > (ulong)scratch + scratch_footprint( tile ) ) )
13051346
FD_LOG_ERR(( "scratch overflow %lu %lu %lu", scratch_top - (ulong)scratch - scratch_footprint( tile ), scratch_top, (ulong)scratch + scratch_footprint( tile ) ));
1347+
1348+
memset( ctx->block_ids, 0, sizeof(ctx->block_ids) );
13061349
}
13071350

13081351
static ulong

src/discof/poh/fd_poh_tile.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,8 +1255,6 @@ fd_ext_poh_reset( ulong completed_bank_slot, /* The slot that successful
12551255
if( FD_LIKELY( parent_block_id!=NULL ) ) {
12561256
ctx->parent_slot = completed_bank_slot;
12571257
memcpy( ctx->parent_block_id, parent_block_id, 32UL );
1258-
} else {
1259-
FD_LOG_WARNING(( "fd_ext_poh_reset(block_id=null,reset_slot=%lu,parent_slot=%lu) - ignored", completed_bank_slot, ctx->parent_slot ));
12601258
}
12611259
ctx->slot = completed_bank_slot+1UL;
12621260
ctx->hashcnt = 0UL;

src/discoh/poh/fd_poh_tile.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,8 +1259,6 @@ fd_ext_poh_reset( ulong completed_bank_slot, /* The slot that successful
12591259
if( FD_LIKELY( parent_block_id!=NULL ) ) {
12601260
ctx->parent_slot = completed_bank_slot;
12611261
memcpy( ctx->parent_block_id, parent_block_id, 32UL );
1262-
} else {
1263-
FD_LOG_WARNING(( "fd_ext_poh_reset(block_id=null,reset_slot=%lu,parent_slot=%lu) - ignored", completed_bank_slot, ctx->parent_slot ));
12641262
}
12651263
ctx->slot = completed_bank_slot+1UL;
12661264
ctx->hashcnt = 0UL;

src/flamenco/leaders/fd_leaders.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ fd_epoch_leaders_delete( void * shleaders );
150150
FD_FN_PURE static inline fd_pubkey_t const *
151151
fd_epoch_leaders_get( fd_epoch_leaders_t const * leaders,
152152
ulong slot ) {
153+
if( FD_UNLIKELY( leaders==NULL ) ) return NULL;
153154
ulong slot_delta = slot - leaders->slot0;
154155
if( FD_UNLIKELY( slot < leaders->slot0 ) ) return NULL;
155156
if( FD_UNLIKELY( slot_delta>=leaders->slot_cnt ) ) return NULL;

0 commit comments

Comments
 (0)