Skip to content

Commit 10b1945

Browse files
runtime: updates to bank_clear functionality with tests
1 parent 10638c2 commit 10b1945

File tree

9 files changed

+134
-38
lines changed

9 files changed

+134
-38
lines changed

src/flamenco/runtime/fd_bank.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -637,10 +637,10 @@ fd_banks_publish( fd_banks_t * banks, ulong slot ) {
637637
/* Decide if we need to free any CoW fields. We free a CoW member
638638
from its pool if the dirty flag is set unless it is the same
639639
pool that the new root uses. */
640-
#define HAS_COW_1(name) \
641-
if( head->name##_dirty && head->name##_pool_idx!=new_root->name##_pool_idx ) { \
642-
fd_bank_##name##_t * name##_pool = fd_banks_get_##name##_pool( banks ); \
643-
fd_bank_##name##_pool_idx_release( name##_pool, head->name##_pool_idx ); \
640+
#define HAS_COW_1(name) \
641+
if( head->name##_dirty && head->name##_pool_idx!=new_root->name##_pool_idx ) { \
642+
fd_bank_##name##_t * name##_pool = fd_banks_get_##name##_pool( banks ); \
643+
fd_bank_##name##_pool_idx_release( name##_pool, head->name##_pool_idx ); \
644644
}
645645
/* Do nothing for these. */
646646
#define HAS_COW_0(name)
@@ -652,7 +652,6 @@ fd_banks_publish( fd_banks_t * banks, ulong slot ) {
652652
#undef HAS_COW_0
653653
#undef HAS_COW_1
654654

655-
656655
fd_banks_pool_ele_release( bank_pool, head );
657656
head = next;
658657
}
@@ -684,15 +683,21 @@ fd_banks_publish( fd_banks_t * banks, ulong slot ) {
684683
}
685684

686685
void
687-
fd_bank_clear_bank( fd_bank_t * bank ) {
688-
689-
#define HAS_COW_1(type, name, footprint) \
690-
fd_bank_##name##_t * name##_pool = fd_bank_get_##name##_pool( bank ); \
691-
if( bank->name##_pool_idx==fd_bank_##name##_pool_idx_null( name##_pool ) ) { \
692-
return; \
693-
} \
694-
fd_bank_##name##_t * name##_ele = fd_bank_##name##_pool_ele( name##_pool, bank->name##_pool_idx ); \
695-
fd_memset( name##_ele->data, 0, footprint );
686+
fd_banks_clear_bank( fd_banks_t * banks, fd_bank_t * bank ) {
687+
688+
/* Get the parent bank. */
689+
fd_bank_t * parent_bank = fd_banks_pool_ele( fd_banks_get_bank_pool( banks ), bank->parent_idx );
690+
691+
#define HAS_COW_1(type, name, footprint) \
692+
fd_bank_##name##_t * name##_pool = fd_bank_get_##name##_pool( bank ); \
693+
if( bank->name##_dirty ) { \
694+
/* If the dirty flag is set, then we have a pool allocated for */ \
695+
/* this specific bank. We need to release the pool index and */ \
696+
/* assign the bank to the idx corresponding to the parent. */ \
697+
fd_bank_##name##_pool_idx_release( name##_pool, bank->name##_pool_idx ); \
698+
bank->name##_dirty = 0; \
699+
bank->name##_pool_idx = !!parent_bank ? parent_bank->name##_pool_idx : fd_bank_##name##_pool_idx_null( name##_pool ); \
700+
}
696701

697702
#define HAS_COW_0(type, name, footprint) \
698703
fd_memset( bank->name, 0, footprint );

src/flamenco/runtime/fd_bank.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,15 @@ fd_banks_clone_from_parent( fd_banks_t * banks,
587587
fd_bank_t const *
588588
fd_banks_publish( fd_banks_t * banks, ulong slot );
589589

590+
/* fd_bank_clear_bank() clears the contents of a bank. This should ONLY
591+
be used with banks that have no children.
592+
593+
This function will memset all non-CoW fields to 0.
594+
595+
For all non-CoW fields, we will reset the indices to its parent. */
596+
590597
void
591-
fd_bank_clear_bank( fd_bank_t * bank );
598+
fd_banks_clear_bank( fd_banks_t * banks, fd_bank_t * bank );
592599

593600
FD_PROTOTYPES_END
594601

src/flamenco/runtime/test_bank.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ main( int argc, char ** argv ) {
7777
FD_TEST( bank9 );
7878
FD_TEST( fd_bank_capitalization_get( bank9 ) == 2100UL );
7979

80+
/* Set some CoW fields. */
81+
fd_account_keys_global_t * keys = fd_bank_vote_account_keys_locking_modify( bank9 );
82+
keys->account_keys_pool_offset = 100UL;
83+
keys->account_keys_root_offset = 100UL;
84+
fd_bank_vote_account_keys_end_locking_modify( bank9 );
85+
86+
fd_account_keys_global_t * keys2 = fd_bank_stake_account_keys_locking_modify( bank9 );
87+
keys2->account_keys_pool_offset = 101UL;
88+
keys2->account_keys_root_offset = 101UL;
89+
fd_bank_stake_account_keys_end_locking_modify( bank9 );
90+
8091
/* Verify that the bank is published and that it is indeed bank7 */
8192

8293
fd_bank_t const * new_root = fd_banks_publish( banks, 7UL );
@@ -92,6 +103,30 @@ main( int argc, char ** argv ) {
92103
FD_TEST( bank11 );
93104
FD_TEST( fd_bank_capitalization_get( bank11 ) == 2100UL );
94105

106+
fd_account_keys_global_t const * keys3 = fd_bank_vote_account_keys_locking_query( bank11 );
107+
FD_TEST( keys3->account_keys_pool_offset == 100UL );
108+
FD_TEST( keys3->account_keys_root_offset == 100UL );
109+
fd_bank_vote_account_keys_end_locking_query( bank11 );
110+
111+
fd_account_keys_global_t const * keys4 = fd_bank_stake_account_keys_locking_query( bank11 );
112+
FD_TEST( keys4->account_keys_pool_offset == 101UL );
113+
FD_TEST( keys4->account_keys_root_offset == 101UL );
114+
fd_bank_stake_account_keys_end_locking_query( bank11 );
115+
116+
keys = fd_bank_vote_account_keys_locking_modify( bank11 );
117+
keys->account_keys_pool_offset = 200UL;
118+
keys->account_keys_root_offset = 200UL;
119+
fd_bank_vote_account_keys_end_locking_modify( bank11 );
120+
121+
fd_clock_timestamp_votes_global_t const * votes_const = fd_bank_clock_timestamp_votes_locking_query( bank11 );
122+
FD_TEST( !votes_const );
123+
fd_bank_clock_timestamp_votes_end_locking_query( bank11 );
124+
125+
fd_clock_timestamp_votes_global_t * votes = fd_bank_clock_timestamp_votes_locking_modify( bank11 );
126+
votes->votes_pool_offset = 102UL;
127+
votes->votes_root_offset = 102UL;
128+
fd_bank_clock_timestamp_votes_end_locking_modify( bank11 );
129+
95130
/* Now there should be 3 forks:
96131
1. 7 -> 8
97132
2. 7 -> 9 -> 11
@@ -108,6 +143,48 @@ main( int argc, char ** argv ) {
108143
FD_TEST( !!fd_banks_get_bank( banks, 9UL ) );
109144
FD_TEST( !!fd_banks_get_bank( banks, 10UL ) );
110145

146+
/* Verify that the CoW fields are properly set for bank11 */
147+
keys3 = fd_bank_vote_account_keys_locking_query( bank11 );
148+
FD_TEST( keys3->account_keys_pool_offset == 200UL );
149+
FD_TEST( keys3->account_keys_root_offset == 200UL );
150+
fd_bank_vote_account_keys_end_locking_query( bank11 );
151+
152+
keys4 = fd_bank_stake_account_keys_locking_query( bank11 );
153+
FD_TEST( keys4->account_keys_pool_offset == 101UL );
154+
FD_TEST( keys4->account_keys_root_offset == 101UL );
155+
fd_bank_stake_account_keys_end_locking_query( bank11 );
156+
157+
votes_const = fd_bank_clock_timestamp_votes_locking_query( bank11 );
158+
FD_TEST( votes->votes_pool_offset == 102UL );
159+
FD_TEST( votes->votes_root_offset == 102UL );
160+
fd_bank_clock_timestamp_votes_end_locking_query( bank11 );
161+
162+
/* Clear bank11, we need to make sure that the pool indices are
163+
cleared and properly released.
164+
165+
We test the cases where:
166+
1. Pool was not made dirty and had a non-null parent pool idx.
167+
2. Pool was not made dirty and had a null parent pool idx.
168+
3. Pool was made dirty and had a non-null parent pool idx.
169+
4. Pool was made dirty and had a null parent pool idx. */
170+
fd_banks_clear_bank( banks, bank11 );
171+
FD_TEST( fd_bank_slot_get( bank11 ) == 11UL );
172+
FD_TEST( fd_bank_capitalization_get( bank11 ) == 0UL );
173+
174+
keys3 = fd_bank_vote_account_keys_locking_query( bank11 );
175+
FD_TEST( keys3->account_keys_pool_offset == 100UL );
176+
FD_TEST( keys3->account_keys_root_offset == 100UL );
177+
fd_bank_vote_account_keys_end_locking_query( bank11 );
178+
179+
keys4 = fd_bank_stake_account_keys_locking_query( bank11 );
180+
FD_TEST( keys4->account_keys_pool_offset == 101UL );
181+
FD_TEST( keys4->account_keys_root_offset == 101UL );
182+
fd_bank_stake_account_keys_end_locking_query( bank11 );
183+
184+
votes_const = fd_bank_clock_timestamp_votes_locking_query( bank11 );
185+
FD_TEST( !votes_const );
186+
fd_bank_clock_timestamp_votes_end_locking_query( bank11 );
187+
111188
FD_LOG_NOTICE(( "pass" ));
112189

113190
fd_halt();

src/flamenco/runtime/tests/harness/fd_block_harness.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,9 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner,
201201
fd_exec_test_block_context_t const * test_ctx ) {
202202
fd_funk_t * funk = runner->funk;
203203

204-
slot_ctx->bank = runner->bank;
205-
fd_bank_clear_bank( slot_ctx->bank );
204+
slot_ctx->banks = runner->banks;
205+
slot_ctx->bank = runner->bank;
206+
fd_banks_clear_bank( slot_ctx->banks, slot_ctx->bank );
206207

207208
/* Generate unique ID for funk txn */
208209
fd_funk_txn_xid_t xid[1] = {0};

src/flamenco/runtime/tests/harness/fd_exec_sol_compat.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ typedef struct {
4242

4343
static sol_compat_features_t features;
4444
static uchar * spad_mem;
45-
static fd_wksp_t * wksp = NULL;
46-
static fd_bank_t * bank = NULL;
45+
static fd_wksp_t * wksp = NULL;
46+
static fd_banks_t * banks = NULL;
47+
static fd_bank_t * bank = NULL;
4748

4849
#define WKSP_EXECUTE_ALLOC_TAG (2UL)
4950
#define WKSP_INIT_ALLOC_TAG (3UL)
@@ -91,7 +92,7 @@ sol_compat_wksp_init( ulong wksp_page_sz ) {
9192
FD_LOG_CRIT(( "Unable to allocate memory for banks" ));
9293
}
9394

94-
fd_banks_t * banks = fd_banks_join( fd_banks_new( banks_mem, 1UL ) );
95+
banks = fd_banks_join( fd_banks_new( banks_mem, 1UL ) );
9596
if( FD_UNLIKELY( !banks ) ) {
9697
FD_LOG_CRIT(( "Unable to create and join banks" ));
9798
}
@@ -149,7 +150,7 @@ sol_compat_setup_runner( void ) {
149150

150151
// Setup test runner
151152
void * runner_mem = fd_wksp_alloc_laddr( wksp, fd_runtime_fuzz_runner_align(), fd_runtime_fuzz_runner_footprint(), WKSP_EXECUTE_ALLOC_TAG );
152-
fd_runtime_fuzz_runner_t * runner = fd_runtime_fuzz_runner_new( runner_mem, spad_mem, bank, WKSP_EXECUTE_ALLOC_TAG );
153+
fd_runtime_fuzz_runner_t * runner = fd_runtime_fuzz_runner_new( runner_mem, spad_mem, banks, bank, WKSP_EXECUTE_ALLOC_TAG );
153154
return runner;
154155
}
155156

src/flamenco/runtime/tests/harness/fd_harness_common.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ fd_runtime_fuzz_runner_footprint( void ) {
1818
}
1919

2020
fd_runtime_fuzz_runner_t *
21-
fd_runtime_fuzz_runner_new( void * mem,
22-
void * spad_mem,
23-
fd_bank_t * bank,
24-
ulong wksp_tag ) {
21+
fd_runtime_fuzz_runner_new( void * mem,
22+
void * spad_mem,
23+
fd_banks_t * banks,
24+
fd_bank_t * bank,
25+
ulong wksp_tag ) {
2526
ulong txn_max = 4+fd_tile_cnt();
2627
uint rec_max = 1024;
2728

@@ -43,7 +44,8 @@ fd_runtime_fuzz_runner_new( void * mem,
4344
runner->wksp = fd_wksp_containing( runner->spad );
4445

4546
/* Reuse the same bank for each iteration of the fuzzer */
46-
runner->bank = bank;
47+
runner->banks = banks;
48+
runner->bank = bank;
4749

4850
return runner;
4951
}

src/flamenco/runtime/tests/harness/fd_harness_common.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
for all harnesses. */
1111

1212
struct fd_runtime_fuzz_runner {
13-
fd_funk_t funk[1];
14-
fd_wksp_t * wksp;
15-
fd_spad_t * spad;
16-
fd_bank_t * bank;
13+
fd_funk_t funk[1];
14+
fd_wksp_t * wksp;
15+
fd_spad_t * spad;
16+
fd_banks_t * banks;
17+
fd_bank_t * bank;
1718
};
1819
typedef struct fd_runtime_fuzz_runner fd_runtime_fuzz_runner_t;
1920

@@ -37,10 +38,11 @@ fd_runtime_fuzz_runner_footprint( void );
3738
NULL and logs reason for error. */
3839

3940
fd_runtime_fuzz_runner_t *
40-
fd_runtime_fuzz_runner_new( void * mem,
41-
void * spad_mem,
42-
fd_bank_t * bank,
43-
ulong wksp_tag );
41+
fd_runtime_fuzz_runner_new( void * mem,
42+
void * spad_mem,
43+
fd_banks_t * banks,
44+
fd_bank_t * bank,
45+
ulong wksp_tag );
4446

4547
/* fd_runtime_fuzz_runner_delete frees wksp allocations managed by
4648
runner and returns the memory region backing runner itself back to

src/flamenco/runtime/tests/harness/fd_instr_harness.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ fd_runtime_fuzz_instr_ctx_create( fd_runtime_fuzz_runner_t * runner,
4848
slot_ctx->funk = funk;
4949

5050
/* Bank manager */
51-
51+
slot_ctx->banks = runner->banks;
5252
slot_ctx->bank = runner->bank;
53-
fd_bank_clear_bank( slot_ctx->bank );
53+
fd_banks_clear_bank( slot_ctx->banks, slot_ctx->bank );
5454

5555
fd_features_t * features = fd_bank_features_modify( slot_ctx->bank );
5656
fd_exec_test_feature_set_t const * feature_set = &test_ctx->epoch_context.features;

src/flamenco/runtime/tests/harness/fd_txn_harness.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner,
3838
slot_ctx->funk_txn = funk_txn;
3939
slot_ctx->funk = funk;
4040

41-
slot_ctx->bank = runner->bank;
42-
fd_bank_clear_bank( slot_ctx->bank );
41+
slot_ctx->banks = runner->banks;
42+
slot_ctx->bank = runner->bank;
43+
fd_banks_clear_bank( slot_ctx->banks, slot_ctx->bank );
4344

4445
/* Restore feature flags */
4546

0 commit comments

Comments
 (0)