Skip to content

Commit

Permalink
funk: adding txn metadata to erased records
Browse files Browse the repository at this point in the history
  • Loading branch information
ibhatt-jumptrading committed Dec 19, 2024
1 parent 11f556e commit 801cce6
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/app/ledger/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ prune( fd_ledger_args_t * args ) {
fd_funk_val_sz( original_rec ) ) == 0 ));
} else {
fd_funk_rec_t * mod_rec = fd_funk_rec_modify( pruned_funk, rec );
int res = fd_funk_rec_remove( pruned_funk, mod_rec );
int res = fd_funk_rec_remove( pruned_funk, mod_rec, rec->pair.xid->ul[0] );
FD_TEST(( res == 0 ));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/flamenco/runtime/fd_hashes.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ fd_update_hash_bank_tpool( fd_exec_slot_ctx_t * slot_ctx,
continue;
}

fd_funk_rec_remove(funk, fd_funk_rec_modify(funk, task_info->rec));
fd_funk_rec_remove( funk, fd_funk_rec_modify(funk, task_info->rec), task_info->rec->pair.xid->ul[0] );
}

// Sanity-check LT Hash
Expand Down
2 changes: 1 addition & 1 deletion src/flamenco/runtime/fd_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -3694,7 +3694,7 @@ fd_runtime_cleanup_incinerator( fd_exec_slot_ctx_t * slot_ctx ) {
fd_funk_t * funk = slot_ctx->acc_mgr->funk;
fd_funk_rec_t const * rec = fd_funk_rec_query( funk, slot_ctx->funk_txn, &id );
if( rec )
fd_funk_rec_remove( funk, fd_funk_rec_modify( funk, rec ));
fd_funk_rec_remove( funk, fd_funk_rec_modify( funk, rec ), rec->pair.xid->ul[0] );
}

void
Expand Down
4 changes: 2 additions & 2 deletions src/flamenco/runtime/program/fd_bpf_program_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx,
if( FD_UNLIKELY( 0!=fd_sbpf_program_load( prog, program_data, program_data_len, syscalls, false ) ) ) {
/* Remove pending funk record */
FD_LOG_DEBUG(( "fd_sbpf_program_load() failed: %s", fd_sbpf_strerror() ));
fd_funk_rec_remove( funk, rec );
fd_funk_rec_remove( funk, rec, funk_txn->xid.ul[0] );
return -1;
}

Expand Down Expand Up @@ -267,7 +267,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx,
if( FD_UNLIKELY( res ) ) {
/* Remove pending funk record */
FD_LOG_DEBUG(( "fd_vm_validate() failed" ));
fd_funk_rec_remove( funk, rec );
fd_funk_rec_remove( funk, rec, 0UL );
return -1;
}

