@@ -387,6 +387,13 @@ typedef struct {
387
387
microblocks that the pack tile can publish in each slot. */
388
388
ulong max_microblocks_per_slot ;
389
389
390
+ /* If perf_mode==1, then instead of using slot_duration_ns and
391
+ hashcnt_duration_ns to pace hashes during our leader slot, we just
392
+ hash as fast as possible. In practice, this means we'll hardly mix
393
+ in any transactions for the first portion of the slot, which can
394
+ cause backpressure. */
395
+ int perf_mode ;
396
+
390
397
/* Consensus-critical slot cost limits. */
391
398
struct {
392
399
ulong slot_max_cost ;
@@ -483,6 +490,10 @@ typedef struct {
483
490
/* If an in progress frag should be skipped */
484
491
int skip_frag ;
485
492
493
+ /* If the poh tile has sent a DONE_HASHING message to pack for this
494
+ slot. */
495
+ int sent_done_hashing ;
496
+
486
497
ulong max_active_descendant ;
487
498
488
499
/* If we currently are the leader according the clock AND we have
@@ -1096,6 +1107,7 @@ fd_ext_poh_begin_leader( void const * bank,
1096
1107
ctx -> microblocks_lower_bound = 0UL ;
1097
1108
ctx -> cus_used = 0UL ;
1098
1109
ctx -> expect_microblock_idx = 0UL ;
1110
+ ctx -> sent_done_hashing = 0 ;
1099
1111
1100
1112
ctx -> limits .slot_max_cost = cus_block_limit ;
1101
1113
ctx -> limits .slot_max_vote_cost = cus_vote_cost_limit ;
@@ -1243,9 +1255,10 @@ fd_ext_poh_reset( ulong completed_bank_slot, /* The slot that successful
1243
1255
1244
1256
But: if we were leader in the prior slot, and the block was our
1245
1257
own we can do better. We know that the next slot should start
1246
- exactly 400ms after the prior one started, so we can use that as
1247
- the reset slot start time instead. */
1248
- ctx -> reset_slot_start_ns = ctx -> reset_slot_start_ns + (long )((double )((completed_bank_slot + 1UL )- ctx -> reset_slot )* ctx -> slot_duration_ns );
1258
+ no later than 400ms after the prior one started, so we can use
1259
+ that as the reset slot start time instead. */
1260
+ ctx -> reset_slot_start_ns = fd_long_min ( ctx -> reset_slot_start_ns + (long )((double )((completed_bank_slot + 1UL )- ctx -> reset_slot )* ctx -> slot_duration_ns ),
1261
+ ctx -> leader_bank_start_ns );
1249
1262
} else {
1250
1263
ctx -> reset_slot_start_ns = ctx -> leader_bank_start_ns ;
1251
1264
}
@@ -1631,7 +1644,7 @@ after_credit( fd_poh_ctx_t * ctx,
1631
1644
ulong target_hashcnt ;
1632
1645
if ( FD_LIKELY ( !is_leader ) ) {
1633
1646
target_hashcnt = (ulong )((double )(now - ctx -> reset_slot_start_ns ) / ctx -> hashcnt_duration_ns ) - (ctx -> slot - ctx -> reset_slot )* ctx -> hashcnt_per_slot ;
1634
- } else {
1647
+ } else if ( FD_LIKELY ( ctx -> perf_mode == 0 ) ) {
1635
1648
/* We might have gotten very behind on hashes, but if we are leader
1636
1649
we want to catch up gradually over the remainder of our leader
1637
1650
slot, not all at once right now. This helps keep the tile from
@@ -1641,7 +1654,10 @@ after_credit( fd_poh_ctx_t * ctx,
1641
1654
double actual_slot_duration_ns = ctx -> slot_duration_ns < (double )(ctx -> leader_bank_start_ns - expected_slot_start_ns ) ? 0.0 : ctx -> slot_duration_ns - (double )(ctx -> leader_bank_start_ns - expected_slot_start_ns );
1642
1655
double actual_hashcnt_duration_ns = actual_slot_duration_ns / (double )ctx -> hashcnt_per_slot ;
1643
1656
target_hashcnt = fd_ulong_if ( actual_hashcnt_duration_ns == 0.0 , restricted_hashcnt , (ulong )((double )(now - ctx -> leader_bank_start_ns ) / actual_hashcnt_duration_ns ) );
1657
+ } else {
1658
+ target_hashcnt = ULONG_MAX ; /* It gets clamped down immediately */
1644
1659
}
1660
+
1645
1661
/* Clamp to [min_hashcnt, restricted_hashcnt] as above */
1646
1662
target_hashcnt = fd_ulong_max ( fd_ulong_min ( target_hashcnt , restricted_hashcnt ), min_hashcnt );
1647
1663
@@ -1689,9 +1705,13 @@ after_credit( fd_poh_ctx_t * ctx,
1689
1705
1690
1706
* charge_busy = 1 ;
1691
1707
1692
- if ( FD_LIKELY ( ctx -> hashcnt < target_hashcnt ) ) {
1693
- fd_sha256_hash_32_repeated ( ctx -> hash , ctx -> hash , target_hashcnt - ctx -> hashcnt );
1694
- ctx -> hashcnt = target_hashcnt ;
1708
+ fd_sha256_hash_32_repeated ( ctx -> hash , ctx -> hash , target_hashcnt - ctx -> hashcnt );
1709
+ ctx -> hashcnt = target_hashcnt ;
1710
+
1711
+ if ( FD_UNLIKELY ( (ctx -> hashcnt == restricted_hashcnt ) && (!ctx -> sent_done_hashing ) ) ) {
1712
+ ulong sig = fd_disco_poh_sig ( ctx -> slot , POH_PKT_TYPE_DONE_HASHING , 0UL );
1713
+ fd_stem_publish ( ctx -> stem , ctx -> pack_out -> idx , sig , ctx -> pack_out -> chunk , 0UL , 0UL , 0UL , 0UL );
1714
+ ctx -> sent_done_hashing = 1 ;
1695
1715
}
1696
1716
1697
1717
if ( FD_UNLIKELY ( ctx -> hashcnt == ctx -> hashcnt_per_slot ) ) {
@@ -2241,6 +2261,8 @@ unprivileged_init( fd_topo_t * topo,
2241
2261
ctx -> highwater_leader_slot = ULONG_MAX ;
2242
2262
ctx -> next_leader_slot = ULONG_MAX ;
2243
2263
ctx -> reset_slot = ULONG_MAX ;
2264
+ ctx -> sent_done_hashing = 0 ;
2265
+ ctx -> perf_mode = tile -> poh .perf_mode ;
2244
2266
2245
2267
ctx -> lagged_consecutive_leader_start = tile -> poh .lagged_consecutive_leader_start ;
2246
2268
ctx -> expect_sequential_leader_slot = ULONG_MAX ;
0 commit comments