From 6a72f5d3a4864093d3e70fdede32b276ceef5b92 Mon Sep 17 00:00:00 2001 From: ibhatt-jumptrading Date: Sat, 27 Apr 2024 12:50:32 +0000 Subject: [PATCH] adding CPI to native program with ledger test Co-authored-by: ripatel-fd error code cleanup --- .../program/fd_address_lookup_table_program.c | 163 +++++++++--------- .../program/fd_bpf_loader_v3_program.c | 59 +++++-- src/flamenco/runtime/program/fd_native_cpi.c | 12 +- src/flamenco/runtime/tests/Local.mk | 1 + 4 files changed, 135 insertions(+), 100 deletions(-) diff --git a/src/flamenco/runtime/program/fd_address_lookup_table_program.c b/src/flamenco/runtime/program/fd_address_lookup_table_program.c index d6cbaaed87..82153b0f66 100644 --- a/src/flamenco/runtime/program/fd_address_lookup_table_program.c +++ b/src/flamenco/runtime/program/fd_address_lookup_table_program.c @@ -317,77 +317,80 @@ create_lookup_table( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L144-L149 */ if( required_lamports > 0UL ) { // Create account metas - fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t*) fd_valloc_malloc(ctx->valloc, FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t)); - fd_native_cpi_create_account_meta(payer_key, 1, 1, &acct_metas[0]); - fd_native_cpi_create_account_meta(lut_key, 0, 1, &acct_metas[1]); + FD_SCRATCH_SCOPE_BEGIN { + fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t *) + fd_scratch_alloc( FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t) ); + fd_native_cpi_create_account_meta( payer_key, 1, 1, &acct_metas[0] ); + fd_native_cpi_create_account_meta( lut_key, 0, 1, &acct_metas[1] ); + + // Create signers list + fd_pubkey_t signers[16]; + ulong signers_cnt = 1; + signers[0] = *payer_key; + + // Create system program instruction + fd_system_program_instruction_t instr = {0}; + instr.discriminant = fd_system_program_instruction_enum_transfer; + instr.inner.transfer = required_lamports; + + int err = fd_native_cpi_execute_system_program_instruction( + ctx, + &instr, + acct_metas, + 2, + signers, + signers_cnt + ); + if ( err != 0 ) { + return FD_EXECUTOR_INSTR_ERR_GENERIC_ERR; + } + } FD_SCRATCH_SCOPE_END; + } + + FD_SCRATCH_SCOPE_BEGIN { + fd_vm_rust_account_meta_t * acct_metas = ( fd_vm_rust_account_meta_t * ) + fd_scratch_alloc( FD_VM_RUST_ACCOUNT_META_ALIGN, sizeof(fd_vm_rust_account_meta_t) ); + fd_native_cpi_create_account_meta( lut_key, 1, 1, &acct_metas[0] ); // Create signers list fd_pubkey_t signers[16]; ulong signers_cnt = 1; - signers[0] = *payer_key; + signers[0] = *lut_key; // Create system program instruction - fd_system_program_instruction_t instr; - instr.discriminant = fd_system_program_instruction_enum_transfer; - instr.inner.transfer = required_lamports; + fd_system_program_instruction_t instr = {0}; + instr.discriminant = fd_system_program_instruction_enum_allocate; + instr.inner.allocate = 56; + // Execute allocate instruction int err = fd_native_cpi_execute_system_program_instruction( ctx, &instr, acct_metas, - 2, + 1, signers, signers_cnt ); - fd_valloc_free(ctx->valloc, acct_metas); if ( err != 0 ) { return FD_EXECUTOR_INSTR_ERR_GENERIC_ERR; } - } - fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t*) fd_valloc_malloc(ctx->valloc, FD_VM_RUST_ACCOUNT_META_ALIGN, sizeof(fd_vm_rust_account_meta_t)); - fd_native_cpi_create_account_meta(lut_key, 1, 1, &acct_metas[0]); - - // Create signers list - fd_pubkey_t signers[16]; - ulong signers_cnt = 1; - signers[0] = *lut_key; - - // Create system program instruction - fd_system_program_instruction_t instr; - instr.discriminant = fd_system_program_instruction_enum_allocate; - instr.inner.allocate = 56; - - // Execute allocate instruction - int err = fd_native_cpi_execute_system_program_instruction( - ctx, - &instr, - acct_metas, - 1, - signers, - signers_cnt - ); - if ( err != 0 ) { - return FD_EXECUTOR_INSTR_ERR_GENERIC_ERR; - } - - instr.discriminant = fd_system_program_instruction_enum_assign; - instr.inner.assign = fd_solana_address_lookup_table_program_id; - - // Execute assign instruction - err = fd_native_cpi_execute_system_program_instruction( - ctx, - &instr, - acct_metas, - 1, - signers, - signers_cnt - ); - if ( err != 0 ) { - return FD_EXECUTOR_INSTR_ERR_GENERIC_ERR; - } + instr.discriminant = fd_system_program_instruction_enum_assign; + instr.inner.assign = fd_solana_address_lookup_table_program_id; - fd_valloc_free(ctx->valloc, acct_metas); + // Execute assign instruction + err = fd_native_cpi_execute_system_program_instruction( + ctx, + &instr, + acct_metas, + 1, + signers, + signers_cnt + ); + if ( err != 0 ) { + return err; + } + } FD_SCRATCH_SCOPE_END; if( FD_UNLIKELY( !fd_borrowed_account_acquire_write( lut_acct ) ) ) return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED; @@ -702,33 +705,35 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } - // Create account metas - fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t*) fd_valloc_malloc(ctx->valloc, FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t)); - fd_native_cpi_create_account_meta(payer_key, 1, 1, &acct_metas[0]); - fd_native_cpi_create_account_meta(lut_key, 0, 1, &acct_metas[1]); - - // Create signers list - fd_pubkey_t signers[16]; - ulong signers_cnt = 1; - signers[0] = *payer_key; - - // Create system program instruction - fd_system_program_instruction_t instr; - instr.discriminant = fd_system_program_instruction_enum_transfer; - instr.inner.transfer = required_lamports; - - int err = fd_native_cpi_execute_system_program_instruction( - ctx, - &instr, - acct_metas, - 2, - signers, - signers_cnt - ); - fd_valloc_free(ctx->valloc, acct_metas); - if ( err != 0 ) { - return err; - } + FD_SCRATCH_SCOPE_BEGIN { + // Create account metas + fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t *) + fd_scratch_alloc( FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t) ); + fd_native_cpi_create_account_meta( payer_key, 1, 1, &acct_metas[0] ); + fd_native_cpi_create_account_meta( lut_key, 0, 1, &acct_metas[1] ); + + // Create signers list + fd_pubkey_t signers[16]; + ulong signers_cnt = 1; + signers[0] = *payer_key; + + // Create system program instruction + fd_system_program_instruction_t instr = {0}; + instr.discriminant = fd_system_program_instruction_enum_transfer; + instr.inner.transfer = required_lamports; + + int err = fd_native_cpi_execute_system_program_instruction( + ctx, + &instr, + acct_metas, + 2, + signers, + signers_cnt + ); + if ( err != 0 ) { + return err; + } + } FD_SCRATCH_SCOPE_END; } return FD_EXECUTOR_INSTR_SUCCESS; diff --git a/src/flamenco/runtime/program/fd_bpf_loader_v3_program.c b/src/flamenco/runtime/program/fd_bpf_loader_v3_program.c index 730da4f75b..e63ae2c8f4 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_v3_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_v3_program.c @@ -370,7 +370,7 @@ setup_program( fd_exec_instr_ctx_t * ctx, fd_sbpf_elf_info_t _elf_info[1]; fd_sbpf_elf_info_t * elf_info = fd_sbpf_elf_peek( _elf_info, program_data, program_data_len ); if( FD_UNLIKELY( !elf_info ) ) { - FD_LOG_HEXDUMP_WARNING(("Program data hexdumpppp", program_data, program_data_len)); + FD_LOG_HEXDUMP_WARNING(("Program data hexdump", program_data, program_data_len)); FD_LOG_WARNING(("Elf info failing")); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -701,25 +701,28 @@ fd_bpf_loader_v3_program_execute( fd_exec_instr_ctx_t ctx ) { create_acct.space = programdata_len; create_acct.owner = ctx.instr->program_id_pubkey; - fd_system_program_instruction_t FD_FN_UNUSED instr; + fd_system_program_instruction_t instr; instr.discriminant = fd_system_program_instruction_enum_create_account; instr.inner.create_account = create_acct; /* Setup the accounts passed into the system program create call. Index zero and one are the from and to accounts respectively for the transfer. The buffer - account is also passed in here. */ //TODO: free these afterwards - fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t *) - fd_valloc_malloc( ctx.valloc, FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t) ); - fd_native_cpi_create_account_meta( payer_acc, 1, 1, &acct_metas[0] ); - fd_native_cpi_create_account_meta( programdata_acc, 1, 1, &acct_metas[1] ); - fd_pubkey_t signers[2]; - ulong signers_cnt = 2; - signers[0] = *payer_acc; - signers[1] = *programdata_acc; - - fd_native_cpi_execute_system_program_instruction( &ctx, &instr, acct_metas, 2, signers, signers_cnt ); - - fd_valloc_free( ctx.valloc, acct_metas ); + account is also passed in here. */ + FD_SCRATCH_SCOPE_BEGIN { + fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t *) + fd_scratch_alloc( FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t) ); + fd_native_cpi_create_account_meta( payer_acc, 1, 1, &acct_metas[0] ); + fd_native_cpi_create_account_meta( programdata_acc, 1, 1, &acct_metas[1] ); + fd_pubkey_t signers[2]; + ulong signers_cnt = 2; + signers[0] = *payer_acc; + signers[1] = *programdata_acc; + + err = fd_native_cpi_execute_system_program_instruction( &ctx, &instr, acct_metas, 2, signers, signers_cnt ); + if (err != 0) { + return err; + } + } FD_SCRATCH_SCOPE_END; ulong total_size = PROGRAMDATA_METADATA_SIZE + instruction.inner.deploy_with_max_data_len.max_data_len; fd_borrowed_account_t * programdata_rec = NULL; @@ -1486,6 +1489,32 @@ fd_bpf_loader_v3_program_execute( fd_exec_instr_ctx_t ctx ) { // .into(), // &[], // )?; + fd_system_program_instruction_t instr = {0}; + instr.discriminant = fd_system_program_instruction_enum_transfer; + instr.inner.transfer = required_payment; + + FD_SCRATCH_SCOPE_BEGIN { + fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t*) + fd_scratch_alloc( FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t) ); + fd_native_cpi_create_account_meta( payer_key, 1, 1, &acct_metas[0] ); + fd_native_cpi_create_account_meta( programdata_acc, 0, 1, &acct_metas[1] ); + + fd_pubkey_t signers[1]; + ulong signers_cnt = 1; + signers[0] = *payer_key; + + err = fd_native_cpi_execute_system_program_instruction( + &ctx, + &instr, + acct_metas, + 2, + signers, + signers_cnt + ); + if ( err ) { + return err; + } + } FD_SCRATCH_SCOPE_END; } result = fd_instr_borrowed_account_modify(&ctx, programdata_acc, new_len, &programdata_acc_rec); diff --git a/src/flamenco/runtime/program/fd_native_cpi.c b/src/flamenco/runtime/program/fd_native_cpi.c index 5cb6f7cf13..64b3df438a 100644 --- a/src/flamenco/runtime/program/fd_native_cpi.c +++ b/src/flamenco/runtime/program/fd_native_cpi.c @@ -67,17 +67,17 @@ fd_native_cpi_execute_system_program_instruction( fd_exec_instr_ctx_t * ctx, } fd_bincode_encode_ctx_t ctx2; - uchar buf[4096UL]; + uchar buf[4096UL]; // Size that is large enough for the instruction ctx2.data = buf; - ctx2.dataend = (uchar*)ctx2.data + 4096UL; + ctx2.dataend = (uchar*)ctx2.data + sizeof(buf); int err = fd_system_program_instruction_encode( instr, &ctx2 ); - if (err != FD_EXECUTOR_INSTR_SUCCESS) { - FD_LOG_WARNING(("Encode failed")); - return err; + if( err ) { + FD_LOG_WARNING(( "Encode failed" )); + return FD_EXECUTOR_INSTR_ERR_FATAL; } instr_info->data = buf; - instr_info->data_sz = 4096UL; + instr_info->data_sz = sizeof(buf); ulong exec_err = fd_vm_prepare_instruction( ctx->instr, instr_info, ctx, instruction_accounts, &instruction_accounts_cnt, signers, signers_cnt ); if( exec_err != FD_EXECUTOR_INSTR_SUCCESS ) { diff --git a/src/flamenco/runtime/tests/Local.mk b/src/flamenco/runtime/tests/Local.mk index f47a68ac67..33e6342c96 100644 --- a/src/flamenco/runtime/tests/Local.mk +++ b/src/flamenco/runtime/tests/Local.mk @@ -27,6 +27,7 @@ run-runtime-test-1: $(OBJDIR)/unit-test/test_runtime $(OBJDIR)/bin/fd_frank_ledg OBJDIR=$(OBJDIR) src/flamenco/runtime/tests/run_ledger_tests.sh -l mainnet-251418170 -s snapshot-251418170-8sAkojR9PYTZvqiQZ1VWu27ewX5tXeVdC97wMXAtgHnT.tar.zst -p 64 -m 2000000 -e 251418233 OBJDIR=$(OBJDIR) src/flamenco/runtime/tests/run_ledger_tests.sh -l mainnet-257066033 -s snapshot-257066033-AD2nFFTCtZVmo5nXLVsQMV1hiQDjzoEBXibRicBJc5Vw.tar.zst -p 16 -m 5000000 -e 257066038 --zst OBJDIR=$(OBJDIR) src/flamenco/runtime/tests/run_ledger_tests.sh -l mainnet-257066844 -s snapshot-257066844-B5JpRYzvMa4iyQeR8w9co4y7oEayphgbXVeQHXLDoWvV.tar.zst -p 16 -m 5000000 -e 257066849 --zst + OBJDIR=$(OBJDIR) src/flamenco/runtime/tests/run_ledger_tests.sh -l mainnet-257067457 -s snapshot-257067457-DxbpHefwdjLkPecZG2jLuqyQp8me9dFZQMQ8hZMyfhsw.tar.zst -p 16 -m 5000000 -e 257067461 --zst # src/flamenco/runtime/run_bpf_tests.sh