diff --git a/Cargo.lock b/Cargo.lock index 45e26047c7..466ade32a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6119,9 +6119,9 @@ dependencies = [ [[package]] name = "solana_rbpf" -version = "0.2.27" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dec11db92171a996e44d36fb1d223233f2cefacf9ba6884b33e5baa92a81d37" +checksum = "bec5c1525c69ec74323d6a2d145a29b51844c4153a2cd5e4ac0d08b3fe81c806" dependencies = [ "byteorder", "combine", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a79aae0c85..b139bce347 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -42,7 +42,7 @@ solana-sdk = { path = "../sdk", version = "=1.11.0" } solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" } solana-version = { path = "../version", version = "=1.11.0" } solana-vote-program = { path = "../programs/vote", version = "=1.11.0" } -solana_rbpf = "=0.2.27" +solana_rbpf = "=0.2.26" spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] } thiserror = "1.0.30" tiny-bip39 = "0.8.2" diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index eb7864fc7d..be796f4003 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -5376,9 +5376,9 @@ dependencies = [ [[package]] name = "solana_rbpf" -version = "0.2.27" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dec11db92171a996e44d36fb1d223233f2cefacf9ba6884b33e5baa92a81d37" +checksum = "bec5c1525c69ec74323d6a2d145a29b51844c4153a2cd5e4ac0d08b3fe81c806" dependencies = [ "byteorder 1.4.3", "combine", diff --git a/programs/bpf/Cargo.toml b/programs/bpf/Cargo.toml index d0e60b135c..9566d86a3d 100644 --- a/programs/bpf/Cargo.toml +++ b/programs/bpf/Cargo.toml @@ -33,7 +33,7 @@ solana-bpf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.1 solana-cli-output = { path = "../../cli-output", version = "=1.11.0" } solana-logger = { path = "../../logger", version = "=1.11.0" } solana-measure = { path = "../../measure", version = "=1.11.0" } -solana_rbpf = "=0.2.27" +solana_rbpf = "=0.2.26" solana-runtime = { path = "../../runtime", version = "=1.11.0" } solana-program-runtime = { path = "../../program-runtime", version = "=1.11.0" } solana-sdk = { path = "../../sdk", version = "=1.11.0" } diff --git a/programs/bpf/rust/sysvar/src/lib.rs b/programs/bpf/rust/sysvar/src/lib.rs index 77f7d96449..4641abaefc 100644 --- a/programs/bpf/rust/sysvar/src/lib.rs +++ b/programs/bpf/rust/sysvar/src/lib.rs @@ -2,6 +2,8 @@ extern crate solana_program; #[allow(deprecated)] +use solana_program::sysvar::fees::Fees; +#[allow(deprecated)] use solana_program::sysvar::recent_blockhashes::RecentBlockhashes; use solana_program::{ account_info::AccountInfo, @@ -21,7 +23,7 @@ solana_program::entrypoint!(process_instruction); pub fn process_instruction( program_id: &Pubkey, accounts: &[AccountInfo], - _instruction_data: &[u8], + instruction_data: &[u8], ) -> ProgramResult { // Clock { @@ -54,7 +56,7 @@ pub fn process_instruction( instruction, Instruction::new_with_bytes( *program_id, - &[] as &[u8], + instruction_data, vec![ AccountMeta::new(*accounts[0].key, true), AccountMeta::new(*accounts[1].key, false), @@ -66,6 +68,7 @@ pub fn process_instruction( AccountMeta::new_readonly(*accounts[7].key, false), AccountMeta::new_readonly(*accounts[8].key, false), AccountMeta::new_readonly(*accounts[9].key, false), + AccountMeta::new_readonly(*accounts[10].key, false), ], ) ); @@ -110,5 +113,15 @@ pub fn process_instruction( sysvar::stake_history::id().log(); let _ = StakeHistory::from_account_info(&accounts[9]).unwrap(); + // Fees + #[allow(deprecated)] + if instruction_data[0] == 1 { + msg!("Fee identifier:"); + sysvar::fees::id().log(); + let fees = Fees::from_account_info(&accounts[10]).unwrap(); + let got_fees = Fees::get()?; + assert_eq!(fees, got_fees); + } + Ok(()) } diff --git a/programs/bpf/rust/sysvar/tests/lib.rs b/programs/bpf/rust/sysvar/tests/lib.rs index fb01dfe22a..a3a97dfe12 100644 --- a/programs/bpf/rust/sysvar/tests/lib.rs +++ b/programs/bpf/rust/sysvar/tests/lib.rs @@ -2,11 +2,12 @@ use { solana_bpf_rust_sysvar::process_instruction, solana_program_test::*, solana_sdk::{ + feature_set::disable_fees_sysvar, instruction::{AccountMeta, Instruction}, pubkey::Pubkey, signature::Signer, sysvar::{ - clock, epoch_schedule, instructions, recent_blockhashes, rent, slot_hashes, + clock, epoch_schedule, fees, instructions, recent_blockhashes, rent, slot_hashes, slot_history, stake_history, }, transaction::Transaction, @@ -16,6 +17,7 @@ use { #[tokio::test] async fn test_sysvars() { let program_id = Pubkey::new_unique(); + let program_test = ProgramTest::new( "solana_bpf_rust_sysvar", program_id, @@ -26,7 +28,7 @@ async fn test_sysvars() { let mut transaction = Transaction::new_with_payer( &[Instruction::new_with_bincode( program_id, - &(), + &[0u8], vec![ AccountMeta::new(payer.pubkey(), true), AccountMeta::new(Pubkey::new_unique(), false), @@ -39,6 +41,41 @@ async fn test_sysvars() { AccountMeta::new_readonly(slot_hashes::id(), false), AccountMeta::new_readonly(slot_history::id(), false), AccountMeta::new_readonly(stake_history::id(), false), + #[allow(deprecated)] + AccountMeta::new_readonly(fees::id(), false), + ], + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let mut program_test = ProgramTest::new( + "solana_bpf_rust_sysvar", + program_id, + processor!(process_instruction), + ); + program_test.deactivate_feature(disable_fees_sysvar::id()); + let (mut banks_client, payer, recent_blockhash) = program_test.start().await; + + let mut transaction = Transaction::new_with_payer( + &[Instruction::new_with_bincode( + program_id, + &[1u8], + vec![ + AccountMeta::new(payer.pubkey(), true), + AccountMeta::new(Pubkey::new_unique(), false), + AccountMeta::new_readonly(clock::id(), false), + AccountMeta::new_readonly(epoch_schedule::id(), false), + AccountMeta::new_readonly(instructions::id(), false), + #[allow(deprecated)] + AccountMeta::new_readonly(recent_blockhashes::id(), false), + AccountMeta::new_readonly(rent::id(), false), + AccountMeta::new_readonly(slot_hashes::id(), false), + AccountMeta::new_readonly(slot_history::id(), false), + AccountMeta::new_readonly(stake_history::id(), false), + #[allow(deprecated)] + AccountMeta::new_readonly(fees::id(), false), ], )], Some(&payer.pubkey()), diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 70e0a96bcd..98b66f1944 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -264,7 +264,7 @@ fn run_program(name: &str) -> u64 { if config.enable_instruction_tracing { if i == 1 { if !Tracer::compare(tracer.as_ref().unwrap(), vm.get_tracer()) { - let analysis = Analysis::from_executable(&executable).unwrap(); + let analysis = Analysis::from_executable(&executable); let stdout = std::io::stdout(); println!("TRACE (interpreted):"); tracer @@ -278,7 +278,7 @@ fn run_program(name: &str) -> u64 { .unwrap(); assert!(false); } else if log_enabled!(Trace) { - let analysis = Analysis::from_executable(&executable).unwrap(); + let analysis = Analysis::from_executable(&executable); let mut trace_buffer = Vec::::new(); tracer .as_ref() diff --git a/programs/bpf_loader/Cargo.toml b/programs/bpf_loader/Cargo.toml index 940fe10ab5..31269b53a8 100644 --- a/programs/bpf_loader/Cargo.toml +++ b/programs/bpf_loader/Cargo.toml @@ -19,7 +19,7 @@ solana-metrics = { path = "../../metrics", version = "=1.11.0" } solana-program-runtime = { path = "../../program-runtime", version = "=1.11.0" } solana-sdk = { path = "../../sdk", version = "=1.11.0" } solana-zk-token-sdk = { path = "../../zk-token-sdk", version = "=1.11.0" } -solana_rbpf = "=0.2.27" +solana_rbpf = "=0.2.26" thiserror = "1.0" [dev-dependencies] diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 9d2620ec52..2e6383b9c7 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -28,10 +28,9 @@ use { }, solana_rbpf::{ aligned_memory::AlignedMemory, - ebpf::{HOST_ALIGN, MM_INPUT_START}, + ebpf::HOST_ALIGN, elf::Executable, error::{EbpfError, UserDefinedError}, - memory_region::MemoryRegion, static_analysis::Analysis, verifier::{self, VerifierError}, vm::{Config, EbpfVm, InstructionMeter}, @@ -263,8 +262,7 @@ pub fn create_vm<'a, 'b>( } let mut heap = AlignedMemory::new_with_size(compute_budget.heap_size.unwrap_or(HEAP_LENGTH), HOST_ALIGN); - let parameter_region = MemoryRegion::new_writable(parameter_bytes, MM_INPUT_START); - let mut vm = EbpfVm::new(program, heap.as_slice_mut(), vec![parameter_region])?; + let mut vm = EbpfVm::new(program, heap.as_slice_mut(), parameter_bytes)?; syscalls::bind_syscall_context_objects(&mut vm, invoke_context, heap)?; Ok(vm) } @@ -1199,7 +1197,7 @@ impl Executor for BpfExecutor { ); if log_enabled!(Trace) { let mut trace_buffer = Vec::::new(); - let analysis = Analysis::from_executable(&self.executable).unwrap(); + let analysis = Analysis::from_executable(&self.executable); vm.get_tracer().write(&mut trace_buffer, &analysis).unwrap(); let trace_string = String::from_utf8(trace_buffer).unwrap(); trace!("BPF Program Instruction Trace:\n{}", trace_string); @@ -1360,7 +1358,7 @@ mod tests { 0x05, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, // goto -2 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit ]; - let mut input_mem = [0x00]; + let input = &mut [0x00]; let config = Config::default(); let syscall_registry = SyscallRegistry::default(); let mut bpf_functions = std::collections::BTreeMap::::new(); @@ -1380,10 +1378,8 @@ mod tests { bpf_functions, ) .unwrap(); - let input_region = MemoryRegion::new_writable(&mut input_mem, MM_INPUT_START); let mut vm = - EbpfVm::::new(&program, &mut [], vec![input_region]) - .unwrap(); + EbpfVm::::new(&program, &mut [], input).unwrap(); let mut instruction_meter = TestInstructionMeter { remaining: 10 }; vm.execute_program_interpreted(&mut instruction_meter) .unwrap(); diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index a1240fd298..f69d3c3762 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -115,174 +115,254 @@ impl SyscallConsume for Rc> { } } +macro_rules! register_feature_gated_syscall { + ($syscall_registry:expr, $is_feature_active:expr, $name:expr, $init:expr, $call:expr $(,)?) => { + if $is_feature_active { + $syscall_registry.register_syscall_by_name($name, $init, $call) + } else { + Ok(()) + } + }; +} + pub fn register_syscalls( invoke_context: &mut InvokeContext, ) -> Result> { + let secp256k1_recover_syscall_enabled = invoke_context + .feature_set + .is_active(&secp256k1_recover_syscall_enabled::id()); + let blake3_syscall_enabled = invoke_context + .feature_set + .is_active(&blake3_syscall_enabled::id()); + let zk_token_sdk_enabled = invoke_context + .feature_set + .is_active(&zk_token_sdk_enabled::id()); + let disable_fees_sysvar = invoke_context + .feature_set + .is_active(&disable_fees_sysvar::id()); + let return_data_syscall_enabled = invoke_context + .feature_set + .is_active(&return_data_syscall_enabled::id()); + let sol_log_data_syscall_enabled = invoke_context + .feature_set + .is_active(&sol_log_data_syscall_enabled::id()); + let add_get_processed_sibling_instruction_syscall = invoke_context + .feature_set + .is_active(&add_get_processed_sibling_instruction_syscall::id()); + let mut syscall_registry = SyscallRegistry::default(); - syscall_registry.register_syscall_by_name(b"abort", SyscallAbort::call)?; - syscall_registry.register_syscall_by_name(b"sol_panic_", SyscallPanic::call)?; - syscall_registry.register_syscall_by_name(b"sol_log_", SyscallLog::call)?; - syscall_registry.register_syscall_by_name(b"sol_log_64_", SyscallLogU64::call)?; + // Abort + syscall_registry.register_syscall_by_name(b"abort", SyscallAbort::init, SyscallAbort::call)?; - syscall_registry - .register_syscall_by_name(b"sol_log_compute_units_", SyscallLogBpfComputeUnits::call)?; + // Panic + syscall_registry.register_syscall_by_name( + b"sol_panic_", + SyscallPanic::init, + SyscallPanic::call, + )?; - syscall_registry.register_syscall_by_name(b"sol_log_pubkey", SyscallLogPubkey::call)?; + // Logging + syscall_registry.register_syscall_by_name(b"sol_log_", SyscallLog::init, SyscallLog::call)?; + syscall_registry.register_syscall_by_name( + b"sol_log_64_", + SyscallLogU64::init, + SyscallLogU64::call, + )?; + syscall_registry.register_syscall_by_name( + b"sol_log_compute_units_", + SyscallLogBpfComputeUnits::init, + SyscallLogBpfComputeUnits::call, + )?; + syscall_registry.register_syscall_by_name( + b"sol_log_pubkey", + SyscallLogPubkey::init, + SyscallLogPubkey::call, + )?; + // Program defined addresses (PDA) syscall_registry.register_syscall_by_name( b"sol_create_program_address", + SyscallCreateProgramAddress::init, SyscallCreateProgramAddress::call, )?; syscall_registry.register_syscall_by_name( b"sol_try_find_program_address", + SyscallTryFindProgramAddress::init, SyscallTryFindProgramAddress::call, )?; - syscall_registry.register_syscall_by_name(b"sol_sha256", SyscallSha256::call)?; - syscall_registry.register_syscall_by_name(b"sol_keccak256", SyscallKeccak256::call)?; + // Sha256 + syscall_registry.register_syscall_by_name( + b"sol_sha256", + SyscallSha256::init, + SyscallSha256::call, + )?; - if invoke_context - .feature_set - .is_active(&secp256k1_recover_syscall_enabled::id()) - { - syscall_registry - .register_syscall_by_name(b"sol_secp256k1_recover", SyscallSecp256k1Recover::call)?; - } + // Keccak256 + syscall_registry.register_syscall_by_name( + b"sol_keccak256", + SyscallKeccak256::init, + SyscallKeccak256::call, + )?; - if invoke_context - .feature_set - .is_active(&blake3_syscall_enabled::id()) - { - syscall_registry.register_syscall_by_name(b"sol_blake3", SyscallBlake3::call)?; - } + // Secp256k1 Recover + register_feature_gated_syscall!( + syscall_registry, + secp256k1_recover_syscall_enabled, + b"sol_secp256k1_recover", + SyscallSecp256k1Recover::init, + SyscallSecp256k1Recover::call, + )?; - if invoke_context - .feature_set - .is_active(&zk_token_sdk_enabled::id()) - { - syscall_registry - .register_syscall_by_name(b"sol_zk_token_elgamal_op", SyscallZkTokenElgamalOp::call)?; - syscall_registry.register_syscall_by_name( - b"sol_zk_token_elgamal_op_with_lo_hi", - SyscallZkTokenElgamalOpWithLoHi::call, - )?; - syscall_registry.register_syscall_by_name( - b"sol_zk_token_elgamal_op_with_scalar", - SyscallZkTokenElgamalOpWithScalar::call, - )?; - } + // Blake3 + register_feature_gated_syscall!( + syscall_registry, + blake3_syscall_enabled, + b"sol_blake3", + SyscallBlake3::init, + SyscallBlake3::call, + )?; - syscall_registry - .register_syscall_by_name(b"sol_get_clock_sysvar", SyscallGetClockSysvar::call)?; + // ZK Token + register_feature_gated_syscall!( + syscall_registry, + zk_token_sdk_enabled, + b"sol_zk_token_elgamal_op", + SyscallZkTokenElgamalOp::init, + SyscallZkTokenElgamalOp::call, + )?; + register_feature_gated_syscall!( + syscall_registry, + zk_token_sdk_enabled, + b"sol_zk_token_elgamal_op_with_lo_hi", + SyscallZkTokenElgamalOpWithLoHi::init, + SyscallZkTokenElgamalOpWithLoHi::call, + )?; + register_feature_gated_syscall!( + syscall_registry, + zk_token_sdk_enabled, + b"sol_zk_token_elgamal_op_with_scalar", + SyscallZkTokenElgamalOpWithScalar::init, + SyscallZkTokenElgamalOpWithScalar::call, + )?; + + // Sysvars + syscall_registry.register_syscall_by_name( + b"sol_get_clock_sysvar", + SyscallGetClockSysvar::init, + SyscallGetClockSysvar::call, + )?; syscall_registry.register_syscall_by_name( b"sol_get_epoch_schedule_sysvar", + SyscallGetEpochScheduleSysvar::init, SyscallGetEpochScheduleSysvar::call, )?; - if !invoke_context - .feature_set - .is_active(&disable_fees_sysvar::id()) - { - syscall_registry - .register_syscall_by_name(b"sol_get_fees_sysvar", SyscallGetFeesSysvar::call)?; - } - syscall_registry - .register_syscall_by_name(b"sol_get_rent_sysvar", SyscallGetRentSysvar::call)?; + register_feature_gated_syscall!( + syscall_registry, + !disable_fees_sysvar, + b"sol_get_fees_sysvar", + SyscallGetFeesSysvar::init, + SyscallGetFeesSysvar::call, + )?; + syscall_registry.register_syscall_by_name( + b"sol_get_rent_sysvar", + SyscallGetRentSysvar::init, + SyscallGetRentSysvar::call, + )?; - syscall_registry.register_syscall_by_name(b"sol_memcpy_", SyscallMemcpy::call)?; - syscall_registry.register_syscall_by_name(b"sol_memmove_", SyscallMemmove::call)?; - syscall_registry.register_syscall_by_name(b"sol_memcmp_", SyscallMemcmp::call)?; - syscall_registry.register_syscall_by_name(b"sol_memset_", SyscallMemset::call)?; + // Memory ops + syscall_registry.register_syscall_by_name( + b"sol_memcpy_", + SyscallMemcpy::init, + SyscallMemcpy::call, + )?; + syscall_registry.register_syscall_by_name( + b"sol_memmove_", + SyscallMemmove::init, + SyscallMemmove::call, + )?; + syscall_registry.register_syscall_by_name( + b"sol_memcmp_", + SyscallMemcmp::init, + SyscallMemcmp::call, + )?; + syscall_registry.register_syscall_by_name( + b"sol_memset_", + SyscallMemset::init, + SyscallMemset::call, + )?; - // Cross-program invocation syscalls - syscall_registry - .register_syscall_by_name(b"sol_invoke_signed_c", SyscallInvokeSignedC::call)?; - syscall_registry - .register_syscall_by_name(b"sol_invoke_signed_rust", SyscallInvokeSignedRust::call)?; + // Cross-program invocation + syscall_registry.register_syscall_by_name( + b"sol_invoke_signed_c", + SyscallInvokeSignedC::init, + SyscallInvokeSignedC::call, + )?; + syscall_registry.register_syscall_by_name( + b"sol_invoke_signed_rust", + SyscallInvokeSignedRust::init, + SyscallInvokeSignedRust::call, + )?; // Memory allocator - syscall_registry.register_syscall_by_name(b"sol_alloc_free_", SyscallAllocFree::call)?; + syscall_registry.register_syscall_by_name( + b"sol_alloc_free_", + SyscallAllocFree::init, + SyscallAllocFree::call, + )?; // Return data - if invoke_context - .feature_set - .is_active(&return_data_syscall_enabled::id()) - { - syscall_registry - .register_syscall_by_name(b"sol_set_return_data", SyscallSetReturnData::call)?; - syscall_registry - .register_syscall_by_name(b"sol_get_return_data", SyscallGetReturnData::call)?; - } + register_feature_gated_syscall!( + syscall_registry, + return_data_syscall_enabled, + b"sol_set_return_data", + SyscallSetReturnData::init, + SyscallSetReturnData::call, + )?; + register_feature_gated_syscall!( + syscall_registry, + return_data_syscall_enabled, + b"sol_get_return_data", + SyscallGetReturnData::init, + SyscallGetReturnData::call, + )?; // Log data - if invoke_context - .feature_set - .is_active(&sol_log_data_syscall_enabled::id()) - { - syscall_registry.register_syscall_by_name(b"sol_log_data", SyscallLogData::call)?; - } + register_feature_gated_syscall!( + syscall_registry, + sol_log_data_syscall_enabled, + b"sol_log_data", + SyscallLogData::init, + SyscallLogData::call, + )?; - if invoke_context - .feature_set - .is_active(&add_get_processed_sibling_instruction_syscall::id()) - { - syscall_registry.register_syscall_by_name( - b"sol_get_processed_sibling_instruction", - SyscallGetProcessedSiblingInstruction::call, - )?; - } + // Processed sibling instructions + register_feature_gated_syscall!( + syscall_registry, + add_get_processed_sibling_instruction_syscall, + b"sol_get_processed_sibling_instruction", + SyscallGetProcessedSiblingInstruction::init, + SyscallGetProcessedSiblingInstruction::call, + )?; - if invoke_context - .feature_set - .is_active(&add_get_processed_sibling_instruction_syscall::id()) - { - syscall_registry - .register_syscall_by_name(b"sol_get_stack_height", SyscallGetStackHeight::call)?; - } + // Stack height + register_feature_gated_syscall!( + syscall_registry, + add_get_processed_sibling_instruction_syscall, + b"sol_get_stack_height", + SyscallGetStackHeight::init, + SyscallGetStackHeight::call, + )?; Ok(syscall_registry) } -macro_rules! bind_feature_gated_syscall_context_object { - ($vm:expr, $is_feature_active:expr, $syscall_context_object:expr $(,)?) => { - if $is_feature_active { - match $vm.bind_syscall_context_object($syscall_context_object, None) { - Err(EbpfError::SyscallNotRegistered(_)) | Ok(()) => {} - Err(err) => { - return Err(err); - } - } - } - }; -} - pub fn bind_syscall_context_objects<'a, 'b>( vm: &mut EbpfVm<'a, BpfError, crate::ThisInstructionMeter>, invoke_context: &'a mut InvokeContext<'b>, heap: AlignedMemory, ) -> Result<(), EbpfError> { - let is_blake3_syscall_active = invoke_context - .feature_set - .is_active(&blake3_syscall_enabled::id()); - let is_secp256k1_recover_syscall_active = invoke_context - .feature_set - .is_active(&secp256k1_recover_syscall_enabled::id()); - let is_fee_sysvar_via_syscall_active = !invoke_context - .feature_set - .is_active(&disable_fees_sysvar::id()); - let is_return_data_syscall_active = invoke_context - .feature_set - .is_active(&return_data_syscall_enabled::id()); - let is_sol_log_data_syscall_active = invoke_context - .feature_set - .is_active(&sol_log_data_syscall_enabled::id()); - let is_zk_token_sdk_enabled = invoke_context - .feature_set - .is_active(&zk_token_sdk_enabled::id()); - let add_get_processed_sibling_instruction_syscall = invoke_context - .feature_set - .is_active(&add_get_processed_sibling_instruction_syscall::id()); - invoke_context.set_check_aligned( bpf_loader_deprecated::id() != invoke_context @@ -310,225 +390,7 @@ pub fn bind_syscall_context_objects<'a, 'b>( let invoke_context = Rc::new(RefCell::new(invoke_context)); - // Syscall functions common across languages - - vm.bind_syscall_context_object( - Box::new(SyscallAbort { - _invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallPanic { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallLog { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallLogU64 { - invoke_context: invoke_context.clone(), - }), - None, - )?; - - vm.bind_syscall_context_object( - Box::new(SyscallLogBpfComputeUnits { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallLogPubkey { - invoke_context: invoke_context.clone(), - }), - None, - )?; - - vm.bind_syscall_context_object( - Box::new(SyscallCreateProgramAddress { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallTryFindProgramAddress { - invoke_context: invoke_context.clone(), - }), - None, - )?; - - vm.bind_syscall_context_object( - Box::new(SyscallSha256 { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallKeccak256 { - invoke_context: invoke_context.clone(), - }), - None, - )?; - - vm.bind_syscall_context_object( - Box::new(SyscallMemcpy { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallMemmove { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallMemcmp { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallMemset { - invoke_context: invoke_context.clone(), - }), - None, - )?; - - bind_feature_gated_syscall_context_object!( - vm, - is_secp256k1_recover_syscall_active, - Box::new(SyscallSecp256k1Recover { - invoke_context: invoke_context.clone(), - }), - ); - bind_feature_gated_syscall_context_object!( - vm, - is_blake3_syscall_active, - Box::new(SyscallBlake3 { - invoke_context: invoke_context.clone(), - }), - ); - - bind_feature_gated_syscall_context_object!( - vm, - is_zk_token_sdk_enabled, - Box::new(SyscallZkTokenElgamalOp { - invoke_context: invoke_context.clone(), - }), - ); - bind_feature_gated_syscall_context_object!( - vm, - is_zk_token_sdk_enabled, - Box::new(SyscallZkTokenElgamalOpWithLoHi { - invoke_context: invoke_context.clone(), - }), - ); - bind_feature_gated_syscall_context_object!( - vm, - is_zk_token_sdk_enabled, - Box::new(SyscallZkTokenElgamalOpWithScalar { - invoke_context: invoke_context.clone(), - }), - ); - - vm.bind_syscall_context_object( - Box::new(SyscallGetClockSysvar { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallGetEpochScheduleSysvar { - invoke_context: invoke_context.clone(), - }), - None, - )?; - bind_feature_gated_syscall_context_object!( - vm, - is_fee_sysvar_via_syscall_active, - Box::new(SyscallGetFeesSysvar { - invoke_context: invoke_context.clone(), - }), - ); - vm.bind_syscall_context_object( - Box::new(SyscallGetRentSysvar { - invoke_context: invoke_context.clone(), - }), - None, - )?; - - // Return data - bind_feature_gated_syscall_context_object!( - vm, - is_return_data_syscall_active, - Box::new(SyscallSetReturnData { - invoke_context: invoke_context.clone(), - }), - ); - - bind_feature_gated_syscall_context_object!( - vm, - is_return_data_syscall_active, - Box::new(SyscallGetReturnData { - invoke_context: invoke_context.clone(), - }), - ); - - // sol_log_data - bind_feature_gated_syscall_context_object!( - vm, - is_sol_log_data_syscall_active, - Box::new(SyscallLogData { - invoke_context: invoke_context.clone(), - }), - ); - - // processed inner instructions - bind_feature_gated_syscall_context_object!( - vm, - add_get_processed_sibling_instruction_syscall, - Box::new(SyscallGetProcessedSiblingInstruction { - invoke_context: invoke_context.clone(), - }), - ); - - // Get stack height - bind_feature_gated_syscall_context_object!( - vm, - add_get_processed_sibling_instruction_syscall, - Box::new(SyscallGetStackHeight { - invoke_context: invoke_context.clone(), - }), - ); - - // Cross-program invocation syscalls - vm.bind_syscall_context_object( - Box::new(SyscallInvokeSignedC { - invoke_context: invoke_context.clone(), - }), - None, - )?; - vm.bind_syscall_context_object( - Box::new(SyscallInvokeSignedRust { - invoke_context: invoke_context.clone(), - }), - None, - )?; - - // Memory allocator - vm.bind_syscall_context_object( - Box::new(SyscallAllocFree { - invoke_context: invoke_context.clone(), - }), - None, - )?; + vm.bind_syscall_context_objects(invoke_context, None)?; Ok(()) } @@ -651,14 +513,33 @@ fn translate_string_and_do( } } -/// Abort syscall functions, called when the BPF program calls `abort()` -/// LLVM will insert calls to `abort()` if it detects an untenable situation, -/// `abort()` is not intended to be called explicitly by the program. -/// Causes the BPF program to be halted immediately -pub struct SyscallAbort<'a, 'b> { - _invoke_context: Rc>>, +type SyscallContext<'a, 'b> = Rc>>; + +macro_rules! declare_syscall { + ($(#[$attr:meta])* $name:ident, $call:item) => { + $(#[$attr])* + pub struct $name<'a, 'b> { + invoke_context: SyscallContext<'a, 'b>, + } + impl<'a, 'b> $name<'a, 'b> { + pub fn init( + invoke_context: SyscallContext<'a, 'b>, + ) -> Box<(dyn SyscallObject + 'a)> { + Box::new(Self { invoke_context }) + } + } + impl<'a, 'b> SyscallObject for $name<'a, 'b> { + $call + } + }; } -impl<'a, 'b> SyscallObject for SyscallAbort<'a, 'b> { + +declare_syscall!( + /// Abort syscall functions, called when the BPF program calls `abort()` + /// LLVM will insert calls to `abort()` if it detects an untenable situation, + /// `abort()` is not intended to be called explicitly by the program. + /// Causes the BPF program to be halted immediately + SyscallAbort, fn call( &mut self, _arg1: u64, @@ -669,17 +550,20 @@ impl<'a, 'b> SyscallObject for SyscallAbort<'a, 'b> { _memory_mapping: &MemoryMapping, result: &mut Result>, ) { + let _ = question_mark!( + self.invoke_context + .try_borrow() + .map_err(|_| SyscallError::InvokeContextBorrowFailed), + result + ); *result = Err(SyscallError::Abort.into()); } -} +); -/// Panic syscall function, called when the BPF program calls 'sol_panic_()` -/// Causes the BPF program to be halted immediately -/// Log a user's info message -pub struct SyscallPanic<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallPanic<'a, 'b> { +declare_syscall!( + /// Panic syscall function, called when the BPF program calls 'sol_panic_()` + /// Causes the BPF program to be halted immediately + SyscallPanic, fn call( &mut self, file: u64, @@ -712,13 +596,11 @@ impl<'a, 'b> SyscallObject for SyscallPanic<'a, 'b> { &mut |string: &str| Err(SyscallError::Panic(string.to_string(), line, column).into()), ); } -} +); -/// Log a user's info message -pub struct SyscallLog<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallLog<'a, 'b> { +declare_syscall!( + /// Log a user's info message + SyscallLog, fn call( &mut self, addr: u64, @@ -764,13 +646,11 @@ impl<'a, 'b> SyscallObject for SyscallLog<'a, 'b> { ); *result = Ok(0); } -} +); -/// Log 5 64-bit values -pub struct SyscallLogU64<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallLogU64<'a, 'b> { +declare_syscall!( + /// Log 5 64-bit values + SyscallLogU64, fn call( &mut self, arg1: u64, @@ -799,13 +679,11 @@ impl<'a, 'b> SyscallObject for SyscallLogU64<'a, 'b> { ); *result = Ok(0); } -} +); -/// Log current compute consumption -pub struct SyscallLogBpfComputeUnits<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallLogBpfComputeUnits<'a, 'b> { +declare_syscall!( + /// Log current compute consumption + SyscallLogBpfComputeUnits, fn call( &mut self, _arg1: u64, @@ -839,13 +717,11 @@ impl<'a, 'b> SyscallObject for SyscallLogBpfComputeUnits<'a, 'b> { ); *result = Ok(0); } -} +); -/// Log 5 64-bit values -pub struct SyscallLogPubkey<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallLogPubkey<'a, 'b> { +declare_syscall!( + /// Log 5 64-bit values + SyscallLogPubkey, fn call( &mut self, pubkey_addr: u64, @@ -876,18 +752,16 @@ impl<'a, 'b> SyscallObject for SyscallLogPubkey<'a, 'b> { stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string()); *result = Ok(0); } -} +); -/// Dynamic memory allocation syscall called when the BPF program calls -/// `sol_alloc_free_()`. The allocator is expected to allocate/free -/// from/to a given chunk of memory and enforce size restrictions. The -/// memory chunk is given to the allocator during allocator creation and -/// information about that memory (start address and size) is passed -/// to the VM to use for enforcement. -pub struct SyscallAllocFree<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallAllocFree<'a, 'b> { +declare_syscall!( + /// Dynamic memory allocation syscall called when the BPF program calls + /// `sol_alloc_free_()`. The allocator is expected to allocate/free + /// from/to a given chunk of memory and enforce size restrictions. The + /// memory chunk is given to the allocator during allocator creation and + /// information about that memory (start address and size) is passed + /// to the VM to use for enforcement. + SyscallAllocFree, fn call( &mut self, size: u64, @@ -939,7 +813,7 @@ impl<'a, 'b> SyscallObject for SyscallAllocFree<'a, 'b> { Ok(0) }; } -} +); fn translate_and_check_program_address_inputs<'a>( seeds_addr: u64, @@ -978,11 +852,9 @@ fn translate_and_check_program_address_inputs<'a>( Ok((seeds, program_id)) } -/// Create a program address -struct SyscallCreateProgramAddress<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallCreateProgramAddress<'a, 'b> { +declare_syscall!( + /// Create a program address + SyscallCreateProgramAddress, fn call( &mut self, seeds_addr: u64, @@ -1036,13 +908,11 @@ impl<'a, 'b> SyscallObject for SyscallCreateProgramAddress<'a, 'b> { address.copy_from_slice(new_address.as_ref()); *result = Ok(0); } -} +); -/// Create a program address -struct SyscallTryFindProgramAddress<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallTryFindProgramAddress<'a, 'b> { +declare_syscall!( + /// Create a program address + SyscallTryFindProgramAddress, fn call( &mut self, seeds_addr: u64, @@ -1114,13 +984,11 @@ impl<'a, 'b> SyscallObject for SyscallTryFindProgramAddress<'a, 'b> { } *result = Ok(1); } -} +); -/// SHA256 -pub struct SyscallSha256<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallSha256<'a, 'b> { +declare_syscall!( + /// SHA256 + SyscallSha256, fn call( &mut self, vals_addr: u64, @@ -1213,7 +1081,7 @@ impl<'a, 'b> SyscallObject for SyscallSha256<'a, 'b> { hash_result.copy_from_slice(&hasher.result().to_bytes()); *result = Ok(0); } -} +); fn get_sysvar( sysvar: Result, InstructionError>, @@ -1236,11 +1104,9 @@ fn get_sysvar( Ok(SUCCESS) } -/// Get a Clock sysvar -struct SyscallGetClockSysvar<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallGetClockSysvar<'a, 'b> { +declare_syscall!( + /// Get a Clock sysvar + SyscallGetClockSysvar, fn call( &mut self, var_addr: u64, @@ -1265,12 +1131,11 @@ impl<'a, 'b> SyscallObject for SyscallGetClockSysvar<'a, 'b> { &mut invoke_context, ); } -} -/// Get a EpochSchedule sysvar -struct SyscallGetEpochScheduleSysvar<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallGetEpochScheduleSysvar<'a, 'b> { +); + +declare_syscall!( + /// Get a EpochSchedule sysvar + SyscallGetEpochScheduleSysvar, fn call( &mut self, var_addr: u64, @@ -1295,13 +1160,11 @@ impl<'a, 'b> SyscallObject for SyscallGetEpochScheduleSysvar<'a, 'b> { &mut invoke_context, ); } -} -/// Get a Fees sysvar -struct SyscallGetFeesSysvar<'a, 'b> { - invoke_context: Rc>>, -} -#[allow(deprecated)] -impl<'a, 'b> SyscallObject for SyscallGetFeesSysvar<'a, 'b> { +); + +declare_syscall!( + /// Get a Fees sysvar + SyscallGetFeesSysvar, fn call( &mut self, var_addr: u64, @@ -1318,20 +1181,22 @@ impl<'a, 'b> SyscallObject for SyscallGetFeesSysvar<'a, 'b> { .map_err(|_| SyscallError::InvokeContextBorrowFailed), result ); - *result = get_sysvar( - invoke_context.get_sysvar_cache().get_fees(), - var_addr, - invoke_context.get_check_aligned(), - memory_mapping, - &mut invoke_context, - ); + #[allow(deprecated)] + { + *result = get_sysvar( + invoke_context.get_sysvar_cache().get_fees(), + var_addr, + invoke_context.get_check_aligned(), + memory_mapping, + &mut invoke_context, + ); + } } -} -/// Get a Rent sysvar -struct SyscallGetRentSysvar<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallGetRentSysvar<'a, 'b> { +); + +declare_syscall!( + /// Get a Rent sysvar + SyscallGetRentSysvar, fn call( &mut self, var_addr: u64, @@ -1356,13 +1221,11 @@ impl<'a, 'b> SyscallObject for SyscallGetRentSysvar<'a, 'b> { &mut invoke_context, ); } -} +); -// Keccak256 -pub struct SyscallKeccak256<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallKeccak256<'a, 'b> { +declare_syscall!( + // Keccak256 + SyscallKeccak256, fn call( &mut self, vals_addr: u64, @@ -1455,7 +1318,7 @@ impl<'a, 'b> SyscallObject for SyscallKeccak256<'a, 'b> { hash_result.copy_from_slice(&hasher.result().to_bytes()); *result = Ok(0); } -} +); /// This function is incorrect due to arithmetic overflow and only exists for /// backwards compatibility. Instead use program_stubs::is_nonoverlapping. @@ -1483,11 +1346,9 @@ fn mem_op_consume<'a, 'b>( invoke_context.get_compute_meter().consume(cost) } -/// memcpy -pub struct SyscallMemcpy<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallMemcpy<'a, 'b> { +declare_syscall!( + /// memcpy + SyscallMemcpy, fn call( &mut self, dst_addr: u64, @@ -1576,12 +1437,11 @@ impl<'a, 'b> SyscallObject for SyscallMemcpy<'a, 'b> { } *result = Ok(0); } -} -/// memmove -pub struct SyscallMemmove<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallMemmove<'a, 'b> { +); + +declare_syscall!( + /// memmove + SyscallMemmove, fn call( &mut self, dst_addr: u64, @@ -1625,12 +1485,11 @@ impl<'a, 'b> SyscallObject for SyscallMemmove<'a, 'b> { } *result = Ok(0); } -} -/// memcmp -pub struct SyscallMemcmp<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallMemcmp<'a, 'b> { +); + +declare_syscall!( + /// memcmp + SyscallMemcmp, fn call( &mut self, s1_addr: u64, @@ -1701,12 +1560,11 @@ impl<'a, 'b> SyscallObject for SyscallMemcmp<'a, 'b> { *cmp_result = 0; *result = Ok(0); } -} -/// memset -pub struct SyscallMemset<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallMemset<'a, 'b> { +); + +declare_syscall!( + /// memset + SyscallMemset, fn call( &mut self, s_addr: u64, @@ -1740,13 +1598,11 @@ impl<'a, 'b> SyscallObject for SyscallMemset<'a, 'b> { } *result = Ok(0); } -} +); -/// secp256k1_recover -pub struct SyscallSecp256k1Recover<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallSecp256k1Recover<'a, 'b> { +declare_syscall!( + /// secp256k1_recover + SyscallSecp256k1Recover, fn call( &mut self, hash_addr: u64, @@ -1853,12 +1709,10 @@ impl<'a, 'b> SyscallObject for SyscallSecp256k1Recover<'a, 'b> { secp256k1_recover_result.copy_from_slice(&public_key[1..65]); *result = Ok(SUCCESS); } -} +); -pub struct SyscallZkTokenElgamalOp<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallZkTokenElgamalOp<'a, 'b> { +declare_syscall!( + SyscallZkTokenElgamalOp, fn call( &mut self, op: u64, @@ -1915,12 +1769,10 @@ impl<'a, 'b> SyscallObject for SyscallZkTokenElgamalOp<'a, 'b> { *result = Ok(1); } } -} +); -pub struct SyscallZkTokenElgamalOpWithLoHi<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallZkTokenElgamalOpWithLoHi<'a, 'b> { +declare_syscall!( + SyscallZkTokenElgamalOpWithLoHi, fn call( &mut self, op: u64, @@ -1985,12 +1837,10 @@ impl<'a, 'b> SyscallObject for SyscallZkTokenElgamalOpWithLoHi<'a, 'b> *result = Ok(1); } } -} +); -pub struct SyscallZkTokenElgamalOpWithScalar<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallZkTokenElgamalOpWithScalar<'a, 'b> { +declare_syscall!( + SyscallZkTokenElgamalOpWithScalar, fn call( &mut self, op: u64, @@ -2039,13 +1889,11 @@ impl<'a, 'b> SyscallObject for SyscallZkTokenElgamalOpWithScalar<'a, ' *result = Ok(1); } } -} +); -// Blake3 -pub struct SyscallBlake3<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallBlake3<'a, 'b> { +declare_syscall!( + // Blake3 + SyscallBlake3, fn call( &mut self, vals_addr: u64, @@ -2146,7 +1994,7 @@ impl<'a, 'b> SyscallObject for SyscallBlake3<'a, 'b> { hash_result.copy_from_slice(&hasher.result().to_bytes()); *result = Ok(0); } -} +); // Cross-program invocation syscalls @@ -2191,11 +2039,9 @@ trait SyscallInvokeSigned<'a, 'b> { ) -> Result, EbpfError>; } -/// Cross-SyscallInvokeSignedRust invocation called from Rust -pub struct SyscallInvokeSignedRust<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallInvokeSignedRust<'a, 'b> { +declare_syscall!( + /// Cross-program invocation called from Rust + SyscallInvokeSignedRust, fn call( &mut self, instruction_addr: u64, @@ -2216,7 +2062,7 @@ impl<'a, 'b> SyscallObject for SyscallInvokeSignedRust<'a, 'b> { memory_mapping, ); } -} +); impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedRust<'a, 'b> { fn get_context_mut(&self) -> Result>, EbpfError> { @@ -2484,11 +2330,9 @@ struct SolSignerSeedsC { len: u64, } -/// Cross-program invocation called from C -pub struct SyscallInvokeSignedC<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallInvokeSignedC<'a, 'b> { +declare_syscall!( + /// Cross-program invocation called from C + SyscallInvokeSignedC, fn call( &mut self, instruction_addr: u64, @@ -2509,7 +2353,7 @@ impl<'a, 'b> SyscallObject for SyscallInvokeSignedC<'a, 'b> { memory_mapping, ); } -} +); impl<'a, 'b> SyscallInvokeSigned<'a, 'b> for SyscallInvokeSignedC<'a, 'b> { fn get_context_mut(&self) -> Result>, EbpfError> { @@ -3079,11 +2923,9 @@ fn call<'a, 'b: 'a>( Ok(SUCCESS) } -// Return data handling -pub struct SyscallSetReturnData<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallSetReturnData<'a, 'b> { +declare_syscall!( + /// Set return data + SyscallSetReturnData, fn call( &mut self, addr: u64, @@ -3155,12 +2997,11 @@ impl<'a, 'b> SyscallObject for SyscallSetReturnData<'a, 'b> { *result = Ok(0); } -} +); -pub struct SyscallGetReturnData<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallGetReturnData<'a, 'b> { +declare_syscall!( + /// Get return data + SyscallGetReturnData, fn call( &mut self, return_data_addr: u64, @@ -3243,13 +3084,11 @@ impl<'a, 'b> SyscallObject for SyscallGetReturnData<'a, 'b> { // Return the actual length, rather the length returned *result = Ok(return_data.len() as u64); } -} +); -// Log data handling -pub struct SyscallLogData<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallLogData<'a, 'b> { +declare_syscall!( + /// Log data handling + SyscallLogData, fn call( &mut self, addr: u64, @@ -3324,12 +3163,11 @@ impl<'a, 'b> SyscallObject for SyscallLogData<'a, 'b> { *result = Ok(0); } -} +); -pub struct SyscallGetProcessedSiblingInstruction<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallGetProcessedSiblingInstruction<'a, 'b> { +declare_syscall!( + /// Get a processed sigling instruction + SyscallGetProcessedSiblingInstruction, fn call( &mut self, index: u64, @@ -3453,12 +3291,11 @@ impl<'a, 'b> SyscallObject for SyscallGetProcessedSiblingInstruction<' } *result = Ok(false as u64); } -} +); -pub struct SyscallGetStackHeight<'a, 'b> { - invoke_context: Rc>>, -} -impl<'a, 'b> SyscallObject for SyscallGetStackHeight<'a, 'b> { +declare_syscall!( + /// Get current call stack height + SyscallGetStackHeight, fn call( &mut self, _arg1: u64, @@ -3486,7 +3323,7 @@ impl<'a, 'b> SyscallObject for SyscallGetStackHeight<'a, 'b> { *result = Ok(invoke_context.get_stack_height() as u64); } -} +); #[cfg(test)] mod tests { @@ -3559,7 +3396,7 @@ mod tests { let memory_mapping = MemoryMapping::new::( vec![ MemoryRegion::default(), - MemoryRegion::new_readonly(&data, START), + MemoryRegion::new_from_slice(&data, START, 0, false), ], &config, ) @@ -3812,7 +3649,7 @@ mod tests { let mut result: Result> = Ok(0); SyscallAbort::call( &mut SyscallAbort { - _invoke_context: Rc::new(RefCell::new(&mut invoke_context)), + invoke_context: Rc::new(RefCell::new(&mut invoke_context)), }, 0, 0, @@ -4126,14 +3963,14 @@ mod tests { program_id, bpf_loader::id(), ); - let mut heap = AlignedMemory::new_with_size(100, HOST_ALIGN); + let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let memory_mapping = MemoryMapping::new::( vec![ MemoryRegion::default(), - MemoryRegion::new_readonly(&[], ebpf::MM_PROGRAM_START), - MemoryRegion::new_writable_gapped(&mut [], ebpf::MM_STACK_START, 4096), - MemoryRegion::new_writable(heap.as_slice_mut(), ebpf::MM_HEAP_START), - MemoryRegion::new_writable(&mut [], ebpf::MM_INPUT_START), + MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false), + MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true), + MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true), + MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true), ], &config, ) @@ -4166,14 +4003,14 @@ mod tests { program_id, bpf_loader::id(), ); - let mut heap = AlignedMemory::new_with_size(100, HOST_ALIGN); + let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let memory_mapping = MemoryMapping::new::( vec![ MemoryRegion::default(), - MemoryRegion::new_readonly(&[], ebpf::MM_PROGRAM_START), - MemoryRegion::new_writable_gapped(&mut [], ebpf::MM_STACK_START, 4096), - MemoryRegion::new_writable(heap.as_slice_mut(), ebpf::MM_HEAP_START), - MemoryRegion::new_writable(&mut [], ebpf::MM_INPUT_START), + MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false), + MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true), + MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true), + MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true), ], &config, ) @@ -4206,14 +4043,14 @@ mod tests { program_id, bpf_loader::id(), ); - let mut heap = AlignedMemory::new_with_size(100, HOST_ALIGN); + let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let memory_mapping = MemoryMapping::new::( vec![ MemoryRegion::default(), - MemoryRegion::new_readonly(&[], ebpf::MM_PROGRAM_START), - MemoryRegion::new_writable_gapped(&mut [], ebpf::MM_STACK_START, 4096), - MemoryRegion::new_writable(heap.as_slice_mut(), ebpf::MM_HEAP_START), - MemoryRegion::new_writable(&mut [], ebpf::MM_INPUT_START), + MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false), + MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true), + MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true), + MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true), ], &config, ) @@ -4246,15 +4083,15 @@ mod tests { program_id, bpf_loader::id(), ); - let mut heap = AlignedMemory::new_with_size(100, HOST_ALIGN); + let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let config = Config::default(); let memory_mapping = MemoryMapping::new::( vec![ MemoryRegion::default(), - MemoryRegion::new_readonly(&[], ebpf::MM_PROGRAM_START), - MemoryRegion::new_writable_gapped(&mut [], ebpf::MM_STACK_START, 4096), - MemoryRegion::new_writable(heap.as_slice_mut(), ebpf::MM_HEAP_START), - MemoryRegion::new_writable(&mut [], ebpf::MM_INPUT_START), + MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false), + MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true), + MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true), + MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true), ], &config, ) diff --git a/rbpf-cli/Cargo.toml b/rbpf-cli/Cargo.toml index ef6577869b..2b40456baa 100644 --- a/rbpf-cli/Cargo.toml +++ b/rbpf-cli/Cargo.toml @@ -22,4 +22,4 @@ solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.11. solana-logger = { path = "../logger", version = "=1.11.0" } solana-program-runtime = { path = "../program-runtime", version = "=1.11.0" } solana-sdk = { path = "../sdk", version = "=1.11.0" } -solana_rbpf = "=0.2.27" +solana_rbpf = "=0.2.26" diff --git a/rbpf-cli/src/main.rs b/rbpf-cli/src/main.rs index ff8f965372..a283c32603 100644 --- a/rbpf-cli/src/main.rs +++ b/rbpf-cli/src/main.rs @@ -427,6 +427,6 @@ impl<'a> LazyAnalysis<'a> { return analysis; } self.analysis - .insert(Analysis::from_executable(self.executable).unwrap()) + .insert(Analysis::from_executable(self.executable)) } } diff --git a/sdk/program/src/program_stubs.rs b/sdk/program/src/program_stubs.rs index a94d0a42ab..ec14a3e0e4 100644 --- a/sdk/program/src/program_stubs.rs +++ b/sdk/program/src/program_stubs.rs @@ -139,8 +139,8 @@ pub(crate) fn sol_get_epoch_schedule_sysvar(var_addr: *mut u8) -> u64 { .sol_get_epoch_schedule_sysvar(var_addr) } -pub(crate) fn sol_get_fees_sysvar(_var_addr: *mut u8) -> u64 { - UNSUPPORTED_SYSVAR +pub(crate) fn sol_get_fees_sysvar(var_addr: *mut u8) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_get_fees_sysvar(var_addr) } pub(crate) fn sol_get_rent_sysvar(var_addr: *mut u8) -> u64 {