Expand Down
18 changes: 17 additions & 1 deletion src/funk/fd_funk_rec.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,8 @@ fd_funk_rec_insert( fd_funk_t * funk,

int
fd_funk_rec_remove( fd_funk_t * funk,
fd_funk_rec_t * rec ) {
fd_funk_rec_t * rec,
ulong erase_data ) {

if( FD_UNLIKELY( !funk ) ) return FD_FUNK_ERR_INVAL;
fd_funk_check_write( funk );
Expand Down Expand Up @@ -461,9 +462,24 @@ fd_funk_rec_remove( fd_funk_t * funk,
fd_funk_part_set_intern( fd_funk_get_partvec( funk, wksp ), rec_map, rec, FD_FUNK_PART_NULL );
rec->flags |= FD_FUNK_REC_FLAG_ERASE;

/* At this point, the 5 most significant bytes should store data about the
transaction that the record was updated in. */

fd_funk_rec_set_erase_data( rec, erase_data );

return FD_FUNK_SUCCESS;
}

void
fd_funk_rec_set_erase_data( fd_funk_rec_t * rec, ulong erase_data ) {
rec->flags |= ((erase_data & 0xFFFFFFFFFFUL) << (sizeof(unsigned long) * 8 - 40));
}

ulong
fd_funk_rec_get_erase_data( fd_funk_rec_t const * rec ) {
return (rec->flags >> (sizeof(unsigned long) * 8 - 40)) & 0xFFFFFFFFFFUL;
}

fd_funk_rec_t *
fd_funk_rec_write_prepare( fd_funk_t * funk,
fd_funk_txn_t * txn,
Expand Down
25 changes: 22 additions & 3 deletions src/funk/fd_funk_rec.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@
#define FD_FUNK_REC_ALIGN (32UL)

/* FD_FUNK_REC_FLAG_* are flags that can be bit-ored together to specify
how records are to be interpreted.
how records are to be interpreted. The 5 most signifcant bytes of a
rec's flag are reserved to be used in conjunction with the ERASE flag.
- ERASE indicates a record in an in-preparation transaction should be
erased if and when the in-preparation transaction is published. If
set, there will be no value resources used by this record. Will not
be set on a published record. Will not be set if an in-preparation
transaction ancestor has this record with erase set. If set, the
first ancestor transaction encountered (going from youngest to
oldest) will not have erased set. */
oldest) will not have erased set.
If the ERASE flag is set, then the five most significant bytes of the
flags field for the record will be used to store user-specified data. */

#define FD_FUNK_REC_FLAG_ERASE (1UL<<0)

Expand Down Expand Up @@ -440,7 +444,22 @@ fd_funk_rec_insert( fd_funk_t * funk,

int
fd_funk_rec_remove( fd_funk_t * funk,
fd_funk_rec_t * rec );
fd_funk_rec_t * rec,
ulong erase_data );


/* When a record is erased there is metadata stored in the five most
significant bytes of a record. These are helpers to make setting
and getting these values simple. The caller is responsible for doing
a check on the flag of the record before using the value of the erase
data. The 5 least significant bytes of the erase data parameter will
be used and set into the erase flag. */

void
fd_funk_rec_set_erase_data( fd_funk_rec_t * rec, ulong erase_data );

ulong
fd_funk_rec_get_erase_data( fd_funk_rec_t const * rec );

/* fd_funk_rec_write_prepare combines several operations into one
convenient package. There are 3 basic cases:
Expand Down
20 changes: 10 additions & 10 deletions src/funk/fd_funk_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,12 +552,12 @@ fd_funk_txn_update( ulong * _dst_rec_head_idx, /* Pointer to t
the record map below. Note that we can't just reuse rec_idx in
the update case because that could break map queries. */

ulong val_sz = (ulong)rec_map[ rec_idx ].val_sz;
ulong val_max = (ulong)rec_map[ rec_idx ].val_max;
ulong val_gaddr = rec_map[ rec_idx ].val_gaddr;
int val_no_free = rec_map[ rec_idx ].val_no_free;
uint part = rec_map[ rec_idx ].part;
int erase = rec_map[ rec_idx ].flags & FD_FUNK_REC_FLAG_ERASE;
ulong val_sz = (ulong)rec_map[ rec_idx ].val_sz;
ulong val_max = (ulong)rec_map[ rec_idx ].val_max;
ulong val_gaddr = rec_map[ rec_idx ].val_gaddr;
int val_no_free = rec_map[ rec_idx ].val_no_free;
uint part = rec_map[ rec_idx ].part;
ulong flags = rec_map[ rec_idx ].flags;

fd_funk_part_set_intern( partvec, rec_map, &rec_map[ rec_idx ], FD_FUNK_PART_NULL );
fd_funk_rec_map_remove( rec_map, fd_funk_rec_pair( &rec_map[ rec_idx ] ) );
Expand Down Expand Up @@ -590,11 +590,11 @@ fd_funk_txn_update( ulong * _dst_rec_head_idx, /* Pointer to t

/* Unstash value metadata from stack temporaries into dst_rec */

dst_rec->val_sz = (uint)val_sz;
dst_rec->val_max = (uint)val_max;
dst_rec->val_gaddr = val_gaddr;
dst_rec->val_sz = (uint)val_sz;
dst_rec->val_max = (uint)val_max;
dst_rec->val_gaddr = val_gaddr;
dst_rec->val_no_free = val_no_free;
dst_rec->flags = ( erase ? FD_FUNK_REC_FLAG_ERASE : 0 );
dst_rec->flags = flags;

/* Use the new partition */

Expand Down
2 changes: 1 addition & 1 deletion src/funk/test_funk_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ struct fake_funk {
auto key = rec->real_id();
auto* rec2 = fd_funk_rec_query(_real, txn2, &key);
assert(rec2 != NULL);
assert(fd_funk_rec_remove(_real, (fd_funk_rec_t *)rec2) == FD_FUNK_SUCCESS);
assert(fd_funk_rec_remove(_real, (fd_funk_rec_t *)rec2, 0UL) == FD_FUNK_SUCCESS);

rec->_erased = true;
rec->_data.clear();
Expand Down
2 changes: 1 addition & 1 deletion src/funk/test_funk_part.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ main( int argc,
fd_funk_rec_key_t * key = &recs[i];
fd_funk_rec_t * rec = fd_funk_rec_write_prepare(funk, txn, key, 0, 0, NULL, NULL);
if (rec && !(rec->flags & FD_FUNK_REC_FLAG_ERASE)) {
int err = fd_funk_rec_remove(funk, rec);
int err = fd_funk_rec_remove(funk, rec, 0);
FD_TEST(!err);
}
break;
Expand Down
26 changes: 13 additions & 13 deletions src/funk/test_funk_rec.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,15 @@ main( int argc,
FD_TEST( !fd_funk_rec_modify( tst, rec_map+rec_max ) );
FD_TEST( !fd_funk_rec_modify( tst, (fd_funk_rec_t *)1UL ) );

FD_TEST( fd_funk_rec_remove( NULL, NULL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( NULL, (fd_funk_rec_t *)trec )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, NULL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, rec_map+rec_max )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)1UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( NULL, NULL , 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( NULL, (fd_funk_rec_t *)trec, 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, NULL , 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, rec_map+rec_max , 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)1UL , 0UL )==FD_FUNK_ERR_INVAL );

if( trec ) {
if( is_frozen ) {
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)trec )==FD_FUNK_ERR_FROZEN );
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)trec, 0UL )==FD_FUNK_ERR_FROZEN );
}
}

