Skip to content

Commit

Permalink
flamenco: bpf loader rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
ibhatt-jumptrading committed May 30, 2024
1 parent d3b5ada commit a165379
Show file tree
Hide file tree
Showing 10 changed files with 1,285 additions and 1,205 deletions.
2 changes: 1 addition & 1 deletion src/flamenco/runtime/fd_account_old.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "fd_runtime.h"
#include <assert.h>

#define MAX_PERMITTED_DATA_LENGTH ( 10 * 1024 * 1024 )
#define MAX_PERMITTED_DATA_LENGTH ( 10UL * 1024UL * 1024UL )

/* Represents the lamport balance associated with an account. */
typedef ulong fd_acc_lamports_t;
Expand Down
7 changes: 3 additions & 4 deletions src/flamenco/runtime/fd_executor.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ fd_executor_lookup_native_program( fd_pubkey_t const * pubkey ) {
return fd_precompile_ed25519_verify;
} else if ( !memcmp( pubkey, fd_solana_keccak_secp_256k_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return fd_precompile_secp256k1_verify;
} else if ( !memcmp( pubkey, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return fd_bpf_loader_v3_program_execute;
} else if ( !memcmp( pubkey, fd_solana_bpf_loader_program_id.key, sizeof( fd_pubkey_t ) ) ) {
return fd_bpf_loader_v2_program_execute;
} else if ( !memcmp( pubkey, fd_solana_bpf_loader_deprecated_program_id.key, sizeof( fd_pubkey_t ) ) ) {
Expand Down Expand Up @@ -751,8 +749,9 @@ fd_execute_instr( fd_exec_txn_ctx_t * txn_ctx,
int exec_result = FD_EXECUTOR_INSTR_SUCCESS;
if( native_prog_fn != NULL ) {
exec_result = native_prog_fn( *ctx );
} else if( fd_bpf_loader_v3_is_executable( ctx->slot_ctx, program_id )==0 ) {
exec_result = fd_bpf_loader_v3_user_execute( *ctx );
} else if( fd_bpf_loader_v3_is_executable( ctx->slot_ctx, program_id )==0 ||
!memcmp( program_id, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof( fd_pubkey_t ) ) ) {
exec_result = fd_bpf_loader_v3_program_execute( *ctx );
} else if( fd_bpf_loader_v2_is_executable( ctx->slot_ctx, program_id )==0 ) {
exec_result = fd_bpf_loader_v2_user_execute( *ctx );
} else {
Expand Down
81 changes: 77 additions & 4 deletions src/flamenco/runtime/fd_pubkey_utils.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "fd_pubkey_utils.h"
#include "../vm/fd_vm_syscalls.h"
#include "../../ballet/ed25519/fd_curve25519.h"

int
fd_pubkey_create_with_seed( fd_exec_instr_ctx_t const * ctx,
Expand All @@ -10,13 +12,13 @@ fd_pubkey_create_with_seed( fd_exec_instr_ctx_t const * ctx,

static char const pda_marker[] = {"ProgramDerivedAddress"};

if( seed_sz > 32UL ) {
ctx->txn_ctx->custom_err = 0;
if( seed_sz>MAX_SEED_LEN ) {
ctx->txn_ctx->custom_err = 0U;
return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
}

if( 0==memcmp( owner+11, pda_marker, 21UL ) ) {
ctx->txn_ctx->custom_err = 2;
if( 0==memcmp( owner+11UL, pda_marker, 21UL ) ) {
ctx->txn_ctx->custom_err = 2U;
return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
}

Expand All @@ -31,3 +33,74 @@ fd_pubkey_create_with_seed( fd_exec_instr_ctx_t const * ctx,

return FD_EXECUTOR_INSTR_SUCCESS;
}

/* https://github.com/anza-xyz/agave/blob/77daab497df191ef485a7ad36ed291c1874596e5/sdk/program/src/pubkey.rs#L578-L625 */
int
fd_pubkey_derive_pda( fd_pubkey_t const * program_id,
ulong seeds_cnt,
uchar ** seeds,
uchar * bump_seed,
fd_pubkey_t * out ) {

if( seeds_cnt>MAX_SEEDS ) {
return FD_PUBKEY_ERR_MAX_SEED_LEN_EXCEEDED;
}
/* TODO: This does not contain size checks for the seed as checked in
https://github.com/anza-xyz/agave/blob/77daab497df191ef485a7ad36ed291c1874596e5/sdk/program/src/pubkey.rs#L586-L588 */

fd_sha256_t sha;
fd_sha256_init( &sha );
for ( ulong i=0UL; i<seeds_cnt; i++ ) {
uchar * seed = *(seeds + i);
if( FD_UNLIKELY( !seed ) ) {
break;
}
fd_sha256_append( &sha, seed, 32UL );
}

if( bump_seed ) {
fd_sha256_append( &sha, bump_seed, 1UL );
}
fd_sha256_append( &sha, program_id, sizeof(fd_pubkey_t) );
fd_sha256_append( &sha, "ProgramDerivedAddress", 21UL );

fd_sha256_fini( &sha, out );

/* A PDA is valid if it is not a valid ed25519 curve point.
In most cases the user will have derived the PDA off-chain,
or the PDA is a known signer. */
if( FD_UNLIKELY( fd_ed25519_point_validate( out->key ) ) ) {
return FD_PUBKEY_ERR_INVALID_SEEDS;
}

return FD_PUBKEY_SUCCESS;
}

/* https://github.com/anza-xyz/agave/blob/77daab497df191ef485a7ad36ed291c1874596e5/sdk/program/src/pubkey.rs#L482-L534 */
int
fd_pubkey_try_find_program_address( fd_pubkey_t const * program_id,
ulong seeds_cnt,
uchar ** seeds,
fd_pubkey_t * out,
uchar * out_bump_seed ) {
uchar bump_seed[ 1UL ];
for ( ulong i=0UL; i<256UL; ++i ) {
bump_seed[ 0UL ] = (uchar)(255UL - i);

fd_pubkey_t derived[ 1UL ];
int err = fd_pubkey_derive_pda( program_id, seeds_cnt, seeds, bump_seed, derived );
if( err==FD_PUBKEY_SUCCESS ) {
/* Stop looking if we have found a valid PDA */
fd_memcpy( out, derived, sizeof(fd_pubkey_t) );
fd_memcpy( out_bump_seed, bump_seed, 1UL );
break;
} else if( err!=FD_PUBKEY_ERR_INVALID_SEEDS ) {
return err;
}
}

if( out ) {
return FD_PUBKEY_SUCCESS;
}
return FD_PUBKEY_ERR_NO_PDA_FOUND;
}
36 changes: 36 additions & 0 deletions src/flamenco/runtime/fd_pubkey_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
#include "context/fd_exec_instr_ctx.h"
#include "context/fd_exec_txn_ctx.h"

#define MAX_SEEDS (16UL)
#define MAX_SEED_LEN (32UL)

/* TODO: firedancer pubkey errors don't map to agave's implementation */
#define FD_PUBKEY_ERR_MAX_SEED_LEN_EXCEEDED (-1)
#define FD_PUBKEY_ERR_INVALID_SEEDS (-2)
#define FD_PUBKEY_ERR_NO_PDA_FOUND (-3)
#define FD_PUBKEY_SUCCESS (0 )

FD_PROTOTYPES_BEGIN

int
Expand All @@ -14,6 +23,33 @@ fd_pubkey_create_with_seed( fd_exec_instr_ctx_t const * ctx,
uchar const owner[ static 32 ],
uchar out [ static 32 ] );

/* fd_pubkey_derive_pda mirrors the vm helper function fd_vm_derive_pda
to derive a PDA not on a ed25519 point.
TODO: Potentially replace with shared function in fd_vm_syscall_pda.c */

int
fd_pubkey_derive_pda( fd_pubkey_t const * program_id,
ulong seeds_cnt,
uchar ** seeds,
uchar * bump_seed,
fd_pubkey_t * out );

/* fd_pubkey_try_find_program_address mirrors the vm syscall function
fd_vm_syscall_sol_try_find_program_address and creates a valid
program derived address searching for a valid ed25519 curve point by
iterating through 255 possible bump seeds. If any of the possible addresses
are on the curve then we know that it is not a valid PDA. This also returns
the bump seed along with the program derived address.
TODO: Potentially replace with shared function in fd_vm_syscall_pda.c */

int
fd_pubkey_try_find_program_address( fd_pubkey_t const * program_id,
ulong seeds_cnt,
uchar ** seeds,
fd_pubkey_t * out,
uchar * out_bump_seed );


FD_PROTOTYPES_END

#endif /* HEADER_fd_src_flamenco_runtime_fd_pubkey_utils_h */
4 changes: 2 additions & 2 deletions src/flamenco/runtime/fd_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
#include "../repair/fd_repair.h"
#include "../../ballet/pack/fd_microblock.h"

#define MAX_PERMITTED_DATA_LENGTH ( 10 * 1024 * 1024 )
#define MAX_PERMITTED_DATA_LENGTH ( 10UL * 1024UL * 1024UL )

#define DEFAULT_HASHES_PER_TICK 12500
#define DEFAULT_HASHES_PER_TICK 12500
#define UPDATED_HASHES_PER_TICK2 17500
#define UPDATED_HASHES_PER_TICK3 27500
#define UPDATED_HASHES_PER_TICK4 47500
Expand Down
Loading

0 comments on commit a165379

Please sign in to comment.