Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/flamenco/features/fd_features_generated.c
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,12 @@ fd_feature_id_t const ids[] = {
.name = "provide_instruction_data_offset_in_vm_r2",
.cleaned_up = {UINT_MAX, UINT_MAX, UINT_MAX} },

{ .index = offsetof(fd_features_t, static_instruction_limit)>>3,
.id = {"\x4b\x3e\xa0\x91\xa9\xb6\xb5\xda\x05\x3a\x32\x6f\x7c\x18\xd9\x0d\x60\x87\x99\x76\xfb\xc6\x6f\x18\xc1\xfa\x37\x38\x94\x41\xc1\xf9"},
/* 64ixypL1HPu8WtJhNSMb9mSgfFaJvsANuRkTbHyuLfnx */
.name = "static_instruction_limit",
.cleaned_up = {UINT_MAX, UINT_MAX, UINT_MAX} },

{ .index = ULONG_MAX }
};
/* TODO replace this with fd_map_perfect */
Expand Down Expand Up @@ -1958,6 +1964,7 @@ fd_feature_id_query( ulong prefix ) {
case 0x8c7bee4552d93e0c: return &ids[ 246 ];
case 0x866094bbfe00a7c6: return &ids[ 247 ];
case 0x7c4802b8ba3fa849: return &ids[ 248 ];
case 0xdab5b6a991a03e4b: return &ids[ 249 ];
default: break;
}
return NULL;
Expand Down Expand Up @@ -2212,4 +2219,5 @@ FD_STATIC_ASSERT( offsetof( fd_features_t, fix_alt_bn128_pairing_length_check
FD_STATIC_ASSERT( offsetof( fd_features_t, poseidon_enforce_padding )>>3==246UL, layout );
FD_STATIC_ASSERT( offsetof( fd_features_t, relax_intrabatch_account_locks )>>3==247UL, layout );
FD_STATIC_ASSERT( offsetof( fd_features_t, provide_instruction_data_offset_in_vm_r2 )>>3==248UL, layout );
FD_STATIC_ASSERT( offsetof( fd_features_t, static_instruction_limit )>>3==249UL, layout );
FD_STATIC_ASSERT( sizeof( fd_features_t )>>3==FD_FEATURE_ID_CNT, layout );
5 changes: 3 additions & 2 deletions src/flamenco/features/fd_features_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#endif

/* FEATURE_ID_CNT is the number of features in ids */
#define FD_FEATURE_ID_CNT (249UL)
#define FD_FEATURE_ID_CNT (250UL)

/* Feature set ID calculated from all feature names */
#define FD_FEATURE_SET_ID (4167120720U)
#define FD_FEATURE_SET_ID (3098242546U)

union fd_features {
ulong f[ FD_FEATURE_ID_CNT ];
Expand Down Expand Up @@ -265,5 +265,6 @@ union fd_features {
/* 0x8c7bee4552d93e0c */ ulong poseidon_enforce_padding;
/* 0x866094bbfe00a7c6 */ ulong relax_intrabatch_account_locks;
/* 0x7c4802b8ba3fa849 */ ulong provide_instruction_data_offset_in_vm_r2;
/* 0xdab5b6a991a03e4b */ ulong static_instruction_limit;
};
};
3 changes: 2 additions & 1 deletion src/flamenco/features/feature_map.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,5 +247,6 @@
{"name":"fix_alt_bn128_pairing_length_check","pubkey":"bnYzodLwmybj7e1HAe98yZrdJTd7we69eMMLgCXqKZm"},
{"name":"poseidon_enforce_padding","pubkey":"poUdAqRXXsNmfqAZ6UqpjbeYgwBygbfQLEvWSqVhSnb"},
{"name":"relax_intrabatch_account_locks","pubkey":"ENTRYnPAoT5Swwx73YDGzMp3XnNH1kxacyvLosRHza1i"},
{"name":"provide_instruction_data_offset_in_vm_r2","pubkey":"5xXZc66h4UdB6Yq7FzdBxBiRAFMMScMLwHxk2QZDaNZL"}
{"name":"provide_instruction_data_offset_in_vm_r2","pubkey":"5xXZc66h4UdB6Yq7FzdBxBiRAFMMScMLwHxk2QZDaNZL"},
{"name":"static_instruction_limit","pubkey":"64ixypL1HPu8WtJhNSMb9mSgfFaJvsANuRkTbHyuLfnx"}
]
2 changes: 2 additions & 0 deletions src/flamenco/runtime/Local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ ifdef FD_HAS_HOSTED
ifdef FD_HAS_SECP256K1
$(call make-unit-test,test_bank,test_bank,fd_flamenco fd_funk fd_ballet fd_util)
$(call run-unit-test,test_bank,)
$(call make-unit-test,test_static_instruction_limit,test_static_instruction_limit,fd_flamenco fd_funk fd_ballet fd_util)
$(call run-unit-test,test_static_instruction_limit,)
endif
endif

Expand Down
9 changes: 8 additions & 1 deletion src/flamenco/runtime/fd_executor.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,18 @@ fd_executor_check_transactions( fd_runtime_t * runtime,

https://github.com/anza-xyz/agave/blob/v2.3.1/runtime/src/bank.rs#L5725-L5753 */
int
fd_executor_verify_transaction( fd_bank_t * bank,
fd_executor_verify_transaction( fd_bank_t const * bank,
fd_txn_in_t const * txn_in,
fd_txn_out_t * txn_out ) {
int err = FD_RUNTIME_EXECUTE_SUCCESS;

/* SIMD-0160: enforce static limit on number of instructions.
https://github.com/anza-xyz/agave/blob/v3.1.4/runtime/src/bank.rs#L4710-L4716 */
if( FD_UNLIKELY( FD_FEATURE_ACTIVE_BANK( bank, static_instruction_limit ) &&
TXN( txn_in->txn )->instr_cnt > FD_MAX_INSTRUCTION_TRACE_LENGTH ) ) {
return FD_RUNTIME_TXN_ERR_SANITIZE_FAILURE;
}

/* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L566-L569 */
err = fd_executor_compute_budget_program_execute_instructions( bank, txn_in, txn_out );
if( FD_UNLIKELY( err ) ) return err;
Expand Down
2 changes: 1 addition & 1 deletion src/flamenco/runtime/fd_executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ uchar
fd_executor_pubkey_is_bpf_loader( fd_pubkey_t const * pubkey );

int
fd_executor_verify_transaction( fd_bank_t * bank,
fd_executor_verify_transaction( fd_bank_t const * bank,
fd_txn_in_t const * txn_in,
fd_txn_out_t * txn_out );

Expand Down
2 changes: 1 addition & 1 deletion src/flamenco/runtime/program/fd_builtin_programs.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ fd_num_precompiles( void ) {
}

uchar
fd_is_migrating_builtin_program( fd_bank_t * bank,
fd_is_migrating_builtin_program( fd_bank_t const * bank,
fd_pubkey_t const * pubkey,
uchar * migrated_yet ) {
*migrated_yet = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/flamenco/runtime/program/fd_builtin_programs.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ fd_num_stateless_builtins( void );
| 1 | 1 | Program is a migrating builtin program id, AND has been migrated to BPF |
*/
uchar
fd_is_migrating_builtin_program( fd_bank_t * bank,
fd_is_migrating_builtin_program( fd_bank_t const * bank,
fd_pubkey_t const * pubkey,
uchar * migrated_yet );

Expand Down
4 changes: 2 additions & 2 deletions src/flamenco/runtime/program/fd_compute_budget_program.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT (3000UL)

FD_FN_PURE static inline uchar
get_program_kind( fd_bank_t * bank,
get_program_kind( fd_bank_t const * bank,
fd_txn_in_t const * txn_in,
fd_txn_instr_t const * instr ) {
fd_acct_addr_t const * txn_accs = fd_txn_get_acct_addrs( TXN( txn_in->txn ), txn_in->txn->payload );
Expand Down Expand Up @@ -114,7 +114,7 @@ fd_sanitize_compute_unit_limits( fd_txn_out_t * txn_out ) {

https://github.com/anza-xyz/agave/blob/v2.3.1/compute-budget-instruction/src/compute_budget_instruction_details.rs#L54-L99 */
int
fd_executor_compute_budget_program_execute_instructions( fd_bank_t * bank,
fd_executor_compute_budget_program_execute_instructions( fd_bank_t const * bank,
fd_txn_in_t const * txn_in,
fd_txn_out_t * txn_out ) {
fd_compute_budget_details_t * details = &txn_out->details.compute_budget;
Expand Down
2 changes: 1 addition & 1 deletion src/flamenco/runtime/program/fd_compute_budget_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int
fd_sanitize_compute_unit_limits( fd_txn_out_t * txn_out );

int
fd_executor_compute_budget_program_execute_instructions( fd_bank_t * bank,
fd_executor_compute_budget_program_execute_instructions( fd_bank_t const * bank,
fd_txn_in_t const * txn_in,
fd_txn_out_t * txn_out );

Expand Down
125 changes: 125 additions & 0 deletions src/flamenco/runtime/test_static_instruction_limit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* Test for SIMD-0160 static_instruction_limit */

#include "fd_executor.h"
#include "fd_bank.h"
#include "fd_runtime.h"
#include "fd_runtime_err.h"
#include "../features/fd_features.h"

static void
init_bank( fd_bank_t * bank ) {
memset( bank, 0, sizeof(fd_bank_t) );
fd_bank_slot_set( bank, 1UL );
}

static void
init_txn_with_instr_cnt( fd_txn_p_t * txn_p,
ushort instr_cnt ) {
fd_txn_t * txn = TXN( txn_p );

txn->transaction_version = FD_TXN_V0;
txn->instr_cnt = instr_cnt;

for( ushort i=0; i<instr_cnt; i++ ) {
txn->instr[i].program_id = 0;
txn->instr[i].acct_cnt = 0;
txn->instr[i].data_sz = 0;
txn->instr[i].acct_off = 0;
txn->instr[i].data_off = 0;
}
}

static void
activate_static_instruction_limit( fd_bank_t * bank ) {
fd_bank_features_modify( bank )->static_instruction_limit = 0UL;
}

static void
deactivate_static_instruction_limit( fd_bank_t * bank ) {
fd_bank_features_modify( bank )->static_instruction_limit = FD_FEATURE_DISABLED;
}

static void
test_static_instruction_limit_deactivated( fd_bank_t * bank ) {
fd_txn_p_t txn_p[1] = {0};
fd_txn_out_t txn_out[1] = {0};

init_bank( bank );
deactivate_static_instruction_limit( bank );
init_txn_with_instr_cnt( txn_p, 65 );

fd_txn_in_t txn_in = { .txn = txn_p };

FD_TEST( fd_executor_verify_transaction( bank, &txn_in, txn_out )==FD_RUNTIME_EXECUTE_SUCCESS );
}

static void
test_static_instruction_limit_exceeded( fd_bank_t * bank ) {
fd_txn_p_t txn_p[1] = {0};
fd_txn_out_t txn_out[1] = {0};

init_bank( bank );
activate_static_instruction_limit( bank );
init_txn_with_instr_cnt( txn_p, 65 );

fd_txn_in_t txn_in = { .txn = txn_p };

FD_TEST( fd_executor_verify_transaction( bank, &txn_in, txn_out )==FD_RUNTIME_TXN_ERR_SANITIZE_FAILURE );
}

static void
test_static_instruction_limit_at_limit( fd_bank_t * bank ) {
fd_txn_p_t txn_p[1] = {0};
fd_txn_out_t txn_out[1] = {0};

init_bank( bank );
activate_static_instruction_limit( bank );
init_txn_with_instr_cnt( txn_p, 64 );

fd_txn_in_t txn_in = { .txn = txn_p };

FD_TEST( fd_executor_verify_transaction( bank, &txn_in, txn_out )==FD_RUNTIME_EXECUTE_SUCCESS );
}

static void
test_static_instruction_limit_under_limit( fd_bank_t * bank ) {
fd_txn_p_t txn_p[1] = {0};
fd_txn_out_t txn_out[1] = {0};

init_bank( bank );
activate_static_instruction_limit( bank );
init_txn_with_instr_cnt( txn_p, 1 );

fd_txn_in_t txn_in = { .txn = txn_p };

FD_TEST( fd_executor_verify_transaction( bank, &txn_in, txn_out )==FD_RUNTIME_EXECUTE_SUCCESS );
}

int
main( int argc,
char ** argv ) {
fd_boot( &argc, &argv );

char * _page_sz = "gigantic";
ulong numa_idx = fd_shmem_numa_idx( 0 );
fd_wksp_t * wksp = fd_wksp_new_anonymous( fd_cstr_to_shmem_page_sz( _page_sz ),
1UL,
fd_shmem_cpu_idx( numa_idx ),
"wksp",
0UL );
FD_TEST( wksp );

fd_bank_t * bank = fd_wksp_alloc_laddr( wksp, alignof(fd_bank_t), sizeof(fd_bank_t), 1UL );
FD_TEST( bank );

test_static_instruction_limit_deactivated( bank );
test_static_instruction_limit_exceeded( bank );
test_static_instruction_limit_at_limit( bank );
test_static_instruction_limit_under_limit( bank );

fd_wksp_delete_anonymous( wksp );

FD_LOG_NOTICE(( "pass" ));
fd_halt();
return 0;
}
Loading