Expand Down Expand Up @@ -248,14 +248,14 @@ main( int argc,
FD_TEST( !fd_funk_rec_modify( tst, rec_map+rec_max ) );
FD_TEST( !fd_funk_rec_modify( tst, (fd_funk_rec_t *)1UL ) );

FD_TEST( fd_funk_rec_remove( NULL, NULL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( NULL, (fd_funk_rec_t *)trec )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, NULL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, rec_map+rec_max )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)1UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( NULL, NULL , 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( NULL, (fd_funk_rec_t *)trec, 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, NULL , 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, rec_map+rec_max , 0UL )==FD_FUNK_ERR_INVAL );
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)1UL , 0UL )==FD_FUNK_ERR_INVAL );

if( trec && ttxn_is_frozen ) {
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)trec )==FD_FUNK_ERR_FROZEN );
FD_TEST( fd_funk_rec_remove( tst, (fd_funk_rec_t *)trec, 0UL )==FD_FUNK_ERR_FROZEN );
}

int err;
Expand Down Expand Up @@ -406,7 +406,7 @@ main( int argc,

fd_funk_rec_t * _trec = fd_funk_rec_modify( tst, trec );
FD_TEST( trec==(fd_funk_rec_t const *)_trec );
FD_TEST( !fd_funk_rec_remove( tst, _trec ) );
FD_TEST( !fd_funk_rec_remove( tst, _trec, 0UL ) );

} else if( op>=2 ) { /* Prepare 8x as publish and cancel combined */

Expand Down
2 changes: 1 addition & 1 deletion src/funk/test_funk_val.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ main( int argc,
fd_funk_rec_t const * trec = fd_funk_rec_query( tst, ttxn, key_set( tkey, rkey ) );

fd_funk_rec_t * _trec = fd_funk_rec_modify( tst, trec );
FD_TEST( !fd_funk_rec_remove( tst, _trec ) );
FD_TEST( !fd_funk_rec_remove( tst, _trec, 0UL ) );

} else if( op>=2 ) { /* Prepare 8x as publish and cancel combined */

Expand Down

0 comments on commit 801cce6

Please sign in to comment.