Bump solana_rbpf to v0.2.38 (#29137)
* Refactor register_syscalls() => create_loader(). * Bumps solana_rbpf to v0.2.38 * Replaces Config::encrypt_environment_registers by Config::runtime_environment_key. * Adds pc parameter to MemoryMapping::map() * Removes debugger from rbpf CLI. * Adds debugger to rbpf CLI again. * Renames vm.context_object => vm.env.context_object_pointer. * Renames SyscallRegistry => BuiltInProgram. Renames SyscallFunction => BuiltInFunction. Renames register_syscall_by_name() => register_function_by_name(). * Removes ContextObject from Analysis. * Renames Config::error_on_syscall_bpf_function_hash_collisions => Config::external_internal_function_hash_collision.
This commit is contained in:
parent
254d3f20b2
commit
013f784e92
|
@ -6992,9 +6992,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana_rbpf"
|
name = "solana_rbpf"
|
||||||
version = "0.2.37"
|
version = "0.2.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0669f9f5c355899600732451c65cc717d0ef0c53717749f03520337c824fd8a1"
|
checksum = "a4e9e5085099858adba23d0a0b5298da8803f89999cb567ecafab9c916cdf53d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"combine",
|
"combine",
|
||||||
|
@ -7007,6 +7007,7 @@ dependencies = [
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"scroll",
|
"scroll",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -55,7 +55,7 @@ solana-tpu-client = { path = "../tpu-client", version = "=1.15.0" }
|
||||||
solana-transaction-status = { path = "../transaction-status", version = "=1.15.0" }
|
solana-transaction-status = { path = "../transaction-status", version = "=1.15.0" }
|
||||||
solana-version = { path = "../version", version = "=1.15.0" }
|
solana-version = { path = "../version", version = "=1.15.0" }
|
||||||
solana-vote-program = { path = "../programs/vote", version = "=1.15.0" }
|
solana-vote-program = { path = "../programs/vote", version = "=1.15.0" }
|
||||||
solana_rbpf = "=0.2.37"
|
solana_rbpf = "=0.2.38"
|
||||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
tiny-bip39 = "0.8.2"
|
tiny-bip39 = "0.8.2"
|
||||||
|
|
|
@ -10,7 +10,7 @@ use {
|
||||||
clap::{App, AppSettings, Arg, ArgMatches, SubCommand},
|
clap::{App, AppSettings, Arg, ArgMatches, SubCommand},
|
||||||
log::*,
|
log::*,
|
||||||
solana_account_decoder::{UiAccountEncoding, UiDataSliceConfig},
|
solana_account_decoder::{UiAccountEncoding, UiDataSliceConfig},
|
||||||
solana_bpf_loader_program::syscalls::register_syscalls,
|
solana_bpf_loader_program::syscalls::create_loader,
|
||||||
solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*},
|
solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*},
|
||||||
solana_cli_output::{
|
solana_cli_output::{
|
||||||
CliProgram, CliProgramAccountType, CliProgramAuthority, CliProgramBuffer, CliProgramId,
|
CliProgram, CliProgramAccountType, CliProgramAuthority, CliProgramBuffer, CliProgramId,
|
||||||
|
@ -21,12 +21,8 @@ use {
|
||||||
connection_cache::ConnectionCache,
|
connection_cache::ConnectionCache,
|
||||||
tpu_client::{TpuClient, TpuClientConfig},
|
tpu_client::{TpuClient, TpuClientConfig},
|
||||||
},
|
},
|
||||||
solana_program_runtime::invoke_context::InvokeContext,
|
solana_program_runtime::{compute_budget::ComputeBudget, invoke_context::InvokeContext},
|
||||||
solana_rbpf::{
|
solana_rbpf::{elf::Executable, verifier::RequisiteVerifier, vm::VerifiedExecutable},
|
||||||
elf::Executable,
|
|
||||||
verifier::RequisiteVerifier,
|
|
||||||
vm::{Config, VerifiedExecutable},
|
|
||||||
},
|
|
||||||
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
||||||
solana_rpc_client::rpc_client::RpcClient,
|
solana_rpc_client::rpc_client::RpcClient,
|
||||||
solana_rpc_client_api::{
|
solana_rpc_client_api::{
|
||||||
|
@ -1994,15 +1990,16 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
|
||||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||||
|
|
||||||
// Verify the program
|
// Verify the program
|
||||||
let executable = Executable::<InvokeContext>::from_elf(
|
let loader = create_loader(
|
||||||
&program_data,
|
&invoke_context.feature_set,
|
||||||
Config {
|
&ComputeBudget::default(),
|
||||||
reject_broken_elfs: true,
|
true,
|
||||||
..Config::default()
|
true,
|
||||||
},
|
false,
|
||||||
register_syscalls(&invoke_context.feature_set, true).unwrap(),
|
|
||||||
)
|
)
|
||||||
.map_err(|err| format!("ELF error: {err}"))?;
|
.unwrap();
|
||||||
|
let executable = Executable::<InvokeContext>::from_elf(&program_data, loader)
|
||||||
|
.map_err(|err| format!("ELF error: {err}"))?;
|
||||||
|
|
||||||
let _ = VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
let _ = VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
||||||
.map_err(|err| format!("ELF error: {err}"))?;
|
.map_err(|err| format!("ELF error: {err}"))?;
|
||||||
|
|
|
@ -26,7 +26,7 @@ solana-frozen-abi = { path = "../frozen-abi", version = "=1.15.0" }
|
||||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.15.0" }
|
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.15.0" }
|
||||||
solana-measure = { path = "../measure", version = "=1.15.0" }
|
solana-measure = { path = "../measure", version = "=1.15.0" }
|
||||||
solana-metrics = { path = "../metrics", version = "=1.15.0" }
|
solana-metrics = { path = "../metrics", version = "=1.15.0" }
|
||||||
solana_rbpf = "=0.2.37"
|
solana_rbpf = "=0.2.38"
|
||||||
solana-sdk = { path = "../sdk", version = "=1.15.0" }
|
solana-sdk = { path = "../sdk", version = "=1.15.0" }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
|
|
|
@ -14,16 +14,14 @@ bincode = "1.3.3"
|
||||||
byteorder = "1.4.3"
|
byteorder = "1.4.3"
|
||||||
libsecp256k1 = "0.6.0"
|
libsecp256k1 = "0.6.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
|
rand = "0.7.3"
|
||||||
solana-measure = { path = "../../measure", version = "=1.15.0" }
|
solana-measure = { path = "../../measure", version = "=1.15.0" }
|
||||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.15.0" }
|
solana-program-runtime = { path = "../../program-runtime", version = "=1.15.0" }
|
||||||
solana-sdk = { path = "../../sdk", version = "=1.15.0" }
|
solana-sdk = { path = "../../sdk", version = "=1.15.0" }
|
||||||
solana-zk-token-sdk = { path = "../../zk-token-sdk", version = "=1.15.0" }
|
solana-zk-token-sdk = { path = "../../zk-token-sdk", version = "=1.15.0" }
|
||||||
solana_rbpf = "=0.2.37"
|
solana_rbpf = "=0.2.38"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
rand = "0.7.3"
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
name = "solana_bpf_loader_program"
|
name = "solana_bpf_loader_program"
|
||||||
|
|
|
@ -33,7 +33,7 @@ use {
|
||||||
error::{EbpfError, UserDefinedError},
|
error::{EbpfError, UserDefinedError},
|
||||||
memory_region::MemoryRegion,
|
memory_region::MemoryRegion,
|
||||||
verifier::{RequisiteVerifier, VerifierError},
|
verifier::{RequisiteVerifier, VerifierError},
|
||||||
vm::{Config, ContextObject, EbpfVm, ProgramResult, VerifiedExecutable},
|
vm::{ContextObject, EbpfVm, ProgramResult, VerifiedExecutable},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
bpf_loader, bpf_loader_deprecated,
|
bpf_loader, bpf_loader_deprecated,
|
||||||
|
@ -43,9 +43,8 @@ use {
|
||||||
cap_accounts_data_allocations_per_transaction, cap_bpf_program_instruction_accounts,
|
cap_accounts_data_allocations_per_transaction, cap_bpf_program_instruction_accounts,
|
||||||
check_slice_translation_size, disable_deploy_of_alloc_free_syscall,
|
check_slice_translation_size, disable_deploy_of_alloc_free_syscall,
|
||||||
disable_deprecated_loader, enable_bpf_loader_extend_program_ix,
|
disable_deprecated_loader, enable_bpf_loader_extend_program_ix,
|
||||||
enable_bpf_loader_set_authority_checked_ix,
|
enable_bpf_loader_set_authority_checked_ix, limit_max_instruction_trace_length,
|
||||||
error_on_syscall_bpf_function_hash_collisions, limit_max_instruction_trace_length,
|
FeatureSet,
|
||||||
reject_callx_r10, FeatureSet,
|
|
||||||
},
|
},
|
||||||
instruction::{AccountMeta, InstructionError},
|
instruction::{AccountMeta, InstructionError},
|
||||||
loader_instruction::LoaderInstruction,
|
loader_instruction::LoaderInstruction,
|
||||||
|
@ -132,45 +131,24 @@ fn create_executor_from_bytes(
|
||||||
let mut register_syscalls_time = Measure::start("register_syscalls_time");
|
let mut register_syscalls_time = Measure::start("register_syscalls_time");
|
||||||
let disable_deploy_of_alloc_free_syscall = reject_deployment_of_broken_elfs
|
let disable_deploy_of_alloc_free_syscall = reject_deployment_of_broken_elfs
|
||||||
&& feature_set.is_active(&disable_deploy_of_alloc_free_syscall::id());
|
&& feature_set.is_active(&disable_deploy_of_alloc_free_syscall::id());
|
||||||
let register_syscall_result =
|
let loader = syscalls::create_loader(
|
||||||
syscalls::register_syscalls(feature_set, disable_deploy_of_alloc_free_syscall);
|
feature_set,
|
||||||
register_syscalls_time.stop();
|
compute_budget,
|
||||||
create_executor_metrics.register_syscalls_us = register_syscalls_time.as_us();
|
reject_deployment_of_broken_elfs,
|
||||||
let syscall_registry = register_syscall_result.map_err(|e| {
|
disable_deploy_of_alloc_free_syscall,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
ic_logger_msg!(log_collector, "Failed to register syscalls: {}", e);
|
ic_logger_msg!(log_collector, "Failed to register syscalls: {}", e);
|
||||||
InstructionError::ProgramEnvironmentSetupFailure
|
InstructionError::ProgramEnvironmentSetupFailure
|
||||||
})?;
|
})?;
|
||||||
let config = Config {
|
register_syscalls_time.stop();
|
||||||
max_call_depth: compute_budget.max_call_depth,
|
create_executor_metrics.register_syscalls_us = register_syscalls_time.as_us();
|
||||||
stack_frame_size: compute_budget.stack_frame_size,
|
|
||||||
enable_stack_frame_gaps: true,
|
|
||||||
instruction_meter_checkpoint_distance: 10000,
|
|
||||||
enable_instruction_meter: true,
|
|
||||||
enable_instruction_tracing: false,
|
|
||||||
enable_symbol_and_section_labels: false,
|
|
||||||
reject_broken_elfs: reject_deployment_of_broken_elfs,
|
|
||||||
noop_instruction_rate: 256,
|
|
||||||
sanitize_user_provided_values: true,
|
|
||||||
encrypt_environment_registers: true,
|
|
||||||
syscall_bpf_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,
|
|
||||||
optimize_rodata: false,
|
|
||||||
static_syscalls: false,
|
|
||||||
enable_elf_vaddr: false,
|
|
||||||
reject_rodata_stack_overlap: false,
|
|
||||||
new_elf_parser: false,
|
|
||||||
aligned_memory_mapping: true,
|
|
||||||
// Warning, do not use `Config::default()` so that configuration here is explicit.
|
|
||||||
};
|
|
||||||
let mut load_elf_time = Measure::start("load_elf_time");
|
let mut load_elf_time = Measure::start("load_elf_time");
|
||||||
let executable = Executable::<InvokeContext>::from_elf(programdata, config, syscall_registry)
|
let executable = Executable::<InvokeContext>::from_elf(programdata, loader).map_err(|err| {
|
||||||
.map_err(|err| {
|
ic_logger_msg!(log_collector, "{}", err);
|
||||||
ic_logger_msg!(log_collector, "{}", err);
|
InstructionError::InvalidAccountData
|
||||||
InstructionError::InvalidAccountData
|
});
|
||||||
});
|
|
||||||
load_elf_time.stop();
|
load_elf_time.stop();
|
||||||
create_executor_metrics.load_elf_us = load_elf_time.as_us();
|
create_executor_metrics.load_elf_us = load_elf_time.as_us();
|
||||||
let executable = executable?;
|
let executable = executable?;
|
||||||
|
@ -1527,7 +1505,7 @@ mod tests {
|
||||||
solana_rbpf::{
|
solana_rbpf::{
|
||||||
ebpf::MM_INPUT_START,
|
ebpf::MM_INPUT_START,
|
||||||
verifier::Verifier,
|
verifier::Verifier,
|
||||||
vm::{ContextObject, FunctionRegistry, SyscallRegistry},
|
vm::{BuiltInProgram, Config, ContextObject, FunctionRegistry},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{
|
account::{
|
||||||
|
@ -1611,13 +1589,10 @@ mod tests {
|
||||||
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit
|
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit
|
||||||
];
|
];
|
||||||
let mut input_mem = [0x00];
|
let mut input_mem = [0x00];
|
||||||
let config = Config::default();
|
|
||||||
let syscall_registry = SyscallRegistry::default();
|
|
||||||
let bpf_functions = std::collections::BTreeMap::<u32, (usize, String)>::new();
|
let bpf_functions = std::collections::BTreeMap::<u32, (usize, String)>::new();
|
||||||
let executable = Executable::<TestContextObject>::from_text_bytes(
|
let executable = Executable::<TestContextObject>::from_text_bytes(
|
||||||
program,
|
program,
|
||||||
config,
|
Arc::new(BuiltInProgram::new_loader(Config::default())),
|
||||||
syscall_registry,
|
|
||||||
bpf_functions,
|
bpf_functions,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -13,12 +13,13 @@ pub use self::{
|
||||||
use {
|
use {
|
||||||
crate::BpfError,
|
crate::BpfError,
|
||||||
solana_program_runtime::{
|
solana_program_runtime::{
|
||||||
ic_logger_msg, ic_msg, invoke_context::InvokeContext, stable_log, timings::ExecuteTimings,
|
compute_budget::ComputeBudget, ic_logger_msg, ic_msg, invoke_context::InvokeContext,
|
||||||
|
stable_log, timings::ExecuteTimings,
|
||||||
},
|
},
|
||||||
solana_rbpf::{
|
solana_rbpf::{
|
||||||
error::EbpfError,
|
error::EbpfError,
|
||||||
memory_region::{AccessType, MemoryMapping},
|
memory_region::{AccessType, MemoryMapping},
|
||||||
vm::{ProgramResult, SyscallRegistry},
|
vm::{BuiltInProgram, Config, ProgramResult, PROGRAM_ENVIRONMENT_KEY_SHIFT},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{ReadableAccount, WritableAccount},
|
account::{ReadableAccount, WritableAccount},
|
||||||
|
@ -36,7 +37,8 @@ use {
|
||||||
check_syscall_outputs_do_not_overlap, curve25519_syscall_enabled,
|
check_syscall_outputs_do_not_overlap, curve25519_syscall_enabled,
|
||||||
disable_cpi_setting_executable_and_rent_epoch, disable_fees_sysvar,
|
disable_cpi_setting_executable_and_rent_epoch, disable_fees_sysvar,
|
||||||
enable_alt_bn128_syscall, enable_early_verification_of_account_modifications,
|
enable_alt_bn128_syscall, enable_early_verification_of_account_modifications,
|
||||||
libsecp256k1_0_5_upgrade_enabled, limit_secp256k1_recovery_id,
|
error_on_syscall_bpf_function_hash_collisions, libsecp256k1_0_5_upgrade_enabled,
|
||||||
|
limit_secp256k1_recovery_id, reject_callx_r10,
|
||||||
stop_sibling_instruction_search_at_parent,
|
stop_sibling_instruction_search_at_parent,
|
||||||
},
|
},
|
||||||
hash::{Hasher, HASH_BYTES},
|
hash::{Hasher, HASH_BYTES},
|
||||||
|
@ -136,155 +138,180 @@ fn consume_compute_meter(invoke_context: &InvokeContext, amount: u64) -> Result<
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! register_feature_gated_syscall {
|
macro_rules! register_feature_gated_function {
|
||||||
($syscall_registry:expr, $is_feature_active:expr, $name:expr, $call:expr $(,)?) => {
|
($result:expr, $is_feature_active:expr, $name:expr, $call:expr $(,)?) => {
|
||||||
if $is_feature_active {
|
if $is_feature_active {
|
||||||
$syscall_registry.register_syscall_by_name($name, $call)
|
$result.register_function_by_name($name, $call)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_syscalls<'a>(
|
pub fn create_loader<'a>(
|
||||||
feature_set: &FeatureSet,
|
feature_set: &FeatureSet,
|
||||||
|
compute_budget: &ComputeBudget,
|
||||||
|
reject_deployment_of_broken_elfs: bool,
|
||||||
disable_deploy_of_alloc_free_syscall: bool,
|
disable_deploy_of_alloc_free_syscall: bool,
|
||||||
) -> Result<SyscallRegistry<InvokeContext<'a>>, EbpfError> {
|
debugging_features: bool,
|
||||||
|
) -> Result<Arc<BuiltInProgram<InvokeContext<'a>>>, EbpfError> {
|
||||||
|
use rand::Rng;
|
||||||
|
let config = Config {
|
||||||
|
max_call_depth: compute_budget.max_call_depth,
|
||||||
|
stack_frame_size: compute_budget.stack_frame_size,
|
||||||
|
enable_stack_frame_gaps: true,
|
||||||
|
instruction_meter_checkpoint_distance: 10000,
|
||||||
|
enable_instruction_meter: true,
|
||||||
|
enable_instruction_tracing: debugging_features,
|
||||||
|
enable_symbol_and_section_labels: debugging_features,
|
||||||
|
reject_broken_elfs: reject_deployment_of_broken_elfs,
|
||||||
|
noop_instruction_rate: 256,
|
||||||
|
sanitize_user_provided_values: true,
|
||||||
|
runtime_environment_key: rand::thread_rng()
|
||||||
|
.gen::<i32>()
|
||||||
|
.checked_shr(PROGRAM_ENVIRONMENT_KEY_SHIFT)
|
||||||
|
.unwrap_or(0),
|
||||||
|
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,
|
||||||
|
optimize_rodata: false,
|
||||||
|
static_syscalls: false,
|
||||||
|
enable_elf_vaddr: false,
|
||||||
|
reject_rodata_stack_overlap: false,
|
||||||
|
new_elf_parser: false,
|
||||||
|
aligned_memory_mapping: true,
|
||||||
|
// 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_alt_bn128_syscall = feature_set.is_active(&enable_alt_bn128_syscall::id());
|
||||||
let blake3_syscall_enabled = feature_set.is_active(&blake3_syscall_enabled::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 curve25519_syscall_enabled = feature_set.is_active(&curve25519_syscall_enabled::id());
|
||||||
let disable_fees_sysvar = feature_set.is_active(&disable_fees_sysvar::id());
|
let disable_fees_sysvar = feature_set.is_active(&disable_fees_sysvar::id());
|
||||||
let is_abi_v2 = false;
|
let is_abi_v2 = false;
|
||||||
|
|
||||||
let mut syscall_registry = SyscallRegistry::default();
|
let mut result = BuiltInProgram::new_loader(config);
|
||||||
|
|
||||||
// Abort
|
// Abort
|
||||||
syscall_registry.register_syscall_by_name(b"abort", SyscallAbort::call)?;
|
result.register_function_by_name("abort", SyscallAbort::call)?;
|
||||||
|
|
||||||
// Panic
|
// Panic
|
||||||
syscall_registry.register_syscall_by_name(b"sol_panic_", SyscallPanic::call)?;
|
result.register_function_by_name("sol_panic_", SyscallPanic::call)?;
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
syscall_registry.register_syscall_by_name(b"sol_log_", SyscallLog::call)?;
|
result.register_function_by_name("sol_log_", SyscallLog::call)?;
|
||||||
syscall_registry.register_syscall_by_name(b"sol_log_64_", SyscallLogU64::call)?;
|
result.register_function_by_name("sol_log_64_", SyscallLogU64::call)?;
|
||||||
syscall_registry
|
result.register_function_by_name("sol_log_compute_units_", SyscallLogBpfComputeUnits::call)?;
|
||||||
.register_syscall_by_name(b"sol_log_compute_units_", SyscallLogBpfComputeUnits::call)?;
|
result.register_function_by_name("sol_log_pubkey", SyscallLogPubkey::call)?;
|
||||||
syscall_registry.register_syscall_by_name(b"sol_log_pubkey", SyscallLogPubkey::call)?;
|
|
||||||
|
|
||||||
// Program defined addresses (PDA)
|
// Program defined addresses (PDA)
|
||||||
syscall_registry.register_syscall_by_name(
|
result.register_function_by_name(
|
||||||
b"sol_create_program_address",
|
"sol_create_program_address",
|
||||||
SyscallCreateProgramAddress::call,
|
SyscallCreateProgramAddress::call,
|
||||||
)?;
|
)?;
|
||||||
syscall_registry.register_syscall_by_name(
|
result.register_function_by_name(
|
||||||
b"sol_try_find_program_address",
|
"sol_try_find_program_address",
|
||||||
SyscallTryFindProgramAddress::call,
|
SyscallTryFindProgramAddress::call,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Sha256
|
// Sha256
|
||||||
syscall_registry.register_syscall_by_name(b"sol_sha256", SyscallSha256::call)?;
|
result.register_function_by_name("sol_sha256", SyscallSha256::call)?;
|
||||||
|
|
||||||
// Keccak256
|
// Keccak256
|
||||||
syscall_registry.register_syscall_by_name(b"sol_keccak256", SyscallKeccak256::call)?;
|
result.register_function_by_name("sol_keccak256", SyscallKeccak256::call)?;
|
||||||
|
|
||||||
// Secp256k1 Recover
|
// Secp256k1 Recover
|
||||||
syscall_registry
|
result.register_function_by_name("sol_secp256k1_recover", SyscallSecp256k1Recover::call)?;
|
||||||
.register_syscall_by_name(b"sol_secp256k1_recover", SyscallSecp256k1Recover::call)?;
|
|
||||||
|
|
||||||
// Blake3
|
// Blake3
|
||||||
register_feature_gated_syscall!(
|
register_feature_gated_function!(
|
||||||
syscall_registry,
|
result,
|
||||||
blake3_syscall_enabled,
|
blake3_syscall_enabled,
|
||||||
b"sol_blake3",
|
"sol_blake3",
|
||||||
SyscallBlake3::call,
|
SyscallBlake3::call,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Elliptic Curve Operations
|
// Elliptic Curve Operations
|
||||||
register_feature_gated_syscall!(
|
register_feature_gated_function!(
|
||||||
syscall_registry,
|
result,
|
||||||
curve25519_syscall_enabled,
|
curve25519_syscall_enabled,
|
||||||
b"sol_curve_validate_point",
|
"sol_curve_validate_point",
|
||||||
SyscallCurvePointValidation::call,
|
SyscallCurvePointValidation::call,
|
||||||
)?;
|
)?;
|
||||||
register_feature_gated_syscall!(
|
register_feature_gated_function!(
|
||||||
syscall_registry,
|
result,
|
||||||
curve25519_syscall_enabled,
|
curve25519_syscall_enabled,
|
||||||
b"sol_curve_group_op",
|
"sol_curve_group_op",
|
||||||
SyscallCurveGroupOps::call,
|
SyscallCurveGroupOps::call,
|
||||||
)?;
|
)?;
|
||||||
register_feature_gated_syscall!(
|
register_feature_gated_function!(
|
||||||
syscall_registry,
|
result,
|
||||||
curve25519_syscall_enabled,
|
curve25519_syscall_enabled,
|
||||||
b"sol_curve_multiscalar_mul",
|
"sol_curve_multiscalar_mul",
|
||||||
SyscallCurveMultiscalarMultiplication::call,
|
SyscallCurveMultiscalarMultiplication::call,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Sysvars
|
// Sysvars
|
||||||
syscall_registry
|
result.register_function_by_name("sol_get_clock_sysvar", SyscallGetClockSysvar::call)?;
|
||||||
.register_syscall_by_name(b"sol_get_clock_sysvar", SyscallGetClockSysvar::call)?;
|
result.register_function_by_name(
|
||||||
syscall_registry.register_syscall_by_name(
|
"sol_get_epoch_schedule_sysvar",
|
||||||
b"sol_get_epoch_schedule_sysvar",
|
|
||||||
SyscallGetEpochScheduleSysvar::call,
|
SyscallGetEpochScheduleSysvar::call,
|
||||||
)?;
|
)?;
|
||||||
register_feature_gated_syscall!(
|
register_feature_gated_function!(
|
||||||
syscall_registry,
|
result,
|
||||||
!disable_fees_sysvar,
|
!disable_fees_sysvar,
|
||||||
b"sol_get_fees_sysvar",
|
"sol_get_fees_sysvar",
|
||||||
SyscallGetFeesSysvar::call,
|
SyscallGetFeesSysvar::call,
|
||||||
)?;
|
)?;
|
||||||
syscall_registry
|
result.register_function_by_name("sol_get_rent_sysvar", SyscallGetRentSysvar::call)?;
|
||||||
.register_syscall_by_name(b"sol_get_rent_sysvar", SyscallGetRentSysvar::call)?;
|
|
||||||
|
|
||||||
// Memory ops
|
// Memory ops
|
||||||
syscall_registry.register_syscall_by_name(b"sol_memcpy_", SyscallMemcpy::call)?;
|
result.register_function_by_name("sol_memcpy_", SyscallMemcpy::call)?;
|
||||||
syscall_registry.register_syscall_by_name(b"sol_memmove_", SyscallMemmove::call)?;
|
result.register_function_by_name("sol_memmove_", SyscallMemmove::call)?;
|
||||||
syscall_registry.register_syscall_by_name(b"sol_memcmp_", SyscallMemcmp::call)?;
|
result.register_function_by_name("sol_memcmp_", SyscallMemcmp::call)?;
|
||||||
syscall_registry.register_syscall_by_name(b"sol_memset_", SyscallMemset::call)?;
|
result.register_function_by_name("sol_memset_", SyscallMemset::call)?;
|
||||||
|
|
||||||
if !is_abi_v2 {
|
if !is_abi_v2 {
|
||||||
// Processed sibling instructions
|
// Processed sibling instructions
|
||||||
syscall_registry.register_syscall_by_name(
|
result.register_function_by_name(
|
||||||
b"sol_get_processed_sibling_instruction",
|
"sol_get_processed_sibling_instruction",
|
||||||
SyscallGetProcessedSiblingInstruction::call,
|
SyscallGetProcessedSiblingInstruction::call,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Stack height
|
// Stack height
|
||||||
syscall_registry
|
result.register_function_by_name("sol_get_stack_height", SyscallGetStackHeight::call)?;
|
||||||
.register_syscall_by_name(b"sol_get_stack_height", SyscallGetStackHeight::call)?;
|
|
||||||
|
|
||||||
// Return data
|
// Return data
|
||||||
syscall_registry
|
result.register_function_by_name("sol_set_return_data", SyscallSetReturnData::call)?;
|
||||||
.register_syscall_by_name(b"sol_set_return_data", SyscallSetReturnData::call)?;
|
result.register_function_by_name("sol_get_return_data", SyscallGetReturnData::call)?;
|
||||||
syscall_registry
|
|
||||||
.register_syscall_by_name(b"sol_get_return_data", SyscallGetReturnData::call)?;
|
|
||||||
|
|
||||||
// Cross-program invocation
|
// Cross-program invocation
|
||||||
syscall_registry
|
result.register_function_by_name("sol_invoke_signed_c", SyscallInvokeSignedC::call)?;
|
||||||
.register_syscall_by_name(b"sol_invoke_signed_c", SyscallInvokeSignedC::call)?;
|
result
|
||||||
syscall_registry
|
.register_function_by_name("sol_invoke_signed_rust", SyscallInvokeSignedRust::call)?;
|
||||||
.register_syscall_by_name(b"sol_invoke_signed_rust", SyscallInvokeSignedRust::call)?;
|
|
||||||
|
|
||||||
// Memory allocator
|
// Memory allocator
|
||||||
register_feature_gated_syscall!(
|
register_feature_gated_function!(
|
||||||
syscall_registry,
|
result,
|
||||||
!disable_deploy_of_alloc_free_syscall,
|
!disable_deploy_of_alloc_free_syscall,
|
||||||
b"sol_alloc_free_",
|
"sol_alloc_free_",
|
||||||
SyscallAllocFree::call,
|
SyscallAllocFree::call,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Alt_bn128
|
// Alt_bn128
|
||||||
register_feature_gated_syscall!(
|
register_feature_gated_function!(
|
||||||
syscall_registry,
|
result,
|
||||||
enable_alt_bn128_syscall,
|
enable_alt_bn128_syscall,
|
||||||
b"sol_alt_bn128_group_op",
|
"sol_alt_bn128_group_op",
|
||||||
SyscallAltBn128::call,
|
SyscallAltBn128::call,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log data
|
// Log data
|
||||||
syscall_registry.register_syscall_by_name(b"sol_log_data", SyscallLogData::call)?;
|
result.register_function_by_name("sol_log_data", SyscallLogData::call)?;
|
||||||
|
|
||||||
Ok(syscall_registry)
|
Ok(Arc::new(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate(
|
fn translate(
|
||||||
|
@ -293,7 +320,7 @@ fn translate(
|
||||||
vm_addr: u64,
|
vm_addr: u64,
|
||||||
len: u64,
|
len: u64,
|
||||||
) -> Result<u64, EbpfError> {
|
) -> Result<u64, EbpfError> {
|
||||||
memory_mapping.map(access_type, vm_addr, len).into()
|
memory_mapping.map(access_type, vm_addr, len, 0).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_type_inner<'a, T>(
|
fn translate_type_inner<'a, T>(
|
||||||
|
@ -1703,7 +1730,7 @@ mod tests {
|
||||||
aligned_memory::AlignedMemory,
|
aligned_memory::AlignedMemory,
|
||||||
ebpf::{self, HOST_ALIGN},
|
ebpf::{self, HOST_ALIGN},
|
||||||
memory_region::MemoryRegion,
|
memory_region::MemoryRegion,
|
||||||
vm::{Config, SyscallFunction},
|
vm::{BuiltInFunction, Config},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::AccountSharedData,
|
account::AccountSharedData,
|
||||||
|
@ -3627,7 +3654,7 @@ mod tests {
|
||||||
seeds: &[&[u8]],
|
seeds: &[&[u8]],
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
overlap_outputs: bool,
|
overlap_outputs: bool,
|
||||||
syscall: SyscallFunction<InvokeContext<'b>>,
|
syscall: BuiltInFunction<InvokeContext<'b>>,
|
||||||
) -> Result<(Pubkey, u8), EbpfError> {
|
) -> Result<(Pubkey, u8), EbpfError> {
|
||||||
const SEEDS_VA: u64 = 0x100000000;
|
const SEEDS_VA: u64 = 0x100000000;
|
||||||
const PROGRAM_ID_VA: u64 = 0x200000000;
|
const PROGRAM_ID_VA: u64 = 0x200000000;
|
||||||
|
|
|
@ -4311,6 +4311,7 @@ dependencies = [
|
||||||
"byteorder 1.4.3",
|
"byteorder 1.4.3",
|
||||||
"libsecp256k1 0.6.0",
|
"libsecp256k1 0.6.0",
|
||||||
"log",
|
"log",
|
||||||
|
"rand 0.7.3",
|
||||||
"solana-measure",
|
"solana-measure",
|
||||||
"solana-program-runtime",
|
"solana-program-runtime",
|
||||||
"solana-sdk 1.15.0",
|
"solana-sdk 1.15.0",
|
||||||
|
@ -6190,9 +6191,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana_rbpf"
|
name = "solana_rbpf"
|
||||||
version = "0.2.37"
|
version = "0.2.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0669f9f5c355899600732451c65cc717d0ef0c53717749f03520337c824fd8a1"
|
checksum = "a4e9e5085099858adba23d0a0b5298da8803f89999cb567ecafab9c916cdf53d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.4.3",
|
"byteorder 1.4.3",
|
||||||
"combine",
|
"combine",
|
||||||
|
@ -6204,6 +6205,7 @@ dependencies = [
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"scroll",
|
"scroll",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -38,7 +38,7 @@ solana-sbf-rust-realloc = { path = "rust/realloc", version = "=1.15.0" }
|
||||||
solana-sbf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.15.0" }
|
solana-sbf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.15.0" }
|
||||||
solana-sdk = { path = "../../sdk", version = "=1.15.0" }
|
solana-sdk = { path = "../../sdk", version = "=1.15.0" }
|
||||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.15.0" }
|
solana-transaction-status = { path = "../../transaction-status", version = "=1.15.0" }
|
||||||
solana_rbpf = "=0.2.37"
|
solana_rbpf = "=0.2.38"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-ledger = { path = "../../ledger", version = "=1.15.0" }
|
solana-ledger = { path = "../../ledger", version = "=1.15.0" }
|
||||||
|
|
|
@ -8,16 +8,19 @@ extern crate solana_bpf_loader_program;
|
||||||
use {
|
use {
|
||||||
byteorder::{ByteOrder, LittleEndian, WriteBytesExt},
|
byteorder::{ByteOrder, LittleEndian, WriteBytesExt},
|
||||||
solana_bpf_loader_program::{
|
solana_bpf_loader_program::{
|
||||||
create_vm, serialization::serialize_parameters, syscalls::register_syscalls,
|
create_vm, serialization::serialize_parameters, syscalls::create_loader,
|
||||||
},
|
},
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_program_runtime::invoke_context::{with_mock_invoke_context, InvokeContext},
|
solana_program_runtime::{
|
||||||
|
compute_budget::ComputeBudget,
|
||||||
|
invoke_context::{with_mock_invoke_context, InvokeContext},
|
||||||
|
},
|
||||||
solana_rbpf::{
|
solana_rbpf::{
|
||||||
ebpf::MM_INPUT_START,
|
ebpf::MM_INPUT_START,
|
||||||
elf::Executable,
|
elf::Executable,
|
||||||
memory_region::MemoryRegion,
|
memory_region::MemoryRegion,
|
||||||
verifier::RequisiteVerifier,
|
verifier::RequisiteVerifier,
|
||||||
vm::{Config, ContextObject, SyscallRegistry, VerifiedExecutable},
|
vm::{ContextObject, VerifiedExecutable},
|
||||||
},
|
},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
|
@ -29,6 +32,7 @@ use {
|
||||||
bpf_loader,
|
bpf_loader,
|
||||||
client::SyncClient,
|
client::SyncClient,
|
||||||
entrypoint::SUCCESS,
|
entrypoint::SUCCESS,
|
||||||
|
feature_set::FeatureSet,
|
||||||
instruction::{AccountMeta, Instruction},
|
instruction::{AccountMeta, Instruction},
|
||||||
message::Message,
|
message::Message,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
|
@ -80,13 +84,16 @@ const ARMSTRONG_EXPECTED: u64 = 5;
|
||||||
fn bench_program_create_executable(bencher: &mut Bencher) {
|
fn bench_program_create_executable(bencher: &mut Bencher) {
|
||||||
let elf = load_elf("bench_alu").unwrap();
|
let elf = load_elf("bench_alu").unwrap();
|
||||||
|
|
||||||
|
let loader = create_loader(
|
||||||
|
&FeatureSet::default(),
|
||||||
|
&ComputeBudget::default(),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
let _ = Executable::<InvokeContext>::from_elf(
|
let _ = Executable::<InvokeContext>::from_elf(&elf, loader.clone()).unwrap();
|
||||||
&elf,
|
|
||||||
Config::default(),
|
|
||||||
SyscallRegistry::default(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,12 +109,15 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
let elf = load_elf("bench_alu").unwrap();
|
let elf = load_elf("bench_alu").unwrap();
|
||||||
let loader_id = bpf_loader::id();
|
let loader_id = bpf_loader::id();
|
||||||
with_mock_invoke_context(loader_id, 10000001, false, |invoke_context| {
|
with_mock_invoke_context(loader_id, 10000001, false, |invoke_context| {
|
||||||
let executable = Executable::<InvokeContext>::from_elf(
|
let loader = create_loader(
|
||||||
&elf,
|
&invoke_context.feature_set,
|
||||||
Config::default(),
|
&ComputeBudget::default(),
|
||||||
register_syscalls(&invoke_context.feature_set, true).unwrap(),
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let executable = Executable::<InvokeContext>::from_elf(&elf, loader).unwrap();
|
||||||
|
|
||||||
let mut verified_executable =
|
let mut verified_executable =
|
||||||
VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
||||||
|
@ -123,7 +133,9 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("Interpreted:");
|
println!("Interpreted:");
|
||||||
vm.context_object.mock_set_remaining(std::i64::MAX as u64);
|
vm.env
|
||||||
|
.context_object_pointer
|
||||||
|
.mock_set_remaining(std::i64::MAX as u64);
|
||||||
let (instructions, result) = vm.execute_program(true);
|
let (instructions, result) = vm.execute_program(true);
|
||||||
assert_eq!(SUCCESS, result.unwrap());
|
assert_eq!(SUCCESS, result.unwrap());
|
||||||
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||||
|
@ -133,7 +145,9 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
);
|
);
|
||||||
|
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
vm.context_object.mock_set_remaining(std::i64::MAX as u64);
|
vm.env
|
||||||
|
.context_object_pointer
|
||||||
|
.mock_set_remaining(std::i64::MAX as u64);
|
||||||
vm.execute_program(true).1.unwrap();
|
vm.execute_program(true).1.unwrap();
|
||||||
});
|
});
|
||||||
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
|
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
|
||||||
|
@ -153,7 +167,9 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
);
|
);
|
||||||
|
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
vm.context_object.mock_set_remaining(std::i64::MAX as u64);
|
vm.env
|
||||||
|
.context_object_pointer
|
||||||
|
.mock_set_remaining(std::i64::MAX as u64);
|
||||||
vm.execute_program(false).1.unwrap();
|
vm.execute_program(false).1.unwrap();
|
||||||
});
|
});
|
||||||
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
|
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
|
||||||
|
@ -220,12 +236,15 @@ fn bench_create_vm(bencher: &mut Bencher) {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let executable = Executable::<InvokeContext>::from_elf(
|
let loader = create_loader(
|
||||||
&elf,
|
&invoke_context.feature_set,
|
||||||
Config::default(),
|
&ComputeBudget::default(),
|
||||||
register_syscalls(&invoke_context.feature_set, true).unwrap(),
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let executable = Executable::<InvokeContext>::from_elf(&elf, loader).unwrap();
|
||||||
|
|
||||||
let verified_executable =
|
let verified_executable =
|
||||||
VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
||||||
|
@ -262,12 +281,15 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let executable = Executable::<InvokeContext>::from_elf(
|
let loader = create_loader(
|
||||||
&elf,
|
&invoke_context.feature_set,
|
||||||
Config::default(),
|
&ComputeBudget::default(),
|
||||||
register_syscalls(&invoke_context.feature_set, true).unwrap(),
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let executable = Executable::<InvokeContext>::from_elf(&elf, loader).unwrap();
|
||||||
|
|
||||||
let verified_executable =
|
let verified_executable =
|
||||||
VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
VerifiedExecutable::<RequisiteVerifier, InvokeContext>::from_executable(executable)
|
||||||
|
@ -287,12 +309,12 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
0,
|
0,
|
||||||
vm.context_object.get_remaining(),
|
vm.env.context_object_pointer.get_remaining(),
|
||||||
"Tuner must consume the whole budget"
|
"Tuner must consume the whole budget"
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"{:?} compute units took {:?} us ({:?} instructions)",
|
"{:?} compute units took {:?} us ({:?} instructions)",
|
||||||
BUDGET - vm.context_object.get_remaining(),
|
BUDGET - vm.env.context_object_pointer.get_remaining(),
|
||||||
measure.as_us(),
|
measure.as_us(),
|
||||||
instructions,
|
instructions,
|
||||||
);
|
);
|
||||||
|
|
|
@ -56,14 +56,10 @@ use {
|
||||||
solana_bpf_loader_program::{
|
solana_bpf_loader_program::{
|
||||||
create_vm,
|
create_vm,
|
||||||
serialization::{deserialize_parameters, serialize_parameters},
|
serialization::{deserialize_parameters, serialize_parameters},
|
||||||
syscalls::register_syscalls,
|
syscalls::create_loader,
|
||||||
},
|
},
|
||||||
solana_program_runtime::invoke_context::with_mock_invoke_context,
|
solana_program_runtime::invoke_context::with_mock_invoke_context,
|
||||||
solana_rbpf::{
|
solana_rbpf::{elf::Executable, verifier::RequisiteVerifier, vm::VerifiedExecutable},
|
||||||
elf::Executable,
|
|
||||||
verifier::RequisiteVerifier,
|
|
||||||
vm::{Config, VerifiedExecutable},
|
|
||||||
},
|
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_client::BankClient,
|
bank_client::BankClient,
|
||||||
|
@ -224,21 +220,15 @@ fn run_program(name: &str) -> u64 {
|
||||||
file.read_to_end(&mut data).unwrap();
|
file.read_to_end(&mut data).unwrap();
|
||||||
let loader_id = bpf_loader::id();
|
let loader_id = bpf_loader::id();
|
||||||
with_mock_invoke_context(loader_id, 0, false, |invoke_context| {
|
with_mock_invoke_context(loader_id, 0, false, |invoke_context| {
|
||||||
let config = Config {
|
let loader = create_loader(
|
||||||
enable_instruction_tracing: true,
|
&invoke_context.feature_set,
|
||||||
reject_broken_elfs: true,
|
&ComputeBudget::default(),
|
||||||
..Config::default()
|
true,
|
||||||
};
|
true,
|
||||||
let executable = Executable::<InvokeContext>::from_elf(
|
true,
|
||||||
&data,
|
|
||||||
config,
|
|
||||||
register_syscalls(
|
|
||||||
&invoke_context.feature_set,
|
|
||||||
true, /* no sol_alloc_free */
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let executable = Executable::<InvokeContext>::from_elf(&data, loader).unwrap();
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut verified_executable =
|
let mut verified_executable =
|
||||||
|
@ -293,18 +283,16 @@ fn run_program(name: &str) -> u64 {
|
||||||
assert_eq!(instruction_count, compute_units_consumed);
|
assert_eq!(instruction_count, compute_units_consumed);
|
||||||
}
|
}
|
||||||
instruction_count = compute_units_consumed;
|
instruction_count = compute_units_consumed;
|
||||||
if config.enable_instruction_tracing {
|
if i == 0 {
|
||||||
if i == 0 {
|
trace_log = Some(vm.env.context_object_pointer.trace_log.clone());
|
||||||
trace_log = Some(vm.context_object.trace_log.clone());
|
} else {
|
||||||
} else {
|
let interpreter = trace_log.as_ref().unwrap().as_slice();
|
||||||
let interpreter = trace_log.as_ref().unwrap().as_slice();
|
let mut jit = vm.env.context_object_pointer.trace_log.as_slice();
|
||||||
let mut jit = vm.context_object.trace_log.as_slice();
|
if jit.len() > interpreter.len() {
|
||||||
if jit.len() > interpreter.len() {
|
jit = &jit[0..interpreter.len()];
|
||||||
jit = &jit[0..interpreter.len()];
|
|
||||||
}
|
|
||||||
assert_eq!(interpreter, jit);
|
|
||||||
trace_log = None;
|
|
||||||
}
|
}
|
||||||
|
assert_eq!(interpreter, jit);
|
||||||
|
trace_log = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert!(match deserialize_parameters(
|
assert!(match deserialize_parameters(
|
||||||
|
|
|
@ -17,4 +17,4 @@ solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.15.
|
||||||
solana-logger = { path = "../logger", version = "=1.15.0" }
|
solana-logger = { path = "../logger", version = "=1.15.0" }
|
||||||
solana-program-runtime = { path = "../program-runtime", version = "=1.15.0" }
|
solana-program-runtime = { path = "../program-runtime", version = "=1.15.0" }
|
||||||
solana-sdk = { path = "../sdk", version = "=1.15.0" }
|
solana-sdk = { path = "../sdk", version = "=1.15.0" }
|
||||||
solana_rbpf = { version = "=0.2.37", features = ["debugger"] }
|
solana_rbpf = { version = "=0.2.38", features = ["debugger"] }
|
||||||
|
|
|
@ -3,17 +3,15 @@ use {
|
||||||
serde::{Deserialize, Serialize},
|
serde::{Deserialize, Serialize},
|
||||||
serde_json::Result,
|
serde_json::Result,
|
||||||
solana_bpf_loader_program::{
|
solana_bpf_loader_program::{
|
||||||
create_vm, serialization::serialize_parameters, syscalls::register_syscalls,
|
create_vm, serialization::serialize_parameters, syscalls::create_loader,
|
||||||
|
},
|
||||||
|
solana_program_runtime::{
|
||||||
|
compute_budget::ComputeBudget,
|
||||||
|
invoke_context::{prepare_mock_invoke_context, InvokeContext},
|
||||||
},
|
},
|
||||||
solana_program_runtime::invoke_context::{prepare_mock_invoke_context, InvokeContext},
|
|
||||||
solana_rbpf::{
|
solana_rbpf::{
|
||||||
assembler::assemble,
|
assembler::assemble, elf::Executable, static_analysis::Analysis,
|
||||||
debugger,
|
verifier::RequisiteVerifier, vm::VerifiedExecutable,
|
||||||
elf::Executable,
|
|
||||||
interpreter::Interpreter,
|
|
||||||
static_analysis::Analysis,
|
|
||||||
verifier::RequisiteVerifier,
|
|
||||||
vm::{Config, VerifiedExecutable},
|
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::AccountSharedData, bpf_loader, instruction::AccountMeta, pubkey::Pubkey,
|
account::AccountSharedData, bpf_loader, instruction::AccountMeta, pubkey::Pubkey,
|
||||||
|
@ -161,10 +159,6 @@ before execting it in the virtual machine.",
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let config = Config {
|
|
||||||
enable_symbol_and_section_labels: true,
|
|
||||||
..Config::default()
|
|
||||||
};
|
|
||||||
let loader_id = bpf_loader::id();
|
let loader_id = bpf_loader::id();
|
||||||
let mut transaction_accounts = vec![
|
let mut transaction_accounts = vec![
|
||||||
(
|
(
|
||||||
|
@ -247,16 +241,19 @@ before execting it in the virtual machine.",
|
||||||
file.rewind().unwrap();
|
file.rewind().unwrap();
|
||||||
let mut contents = Vec::new();
|
let mut contents = Vec::new();
|
||||||
file.read_to_end(&mut contents).unwrap();
|
file.read_to_end(&mut contents).unwrap();
|
||||||
let syscall_registry = register_syscalls(&invoke_context.feature_set, true).unwrap();
|
let loader = create_loader(
|
||||||
|
&invoke_context.feature_set,
|
||||||
|
&ComputeBudget::default(),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let executable = if magic == [0x7f, 0x45, 0x4c, 0x46] {
|
let executable = if magic == [0x7f, 0x45, 0x4c, 0x46] {
|
||||||
Executable::<InvokeContext>::from_elf(&contents, config, syscall_registry)
|
Executable::<InvokeContext>::from_elf(&contents, loader)
|
||||||
.map_err(|err| format!("Executable constructor failed: {err:?}"))
|
.map_err(|err| format!("Executable constructor failed: {err:?}"))
|
||||||
} else {
|
} else {
|
||||||
assemble::<InvokeContext>(
|
assemble::<InvokeContext>(std::str::from_utf8(contents.as_slice()).unwrap(), loader)
|
||||||
std::str::from_utf8(contents.as_slice()).unwrap(),
|
|
||||||
config,
|
|
||||||
syscall_registry,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -293,13 +290,10 @@ before execting it in the virtual machine.",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let (instruction_count, result) = if matches.value_of("use").unwrap() == "debugger" {
|
if matches.value_of("use").unwrap() == "debugger" {
|
||||||
let mut interpreter = Interpreter::new(&mut vm).unwrap();
|
vm.debug_port = Some(matches.value_of("port").unwrap().parse::<u16>().unwrap());
|
||||||
let port = matches.value_of("port").unwrap().parse::<u16>().unwrap();
|
}
|
||||||
debugger::execute(&mut interpreter, port)
|
let (instruction_count, result) = vm.execute_program(matches.value_of("use").unwrap() != "jit");
|
||||||
} else {
|
|
||||||
vm.execute_program(matches.value_of("use").unwrap() == "interpreter")
|
|
||||||
};
|
|
||||||
let duration = Instant::now() - start_time;
|
let duration = Instant::now() - start_time;
|
||||||
drop(vm);
|
drop(vm);
|
||||||
|
|
||||||
|
@ -351,7 +345,7 @@ impl Debug for Output {
|
||||||
// Replace with std::lazy::Lazy when stabilized.
|
// Replace with std::lazy::Lazy when stabilized.
|
||||||
// https://github.com/rust-lang/rust/issues/74465
|
// https://github.com/rust-lang/rust/issues/74465
|
||||||
struct LazyAnalysis<'a, 'b> {
|
struct LazyAnalysis<'a, 'b> {
|
||||||
analysis: Option<Analysis<'a, InvokeContext<'b>>>,
|
analysis: Option<Analysis<'a>>,
|
||||||
executable: &'a Executable<InvokeContext<'b>>,
|
executable: &'a Executable<InvokeContext<'b>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +357,7 @@ impl<'a, 'b> LazyAnalysis<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn analyze(&mut self) -> &Analysis<InvokeContext<'b>> {
|
fn analyze(&mut self) -> &Analysis {
|
||||||
if let Some(ref analysis) = self.analysis {
|
if let Some(ref analysis) = self.analysis {
|
||||||
return analysis;
|
return analysis;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue