Skip to content

Commit f37bff0

Browse files
committed
accdb: add RAII-style read API
Provides syntax sugar for acquiring an account read-only handle that automatically releases resources when exiting scope.
1 parent 0722cee commit f37bff0

File tree

6 files changed

+70
-24
lines changed

6 files changed

+70
-24
lines changed

src/flamenco/accdb/fd_accdb_impl_v1.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,8 @@ fd_accdb_user_v1_init( fd_accdb_user_t * accdb,
488488
fd_funk_t *
489489
fd_accdb_user_v1_funk( fd_accdb_user_t * accdb ) {
490490
fd_accdb_user_v1_t * v1 = (fd_accdb_user_v1_t *)accdb;
491-
if( FD_UNLIKELY( accdb->base.accdb_type!=FD_ACCDB_TYPE_V1 ) ) {
491+
uint accdb_type = accdb->base.accdb_type;
492+
if( FD_UNLIKELY( accdb_type!=FD_ACCDB_TYPE_V1 && accdb_type!=FD_ACCDB_TYPE_V2 ) ) {
492493
FD_LOG_CRIT(( "fd_accdb_user_v1_funk called on non-v1 accdb_user (type %u)", accdb->base.accdb_type ));
493494
}
494495
return v1->funk;

src/flamenco/accdb/fd_accdb_sync.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,51 @@ fd_accdb_close_ro( fd_accdb_user_t * accdb,
7171
accdb->base.vt->close_ro( accdb, ro );
7272
}
7373

74+
/* FD_ACDB_RO_{BEGIN,END} provides RAII-style safe macros for
75+
fd_accdb_{open,close}_ro.
76+
77+
Typical usage like:
78+
79+
FD_ACCDB_RO_BEGIN( accdb, ro, xid, address ) {
80+
FD_LOG_NOTICE(( "Account has %lu lamports", fd_accdb_ref_lamports( ro ) ));
81+
}
82+
FD_ACCDB_RO_NOT_FOUND {
83+
FD_LOG_NOTICE(( "Account does not exist" ));
84+
}
85+
FD_ACCDB_RO_END; */
86+
87+
struct fd_accdb_ro_scope_guard {
88+
fd_accdb_user_t * accdb;
89+
fd_accdb_ro_t * ro;
90+
};
91+
typedef struct fd_accdb_ro_scope_guard fd_accdb_ro_scope_guard_t;
92+
93+
FD_FN_UNUSED static inline void
94+
fd_accdb_ro_scope_exit( fd_accdb_ro_scope_guard_t * guard ) {
95+
fd_accdb_close_ro( guard->accdb, guard->ro );
96+
}
97+
98+
#define FD_ACCDB_RO_BEGIN( accdb__, handle, xid, address) \
99+
{ \
100+
fd_accdb_ro_t handle[1]; \
101+
fd_accdb_user_t * accdb_ = (accdb__); \
102+
void const * addr_ = (address); \
103+
if( fd_accdb_open_ro( accdb, handle, (xid), addr_ ) ) { \
104+
fd_accdb_ro_scope_guard_t __attribute__((cleanup(fd_accdb_ro_scope_exit))) guard_ = \
105+
{ .accdb=accdb_, .ro=handle }; \
106+
(void)guard_; \
107+
{ \
108+
/* User-provided account found snippet */
109+
#define FD_ACCDB_RO_NOT_FOUND \
110+
} \
111+
} else { \
112+
{ \
113+
/* User-provided account not found snippet */
114+
#define FD_ACCDB_RO_END \
115+
} \
116+
} \
117+
}
118+
74119
/* In-place transactional write APIs **********************************/
75120

76121
FD_PROTOTYPES_BEGIN

src/flamenco/runtime/sysvar/fd_sysvar_clock.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,30 +74,31 @@ fd_sysvar_clock_write( fd_bank_t * bank,
7474
fd_sysvar_account_update( bank, accdb, xid, capture_ctx, &fd_sysvar_clock_id, enc, sizeof(fd_sol_sysvar_clock_t) );
7575
}
7676

77-
7877
fd_sol_sysvar_clock_t *
79-
fd_sysvar_clock_read( fd_funk_t * funk,
78+
fd_sysvar_clock_read( fd_accdb_user_t * accdb,
8079
fd_funk_txn_xid_t const * xid,
8180
fd_sol_sysvar_clock_t * clock ) {
82-
fd_txn_account_t acc[1];
83-
int rc = fd_txn_account_init_from_funk_readonly( acc, &fd_sysvar_clock_id, funk, xid );
84-
if( FD_UNLIKELY( rc!=FD_ACC_MGR_SUCCESS ) ) {
85-
return NULL;
86-
}
81+
FD_ACCDB_RO_BEGIN( accdb, acc, xid, &fd_sysvar_clock_id ) {
82+
83+
/* This check is needed as a quirk of the fuzzer. If a sysvar account
84+
exists in the accounts database, but doesn't have any lamports,
85+
this means that the account does not exist. This wouldn't happen
86+
in a real execution environment. */
87+
if( FD_UNLIKELY( fd_accdb_ref_lamports( acc )==0UL ) ) {
88+
return NULL;
89+
}
90+
91+
return fd_bincode_decode_static(
92+
sol_sysvar_clock, clock,
93+
fd_accdb_ref_data_const( acc ),
94+
fd_accdb_ref_data_sz ( acc ),
95+
NULL );
96+
97+
} FD_ACCDB_RO_NOT_FOUND {
8798

88-
/* This check is needed as a quirk of the fuzzer. If a sysvar account
89-
exists in the accounts database, but doesn't have any lamports,
90-
this means that the account does not exist. This wouldn't happen
91-
in a real execution environment. */
92-
if( FD_UNLIKELY( fd_txn_account_get_lamports( acc )==0UL ) ) {
9399
return NULL;
94-
}
95100

96-
return fd_bincode_decode_static(
97-
sol_sysvar_clock, clock,
98-
fd_txn_account_get_data( acc ),
99-
fd_txn_account_get_data_len( acc ),
100-
NULL );
101+
} FD_ACCDB_RO_END;
101102
}
102103

103104
void
@@ -268,9 +269,8 @@ fd_sysvar_clock_update( fd_bank_t * bank,
268269
fd_capture_ctx_t * capture_ctx,
269270
fd_runtime_stack_t * runtime_stack,
270271
ulong const * parent_epoch ) {
271-
fd_funk_t * funk = fd_accdb_user_v1_funk( accdb );
272272
fd_sol_sysvar_clock_t clock_[1];
273-
fd_sol_sysvar_clock_t * clock = fd_sysvar_clock_read( funk, xid, clock_ );
273+
fd_sol_sysvar_clock_t * clock = fd_sysvar_clock_read( accdb, xid, clock_ );
274274
if( FD_UNLIKELY( !clock ) ) FD_LOG_ERR(( "fd_sysvar_clock_read failed" ));
275275

276276
fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank );

src/flamenco/runtime/sysvar/fd_sysvar_clock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fd_sysvar_clock_write( fd_bank_t * bank,
6464
has zero lamports, this function returns NULL. */
6565

6666
fd_sol_sysvar_clock_t *
67-
fd_sysvar_clock_read( fd_funk_t * funk,
67+
fd_sysvar_clock_read( fd_accdb_user_t * accdb,
6868
fd_funk_txn_xid_t const * xid,
6969
fd_sol_sysvar_clock_t * clock );
7070

src/flamenco/runtime/tests/fd_instr_harness.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner,
246246
FD_TEST( fd_sysvar_last_restart_slot_read( funk, xid, last_restart_slot_ ) );
247247

248248
fd_sol_sysvar_clock_t clock_[1];
249-
fd_sol_sysvar_clock_t * clock = fd_sysvar_clock_read( funk, xid, clock_ );
249+
fd_sol_sysvar_clock_t * clock = fd_sysvar_clock_read( runner->accdb, xid, clock_ );
250250
FD_TEST( clock );
251251
fd_bank_slot_set( runner->bank, clock->slot );
252252

src/flamenco/runtime/tests/fd_txn_harness.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ fd_solfuzz_pb_txn_ctx_create( fd_solfuzz_runner_t * runner,
119119
FD_TEST( stake_history );
120120

121121
fd_sol_sysvar_clock_t clock_[1];
122-
fd_sol_sysvar_clock_t const * clock = fd_sysvar_clock_read( funk, &xid, clock_ );
122+
fd_sol_sysvar_clock_t const * clock = fd_sysvar_clock_read( runner->accdb, &xid, clock_ );
123123
FD_TEST( clock );
124124

125125
/* Setup vote states dummy account */

0 commit comments

Comments
 (0)