Skip to content

Commit 76b4e60

Browse files
committed
feat(tower): minor hard fork detector revisions and integration
1 parent 5b9dd64 commit 76b4e60

File tree

4 files changed

+34
-22
lines changed

4 files changed

+34
-22
lines changed

src/discof/tower/fd_hard_fork_detector.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ typedef struct voted_on voted_on_t;
8686

8787
struct block_result_key {
8888
fd_pubkey_t block_id;
89-
fd_pubkey_t block_hash;
89+
fd_pubkey_t bank_hash;
9090
};
9191

9292
typedef struct block_result_key block_result_key_t;
@@ -126,8 +126,8 @@ typedef struct block_result block_result_t;
126126
#define MAP_PREV map.prev
127127
#define MAP_NEXT map.next
128128
#define MAP_KEY_EQ(k0,k1) ( fd_pubkey_eq( &((k0)->block_id), &((k1)->block_id) ) &\
129-
fd_pubkey_eq( &((k0)->block_hash), &((k1)->block_hash) ) )
130-
#define MAP_KEY_HASH(key,seed) ( seed ^ fd_ulong_load_8( (key)->block_id.uc ) ^ fd_ulong_load_8( (key)->block_hash.uc ) )
129+
fd_pubkey_eq( &((k0)->bank_hash), &((k1)->bank_hash) ) )
130+
#define MAP_KEY_HASH(key,seed) ( seed ^ fd_ulong_load_8( (key)->block_id.uc ) ^ fd_ulong_load_8( (key)->bank_hash.uc ) )
131131
#define MAP_OPTIMIZE_RANDOM_ACCESS_REMOVAL 1
132132
#include "../../util/tmpl/fd_map_chain.c"
133133

@@ -139,7 +139,7 @@ typedef struct block_result block_result_t;
139139

