Bump solana_rbpf to v0.6.0 (#32313)
This commit is contained in:
parent
356a827087
commit
9731331be4
|
@ -7347,9 +7347,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "solana_rbpf"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ae90c406f0a2d4a15f08d16c8b64f37997a57611fec0a89f1277854166996e8"
|
||||
checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"combine",
|
||||
|
|
|
@ -292,7 +292,7 @@ siphasher = "0.3.10"
|
|||
smpl_jwt = "0.7.1"
|
||||
socket2 = "0.4.9"
|
||||
soketto = "0.7"
|
||||
solana_rbpf = "=0.5.0"
|
||||
solana_rbpf = "=0.6.0"
|
||||
solana-account-decoder = { path = "account-decoder", version = "=1.17.0" }
|
||||
solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.17.0" }
|
||||
solana-banks-client = { path = "banks-client", version = "=1.17.0" }
|
||||
|
|
|
@ -579,17 +579,17 @@ pub fn program(ledger_path: &Path, matches: &ArgMatches<'_>) {
|
|||
if matches.value_of("mode").unwrap() == "debugger" {
|
||||
vm.debug_port = Some(matches.value_of("port").unwrap().parse::<u16>().unwrap());
|
||||
}
|
||||
let (instruction_count, result) = vm.execute_program(interpreted);
|
||||
let (instruction_count, result) = vm.execute_program(&verified_executable, interpreted);
|
||||
let duration = Instant::now() - start_time;
|
||||
if matches.occurrences_of("trace") > 0 {
|
||||
// top level trace is stored in syscall_context
|
||||
if let Some(Some(syscall_context)) = vm.env.context_object_pointer.syscall_context.last() {
|
||||
if let Some(Some(syscall_context)) = vm.context_object_pointer.syscall_context.last() {
|
||||
let trace = syscall_context.trace_log.as_slice();
|
||||
output_trace(matches, trace, 0, &mut analysis);
|
||||
}
|
||||
// the remaining traces are saved in InvokeContext when
|
||||
// corresponding syscall_contexts are popped
|
||||
let traces = vm.env.context_object_pointer.get_traces();
|
||||
let traces = vm.context_object_pointer.get_traces();
|
||||
for (frame, trace) in traces.iter().filter(|t| !t.is_empty()).enumerate() {
|
||||
output_trace(matches, trace, frame + 1, &mut analysis);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ use {
|
|||
solana_measure::measure::Measure,
|
||||
solana_rbpf::{
|
||||
ebpf::MM_HEAP_START,
|
||||
elf::SBPFVersion,
|
||||
memory_region::MemoryMapping,
|
||||
vm::{BuiltinFunction, Config, ContextObject, ProgramResult},
|
||||
},
|
||||
|
@ -744,7 +745,8 @@ impl<'a> InvokeContext<'a> {
|
|||
stable_log::program_invoke(&logger, &program_id, self.get_stack_height());
|
||||
let pre_remaining_units = self.get_remaining();
|
||||
let mock_config = Config::default();
|
||||
let mut mock_memory_mapping = MemoryMapping::new(Vec::new(), &mock_config).unwrap();
|
||||
let mut mock_memory_mapping =
|
||||
MemoryMapping::new(Vec::new(), &mock_config, &SBPFVersion::V2).unwrap();
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
process_instruction(
|
||||
// Removes lifetime tracking
|
||||
|
|
|
@ -275,7 +275,7 @@ pub fn create_vm<'a, 'b>(
|
|||
invoke_context: &'a mut InvokeContext<'b>,
|
||||
stack: &mut AlignedMemory<HOST_ALIGN>,
|
||||
heap: &mut AlignedMemory<HOST_ALIGN>,
|
||||
) -> Result<EbpfVm<'a, RequisiteVerifier, InvokeContext<'b>>, Box<dyn std::error::Error>> {
|
||||
) -> Result<EbpfVm<'a, InvokeContext<'b>>, Box<dyn std::error::Error>> {
|
||||
let stack_size = stack.len();
|
||||
let heap_size = heap.len();
|
||||
let accounts = Arc::clone(invoke_context.transaction_context.accounts());
|
||||
|
@ -309,7 +309,8 @@ pub fn create_vm<'a, 'b>(
|
|||
trace_log: Vec::new(),
|
||||
})?;
|
||||
Ok(EbpfVm::new(
|
||||
program,
|
||||
program.get_config(),
|
||||
program.get_sbpf_version(),
|
||||
invoke_context,
|
||||
memory_mapping,
|
||||
stack_size,
|
||||
|
@ -370,7 +371,10 @@ macro_rules! mock_create_vm {
|
|||
solana_rbpf::verifier::TautologyVerifier,
|
||||
InvokeContext,
|
||||
>::from_text_bytes(
|
||||
&[0x95, 0, 0, 0, 0, 0, 0, 0], loader, function_registry
|
||||
&[0x95, 0, 0, 0, 0, 0, 0, 0],
|
||||
loader,
|
||||
SBPFVersion::V2,
|
||||
function_registry,
|
||||
)
|
||||
.unwrap();
|
||||
let verified_executable = solana_rbpf::elf::Executable::verified(executable).unwrap();
|
||||
|
@ -392,12 +396,13 @@ fn create_memory_mapping<'a, 'b, C: ContextObject>(
|
|||
cow_cb: Option<MemoryCowCallback>,
|
||||
) -> Result<MemoryMapping<'a>, Box<dyn std::error::Error>> {
|
||||
let config = executable.get_config();
|
||||
let sbpf_version = executable.get_sbpf_version();
|
||||
let regions: Vec<MemoryRegion> = vec![
|
||||
executable.get_ro_region(),
|
||||
MemoryRegion::new_writable_gapped(
|
||||
stack.as_slice_mut(),
|
||||
ebpf::MM_STACK_START,
|
||||
if !config.dynamic_stack_frames && config.enable_stack_frame_gaps {
|
||||
if !sbpf_version.dynamic_stack_frames() && config.enable_stack_frame_gaps {
|
||||
config.stack_frame_size as u64
|
||||
} else {
|
||||
0
|
||||
|
@ -410,9 +415,9 @@ fn create_memory_mapping<'a, 'b, C: ContextObject>(
|
|||
.collect();
|
||||
|
||||
Ok(if let Some(cow_cb) = cow_cb {
|
||||
MemoryMapping::new_with_cow(regions, cow_cb, config)?
|
||||
MemoryMapping::new_with_cow(regions, cow_cb, config, sbpf_version)?
|
||||
} else {
|
||||
MemoryMapping::new(regions, config)?
|
||||
MemoryMapping::new(regions, config, sbpf_version)?
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1544,6 +1549,11 @@ fn execute<'a, 'b: 'a>(
|
|||
executable: &'a Executable<RequisiteVerifier, InvokeContext<'static>>,
|
||||
invoke_context: &'a mut InvokeContext<'b>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
// We dropped the lifetime tracking in the Executor by setting it to 'static,
|
||||
// thus we need to reintroduce the correct lifetime of InvokeContext here again.
|
||||
let executable = unsafe {
|
||||
mem::transmute::<_, &'a Executable<RequisiteVerifier, InvokeContext<'b>>>(executable)
|
||||
};
|
||||
let log_collector = invoke_context.get_log_collector();
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
|
@ -1580,19 +1590,7 @@ fn execute<'a, 'b: 'a>(
|
|||
let mut execute_time;
|
||||
let execution_result = {
|
||||
let compute_meter_prev = invoke_context.get_remaining();
|
||||
create_vm!(
|
||||
vm,
|
||||
// We dropped the lifetime tracking in the Executor by setting it to 'static,
|
||||
// thus we need to reintroduce the correct lifetime of InvokeContext here again.
|
||||
unsafe {
|
||||
mem::transmute::<_, &'a Executable<RequisiteVerifier, InvokeContext<'b>>>(
|
||||
executable,
|
||||
)
|
||||
},
|
||||
regions,
|
||||
account_lengths,
|
||||
invoke_context,
|
||||
);
|
||||
create_vm!(vm, executable, regions, account_lengths, invoke_context,);
|
||||
let mut vm = match vm {
|
||||
Ok(info) => info,
|
||||
Err(e) => {
|
||||
|
@ -1603,7 +1601,7 @@ fn execute<'a, 'b: 'a>(
|
|||
create_vm_time.stop();
|
||||
|
||||
execute_time = Measure::start("execute");
|
||||
let (compute_units_consumed, result) = vm.execute_program(!use_jit);
|
||||
let (compute_units_consumed, result) = vm.execute_program(executable, !use_jit);
|
||||
drop(vm);
|
||||
ic_logger_msg!(
|
||||
log_collector,
|
||||
|
@ -1761,6 +1759,7 @@ mod tests {
|
|||
invoke_context::mock_process_instruction, with_mock_invoke_context,
|
||||
},
|
||||
solana_rbpf::{
|
||||
elf::SBPFVersion,
|
||||
verifier::Verifier,
|
||||
vm::{Config, ContextObject, FunctionRegistry},
|
||||
},
|
||||
|
@ -1833,7 +1832,13 @@ mod tests {
|
|||
let prog = &[
|
||||
0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55, // first half of lddw
|
||||
];
|
||||
RequisiteVerifier::verify(prog, &Config::default(), &FunctionRegistry::default()).unwrap();
|
||||
RequisiteVerifier::verify(
|
||||
prog,
|
||||
&Config::default(),
|
||||
&SBPFVersion::V2,
|
||||
&FunctionRegistry::default(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1267,7 +1267,9 @@ mod tests {
|
|||
super::*,
|
||||
crate::mock_create_vm,
|
||||
solana_program_runtime::with_mock_invoke_context,
|
||||
solana_rbpf::{ebpf::MM_INPUT_START, memory_region::MemoryRegion, vm::Config},
|
||||
solana_rbpf::{
|
||||
ebpf::MM_INPUT_START, elf::SBPFVersion, memory_region::MemoryRegion, vm::Config,
|
||||
},
|
||||
solana_sdk::{
|
||||
account::{Account, AccountSharedData},
|
||||
clock::Epoch,
|
||||
|
@ -1366,7 +1368,8 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let mut memory_mapping = MemoryMapping::new(vec![region], &config).unwrap();
|
||||
let mut memory_mapping =
|
||||
MemoryMapping::new(vec![region], &config, &SBPFVersion::V2).unwrap();
|
||||
|
||||
let ins = SyscallInvokeSignedRust::translate_instruction(
|
||||
vm_addr,
|
||||
|
@ -1402,7 +1405,8 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let mut memory_mapping = MemoryMapping::new(vec![region], &config).unwrap();
|
||||
let mut memory_mapping =
|
||||
MemoryMapping::new(vec![region], &config, &SBPFVersion::V2).unwrap();
|
||||
|
||||
let signers = SyscallInvokeSignedRust::translate_signers(
|
||||
&program_id,
|
||||
|
@ -1437,7 +1441,7 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let memory_mapping = MemoryMapping::new(vec![region], &config).unwrap();
|
||||
let memory_mapping = MemoryMapping::new(vec![region], &config, &SBPFVersion::V2).unwrap();
|
||||
|
||||
let account_info = translate_type::<AccountInfo>(&memory_mapping, vm_addr, false).unwrap();
|
||||
|
||||
|
@ -1487,8 +1491,12 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let mut memory_mapping =
|
||||
MemoryMapping::new(mock_caller_account.regions.split_off(0), &config).unwrap();
|
||||
let mut memory_mapping = MemoryMapping::new(
|
||||
mock_caller_account.regions.split_off(0),
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut caller_account = mock_caller_account.caller_account();
|
||||
|
||||
|
@ -1541,8 +1549,12 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let mut memory_mapping =
|
||||
MemoryMapping::new(mock_caller_account.regions.split_off(0), &config).unwrap();
|
||||
let mut memory_mapping = MemoryMapping::new(
|
||||
mock_caller_account.regions.split_off(0),
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let data_slice = mock_caller_account.data_slice();
|
||||
let len_ptr = unsafe {
|
||||
|
@ -1662,8 +1674,12 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let mut memory_mapping =
|
||||
MemoryMapping::new(mock_caller_account.regions.split_off(0), &config).unwrap();
|
||||
let mut memory_mapping = MemoryMapping::new(
|
||||
mock_caller_account.regions.split_off(0),
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let data_slice = mock_caller_account.data_slice();
|
||||
let len_ptr = unsafe {
|
||||
|
@ -1829,8 +1845,12 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let mut memory_mapping =
|
||||
MemoryMapping::new(mock_caller_account.regions.split_off(0), &config).unwrap();
|
||||
let mut memory_mapping = MemoryMapping::new(
|
||||
mock_caller_account.regions.split_off(0),
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut caller_account = mock_caller_account.caller_account();
|
||||
|
||||
|
@ -2148,7 +2168,8 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let mut memory_mapping = MemoryMapping::new(vec![region], &config).unwrap();
|
||||
let mut memory_mapping =
|
||||
MemoryMapping::new(vec![region], &config, &SBPFVersion::V2).unwrap();
|
||||
|
||||
let accounts = SyscallInvokeSignedRust::translate_accounts(
|
||||
&[
|
||||
|
|
|
@ -491,7 +491,10 @@ impl<'a> DoubleEndedIterator for MemoryChunkIterator<'a> {
|
|||
#[cfg(test)]
|
||||
#[allow(clippy::indexing_slicing)]
|
||||
mod tests {
|
||||
use {super::*, solana_rbpf::ebpf::MM_PROGRAM_START};
|
||||
use {
|
||||
super::*,
|
||||
solana_rbpf::{ebpf::MM_PROGRAM_START, elf::SBPFVersion},
|
||||
};
|
||||
|
||||
fn to_chunk_vec<'a>(
|
||||
iter: impl Iterator<Item = Result<(&'a MemoryRegion, u64, usize), Error>>,
|
||||
|
@ -507,7 +510,7 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let memory_mapping = MemoryMapping::new(vec![], &config).unwrap();
|
||||
let memory_mapping = MemoryMapping::new(vec![], &config, &SBPFVersion::V2).unwrap();
|
||||
|
||||
let mut src_chunk_iter =
|
||||
MemoryChunkIterator::new(&memory_mapping, AccessType::Load, 0, 1).unwrap();
|
||||
|
@ -521,7 +524,7 @@ mod tests {
|
|||
aligned_memory_mapping: false,
|
||||
..Config::default()
|
||||
};
|
||||
let memory_mapping = MemoryMapping::new(vec![], &config).unwrap();
|
||||
let memory_mapping = MemoryMapping::new(vec![], &config, &SBPFVersion::V2).unwrap();
|
||||
|
||||
let mut src_chunk_iter =
|
||||
MemoryChunkIterator::new(&memory_mapping, AccessType::Load, u64::MAX, 1).unwrap();
|
||||
|
@ -538,6 +541,7 @@ mod tests {
|
|||
let memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(&mem1, MM_PROGRAM_START)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -593,6 +597,7 @@ mod tests {
|
|||
let memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(&mem1, MM_PROGRAM_START)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -647,6 +652,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(&mem2, MM_PROGRAM_START + 8),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -689,6 +695,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(&mem2, MM_PROGRAM_START + 8),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -738,6 +745,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(&mem2, MM_PROGRAM_START + 8),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -762,6 +770,7 @@ mod tests {
|
|||
MemoryRegion::new_writable(&mut mem4, MM_PROGRAM_START + 6),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -795,6 +804,7 @@ mod tests {
|
|||
MemoryRegion::new_writable(&mut mem4, MM_PROGRAM_START + 6),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -825,6 +835,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(&mem2, MM_PROGRAM_START + 8),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -852,6 +863,7 @@ mod tests {
|
|||
MemoryRegion::new_writable(&mut mem4, MM_PROGRAM_START + 6),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -881,6 +893,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(&mem3, MM_PROGRAM_START + 9),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -148,6 +148,17 @@ pub fn create_program_runtime_environment<'a>(
|
|||
reject_deployment_of_broken_elfs: bool,
|
||||
debugging_features: bool,
|
||||
) -> Result<BuiltinProgram<InvokeContext<'a>>, Error> {
|
||||
let enable_alt_bn128_syscall = feature_set.is_active(&enable_alt_bn128_syscall::id());
|
||||
let enable_big_mod_exp_syscall = feature_set.is_active(&enable_big_mod_exp_syscall::id());
|
||||
let blake3_syscall_enabled = feature_set.is_active(&blake3_syscall_enabled::id());
|
||||
let curve25519_syscall_enabled = feature_set.is_active(&curve25519_syscall_enabled::id());
|
||||
let disable_fees_sysvar = feature_set.is_active(&disable_fees_sysvar::id());
|
||||
let epoch_rewards_syscall_enabled =
|
||||
feature_set.is_active(&enable_partitioned_epoch_reward::id());
|
||||
let disable_deploy_of_alloc_free_syscall = reject_deployment_of_broken_elfs
|
||||
&& feature_set.is_active(&disable_deploy_of_alloc_free_syscall::id());
|
||||
let last_restart_slot_syscall_enabled = feature_set.is_active(&last_restart_slot_sysvar::id());
|
||||
|
||||
use rand::Rng;
|
||||
// When adding new features for RBPF,
|
||||
// also add them to `Bank::apply_builtin_program_feature_transitions()`.
|
||||
|
@ -170,28 +181,13 @@ pub fn create_program_runtime_environment<'a>(
|
|||
external_internal_function_hash_collision: feature_set
|
||||
.is_active(&error_on_syscall_bpf_function_hash_collisions::id()),
|
||||
reject_callx_r10: feature_set.is_active(&reject_callx_r10::id()),
|
||||
dynamic_stack_frames: false,
|
||||
enable_sdiv: false,
|
||||
enable_sbpf_v1: true,
|
||||
enable_sbpf_v2: false,
|
||||
optimize_rodata: false,
|
||||
static_syscalls: false,
|
||||
enable_elf_vaddr: false,
|
||||
reject_rodata_stack_overlap: false,
|
||||
new_elf_parser: feature_set.is_active(&switch_to_new_elf_parser::id()),
|
||||
aligned_memory_mapping: !feature_set.is_active(&bpf_account_data_direct_mapping::id()),
|
||||
// Warning, do not use `Config::default()` so that configuration here is explicit.
|
||||
};
|
||||
|
||||
let enable_alt_bn128_syscall = feature_set.is_active(&enable_alt_bn128_syscall::id());
|
||||
let enable_big_mod_exp_syscall = feature_set.is_active(&enable_big_mod_exp_syscall::id());
|
||||
let blake3_syscall_enabled = feature_set.is_active(&blake3_syscall_enabled::id());
|
||||
let curve25519_syscall_enabled = feature_set.is_active(&curve25519_syscall_enabled::id());
|
||||
let disable_fees_sysvar = feature_set.is_active(&disable_fees_sysvar::id());
|
||||
let epoch_rewards_syscall_enabled =
|
||||
feature_set.is_active(&enable_partitioned_epoch_reward::id());
|
||||
let disable_deploy_of_alloc_free_syscall = reject_deployment_of_broken_elfs
|
||||
&& feature_set.is_active(&disable_deploy_of_alloc_free_syscall::id());
|
||||
let last_restart_slot_syscall_enabled = feature_set.is_active(&last_restart_slot_sysvar::id());
|
||||
|
||||
let mut result = BuiltinProgram::new_loader(config);
|
||||
|
||||
// Abort
|
||||
|
@ -1804,6 +1800,7 @@ mod tests {
|
|||
core::slice,
|
||||
solana_program_runtime::{invoke_context::InvokeContext, with_mock_invoke_context},
|
||||
solana_rbpf::{
|
||||
elf::SBPFVersion,
|
||||
error::EbpfError,
|
||||
memory_region::MemoryRegion,
|
||||
vm::{BuiltinFunction, Config},
|
||||
|
@ -1870,8 +1867,12 @@ mod tests {
|
|||
let data = vec![0u8; LENGTH as usize];
|
||||
let addr = data.as_ptr() as u64;
|
||||
let config = Config::default();
|
||||
let memory_mapping =
|
||||
MemoryMapping::new(vec![MemoryRegion::new_readonly(&data, START)], &config).unwrap();
|
||||
let memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(&data, START)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let cases = vec![
|
||||
(true, START, 0, addr),
|
||||
|
@ -1910,6 +1911,7 @@ mod tests {
|
|||
let memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(bytes_of(&pubkey), 0x100000000)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
let translated_pubkey =
|
||||
|
@ -1924,13 +1926,15 @@ mod tests {
|
|||
);
|
||||
let instruction = StableInstruction::from(instruction);
|
||||
let memory_region = MemoryRegion::new_readonly(bytes_of(&instruction), 0x100000000);
|
||||
let memory_mapping = MemoryMapping::new(vec![memory_region], &config).unwrap();
|
||||
let memory_mapping =
|
||||
MemoryMapping::new(vec![memory_region], &config, &SBPFVersion::V2).unwrap();
|
||||
let translated_instruction =
|
||||
translate_type::<StableInstruction>(&memory_mapping, 0x100000000, true).unwrap();
|
||||
assert_eq!(instruction, *translated_instruction);
|
||||
|
||||
let memory_region = MemoryRegion::new_readonly(&bytes_of(&instruction)[..1], 0x100000000);
|
||||
let memory_mapping = MemoryMapping::new(vec![memory_region], &config).unwrap();
|
||||
let memory_mapping =
|
||||
MemoryMapping::new(vec![memory_region], &config, &SBPFVersion::V2).unwrap();
|
||||
assert!(translate_type::<Instruction>(&memory_mapping, 0x100000000, true).is_err());
|
||||
}
|
||||
|
||||
|
@ -1945,6 +1949,7 @@ mod tests {
|
|||
let memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(&good_data, 0x100000000)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
let translated_data =
|
||||
|
@ -1957,6 +1962,7 @@ mod tests {
|
|||
let memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(&data, 0x100000000)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
let translated_data =
|
||||
|
@ -1987,6 +1993,7 @@ mod tests {
|
|||
0x100000000,
|
||||
)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
let translated_data =
|
||||
|
@ -2009,6 +2016,7 @@ mod tests {
|
|||
0x100000000,
|
||||
)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
let translated_data =
|
||||
|
@ -2026,6 +2034,7 @@ mod tests {
|
|||
let memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(string.as_bytes(), 0x100000000)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
|
@ -2051,7 +2060,7 @@ mod tests {
|
|||
fn test_syscall_abort() {
|
||||
prepare_mockup!(invoke_context, program_id, bpf_loader::id());
|
||||
let config = Config::default();
|
||||
let mut memory_mapping = MemoryMapping::new(vec![], &config).unwrap();
|
||||
let mut memory_mapping = MemoryMapping::new(vec![], &config, &SBPFVersion::V2).unwrap();
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
SyscallAbort::call(
|
||||
&mut invoke_context,
|
||||
|
@ -2076,6 +2085,7 @@ mod tests {
|
|||
let mut memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(string.as_bytes(), 0x100000000)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2120,6 +2130,7 @@ mod tests {
|
|||
let mut memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(string.as_bytes(), 0x100000000)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2194,7 +2205,7 @@ mod tests {
|
|||
|
||||
invoke_context.mock_set_remaining(cost);
|
||||
let config = Config::default();
|
||||
let mut memory_mapping = MemoryMapping::new(vec![], &config).unwrap();
|
||||
let mut memory_mapping = MemoryMapping::new(vec![], &config, &SBPFVersion::V2).unwrap();
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
SyscallLogU64::call(
|
||||
&mut invoke_context,
|
||||
|
@ -2228,6 +2239,7 @@ mod tests {
|
|||
let mut memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_readonly(bytes_of(&pubkey), 0x100000000)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2292,8 +2304,8 @@ mod tests {
|
|||
prepare_mockup!(invoke_context, program_id, bpf_loader::id());
|
||||
mock_create_vm!(vm, Vec::new(), Vec::new(), &mut invoke_context);
|
||||
let mut vm = vm.unwrap();
|
||||
let invoke_context = &mut vm.env.context_object_pointer;
|
||||
let memory_mapping = &mut vm.env.memory_mapping;
|
||||
let invoke_context = &mut vm.context_object_pointer;
|
||||
let memory_mapping = &mut vm.memory_mapping;
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
SyscallAllocFree::call(
|
||||
invoke_context,
|
||||
|
@ -2338,8 +2350,8 @@ mod tests {
|
|||
invoke_context.feature_set = Arc::new(FeatureSet::default());
|
||||
mock_create_vm!(vm, Vec::new(), Vec::new(), &mut invoke_context);
|
||||
let mut vm = vm.unwrap();
|
||||
let invoke_context = &mut vm.env.context_object_pointer;
|
||||
let memory_mapping = &mut vm.env.memory_mapping;
|
||||
let invoke_context = &mut vm.context_object_pointer;
|
||||
let memory_mapping = &mut vm.memory_mapping;
|
||||
for _ in 0..100 {
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
SyscallAllocFree::call(invoke_context, 1, 0, 0, 0, 0, memory_mapping, &mut result);
|
||||
|
@ -2364,8 +2376,8 @@ mod tests {
|
|||
prepare_mockup!(invoke_context, program_id, bpf_loader::id());
|
||||
mock_create_vm!(vm, Vec::new(), Vec::new(), &mut invoke_context);
|
||||
let mut vm = vm.unwrap();
|
||||
let invoke_context = &mut vm.env.context_object_pointer;
|
||||
let memory_mapping = &mut vm.env.memory_mapping;
|
||||
let invoke_context = &mut vm.context_object_pointer;
|
||||
let memory_mapping = &mut vm.memory_mapping;
|
||||
for _ in 0..12 {
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
SyscallAllocFree::call(invoke_context, 1, 0, 0, 0, 0, memory_mapping, &mut result);
|
||||
|
@ -2391,8 +2403,8 @@ mod tests {
|
|||
prepare_mockup!(invoke_context, program_id, bpf_loader::id());
|
||||
mock_create_vm!(vm, Vec::new(), Vec::new(), &mut invoke_context);
|
||||
let mut vm = vm.unwrap();
|
||||
let invoke_context = &mut vm.env.context_object_pointer;
|
||||
let memory_mapping = &mut vm.env.memory_mapping;
|
||||
let invoke_context = &mut vm.context_object_pointer;
|
||||
let memory_mapping = &mut vm.memory_mapping;
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
SyscallAllocFree::call(
|
||||
invoke_context,
|
||||
|
@ -2447,6 +2459,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(bytes2.as_bytes(), bytes_to_hash[1].vm_addr),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2554,6 +2567,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(&invalid_bytes, invalid_bytes_va),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2632,6 +2646,7 @@ mod tests {
|
|||
MemoryRegion::new_readonly(&invalid_bytes, invalid_bytes_va),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2726,6 +2741,7 @@ mod tests {
|
|||
MemoryRegion::new_writable(bytes_of_slice_mut(&mut result_point), result_point_va),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2896,6 +2912,7 @@ mod tests {
|
|||
MemoryRegion::new_writable(bytes_of_slice_mut(&mut result_point), result_point_va),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3081,6 +3098,7 @@ mod tests {
|
|||
MemoryRegion::new_writable(bytes_of_slice_mut(&mut result_point), result_point_va),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3235,6 +3253,7 @@ mod tests {
|
|||
got_clock_va,
|
||||
)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3272,6 +3291,7 @@ mod tests {
|
|||
got_epochschedule_va,
|
||||
)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3310,6 +3330,7 @@ mod tests {
|
|||
got_fees_va,
|
||||
)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3343,6 +3364,7 @@ mod tests {
|
|||
got_rent_va,
|
||||
)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3378,6 +3400,7 @@ mod tests {
|
|||
got_rewards_va,
|
||||
)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3440,7 +3463,7 @@ mod tests {
|
|||
bytes_of_slice(&mock_slices),
|
||||
SEEDS_VA,
|
||||
));
|
||||
let mut memory_mapping = MemoryMapping::new(regions, &config).unwrap();
|
||||
let mut memory_mapping = MemoryMapping::new(regions, &config, &SBPFVersion::V2).unwrap();
|
||||
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
syscall(
|
||||
|
@ -3506,6 +3529,7 @@ mod tests {
|
|||
MemoryRegion::new_writable(&mut id_buffer, PROGRAM_ID_VA),
|
||||
],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -3611,6 +3635,7 @@ mod tests {
|
|||
let mut memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_writable(&mut memory, VM_BASE_ADDRESS)],
|
||||
&config,
|
||||
&SBPFVersion::V2,
|
||||
)
|
||||
.unwrap();
|
||||
let processed_sibling_instruction = translate_type_mut::<ProcessedSiblingInstruction>(
|
||||
|
|
|
@ -97,12 +97,9 @@ pub fn load_program_from_account(
|
|||
.unwrap_or(0),
|
||||
external_internal_function_hash_collision: true,
|
||||
reject_callx_r10: true,
|
||||
dynamic_stack_frames: true,
|
||||
enable_sdiv: true,
|
||||
enable_sbpf_v1: false,
|
||||
enable_sbpf_v2: true,
|
||||
optimize_rodata: true,
|
||||
static_syscalls: true,
|
||||
enable_elf_vaddr: true,
|
||||
reject_rodata_stack_overlap: true,
|
||||
new_elf_parser: true,
|
||||
aligned_memory_mapping: true,
|
||||
// Warning, do not use `Config::default()` so that configuration here is explicit.
|
||||
|
@ -144,8 +141,9 @@ fn calculate_heap_cost(heap_size: u64, heap_cost: u64) -> u64 {
|
|||
pub fn create_vm<'a, 'b>(
|
||||
invoke_context: &'a mut InvokeContext<'b>,
|
||||
program: &'a Executable<RequisiteVerifier, InvokeContext<'b>>,
|
||||
) -> Result<EbpfVm<'a, RequisiteVerifier, InvokeContext<'b>>, Box<dyn std::error::Error>> {
|
||||
) -> Result<EbpfVm<'a, InvokeContext<'b>>, Box<dyn std::error::Error>> {
|
||||
let config = program.get_config();
|
||||
let sbpf_version = program.get_sbpf_version();
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
let heap_size = compute_budget.heap_size.unwrap_or(HEAP_LENGTH);
|
||||
invoke_context.consume_checked(calculate_heap_cost(
|
||||
|
@ -163,22 +161,28 @@ pub fn create_vm<'a, 'b>(
|
|||
MemoryRegion::new_writable(heap.as_slice_mut(), ebpf::MM_HEAP_START),
|
||||
];
|
||||
let log_collector = invoke_context.get_log_collector();
|
||||
let memory_mapping = MemoryMapping::new(regions, config).map_err(|err| {
|
||||
let memory_mapping = MemoryMapping::new(regions, config, sbpf_version).map_err(|err| {
|
||||
ic_logger_msg!(log_collector, "Failed to create SBF VM: {}", err);
|
||||
Box::new(InstructionError::ProgramEnvironmentSetupFailure)
|
||||
})?;
|
||||
Ok(EbpfVm::new(
|
||||
program,
|
||||
config,
|
||||
sbpf_version,
|
||||
invoke_context,
|
||||
memory_mapping,
|
||||
stack_len,
|
||||
))
|
||||
}
|
||||
|
||||
fn execute(
|
||||
invoke_context: &mut InvokeContext,
|
||||
program: &Executable<RequisiteVerifier, InvokeContext<'static>>,
|
||||
fn execute<'a, 'b: 'a>(
|
||||
invoke_context: &'a mut InvokeContext<'b>,
|
||||
executable: &'a Executable<RequisiteVerifier, InvokeContext<'static>>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
// We dropped the lifetime tracking in the Executor by setting it to 'static,
|
||||
// thus we need to reintroduce the correct lifetime of InvokeContext here again.
|
||||
let executable = unsafe {
|
||||
std::mem::transmute::<_, &'a Executable<RequisiteVerifier, InvokeContext<'b>>>(executable)
|
||||
};
|
||||
let log_collector = invoke_context.get_log_collector();
|
||||
let stack_height = invoke_context.get_stack_height();
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
|
@ -187,21 +191,16 @@ fn execute(
|
|||
#[cfg(any(target_os = "windows", not(target_arch = "x86_64")))]
|
||||
let use_jit = false;
|
||||
#[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
|
||||
let use_jit = program.get_compiled_program().is_some();
|
||||
let use_jit = executable.get_compiled_program().is_some();
|
||||
|
||||
let compute_meter_prev = invoke_context.get_remaining();
|
||||
let mut create_vm_time = Measure::start("create_vm");
|
||||
let mut vm = create_vm(
|
||||
invoke_context,
|
||||
// We dropped the lifetime tracking in the Executor by setting it to 'static,
|
||||
// thus we need to reintroduce the correct lifetime of InvokeContext here again.
|
||||
unsafe { std::mem::transmute(program) },
|
||||
)?;
|
||||
let mut vm = create_vm(invoke_context, executable)?;
|
||||
create_vm_time.stop();
|
||||
|
||||
let mut execute_time = Measure::start("execute");
|
||||
stable_log::program_invoke(&log_collector, &program_id, stack_height);
|
||||
let (compute_units_consumed, result) = vm.execute_program(!use_jit);
|
||||
let (compute_units_consumed, result) = vm.execute_program(executable, !use_jit);
|
||||
drop(vm);
|
||||
ic_logger_msg!(
|
||||
log_collector,
|
||||
|
|
|
@ -6355,9 +6355,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "solana_rbpf"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ae90c406f0a2d4a15f08d16c8b64f37997a57611fec0a89f1277854166996e8"
|
||||
checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef"
|
||||
dependencies = [
|
||||
"byteorder 1.4.3",
|
||||
"combine",
|
||||
|
|
|
@ -24,7 +24,7 @@ num-traits = "0.2"
|
|||
rand = "0.7"
|
||||
serde = "1.0.112"
|
||||
serde_json = "1.0.56"
|
||||
solana_rbpf = "=0.5.0"
|
||||
solana_rbpf = "=0.6.0"
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.17.0" }
|
||||
solana-address-lookup-table-program = { path = "../../programs/address-lookup-table", version = "=1.17.0" }
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.17.0" }
|
||||
|
|
|
@ -144,10 +144,9 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
|||
let mut vm = vm.unwrap();
|
||||
|
||||
println!("Interpreted:");
|
||||
vm.env
|
||||
.context_object_pointer
|
||||
vm.context_object_pointer
|
||||
.mock_set_remaining(std::i64::MAX as u64);
|
||||
let (instructions, result) = vm.execute_program(true);
|
||||
let (instructions, result) = vm.execute_program(&verified_executable, true);
|
||||
assert_eq!(SUCCESS, result.unwrap());
|
||||
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||
assert_eq!(
|
||||
|
@ -156,10 +155,9 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
|||
);
|
||||
|
||||
bencher.iter(|| {
|
||||
vm.env
|
||||
.context_object_pointer
|
||||
vm.context_object_pointer
|
||||
.mock_set_remaining(std::i64::MAX as u64);
|
||||
vm.execute_program(true).1.unwrap();
|
||||
vm.execute_program(&verified_executable, true).1.unwrap();
|
||||
});
|
||||
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
|
||||
println!(" {:?} instructions", instructions);
|
||||
|
@ -170,7 +168,10 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
|||
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
|
||||
|
||||
println!("JIT to native:");
|
||||
assert_eq!(SUCCESS, vm.execute_program(false).1.unwrap());
|
||||
assert_eq!(
|
||||
SUCCESS,
|
||||
vm.execute_program(&verified_executable, false).1.unwrap()
|
||||
);
|
||||
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||
assert_eq!(
|
||||
ARMSTRONG_EXPECTED,
|
||||
|
@ -178,10 +179,9 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
|||
);
|
||||
|
||||
bencher.iter(|| {
|
||||
vm.env
|
||||
.context_object_pointer
|
||||
vm.context_object_pointer
|
||||
.mock_set_remaining(std::i64::MAX as u64);
|
||||
vm.execute_program(false).1.unwrap();
|
||||
vm.execute_program(&verified_executable, false).1.unwrap();
|
||||
});
|
||||
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
|
||||
println!(" {:?} instructions", instructions);
|
||||
|
@ -324,17 +324,17 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
|||
let mut vm = vm.unwrap();
|
||||
|
||||
let mut measure = Measure::start("tune");
|
||||
let (instructions, _result) = vm.execute_program(true);
|
||||
let (instructions, _result) = vm.execute_program(&verified_executable, true);
|
||||
measure.stop();
|
||||
|
||||
assert_eq!(
|
||||
0,
|
||||
vm.env.context_object_pointer.get_remaining(),
|
||||
vm.context_object_pointer.get_remaining(),
|
||||
"Tuner must consume the whole budget"
|
||||
);
|
||||
println!(
|
||||
"{:?} compute units took {:?} us ({:?} instructions)",
|
||||
BUDGET - vm.env.context_object_pointer.get_remaining(),
|
||||
BUDGET - vm.context_object_pointer.get_remaining(),
|
||||
measure.as_us(),
|
||||
instructions,
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue