Bump rBPF (#25593)
This commit is contained in:
parent
8674c96a66
commit
363d8d1539
|
@ -6308,9 +6308,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana_rbpf"
|
name = "solana_rbpf"
|
||||||
version = "0.2.30"
|
version = "0.2.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4df28dcb607dd56ab0022f99d3a9ff1ee0d87951315762c0b89e946c087ebbea"
|
checksum = "80a28c5dfe7e8af38daa39d6561c8e8b9ed7a2f900951ebe7362ad6348d36c73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"combine",
|
"combine",
|
||||||
|
|
|
@ -42,7 +42,7 @@ solana-sdk = { path = "../sdk", version = "=1.11.0" }
|
||||||
solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
|
solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
|
||||||
solana-version = { path = "../version", version = "=1.11.0" }
|
solana-version = { path = "../version", version = "=1.11.0" }
|
||||||
solana-vote-program = { path = "../programs/vote", version = "=1.11.0" }
|
solana-vote-program = { path = "../programs/vote", version = "=1.11.0" }
|
||||||
solana_rbpf = "=0.2.30"
|
solana_rbpf = "=0.2.31"
|
||||||
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"
|
||||||
|
|
|
@ -25,7 +25,11 @@ use {
|
||||||
tpu_client::{TpuClient, TpuClientConfig},
|
tpu_client::{TpuClient, TpuClientConfig},
|
||||||
},
|
},
|
||||||
solana_program_runtime::invoke_context::InvokeContext,
|
solana_program_runtime::invoke_context::InvokeContext,
|
||||||
solana_rbpf::{elf::Executable, verifier, vm::Config},
|
solana_rbpf::{
|
||||||
|
elf::Executable,
|
||||||
|
verifier::RequisiteVerifier,
|
||||||
|
vm::{Config, VerifiedExecutable},
|
||||||
|
},
|
||||||
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
|
@ -2079,9 +2083,8 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
|
||||||
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||||
|
|
||||||
// Verify the program
|
// Verify the program
|
||||||
Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||||
&program_data,
|
&program_data,
|
||||||
Some(verifier::check),
|
|
||||||
Config {
|
Config {
|
||||||
reject_broken_elfs: true,
|
reject_broken_elfs: true,
|
||||||
..Config::default()
|
..Config::default()
|
||||||
|
@ -2090,6 +2093,12 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
|
||||||
)
|
)
|
||||||
.map_err(|err| format!("ELF error: {}", err))?;
|
.map_err(|err| format!("ELF error: {}", err))?;
|
||||||
|
|
||||||
|
let _ =
|
||||||
|
VerifiedExecutable::<RequisiteVerifier, BpfError, ThisInstructionMeter>::from_executable(
|
||||||
|
executable,
|
||||||
|
)
|
||||||
|
.map_err(|err| format!("ELF error: {}", err))?;
|
||||||
|
|
||||||
Ok(program_data)
|
Ok(program_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5516,9 +5516,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana_rbpf"
|
name = "solana_rbpf"
|
||||||
version = "0.2.30"
|
version = "0.2.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4df28dcb607dd56ab0022f99d3a9ff1ee0d87951315762c0b89e946c087ebbea"
|
checksum = "80a28c5dfe7e8af38daa39d6561c8e8b9ed7a2f900951ebe7362ad6348d36c73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.4.3",
|
"byteorder 1.4.3",
|
||||||
"combine",
|
"combine",
|
||||||
|
|
|
@ -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-cli-output = { path = "../../cli-output", version = "=1.11.0" }
|
||||||
solana-logger = { path = "../../logger", version = "=1.11.0" }
|
solana-logger = { path = "../../logger", version = "=1.11.0" }
|
||||||
solana-measure = { path = "../../measure", version = "=1.11.0" }
|
solana-measure = { path = "../../measure", version = "=1.11.0" }
|
||||||
solana_rbpf = "=0.2.30"
|
solana_rbpf = "=0.2.31"
|
||||||
solana-runtime = { path = "../../runtime", version = "=1.11.0" }
|
solana-runtime = { path = "../../runtime", version = "=1.11.0" }
|
||||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.11.0" }
|
solana-program-runtime = { path = "../../program-runtime", version = "=1.11.0" }
|
||||||
solana-sdk = { path = "../../sdk", version = "=1.11.0" }
|
solana-sdk = { path = "../../sdk", version = "=1.11.0" }
|
||||||
|
|
|
@ -15,7 +15,8 @@ use {
|
||||||
solana_program_runtime::invoke_context::with_mock_invoke_context,
|
solana_program_runtime::invoke_context::with_mock_invoke_context,
|
||||||
solana_rbpf::{
|
solana_rbpf::{
|
||||||
elf::Executable,
|
elf::Executable,
|
||||||
vm::{Config, InstructionMeter, SyscallRegistry},
|
verifier::RequisiteVerifier,
|
||||||
|
vm::{Config, InstructionMeter, SyscallRegistry, VerifiedExecutable},
|
||||||
},
|
},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
|
@ -81,7 +82,6 @@ fn bench_program_create_executable(bencher: &mut Bencher) {
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
let _ = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
let _ = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||||
&elf,
|
&elf,
|
||||||
None,
|
|
||||||
Config::default(),
|
Config::default(),
|
||||||
SyscallRegistry::default(),
|
SyscallRegistry::default(),
|
||||||
)
|
)
|
||||||
|
@ -105,17 +105,30 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
.get_compute_meter()
|
.get_compute_meter()
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.mock_set_remaining(std::i64::MAX as u64);
|
.mock_set_remaining(std::i64::MAX as u64);
|
||||||
let mut executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||||
&elf,
|
&elf,
|
||||||
None,
|
|
||||||
Config::default(),
|
Config::default(),
|
||||||
register_syscalls(invoke_context, true).unwrap(),
|
register_syscalls(invoke_context, true).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable).unwrap();
|
|
||||||
|
let mut verified_executable = VerifiedExecutable::<
|
||||||
|
RequisiteVerifier,
|
||||||
|
BpfError,
|
||||||
|
ThisInstructionMeter,
|
||||||
|
>::from_executable(executable)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
verified_executable.jit_compile().unwrap();
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
let compute_meter = invoke_context.get_compute_meter();
|
||||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
||||||
let mut vm = create_vm(&executable, &mut inner_iter, vec![], invoke_context).unwrap();
|
let mut vm = create_vm(
|
||||||
|
&verified_executable,
|
||||||
|
&mut inner_iter,
|
||||||
|
vec![],
|
||||||
|
invoke_context,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
println!("Interpreted:");
|
println!("Interpreted:");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -222,15 +235,21 @@ fn bench_create_vm(bencher: &mut Bencher) {
|
||||||
|
|
||||||
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||||
&elf,
|
&elf,
|
||||||
None,
|
|
||||||
Config::default(),
|
Config::default(),
|
||||||
register_syscalls(invoke_context, true).unwrap(),
|
register_syscalls(invoke_context, true).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let verified_executable = VerifiedExecutable::<
|
||||||
|
RequisiteVerifier,
|
||||||
|
BpfError,
|
||||||
|
ThisInstructionMeter,
|
||||||
|
>::from_executable(executable)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
let _ = create_vm(
|
let _ = create_vm(
|
||||||
&executable,
|
&verified_executable,
|
||||||
serialized.as_slice_mut(),
|
serialized.as_slice_mut(),
|
||||||
account_lengths.clone(),
|
account_lengths.clone(),
|
||||||
invoke_context,
|
invoke_context,
|
||||||
|
@ -263,15 +282,22 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
|
|
||||||
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||||
&elf,
|
&elf,
|
||||||
None,
|
|
||||||
Config::default(),
|
Config::default(),
|
||||||
register_syscalls(invoke_context, true).unwrap(),
|
register_syscalls(invoke_context, true).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let verified_executable = VerifiedExecutable::<
|
||||||
|
RequisiteVerifier,
|
||||||
|
BpfError,
|
||||||
|
ThisInstructionMeter,
|
||||||
|
>::from_executable(executable)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
let compute_meter = invoke_context.get_compute_meter();
|
||||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
||||||
let mut vm = create_vm(
|
let mut vm = create_vm(
|
||||||
&executable,
|
&verified_executable,
|
||||||
serialized.as_slice_mut(),
|
serialized.as_slice_mut(),
|
||||||
account_lengths,
|
account_lengths,
|
||||||
invoke_context,
|
invoke_context,
|
||||||
|
|
|
@ -25,7 +25,8 @@ use {
|
||||||
solana_rbpf::{
|
solana_rbpf::{
|
||||||
elf::Executable,
|
elf::Executable,
|
||||||
static_analysis::Analysis,
|
static_analysis::Analysis,
|
||||||
vm::{Config, Tracer},
|
verifier::RequisiteVerifier,
|
||||||
|
vm::{Config, Tracer, VerifiedExecutable},
|
||||||
},
|
},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
bank::{
|
bank::{
|
||||||
|
@ -222,14 +223,20 @@ fn run_program(name: &str) -> u64 {
|
||||||
reject_broken_elfs: true,
|
reject_broken_elfs: true,
|
||||||
..Config::default()
|
..Config::default()
|
||||||
};
|
};
|
||||||
let mut executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||||
&data,
|
&data,
|
||||||
None,
|
|
||||||
config,
|
config,
|
||||||
register_syscalls(invoke_context, true /* no sol_alloc_free */).unwrap(),
|
register_syscalls(invoke_context, true /* no sol_alloc_free */).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable).unwrap();
|
|
||||||
|
let mut verified_executable = VerifiedExecutable::<
|
||||||
|
RequisiteVerifier,
|
||||||
|
BpfError,
|
||||||
|
ThisInstructionMeter,
|
||||||
|
>::from_executable(executable)
|
||||||
|
.unwrap();
|
||||||
|
verified_executable.jit_compile().unwrap();
|
||||||
|
|
||||||
let mut instruction_count = 0;
|
let mut instruction_count = 0;
|
||||||
let mut tracer = None;
|
let mut tracer = None;
|
||||||
|
@ -247,7 +254,7 @@ fn run_program(name: &str) -> u64 {
|
||||||
let mut parameter_bytes = parameter_bytes.clone();
|
let mut parameter_bytes = parameter_bytes.clone();
|
||||||
{
|
{
|
||||||
let mut vm = create_vm(
|
let mut vm = create_vm(
|
||||||
&executable,
|
&verified_executable,
|
||||||
parameter_bytes.as_slice_mut(),
|
parameter_bytes.as_slice_mut(),
|
||||||
account_lengths.clone(),
|
account_lengths.clone(),
|
||||||
invoke_context,
|
invoke_context,
|
||||||
|
@ -266,7 +273,9 @@ fn run_program(name: &str) -> u64 {
|
||||||
if config.enable_instruction_tracing {
|
if config.enable_instruction_tracing {
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
if !Tracer::compare(tracer.as_ref().unwrap(), vm.get_tracer()) {
|
if !Tracer::compare(tracer.as_ref().unwrap(), vm.get_tracer()) {
|
||||||
let analysis = Analysis::from_executable(&executable).unwrap();
|
let analysis =
|
||||||
|
Analysis::from_executable(verified_executable.get_executable())
|
||||||
|
.unwrap();
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
println!("TRACE (interpreted):");
|
println!("TRACE (interpreted):");
|
||||||
tracer
|
tracer
|
||||||
|
@ -280,7 +289,9 @@ fn run_program(name: &str) -> u64 {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(false);
|
assert!(false);
|
||||||
} else if log_enabled!(Trace) {
|
} else if log_enabled!(Trace) {
|
||||||
let analysis = Analysis::from_executable(&executable).unwrap();
|
let analysis =
|
||||||
|
Analysis::from_executable(verified_executable.get_executable())
|
||||||
|
.unwrap();
|
||||||
let mut trace_buffer = Vec::<u8>::new();
|
let mut trace_buffer = Vec::<u8>::new();
|
||||||
tracer
|
tracer
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
|
@ -19,7 +19,7 @@ solana-metrics = { path = "../../metrics", version = "=1.11.0" }
|
||||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.11.0" }
|
solana-program-runtime = { path = "../../program-runtime", version = "=1.11.0" }
|
||||||
solana-sdk = { path = "../../sdk", 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-zk-token-sdk = { path = "../../zk-token-sdk", version = "=1.11.0" }
|
||||||
solana_rbpf = "=0.2.30"
|
solana_rbpf = "=0.2.31"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -33,8 +33,8 @@ use {
|
||||||
error::{EbpfError, UserDefinedError},
|
error::{EbpfError, UserDefinedError},
|
||||||
memory_region::MemoryRegion,
|
memory_region::MemoryRegion,
|
||||||
static_analysis::Analysis,
|
static_analysis::Analysis,
|
||||||
verifier::{self, VerifierError},
|
verifier::{RequisiteVerifier, VerifierError},
|
||||||
vm::{Config, EbpfVm, InstructionMeter},
|
vm::{Config, EbpfVm, InstructionMeter, VerifiedExecutable},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
bpf_loader, bpf_loader_deprecated,
|
bpf_loader, bpf_loader_deprecated,
|
||||||
|
@ -57,7 +57,7 @@ use {
|
||||||
system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
|
system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
|
||||||
transaction_context::{InstructionContext, TransactionContext},
|
transaction_context::{InstructionContext, TransactionContext},
|
||||||
},
|
},
|
||||||
std::{cell::RefCell, fmt::Debug, pin::Pin, rc::Rc, sync::Arc},
|
std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ pub fn create_executor(
|
||||||
// Warning, do not use `Config::default()` so that configuration here is explicit.
|
// Warning, do not use `Config::default()` so that configuration here is explicit.
|
||||||
};
|
};
|
||||||
let mut create_executor_metrics = executor_metrics::CreateMetrics::default();
|
let mut create_executor_metrics = executor_metrics::CreateMetrics::default();
|
||||||
let mut executable = {
|
let executable = {
|
||||||
let transaction_context = &invoke_context.transaction_context;
|
let transaction_context = &invoke_context.transaction_context;
|
||||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||||
let programdata = instruction_context
|
let programdata = instruction_context
|
||||||
|
@ -170,7 +170,6 @@ pub fn create_executor(
|
||||||
.get_data()
|
.get_data()
|
||||||
.get(programdata_offset..)
|
.get(programdata_offset..)
|
||||||
.ok_or(InstructionError::AccountDataTooSmall)?,
|
.ok_or(InstructionError::AccountDataTooSmall)?,
|
||||||
None,
|
|
||||||
config,
|
config,
|
||||||
syscall_registry,
|
syscall_registry,
|
||||||
);
|
);
|
||||||
|
@ -183,10 +182,12 @@ pub fn create_executor(
|
||||||
executable
|
executable
|
||||||
}
|
}
|
||||||
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
||||||
let text_bytes = executable.get_text_bytes().1;
|
|
||||||
let mut verify_code_time = Measure::start("verify_code_time");
|
let mut verify_code_time = Measure::start("verify_code_time");
|
||||||
verifier::check(text_bytes, &config)
|
let mut verified_executable =
|
||||||
.map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e.into())))?;
|
VerifiedExecutable::<RequisiteVerifier, BpfError, ThisInstructionMeter>::from_executable(
|
||||||
|
executable,
|
||||||
|
)
|
||||||
|
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
||||||
verify_code_time.stop();
|
verify_code_time.stop();
|
||||||
create_executor_metrics.verify_code_us = verify_code_time.as_us();
|
create_executor_metrics.verify_code_us = verify_code_time.as_us();
|
||||||
invoke_context.timings.create_executor_verify_code_us = invoke_context
|
invoke_context.timings.create_executor_verify_code_us = invoke_context
|
||||||
|
@ -195,8 +196,7 @@ pub fn create_executor(
|
||||||
.saturating_add(create_executor_metrics.verify_code_us);
|
.saturating_add(create_executor_metrics.verify_code_us);
|
||||||
if use_jit {
|
if use_jit {
|
||||||
let mut jit_compile_time = Measure::start("jit_compile_time");
|
let mut jit_compile_time = Measure::start("jit_compile_time");
|
||||||
let jit_compile_result =
|
let jit_compile_result = verified_executable.jit_compile();
|
||||||
Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable);
|
|
||||||
jit_compile_time.stop();
|
jit_compile_time.stop();
|
||||||
create_executor_metrics.jit_compile_us = jit_compile_time.as_us();
|
create_executor_metrics.jit_compile_us = jit_compile_time.as_us();
|
||||||
invoke_context.timings.create_executor_jit_compile_us = invoke_context
|
invoke_context.timings.create_executor_jit_compile_us = invoke_context
|
||||||
|
@ -210,7 +210,7 @@ pub fn create_executor(
|
||||||
}
|
}
|
||||||
create_executor_metrics.submit_datapoint();
|
create_executor_metrics.submit_datapoint();
|
||||||
Ok(Arc::new(BpfExecutor {
|
Ok(Arc::new(BpfExecutor {
|
||||||
executable,
|
verified_executable,
|
||||||
use_jit,
|
use_jit,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -250,11 +250,11 @@ fn check_loader_id(id: &Pubkey) -> bool {
|
||||||
|
|
||||||
/// Create the BPF virtual machine
|
/// Create the BPF virtual machine
|
||||||
pub fn create_vm<'a, 'b>(
|
pub fn create_vm<'a, 'b>(
|
||||||
program: &'a Pin<Box<Executable<BpfError, ThisInstructionMeter>>>,
|
program: &'a VerifiedExecutable<RequisiteVerifier, BpfError, ThisInstructionMeter>,
|
||||||
parameter_bytes: &mut [u8],
|
parameter_bytes: &mut [u8],
|
||||||
orig_account_lengths: Vec<usize>,
|
orig_account_lengths: Vec<usize>,
|
||||||
invoke_context: &'a mut InvokeContext<'b>,
|
invoke_context: &'a mut InvokeContext<'b>,
|
||||||
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
|
) -> Result<EbpfVm<'a, RequisiteVerifier, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
|
||||||
let compute_budget = invoke_context.get_compute_budget();
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
let heap_size = compute_budget.heap_size.unwrap_or(HEAP_LENGTH);
|
let heap_size = compute_budget.heap_size.unwrap_or(HEAP_LENGTH);
|
||||||
if invoke_context
|
if invoke_context
|
||||||
|
@ -1157,7 +1157,7 @@ impl InstructionMeter for ThisInstructionMeter {
|
||||||
|
|
||||||
/// BPF Loader's Executor implementation
|
/// BPF Loader's Executor implementation
|
||||||
pub struct BpfExecutor {
|
pub struct BpfExecutor {
|
||||||
executable: Pin<Box<Executable<BpfError, ThisInstructionMeter>>>,
|
verified_executable: VerifiedExecutable<RequisiteVerifier, BpfError, ThisInstructionMeter>,
|
||||||
use_jit: bool,
|
use_jit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1190,7 +1190,7 @@ impl Executor for BpfExecutor {
|
||||||
let mut execute_time;
|
let mut execute_time;
|
||||||
let execution_result = {
|
let execution_result = {
|
||||||
let mut vm = match create_vm(
|
let mut vm = match create_vm(
|
||||||
&self.executable,
|
&self.verified_executable,
|
||||||
parameter_bytes.as_slice_mut(),
|
parameter_bytes.as_slice_mut(),
|
||||||
account_lengths,
|
account_lengths,
|
||||||
invoke_context,
|
invoke_context,
|
||||||
|
@ -1222,7 +1222,8 @@ impl Executor for BpfExecutor {
|
||||||
);
|
);
|
||||||
if log_enabled!(Trace) {
|
if log_enabled!(Trace) {
|
||||||
let mut trace_buffer = Vec::<u8>::new();
|
let mut trace_buffer = Vec::<u8>::new();
|
||||||
let analysis = Analysis::from_executable(&self.executable).unwrap();
|
let analysis =
|
||||||
|
Analysis::from_executable(self.verified_executable.get_executable()).unwrap();
|
||||||
vm.get_tracer().write(&mut trace_buffer, &analysis).unwrap();
|
vm.get_tracer().write(&mut trace_buffer, &analysis).unwrap();
|
||||||
let trace_string = String::from_utf8(trace_buffer).unwrap();
|
let trace_string = String::from_utf8(trace_buffer).unwrap();
|
||||||
trace!("BPF Program Instruction Trace:\n{}", trace_string);
|
trace!("BPF Program Instruction Trace:\n{}", trace_string);
|
||||||
|
@ -1305,7 +1306,7 @@ mod tests {
|
||||||
super::*,
|
super::*,
|
||||||
rand::Rng,
|
rand::Rng,
|
||||||
solana_program_runtime::invoke_context::mock_process_instruction,
|
solana_program_runtime::invoke_context::mock_process_instruction,
|
||||||
solana_rbpf::vm::SyscallRegistry,
|
solana_rbpf::{verifier::Verifier, vm::SyscallRegistry},
|
||||||
solana_runtime::{bank::Bank, bank_client::BankClient},
|
solana_runtime::{bank::Bank, bank_client::BankClient},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{
|
account::{
|
||||||
|
@ -1374,6 +1375,13 @@ mod tests {
|
||||||
program_account
|
program_account
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TautologyVerifier {}
|
||||||
|
impl Verifier for TautologyVerifier {
|
||||||
|
fn verify(_prog: &[u8], _config: &Config) -> std::result::Result<(), VerifierError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "ExceededMaxInstructions(31, 10)")]
|
#[should_panic(expected = "ExceededMaxInstructions(31, 10)")]
|
||||||
fn test_bpf_loader_non_terminating_program() {
|
fn test_bpf_loader_non_terminating_program() {
|
||||||
|
@ -1395,18 +1403,21 @@ mod tests {
|
||||||
"entrypoint",
|
"entrypoint",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let program = Executable::<BpfError, TestInstructionMeter>::from_text_bytes(
|
let executable = Executable::<BpfError, TestInstructionMeter>::from_text_bytes(
|
||||||
program,
|
program,
|
||||||
None,
|
|
||||||
config,
|
config,
|
||||||
syscall_registry,
|
syscall_registry,
|
||||||
bpf_functions,
|
bpf_functions,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let verified_executable = VerifiedExecutable::<
|
||||||
|
TautologyVerifier,
|
||||||
|
BpfError,
|
||||||
|
TestInstructionMeter,
|
||||||
|
>::from_executable(executable)
|
||||||
|
.unwrap();
|
||||||
let input_region = MemoryRegion::new_writable(&mut input_mem, MM_INPUT_START);
|
let input_region = MemoryRegion::new_writable(&mut input_mem, MM_INPUT_START);
|
||||||
let mut vm =
|
let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![input_region]).unwrap();
|
||||||
EbpfVm::<BpfError, TestInstructionMeter>::new(&program, &mut [], vec![input_region])
|
|
||||||
.unwrap();
|
|
||||||
let mut instruction_meter = TestInstructionMeter { remaining: 10 };
|
let mut instruction_meter = TestInstructionMeter { remaining: 10 };
|
||||||
vm.execute_program_interpreted(&mut instruction_meter)
|
vm.execute_program_interpreted(&mut instruction_meter)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1418,7 +1429,7 @@ mod tests {
|
||||||
let prog = &[
|
let prog = &[
|
||||||
0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55, // first half of lddw
|
0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55, // first half of lddw
|
||||||
];
|
];
|
||||||
verifier::check(prog, &Config::default()).unwrap();
|
RequisiteVerifier::verify(prog, &Config::default()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -13,6 +13,7 @@ use {
|
||||||
error::EbpfError,
|
error::EbpfError,
|
||||||
memory_region::{AccessType, MemoryMapping},
|
memory_region::{AccessType, MemoryMapping},
|
||||||
question_mark,
|
question_mark,
|
||||||
|
verifier::RequisiteVerifier,
|
||||||
vm::{EbpfVm, SyscallObject, SyscallRegistry},
|
vm::{EbpfVm, SyscallObject, SyscallRegistry},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
|
@ -384,7 +385,7 @@ pub fn register_syscalls(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_syscall_context_objects<'a, 'b>(
|
pub fn bind_syscall_context_objects<'a, 'b>(
|
||||||
vm: &mut EbpfVm<'a, BpfError, crate::ThisInstructionMeter>,
|
vm: &mut EbpfVm<'a, RequisiteVerifier, BpfError, crate::ThisInstructionMeter>,
|
||||||
invoke_context: &'a mut InvokeContext<'b>,
|
invoke_context: &'a mut InvokeContext<'b>,
|
||||||
heap: AlignedMemory,
|
heap: AlignedMemory,
|
||||||
orig_account_lengths: Vec<usize>,
|
orig_account_lengths: Vec<usize>,
|
||||||
|
|
|
@ -17,4 +17,4 @@ solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.11.
|
||||||
solana-logger = { path = "../logger", version = "=1.11.0" }
|
solana-logger = { path = "../logger", version = "=1.11.0" }
|
||||||
solana-program-runtime = { path = "../program-runtime", version = "=1.11.0" }
|
solana-program-runtime = { path = "../program-runtime", version = "=1.11.0" }
|
||||||
solana-sdk = { path = "../sdk", version = "=1.11.0" }
|
solana-sdk = { path = "../sdk", version = "=1.11.0" }
|
||||||
solana_rbpf = "=0.2.30"
|
solana_rbpf = "=0.2.31"
|
||||||
|
|
|
@ -11,8 +11,8 @@ use {
|
||||||
assembler::assemble,
|
assembler::assemble,
|
||||||
elf::Executable,
|
elf::Executable,
|
||||||
static_analysis::Analysis,
|
static_analysis::Analysis,
|
||||||
verifier::check,
|
verifier::RequisiteVerifier,
|
||||||
vm::{Config, DynamicAnalysis},
|
vm::{Config, DynamicAnalysis, VerifiedExecutable},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::AccountSharedData, bpf_loader, instruction::AccountMeta, pubkey::Pubkey,
|
account::AccountSharedData, bpf_loader, instruction::AccountMeta, pubkey::Pubkey,
|
||||||
|
@ -152,12 +152,6 @@ native machine code before execting it in the virtual machine.",
|
||||||
.short('p')
|
.short('p')
|
||||||
.long("profile"),
|
.long("profile"),
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::new("verify")
|
|
||||||
.help("Run the verifier before execution or disassembly")
|
|
||||||
.short('v')
|
|
||||||
.long("verify"),
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("output_format")
|
Arg::new("output_format")
|
||||||
.help("Return information in specified output format")
|
.help("Return information in specified output format")
|
||||||
|
@ -250,30 +244,27 @@ native machine code before execting it in the virtual machine.",
|
||||||
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(&mut invoke_context, true).unwrap();
|
let syscall_registry = register_syscalls(&mut invoke_context, true).unwrap();
|
||||||
let mut executable = if magic == [0x7f, 0x45, 0x4c, 0x46] {
|
let executable = if magic == [0x7f, 0x45, 0x4c, 0x46] {
|
||||||
Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
Executable::<BpfError, ThisInstructionMeter>::from_elf(&contents, config, syscall_registry)
|
||||||
&contents,
|
.map_err(|err| format!("Executable constructor failed: {:?}", err))
|
||||||
None,
|
|
||||||
config,
|
|
||||||
syscall_registry,
|
|
||||||
)
|
|
||||||
.map_err(|err| format!("Executable constructor failed: {:?}", err))
|
|
||||||
} else {
|
} else {
|
||||||
assemble::<BpfError, ThisInstructionMeter>(
|
assemble::<BpfError, ThisInstructionMeter>(
|
||||||
std::str::from_utf8(contents.as_slice()).unwrap(),
|
std::str::from_utf8(contents.as_slice()).unwrap(),
|
||||||
None,
|
|
||||||
config,
|
config,
|
||||||
syscall_registry,
|
syscall_registry,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if matches.is_present("verify") {
|
let mut verified_executable =
|
||||||
let text_bytes = executable.get_text_bytes().1;
|
VerifiedExecutable::<RequisiteVerifier, BpfError, ThisInstructionMeter>::from_executable(
|
||||||
check(text_bytes, &config).unwrap();
|
executable,
|
||||||
}
|
)
|
||||||
Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable).unwrap();
|
.map_err(|err| format!("Executable verifier failed: {:?}", err))
|
||||||
let mut analysis = LazyAnalysis::new(&executable);
|
.unwrap();
|
||||||
|
|
||||||
|
verified_executable.jit_compile().unwrap();
|
||||||
|
let mut analysis = LazyAnalysis::new(verified_executable.get_executable());
|
||||||
|
|
||||||
match matches.value_of("use") {
|
match matches.value_of("use") {
|
||||||
Some("cfg") => {
|
Some("cfg") => {
|
||||||
|
@ -293,7 +284,7 @@ native machine code before execting it in the virtual machine.",
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut vm = create_vm(
|
let mut vm = create_vm(
|
||||||
&executable,
|
&verified_executable,
|
||||||
parameter_bytes.as_slice_mut(),
|
parameter_bytes.as_slice_mut(),
|
||||||
account_lengths,
|
account_lengths,
|
||||||
&mut invoke_context,
|
&mut invoke_context,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
/Users/jack/.cache/solana/v1.27/sbf-tools
|
Loading…
Reference in New Issue