140140
struct my_result {
141141
fd_pubkey_t block_id;
142-
fd_pubkey_t block_hash;
142+
fd_pubkey_t bank_hash;
143143

144144
ulong slot;
145145

@@ -332,7 +332,7 @@ fd_hard_fork_detector_new( void * shmem,
332332
FD_TEST( hf->my_vote_map );
333333

334334
hf->my_vote_lru = my_vote_lru_join( my_vote_lru_new( _my_vote_lru ) );
335-
FD_TEST( hf->my_vote_lru );
335+
FD_TEST( hf->my_vote_lru );
336336

337337
hf->block_id_pool = block_id_pool_join( block_id_pool_new( _block_id_pool, max_live_slots*max_vote_accounts ) );
338338
FD_TEST( hf->block_id_pool );
@@ -412,16 +412,16 @@ check( fd_hard_fork_detector_t const * detector,
412412
if( detector->fatal ) FD_LOG_ERR(( "%s", msg ));
413413
else FD_LOG_WARNING(( "%s", msg ));
414414
} else {
415-
if( FD_UNLIKELY( memcmp( my_result->block_hash.uc, block_result->key.block_hash.uc, 32UL ) ) ) {
415+
if( FD_UNLIKELY( memcmp( my_result->bank_hash.uc, block_result->key.bank_hash.uc, 32UL ) ) ) {
416416
char msg[ 4096UL ];
417417
FD_TEST( fd_cstr_printf_check( msg, sizeof( msg ), NULL,
418418
"HARD FORK DETECTED: our validator has produced block hash `%s` for slot %lu with block ID `%s`, but %lu validators with %.1f of stake have voted on a different block hash `%s` for the same slot",
419-
FD_BASE58_ENC_32_ALLOCA( my_result->block_hash.uc ),
419+
FD_BASE58_ENC_32_ALLOCA( my_result->bank_hash.uc ),
420420
my_result->slot,
421421
FD_BASE58_ENC_32_ALLOCA( my_result->block_id.uc ),
422422
block_result->voter_count,
423423
100.0*(double)block_result->stake/(double)detector->total_stake,
424-
FD_BASE58_ENC_32_ALLOCA( block_result->key.block_hash.uc ) ) );
424+
FD_BASE58_ENC_32_ALLOCA( block_result->key.bank_hash.uc ) ) );
425425

426426
if( detector->fatal ) FD_LOG_ERR(( "%s", msg ));
427427
else FD_LOG_WARNING(( "%s", msg ));
@@ -433,7 +433,7 @@ void
433433
fd_hard_fork_detector_vote( fd_hard_fork_detector_t * detector,
434434
uchar const * vote_account,
435435
uchar const * block_id,
436-
uchar const * block_hash ) {
436+
uchar const * bank_hash ) {
437437
stake_t const * _stake = stake_map_ele_query_const( detector->stake_map, fd_type_pun_const( vote_account ), NULL, detector->stake_pool );
438438
if( FD_UNLIKELY( !_stake ) ) return; /* Don't care about votes from unstaked */
439439

@@ -482,9 +482,9 @@ fd_hard_fork_detector_vote( fd_hard_fork_detector_t * detector,
482482

483483
block_result_key_t br_key;
484484
fd_memcpy( br_key.block_id.uc, block_id, 32UL );
485-
fd_memcpy( br_key.block_hash.uc, block_hash, 32UL );
485+
fd_memcpy( br_key.bank_hash.uc, bank_hash, 32UL );
486486

487-
block_result_t * block_result = block_result_map_ele_query( detector->block_result_map, fd_type_pun_const( block_hash ), NULL, detector->block_result_pool );
487+
block_result_t * block_result = block_result_map_ele_query( detector->block_result_map, fd_type_pun_const( bank_hash ), NULL, detector->block_result_pool );
488488
if( FD_UNLIKELY( !block_result ) ) {
489489
/* Guaranteed to be space, because the block result pool is larger
490490
than the voted on pool, and there can be at most one unique
@@ -493,7 +493,7 @@ fd_hard_fork_detector_vote( fd_hard_fork_detector_t * detector,
493493

494494
block_result = block_result_pool_ele_acquire( detector->block_result_pool );
495495
fd_memcpy( block_result->key.block_id.uc, block_id, 32UL );
496-
fd_memcpy( block_result->key.block_hash.uc, block_hash, 32UL );
496+
fd_memcpy( block_result->key.bank_hash.uc, bank_hash, 32UL );
497497
block_result->stake = 0UL;
498498
block_result_map_ele_insert( detector->block_result_map, block_result, detector->block_result_pool );
499499
}
@@ -523,7 +523,7 @@ void
523523
fd_hard_fork_detector_block( fd_hard_fork_detector_t * detector,
524524
ulong slot,
525525
uchar const * block_id,
526-
uchar const * block_hash ) {
526+
uchar const * bank_hash ) {
527527
if( FD_LIKELY( !my_vote_pool_free( detector->my_vote_pool ) ) ) {
528528
/* Might also be good eventually to evict a little bit smarter here ... */
529529
my_result_t * lru_result = my_vote_lru_ele_pop_tail( detector->my_vote_lru, detector->my_vote_pool );
@@ -534,10 +534,10 @@ fd_hard_fork_detector_block( fd_hard_fork_detector_t * detector,
534534
my_result_t * my_result = my_vote_pool_ele_acquire( detector->my_vote_pool );
535535
my_result->slot = slot;
536536
fd_memcpy( my_result->block_id.uc, block_id, 32UL );
537-
fd_memcpy( my_result->block_hash.uc, block_hash, 32UL );
537+
fd_memcpy( my_result->bank_hash.uc, bank_hash, 32UL );
538538

539539
uchar zero32[32] = {0};
540-
if( FD_UNLIKELY( !memcmp( block_hash, zero32, 32UL ) ) ) my_result->invalid = 1;
540+
if( FD_UNLIKELY( !memcmp( bank_hash, zero32, 32UL ) ) ) my_result->invalid = 1;
541541

542542
my_vote_map_ele_insert( detector->my_vote_map, my_result, detector->my_vote_pool );
543543
my_vote_lru_ele_push_head( detector->my_vote_lru, my_result, detector->my_vote_pool );

src/discof/tower/fd_hard_fork_detector.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
We detect hard forked blocks by monitoring votes from validators, the
2828
specific criteria is:
2929
30-
- 52% of stake has voted on a block_id and agreed on a blockhash
31-
which is different than the blockhash we have for that block_id.
30+
- 52% of stake has voted on a block_id and agreed on a bank_hash
31+
which is different than the bank_hash we have for that block_id.
3232
33-
- 52% of stake has voted on a block_id and agreed on a blockhash
33+
- 52% of stake has voted on a block_id and agreed on a bank_hash
3434
when we marked the block dead because it failed to execute.
3535
3636
Interestingly we do not need to handle the case where we thought a
@@ -42,7 +42,7 @@
4242
4343
We are essentially receiving a
4444
45-
Stream<Either<(VoteAccountPubkey, BlockId, BlockHash), EpochStakes>>
45+
Stream<Either<(VoteAccountPubkey, BlockId, BankHash), EpochStakes>>
4646
4747
The first variant is a vote from some validator for a certain
4848
block_id and block_hash. This could come from either any replayed
@@ -51,7 +51,7 @@
5151
marked dead because it did not validate), all the matters is that the
5252
vote is validly signed by the vote account.
5353
54-
Internally, we maintain a Map<BlockId, Map<BlockHash, StakeWeight>>.
54+
Internally, we maintain a Map<BlockId, Map<BankHash, StakeWeight>>.
5555
Any time we receive a vote, if it causes an entry in this map to
5656
exceed 52% of the total stake weight, or it is from our own
5757
validator identity, we check if our vote is different, and

src/discof/tower/fd_tower_tile.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "fd_tower_tile.h"
22
#include "generated/fd_tower_tile_seccomp.h"
33

4+
#include "fd_hard_fork_detector.h"
45
#include "../genesis/fd_genesi_tile.h"
56
#include "../../choreo/ghost/fd_ghost.h"
67
#include "../../choreo/notar/fd_notar.h"
@@ -91,6 +92,7 @@ typedef struct {
9192
fd_tower_forks_t * tower_forks;
9293
fd_tower_t * tower_spare; /* spare tower used during processing */
9394
conf_t * confs; /* deque of confirmations queued for publishing */
95+
fd_hard_fork_detector_t * hfd;
9496

9597
/* frag-related structures (consume and publish) */
9698

@@ -151,6 +153,7 @@ scratch_footprint( FD_PARAM_UNUSED fd_topo_tile_t const * tile ) {
151153
l = FD_LAYOUT_APPEND( l, fd_tower_forks_align(), fd_tower_forks_footprint( lg_slot_max ) );
152154
l = FD_LAYOUT_APPEND( l, fd_tower_align(), fd_tower_footprint() );
153155
l = FD_LAYOUT_APPEND( l, confs_align(), confs_footprint( slot_max ) );
156+
l = FD_LAYOUT_APPEND( l, fd_hard_fork_detector_align(), fd_hard_fork_detector_footprint( tile->tower.max_live_slots, FD_REPLAY_TOWER_VOTE_ACC_MAX ) );
154157
return FD_LAYOUT_FINI( l, scratch_align() );
155158
}
156159

@@ -304,11 +307,14 @@ count_vote_txn( ctx_t * ctx,
304307

305308
fd_tower_vote_t const * their_last_vote = fd_tower_peek_tail_const( ctx->tower_spare );
306309
fd_hash_t const * their_block_id = &ctx->compact_tower_sync_serde.block_id;
310+
fd_hash_t const * their_bank_hash = &ctx->compact_tower_sync_serde.hash;
307311

308312
ulong total_stake = fd_ghost_root( ctx->ghost )->total_stake;
309313
fd_notar_blk_t * notar_blk = fd_notar_count_vote( ctx->notar, total_stake, vote_acc, their_last_vote->slot, their_block_id );
310314
if( FD_LIKELY( notar_blk ) ) notar_confirm( ctx, stem, tsorig, notar_blk );
311315

316+
fd_hard_fork_detector_vote( ctx->hfd, vote_acc->uc, their_block_id->uc, their_bank_hash->uc );
317+
312318
fd_tower_forks_t * fork = fd_tower_forks_query( ctx->tower_forks, their_last_vote->slot, NULL );
313319
if( FD_UNLIKELY( !fork ) ) { ctx->metrics.vote_txn_ignored++; return; /* we haven't replayed this slot yet */ };
314320

@@ -379,6 +385,10 @@ replay_slot_completed( ctx_t * ctx,
379385
fd_notar_advance_epoch( ctx->notar, ctx->tower_accts, slot_info->epoch );
380386
}
381387

388+
/* Insert the just replayed block into hard fork detector. */
389+
390+
fd_hard_fork_detector_block( ctx->hfd, slot_info->slot, slot_info->block_id.uc, slot_info->bank_hash.uc );
391+
382392
/* Insert the just replayed block into ghost. */
383393

384394
fd_hash_t const * parent_block_id = &slot_info->parent_block_id;
@@ -668,7 +678,7 @@ privileged_init( fd_topo_t * topo,
668678
ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(ctx_t), sizeof(ctx_t) );
669679
FD_SCRATCH_ALLOC_FINI( l, scratch_align() );
670680

671-
FD_TEST( fd_rng_secure( &ctx->seed, 8 ) );
681+
FD_TEST( fd_rng_secure( &ctx->seed, sizeof(ctx->seed) ) );
672682

673683
if( FD_UNLIKELY( !strcmp( tile->tower.identity_key, "" ) ) ) FD_LOG_ERR(( "identity_key_path not set" ));
674684
ctx->identity_key[ 0 ] = *(fd_pubkey_t const *)fd_type_pun_const( fd_keyload_load( tile->tower.identity_key, /* pubkey only: */ 1 ) );
@@ -707,6 +717,7 @@ unprivileged_init( fd_topo_t * topo,
707717
void * forks = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_forks_align(), fd_tower_forks_footprint( lg_slot_max ) );
708718
void * spare = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_align(), fd_tower_footprint() );
709719
void * slots = FD_SCRATCH_ALLOC_APPEND( l, confs_align(), confs_footprint( slot_max ) );
720+
void * hfd = FD_SCRATCH_ALLOC_APPEND( l, fd_hard_fork_detector_align(), fd_hard_fork_detector_footprint( tile->tower.max_live_slots, FD_REPLAY_TOWER_VOTE_ACC_MAX ) );
710721
FD_SCRATCH_ALLOC_FINI( l, scratch_align() );
711722

712723
ctx->ghost = fd_ghost_join ( fd_ghost_new ( ghost, 2*slot_max, FD_VOTER_MAX, 42UL ) ); /* FIXME seed */
@@ -716,13 +727,15 @@ unprivileged_init( fd_topo_t * topo,
716727
ctx->tower_forks = fd_tower_forks_join( fd_tower_forks_new( forks, lg_slot_max ) );
717728
ctx->tower_spare = fd_tower_join ( fd_tower_new ( spare ) );
718729
ctx->confs = confs_join ( confs_new ( slots, slot_max ) );
730+
ctx->hfd = fd_hard_fork_detector_join( fd_hard_fork_detector_new( hfd, slot_max, FD_VOTER_MAX, tile->tower.fork_fatal, ctx->seed ) );
719731
FD_TEST( ctx->ghost );
720732
FD_TEST( ctx->notar );
721733
FD_TEST( ctx->tower );
722734
FD_TEST( ctx->tower_accts );
723735
FD_TEST( ctx->tower_forks );
724736
FD_TEST( ctx->tower_spare );
725737
FD_TEST( ctx->confs );
738+
FD_TEST( ctx->hfd );
726739

727740
for( ulong i = 0; i<VOTE_TXN_SIG_MAX; i++ ) {
728741
fd_sha512_t * sha = fd_sha512_join( fd_sha512_new( FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_sha512_t), sizeof(fd_sha512_t) ) ) );

src/flamenco/runtime/program/fd_bpf_loader_program.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2624,7 +2624,6 @@ fd_directly_invoke_loader_v3_deploy( fd_bank_t * bank,
26242624
txn_ctx->xid[0] = *xid;
26252625
txn_ctx->progcache = NULL;
26262626
txn_ctx->status_cache = NULL;
2627-
txn_ctx->bank_hash_cmp = NULL;
26282627
txn_ctx->log.enable_exec_recording = !!(bank->flags & FD_BANK_FLAGS_EXEC_RECORDING);
26292628
txn_ctx->bank = bank;
26302629

0 commit comments

Comments
 (0)