Bump solana_rbpf to v0.7.0 (#33104)

* Upgrades RBPF in Cargo.toml

* Adjustments to updated interfaces.
This commit is contained in:
Alexander Meißner 2023-09-06 10:54:15 +02:00 committed by GitHub
parent 903c615559
commit 424666e341
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 214 additions and 234 deletions

5
Cargo.lock generated
View File

@ -6255,7 +6255,6 @@ version = "1.17.0"
dependencies = [ dependencies = [
"bincode", "bincode",
"log", "log",
"rand 0.8.5",
"solana-measure", "solana-measure",
"solana-program-runtime", "solana-program-runtime",
"solana-sdk", "solana-sdk",
@ -7528,9 +7527,9 @@ dependencies = [
[[package]] [[package]]
name = "solana_rbpf" name = "solana_rbpf"
version = "0.6.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef" checksum = "339e8963a8e2721227e46cf7a8488957db94cde0f35d3a769e292baaebdbeb44"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"combine", "combine",

View File

@ -294,7 +294,7 @@ siphasher = "0.3.11"
smpl_jwt = "0.7.1" smpl_jwt = "0.7.1"
socket2 = "0.5.3" socket2 = "0.5.3"
soketto = "0.7" soketto = "0.7"
solana_rbpf = "=0.6.0" solana_rbpf = "=0.7.0"
solana-account-decoder = { path = "account-decoder", version = "=1.17.0" } solana-account-decoder = { path = "account-decoder", version = "=1.17.0" }
solana-accounts-db = { path = "accounts-db", version = "=1.17.0" } solana-accounts-db = { path = "accounts-db", version = "=1.17.0" }
solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.17.0" } solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.17.0" }

View File

@ -27,10 +27,7 @@ use {
tpu_client::{TpuClient, TpuClientConfig}, tpu_client::{TpuClient, TpuClientConfig},
}, },
solana_program_runtime::{compute_budget::ComputeBudget, invoke_context::InvokeContext}, solana_program_runtime::{compute_budget::ComputeBudget, invoke_context::InvokeContext},
solana_rbpf::{ solana_rbpf::{elf::Executable, verifier::RequisiteVerifier},
elf::Executable,
verifier::{RequisiteVerifier, TautologyVerifier},
},
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::{
@ -2033,13 +2030,12 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
false, false,
) )
.unwrap(); .unwrap();
let executable = Executable::<TautologyVerifier, InvokeContext>::from_elf( let executable =
&program_data, Executable::<InvokeContext>::from_elf(&program_data, Arc::new(program_runtime_environment))
Arc::new(program_runtime_environment), .map_err(|err| format!("ELF error: {err}"))?;
)
.map_err(|err| format!("ELF error: {err}"))?;
let _ = Executable::<RequisiteVerifier, InvokeContext>::verified(executable) executable
.verify::<RequisiteVerifier>()
.map_err(|err| format!("ELF error: {err}"))?; .map_err(|err| format!("ELF error: {err}"))?;
Ok(program_data) Ok(program_data)

View File

@ -283,11 +283,11 @@ impl Debug for Output {
// 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>>, analysis: Option<Analysis<'a>>,
executable: &'a Executable<RequisiteVerifier, InvokeContext<'b>>, executable: &'a Executable<InvokeContext<'b>>,
} }
impl<'a, 'b> LazyAnalysis<'a, 'b> { impl<'a, 'b> LazyAnalysis<'a, 'b> {
fn new(executable: &'a Executable<RequisiteVerifier, InvokeContext<'b>>) -> Self { fn new(executable: &'a Executable<InvokeContext<'b>>) -> Self {
Self { Self {
analysis: None, analysis: None,
executable, executable,
@ -330,7 +330,7 @@ fn load_program<'a>(
filename: &Path, filename: &Path,
program_id: Pubkey, program_id: Pubkey,
invoke_context: &InvokeContext<'a>, invoke_context: &InvokeContext<'a>,
) -> Executable<RequisiteVerifier, InvokeContext<'a>> { ) -> Executable<InvokeContext<'a>> {
let mut file = File::open(filename).unwrap(); let mut file = File::open(filename).unwrap();
let mut magic = [0u8; 4]; let mut magic = [0u8; 4];
file.read_exact(&mut magic).unwrap(); file.read_exact(&mut magic).unwrap();
@ -374,22 +374,25 @@ fn load_program<'a>(
Err(err) => Err(format!("Loading executable failed: {err:?}")), Err(err) => Err(format!("Loading executable failed: {err:?}")),
} }
} else { } else {
let executable = assemble::<InvokeContext>( assemble::<InvokeContext>(
std::str::from_utf8(contents.as_slice()).unwrap(), std::str::from_utf8(contents.as_slice()).unwrap(),
Arc::new(program_runtime_environment), Arc::new(program_runtime_environment),
) )
.unwrap(); .map_err(|err| format!("Assembling executable failed: {err:?}"))
Executable::<RequisiteVerifier, InvokeContext>::verified(executable) .and_then(|executable| {
.map_err(|err| format!("Assembling executable failed: {err:?}")) executable
.verify::<RequisiteVerifier>()
.map_err(|err| format!("Verifying executable failed: {err:?}"))?;
Ok(executable)
})
} }
.unwrap(); .unwrap();
#[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))] #[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
verified_executable.jit_compile().unwrap(); verified_executable.jit_compile().unwrap();
unsafe { unsafe {
std::mem::transmute::< std::mem::transmute::<Executable<InvokeContext<'static>>, Executable<InvokeContext<'a>>>(
Executable<RequisiteVerifier, InvokeContext<'static>>, verified_executable,
Executable<RequisiteVerifier, InvokeContext<'a>>, )
>(verified_executable)
} }
} }

View File

@ -748,7 +748,8 @@ impl<'a> InvokeContext<'a> {
.ok_or(InstructionError::UnsupportedProgramId)?; .ok_or(InstructionError::UnsupportedProgramId)?;
let process_instruction = match &entry.program { let process_instruction = match &entry.program {
LoadedProgramType::Builtin(program) => program LoadedProgramType::Builtin(program) => program
.lookup_function(ENTRYPOINT_KEY) .get_function_registry()
.lookup_by_key(ENTRYPOINT_KEY)
.map(|(_name, process_instruction)| process_instruction), .map(|(_name, process_instruction)| process_instruction),
_ => None, _ => None,
} }

View File

@ -1,5 +1,3 @@
#[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
use solana_rbpf::error::EbpfError;
use { use {
crate::{ crate::{
invoke_context::{InvokeContext, ProcessInstructionWithContext}, invoke_context::{InvokeContext, ProcessInstructionWithContext},
@ -9,7 +7,11 @@ use {
log::{debug, log_enabled, trace}, log::{debug, log_enabled, trace},
percentage::PercentageInteger, percentage::PercentageInteger,
solana_measure::measure::Measure, solana_measure::measure::Measure,
solana_rbpf::{elf::Executable, verifier::RequisiteVerifier, vm::BuiltinProgram}, solana_rbpf::{
elf::{Executable, FunctionRegistry},
verifier::RequisiteVerifier,
vm::{BuiltinProgram, Config},
},
solana_sdk::{ solana_sdk::{
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, clock::Slot, loader_v4, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, clock::Slot, loader_v4,
pubkey::Pubkey, saturating_add_assign, pubkey::Pubkey, saturating_add_assign,
@ -66,9 +68,9 @@ pub enum LoadedProgramType {
DelayVisibility, DelayVisibility,
/// Successfully verified but not currently compiled, used to track usage statistics when a compiled program is evicted from memory. /// Successfully verified but not currently compiled, used to track usage statistics when a compiled program is evicted from memory.
Unloaded(Arc<BuiltinProgram<InvokeContext<'static>>>), Unloaded(Arc<BuiltinProgram<InvokeContext<'static>>>),
LegacyV0(Executable<RequisiteVerifier, InvokeContext<'static>>), LegacyV0(Executable<InvokeContext<'static>>),
LegacyV1(Executable<RequisiteVerifier, InvokeContext<'static>>), LegacyV1(Executable<InvokeContext<'static>>),
Typed(Executable<RequisiteVerifier, InvokeContext<'static>>), Typed(Executable<InvokeContext<'static>>),
#[cfg(test)] #[cfg(test)]
TestLoaded(Arc<BuiltinProgram<InvokeContext<'static>>>), TestLoaded(Arc<BuiltinProgram<InvokeContext<'static>>>),
Builtin(BuiltinProgram<InvokeContext<'static>>), Builtin(BuiltinProgram<InvokeContext<'static>>),
@ -228,39 +230,35 @@ impl LoadedProgram {
metrics: &mut LoadProgramMetrics, metrics: &mut LoadProgramMetrics,
) -> Result<Self, Box<dyn std::error::Error>> { ) -> Result<Self, Box<dyn std::error::Error>> {
let mut load_elf_time = Measure::start("load_elf_time"); let mut load_elf_time = Measure::start("load_elf_time");
let executable = Executable::load(elf_bytes, program_runtime_environment.clone())?; let mut executable = Executable::load(elf_bytes, program_runtime_environment.clone())?;
load_elf_time.stop(); load_elf_time.stop();
metrics.load_elf_us = load_elf_time.as_us(); metrics.load_elf_us = load_elf_time.as_us();
let mut verify_code_time = Measure::start("verify_code_time"); let mut verify_code_time = Measure::start("verify_code_time");
executable.verify::<RequisiteVerifier>()?;
// Allowing mut here, since it may be needed for jit compile, which is under a config flag
#[allow(unused_mut)]
let mut program = if bpf_loader_deprecated::check_id(loader_key) {
LoadedProgramType::LegacyV0(Executable::verified(executable)?)
} else if bpf_loader::check_id(loader_key) || bpf_loader_upgradeable::check_id(loader_key) {
LoadedProgramType::LegacyV1(Executable::verified(executable)?)
} else if loader_v4::check_id(loader_key) {
LoadedProgramType::Typed(Executable::verified(executable)?)
} else {
panic!();
};
verify_code_time.stop(); verify_code_time.stop();
metrics.verify_code_us = verify_code_time.as_us(); metrics.verify_code_us = verify_code_time.as_us();
#[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))] #[cfg(all(not(target_os = "windows"), target_arch = "x86_64"))]
{ {
let mut jit_compile_time = Measure::start("jit_compile_time"); let mut jit_compile_time = Measure::start("jit_compile_time");
match &mut program { executable.jit_compile()?;
LoadedProgramType::LegacyV0(executable) => executable.jit_compile(),
LoadedProgramType::LegacyV1(executable) => executable.jit_compile(),
LoadedProgramType::Typed(executable) => executable.jit_compile(),
_ => Err(EbpfError::JitNotCompiled),
}?;
jit_compile_time.stop(); jit_compile_time.stop();
metrics.jit_compile_us = jit_compile_time.as_us(); metrics.jit_compile_us = jit_compile_time.as_us();
} }
// Allowing mut here, since it may be needed for jit compile, which is under a config flag
#[allow(unused_mut)]
let mut program = if bpf_loader_deprecated::check_id(loader_key) {
LoadedProgramType::LegacyV0(executable)
} else if bpf_loader::check_id(loader_key) || bpf_loader_upgradeable::check_id(loader_key) {
LoadedProgramType::LegacyV1(executable)
} else if loader_v4::check_id(loader_key) {
LoadedProgramType::Typed(executable)
} else {
panic!();
};
Ok(Self { Ok(Self {
deployment_slot, deployment_slot,
account_size, account_size,
@ -298,9 +296,9 @@ impl LoadedProgram {
account_size: usize, account_size: usize,
entrypoint: ProcessInstructionWithContext, entrypoint: ProcessInstructionWithContext,
) -> Self { ) -> Self {
let mut program = BuiltinProgram::default(); let mut function_registry = FunctionRegistry::default();
program function_registry
.register_function(b"entrypoint", entrypoint) .register_function_hashed(*b"entrypoint", entrypoint)
.unwrap(); .unwrap();
Self { Self {
deployment_slot, deployment_slot,
@ -308,7 +306,7 @@ impl LoadedProgram {
effective_slot: deployment_slot, effective_slot: deployment_slot,
maybe_expiration_slot: None, maybe_expiration_slot: None,
tx_usage_counter: AtomicU64::new(0), tx_usage_counter: AtomicU64::new(0),
program: LoadedProgramType::Builtin(program), program: LoadedProgramType::Builtin(BuiltinProgram::new_builtin(function_registry)),
ix_usage_counter: AtomicU64::new(0), ix_usage_counter: AtomicU64::new(0),
} }
} }
@ -347,7 +345,7 @@ impl LoadedProgram {
} }
} }
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug)]
pub struct ProgramRuntimeEnvironments { pub struct ProgramRuntimeEnvironments {
/// Globally shared RBPF config and syscall registry /// Globally shared RBPF config and syscall registry
pub program_runtime_v1: Arc<BuiltinProgram<InvokeContext<'static>>>, pub program_runtime_v1: Arc<BuiltinProgram<InvokeContext<'static>>>,
@ -355,6 +353,19 @@ pub struct ProgramRuntimeEnvironments {
pub program_runtime_v2: Arc<BuiltinProgram<InvokeContext<'static>>>, pub program_runtime_v2: Arc<BuiltinProgram<InvokeContext<'static>>>,
} }
impl Default for ProgramRuntimeEnvironments {
fn default() -> Self {
let empty_loader = Arc::new(BuiltinProgram::new_loader(
Config::default(),
FunctionRegistry::default(),
));
Self {
program_runtime_v1: empty_loader.clone(),
program_runtime_v2: empty_loader,
}
}
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct LoadedPrograms { pub struct LoadedPrograms {
/// A two level index: /// A two level index:
@ -832,7 +843,7 @@ mod tests {
}, },
assert_matches::assert_matches, assert_matches::assert_matches,
percentage::Percentage, percentage::Percentage,
solana_rbpf::vm::{BuiltinProgram, Config}, solana_rbpf::vm::BuiltinProgram,
solana_sdk::{clock::Slot, pubkey::Pubkey}, solana_sdk::{clock::Slot, pubkey::Pubkey},
std::{ std::{
ops::ControlFlow, ops::ControlFlow,
@ -845,7 +856,7 @@ mod tests {
fn new_test_builtin_program(deployment_slot: Slot, effective_slot: Slot) -> Arc<LoadedProgram> { fn new_test_builtin_program(deployment_slot: Slot, effective_slot: Slot) -> Arc<LoadedProgram> {
Arc::new(LoadedProgram { Arc::new(LoadedProgram {
program: LoadedProgramType::Builtin(BuiltinProgram::default()), program: LoadedProgramType::Builtin(BuiltinProgram::new_mock()),
account_size: 0, account_size: 0,
deployment_slot, deployment_slot,
effective_slot, effective_slot,
@ -920,7 +931,7 @@ mod tests {
programs.push((program1, *deployment_slot, usage_counter)); programs.push((program1, *deployment_slot, usage_counter));
}); });
let env = Arc::new(BuiltinProgram::new_loader(Config::default())); let env = Arc::new(BuiltinProgram::new_mock());
for slot in 21..31 { for slot in 21..31 {
set_tombstone( set_tombstone(
&mut cache, &mut cache,
@ -1118,7 +1129,7 @@ mod tests {
fn test_replace_tombstones() { fn test_replace_tombstones() {
let mut cache = LoadedPrograms::default(); let mut cache = LoadedPrograms::default();
let program1 = Pubkey::new_unique(); let program1 = Pubkey::new_unique();
let env = Arc::new(BuiltinProgram::new_loader(Config::default())); let env = Arc::new(BuiltinProgram::new_mock());
set_tombstone( set_tombstone(
&mut cache, &mut cache,
program1, program1,
@ -1134,7 +1145,7 @@ mod tests {
#[test] #[test]
fn test_tombstone() { fn test_tombstone() {
let env = Arc::new(BuiltinProgram::new_loader(Config::default())); let env = Arc::new(BuiltinProgram::new_mock());
let tombstone = let tombstone =
LoadedProgram::new_tombstone(0, LoadedProgramType::FailedVerification(env.clone())); LoadedProgram::new_tombstone(0, LoadedProgramType::FailedVerification(env.clone()));
assert_matches!(tombstone.program, LoadedProgramType::FailedVerification(_)); assert_matches!(tombstone.program, LoadedProgramType::FailedVerification(_));
@ -1359,7 +1370,7 @@ mod tests {
usage_counter: AtomicU64, usage_counter: AtomicU64,
expiry: Option<Slot>, expiry: Option<Slot>,
) -> Arc<LoadedProgram> { ) -> Arc<LoadedProgram> {
let env = Arc::new(BuiltinProgram::new_loader(Config::default())); let env = Arc::new(BuiltinProgram::new_mock());
Arc::new(LoadedProgram { Arc::new(LoadedProgram {
program: LoadedProgramType::TestLoaded(env), program: LoadedProgramType::TestLoaded(env),
account_size: 0, account_size: 0,

View File

@ -14,7 +14,6 @@ bincode = { workspace = true }
byteorder = { workspace = true } byteorder = { workspace = true }
libsecp256k1 = { workspace = true } libsecp256k1 = { workspace = true }
log = { workspace = true } log = { workspace = true }
rand = { workspace = true }
scopeguard = { workspace = true } scopeguard = { workspace = true }
solana-measure = { workspace = true } solana-measure = { workspace = true }
solana-program-runtime = { workspace = true } solana-program-runtime = { workspace = true }
@ -26,6 +25,7 @@ thiserror = { workspace = true }
[dev-dependencies] [dev-dependencies]
assert_matches = { workspace = true } assert_matches = { workspace = true }
memoffset = { workspace = true } memoffset = { workspace = true }
rand = { workspace = true }
solana-sdk = { workspace = true, features = ["dev-context-only-utils"] } solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }
[lib] [lib]

View File

@ -22,7 +22,6 @@ use {
elf::Executable, elf::Executable,
error::EbpfError, error::EbpfError,
memory_region::{AccessType, MemoryCowCallback, MemoryMapping, MemoryRegion}, memory_region::{AccessType, MemoryCowCallback, MemoryMapping, MemoryRegion},
verifier::RequisiteVerifier,
vm::{BuiltinProgram, ContextObject, EbpfVm, ProgramResult}, vm::{BuiltinProgram, ContextObject, EbpfVm, ProgramResult},
}, },
solana_sdk::{ solana_sdk::{
@ -191,7 +190,7 @@ pub fn calculate_heap_cost(heap_size: u64, heap_cost: u64, enable_rounding_fix:
/// Only used in macro, do not use directly! /// Only used in macro, do not use directly!
pub fn create_vm<'a, 'b>( pub fn create_vm<'a, 'b>(
program: &'a Executable<RequisiteVerifier, InvokeContext<'b>>, program: &'a Executable<InvokeContext<'b>>,
regions: Vec<MemoryRegion>, regions: Vec<MemoryRegion>,
accounts_metadata: Vec<SerializedAccountMetadata>, accounts_metadata: Vec<SerializedAccountMetadata>,
invoke_context: &'a mut InvokeContext<'b>, invoke_context: &'a mut InvokeContext<'b>,
@ -285,24 +284,21 @@ macro_rules! create_vm {
#[macro_export] #[macro_export]
macro_rules! mock_create_vm { macro_rules! mock_create_vm {
($vm:ident, $additional_regions:expr, $accounts_metadata:expr, $invoke_context:expr $(,)?) => { ($vm:ident, $additional_regions:expr, $accounts_metadata:expr, $invoke_context:expr $(,)?) => {
let loader = std::sync::Arc::new(BuiltinProgram::new_loader( let loader = std::sync::Arc::new(BuiltinProgram::new_mock());
solana_rbpf::vm::Config::default(), let function_registry = solana_rbpf::elf::FunctionRegistry::default();
)); let executable = solana_rbpf::elf::Executable::<InvokeContext>::from_text_bytes(
let function_registry = solana_rbpf::vm::FunctionRegistry::default();
let executable = solana_rbpf::elf::Executable::<
solana_rbpf::verifier::TautologyVerifier,
InvokeContext,
>::from_text_bytes(
&[0x95, 0, 0, 0, 0, 0, 0, 0], &[0x95, 0, 0, 0, 0, 0, 0, 0],
loader, loader,
SBPFVersion::V2, SBPFVersion::V2,
function_registry, function_registry,
) )
.unwrap(); .unwrap();
let verified_executable = solana_rbpf::elf::Executable::verified(executable).unwrap(); executable
.verify::<solana_rbpf::verifier::RequisiteVerifier>()
.unwrap();
$crate::create_vm!( $crate::create_vm!(
$vm, $vm,
&verified_executable, &executable,
$additional_regions, $additional_regions,
$accounts_metadata, $accounts_metadata,
$invoke_context, $invoke_context,
@ -311,7 +307,7 @@ macro_rules! mock_create_vm {
} }
fn create_memory_mapping<'a, 'b, C: ContextObject>( fn create_memory_mapping<'a, 'b, C: ContextObject>(
executable: &'a Executable<RequisiteVerifier, C>, executable: &'a Executable<C>,
stack: &'b mut AlignedMemory<{ HOST_ALIGN }>, stack: &'b mut AlignedMemory<{ HOST_ALIGN }>,
heap: &'b mut AlignedMemory<{ HOST_ALIGN }>, heap: &'b mut AlignedMemory<{ HOST_ALIGN }>,
additional_regions: Vec<MemoryRegion>, additional_regions: Vec<MemoryRegion>,
@ -1483,14 +1479,12 @@ fn process_loader_instruction(invoke_context: &mut InvokeContext) -> Result<(),
} }
fn execute<'a, 'b: 'a>( fn execute<'a, 'b: 'a>(
executable: &'a Executable<RequisiteVerifier, InvokeContext<'static>>, executable: &'a Executable<InvokeContext<'static>>,
invoke_context: &'a mut InvokeContext<'b>, invoke_context: &'a mut InvokeContext<'b>,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
// We dropped the lifetime tracking in the Executor by setting it to 'static, // 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. // thus we need to reintroduce the correct lifetime of InvokeContext here again.
let executable = unsafe { let executable = unsafe { mem::transmute::<_, &'a Executable<InvokeContext<'b>>>(executable) };
mem::transmute::<_, &'a Executable<RequisiteVerifier, InvokeContext<'b>>>(executable)
};
let log_collector = invoke_context.get_log_collector(); let log_collector = invoke_context.get_log_collector();
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()?;
@ -1728,11 +1722,7 @@ mod tests {
solana_program_runtime::{ solana_program_runtime::{
invoke_context::mock_process_instruction, with_mock_invoke_context, invoke_context::mock_process_instruction, with_mock_invoke_context,
}, },
solana_rbpf::{ solana_rbpf::vm::ContextObject,
elf::SBPFVersion,
verifier::Verifier,
vm::{Config, ContextObject, FunctionRegistry},
},
solana_sdk::{ solana_sdk::{
account::{ account::{
create_account_shared_data_for_test as create_account_for_test, AccountSharedData, create_account_shared_data_for_test as create_account_for_test, AccountSharedData,
@ -1796,21 +1786,6 @@ mod tests {
program_account program_account
} }
#[test]
#[should_panic(expected = "LDDWCannotBeLast")]
fn test_bpf_loader_check_load_dw() {
let prog = &[
0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55, // first half of lddw
];
RequisiteVerifier::verify(
prog,
&Config::default(),
&SBPFVersion::V2,
&FunctionRegistry::default(),
)
.unwrap();
}
#[test] #[test]
fn test_bpf_loader_write() { fn test_bpf_loader_write() {
let loader_id = bpf_loader::id(); let loader_id = bpf_loader::id();
@ -4103,7 +4078,7 @@ mod tests {
let transaction_accounts = vec![]; let transaction_accounts = vec![];
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts); with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
let program_id = Pubkey::new_unique(); let program_id = Pubkey::new_unique();
let env = Arc::new(BuiltinProgram::new_loader(Config::default())); let env = Arc::new(BuiltinProgram::new_mock());
let program = LoadedProgram { let program = LoadedProgram {
program: LoadedProgramType::Unloaded(env), program: LoadedProgramType::Unloaded(env),
account_size: 0, account_size: 0,
@ -4143,7 +4118,7 @@ mod tests {
let transaction_accounts = vec![]; let transaction_accounts = vec![];
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts); with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
let program_id = Pubkey::new_unique(); let program_id = Pubkey::new_unique();
let env = Arc::new(BuiltinProgram::new_loader(Config::default())); let env = Arc::new(BuiltinProgram::new_mock());
let program = LoadedProgram { let program = LoadedProgram {
program: LoadedProgramType::Unloaded(env), program: LoadedProgramType::Unloaded(env),
account_size: 0, account_size: 0,

View File

@ -16,8 +16,9 @@ use {
stable_log, timings::ExecuteTimings, stable_log, timings::ExecuteTimings,
}, },
solana_rbpf::{ solana_rbpf::{
elf::FunctionRegistry,
memory_region::{AccessType, MemoryMapping}, memory_region::{AccessType, MemoryMapping},
vm::{BuiltinProgram, Config, ProgramResult, PROGRAM_ENVIRONMENT_KEY_SHIFT}, vm::{BuiltinFunction, BuiltinProgram, Config, ProgramResult},
}, },
solana_sdk::{ solana_sdk::{
account::{ReadableAccount, WritableAccount}, account::{ReadableAccount, WritableAccount},
@ -139,9 +140,9 @@ fn consume_compute_meter(invoke_context: &InvokeContext, amount: u64) -> Result<
macro_rules! register_feature_gated_function { macro_rules! register_feature_gated_function {
($result: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 {
$result.register_function($name, $call) $result.register_function_hashed($name, $call)
} else { } else {
Ok(()) Ok(0)
} }
}; };
} }
@ -167,7 +168,6 @@ pub fn create_program_runtime_environment_v1<'a>(
// When adding new features for RBPF here, // When adding new features for RBPF here,
// also add them to `Bank::apply_builtin_program_feature_transitions()`. // also add them to `Bank::apply_builtin_program_feature_transitions()`.
use rand::Rng;
let config = Config { let config = Config {
max_call_depth: compute_budget.max_call_depth, max_call_depth: compute_budget.max_call_depth,
stack_frame_size: compute_budget.stack_frame_size, stack_frame_size: compute_budget.stack_frame_size,
@ -180,10 +180,7 @@ pub fn create_program_runtime_environment_v1<'a>(
reject_broken_elfs: reject_deployment_of_broken_elfs, reject_broken_elfs: reject_deployment_of_broken_elfs,
noop_instruction_rate: 256, noop_instruction_rate: 256,
sanitize_user_provided_values: true, sanitize_user_provided_values: true,
runtime_environment_key: rand::thread_rng() encrypt_runtime_environment: true,
.gen::<i32>()
.checked_shr(PROGRAM_ENVIRONMENT_KEY_SHIFT)
.unwrap_or(0),
external_internal_function_hash_collision: feature_set external_internal_function_hash_collision: feature_set
.is_active(&error_on_syscall_bpf_function_hash_collisions::id()), .is_active(&error_on_syscall_bpf_function_hash_collisions::id()),
reject_callx_r10: feature_set.is_active(&reject_callx_r10::id()), reject_callx_r10: feature_set.is_active(&reject_callx_r10::id()),
@ -194,44 +191,44 @@ pub fn create_program_runtime_environment_v1<'a>(
aligned_memory_mapping: !feature_set.is_active(&bpf_account_data_direct_mapping::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. // Warning, do not use `Config::default()` so that configuration here is explicit.
}; };
let mut result = BuiltinProgram::new_loader(config); let mut result = FunctionRegistry::<BuiltinFunction<InvokeContext>>::default();
// Abort // Abort
result.register_function(b"abort", SyscallAbort::call)?; result.register_function_hashed(*b"abort", SyscallAbort::call)?;
// Panic // Panic
result.register_function(b"sol_panic_", SyscallPanic::call)?; result.register_function_hashed(*b"sol_panic_", SyscallPanic::call)?;
// Logging // Logging
result.register_function(b"sol_log_", SyscallLog::call)?; result.register_function_hashed(*b"sol_log_", SyscallLog::call)?;
result.register_function(b"sol_log_64_", SyscallLogU64::call)?; result.register_function_hashed(*b"sol_log_64_", SyscallLogU64::call)?;
result.register_function(b"sol_log_compute_units_", SyscallLogBpfComputeUnits::call)?; result.register_function_hashed(*b"sol_log_compute_units_", SyscallLogBpfComputeUnits::call)?;
result.register_function(b"sol_log_pubkey", SyscallLogPubkey::call)?; result.register_function_hashed(*b"sol_log_pubkey", SyscallLogPubkey::call)?;
// Program defined addresses (PDA) // Program defined addresses (PDA)
result.register_function( result.register_function_hashed(
b"sol_create_program_address", *b"sol_create_program_address",
SyscallCreateProgramAddress::call, SyscallCreateProgramAddress::call,
)?; )?;
result.register_function( result.register_function_hashed(
b"sol_try_find_program_address", *b"sol_try_find_program_address",
SyscallTryFindProgramAddress::call, SyscallTryFindProgramAddress::call,
)?; )?;
// Sha256 // Sha256
result.register_function(b"sol_sha256", SyscallSha256::call)?; result.register_function_hashed(*b"sol_sha256", SyscallSha256::call)?;
// Keccak256 // Keccak256
result.register_function(b"sol_keccak256", SyscallKeccak256::call)?; result.register_function_hashed(*b"sol_keccak256", SyscallKeccak256::call)?;
// Secp256k1 Recover // Secp256k1 Recover
result.register_function(b"sol_secp256k1_recover", SyscallSecp256k1Recover::call)?; result.register_function_hashed(*b"sol_secp256k1_recover", SyscallSecp256k1Recover::call)?;
// Blake3 // Blake3
register_feature_gated_function!( register_feature_gated_function!(
result, result,
blake3_syscall_enabled, blake3_syscall_enabled,
b"sol_blake3", *b"sol_blake3",
SyscallBlake3::call, SyscallBlake3::call,
)?; )?;
@ -239,78 +236,78 @@ pub fn create_program_runtime_environment_v1<'a>(
register_feature_gated_function!( register_feature_gated_function!(
result, result,
curve25519_syscall_enabled, curve25519_syscall_enabled,
b"sol_curve_validate_point", *b"sol_curve_validate_point",
SyscallCurvePointValidation::call, SyscallCurvePointValidation::call,
)?; )?;
register_feature_gated_function!( register_feature_gated_function!(
result, result,
curve25519_syscall_enabled, curve25519_syscall_enabled,
b"sol_curve_group_op", *b"sol_curve_group_op",
SyscallCurveGroupOps::call, SyscallCurveGroupOps::call,
)?; )?;
register_feature_gated_function!( register_feature_gated_function!(
result, result,
curve25519_syscall_enabled, curve25519_syscall_enabled,
b"sol_curve_multiscalar_mul", *b"sol_curve_multiscalar_mul",
SyscallCurveMultiscalarMultiplication::call, SyscallCurveMultiscalarMultiplication::call,
)?; )?;
// Sysvars // Sysvars
result.register_function(b"sol_get_clock_sysvar", SyscallGetClockSysvar::call)?; result.register_function_hashed(*b"sol_get_clock_sysvar", SyscallGetClockSysvar::call)?;
result.register_function( result.register_function_hashed(
b"sol_get_epoch_schedule_sysvar", *b"sol_get_epoch_schedule_sysvar",
SyscallGetEpochScheduleSysvar::call, SyscallGetEpochScheduleSysvar::call,
)?; )?;
register_feature_gated_function!( register_feature_gated_function!(
result, result,
!disable_fees_sysvar, !disable_fees_sysvar,
b"sol_get_fees_sysvar", *b"sol_get_fees_sysvar",
SyscallGetFeesSysvar::call, SyscallGetFeesSysvar::call,
)?; )?;
result.register_function(b"sol_get_rent_sysvar", SyscallGetRentSysvar::call)?; result.register_function_hashed(*b"sol_get_rent_sysvar", SyscallGetRentSysvar::call)?;
register_feature_gated_function!( register_feature_gated_function!(
result, result,
last_restart_slot_syscall_enabled, last_restart_slot_syscall_enabled,
b"sol_get_last_restart_slot", *b"sol_get_last_restart_slot",
SyscallGetLastRestartSlotSysvar::call, SyscallGetLastRestartSlotSysvar::call,
)?; )?;
register_feature_gated_function!( register_feature_gated_function!(
result, result,
epoch_rewards_syscall_enabled, epoch_rewards_syscall_enabled,
b"sol_get_epoch_rewards_sysvar", *b"sol_get_epoch_rewards_sysvar",
SyscallGetEpochRewardsSysvar::call, SyscallGetEpochRewardsSysvar::call,
)?; )?;
// Memory ops // Memory ops
result.register_function(b"sol_memcpy_", SyscallMemcpy::call)?; result.register_function_hashed(*b"sol_memcpy_", SyscallMemcpy::call)?;
result.register_function(b"sol_memmove_", SyscallMemmove::call)?; result.register_function_hashed(*b"sol_memmove_", SyscallMemmove::call)?;
result.register_function(b"sol_memcmp_", SyscallMemcmp::call)?; result.register_function_hashed(*b"sol_memcmp_", SyscallMemcmp::call)?;
result.register_function(b"sol_memset_", SyscallMemset::call)?; result.register_function_hashed(*b"sol_memset_", SyscallMemset::call)?;
// Processed sibling instructions // Processed sibling instructions
result.register_function( result.register_function_hashed(
b"sol_get_processed_sibling_instruction", *b"sol_get_processed_sibling_instruction",
SyscallGetProcessedSiblingInstruction::call, SyscallGetProcessedSiblingInstruction::call,
)?; )?;
// Stack height // Stack height
result.register_function(b"sol_get_stack_height", SyscallGetStackHeight::call)?; result.register_function_hashed(*b"sol_get_stack_height", SyscallGetStackHeight::call)?;
// Return data // Return data
result.register_function(b"sol_set_return_data", SyscallSetReturnData::call)?; result.register_function_hashed(*b"sol_set_return_data", SyscallSetReturnData::call)?;
result.register_function(b"sol_get_return_data", SyscallGetReturnData::call)?; result.register_function_hashed(*b"sol_get_return_data", SyscallGetReturnData::call)?;
// Cross-program invocation // Cross-program invocation
result.register_function(b"sol_invoke_signed_c", SyscallInvokeSignedC::call)?; result.register_function_hashed(*b"sol_invoke_signed_c", SyscallInvokeSignedC::call)?;
result.register_function(b"sol_invoke_signed_rust", SyscallInvokeSignedRust::call)?; result.register_function_hashed(*b"sol_invoke_signed_rust", SyscallInvokeSignedRust::call)?;
// Memory allocator // Memory allocator
register_feature_gated_function!( register_feature_gated_function!(
result, result,
!disable_deploy_of_alloc_free_syscall, !disable_deploy_of_alloc_free_syscall,
b"sol_alloc_free_", *b"sol_alloc_free_",
SyscallAllocFree::call, SyscallAllocFree::call,
)?; )?;
@ -318,7 +315,7 @@ pub fn create_program_runtime_environment_v1<'a>(
register_feature_gated_function!( register_feature_gated_function!(
result, result,
enable_alt_bn128_syscall, enable_alt_bn128_syscall,
b"sol_alt_bn128_group_op", *b"sol_alt_bn128_group_op",
SyscallAltBn128::call, SyscallAltBn128::call,
)?; )?;
@ -326,7 +323,7 @@ pub fn create_program_runtime_environment_v1<'a>(
register_feature_gated_function!( register_feature_gated_function!(
result, result,
enable_big_mod_exp_syscall, enable_big_mod_exp_syscall,
b"sol_big_mod_exp", *b"sol_big_mod_exp",
SyscallBigModExp::call, SyscallBigModExp::call,
)?; )?;
@ -334,14 +331,14 @@ pub fn create_program_runtime_environment_v1<'a>(
register_feature_gated_function!( register_feature_gated_function!(
result, result,
enable_poseidon_syscall, enable_poseidon_syscall,
b"sol_poseidon", *b"sol_poseidon",
SyscallPoseidon::call, SyscallPoseidon::call,
)?; )?;
// Log data // Log data
result.register_function(b"sol_log_data", SyscallLogData::call)?; result.register_function_hashed(*b"sol_log_data", SyscallLogData::call)?;
Ok(result) Ok(BuiltinProgram::new_loader(config, result))
} }
fn address_is_aligned<T>(address: u64) -> bool { fn address_is_aligned<T>(address: u64) -> bool {

View File

@ -10,7 +10,6 @@ edition = { workspace = true }
[dependencies] [dependencies]
log = { workspace = true } log = { workspace = true }
rand = { workspace = true }
solana-measure = { workspace = true } solana-measure = { workspace = true }
solana-program-runtime = { workspace = true } solana-program-runtime = { workspace = true }
solana-sdk = { workspace = true } solana-sdk = { workspace = true }

View File

@ -1,5 +1,4 @@
use { use {
rand::Rng,
solana_measure::measure::Measure, solana_measure::measure::Measure,
solana_program_runtime::{ solana_program_runtime::{
compute_budget::ComputeBudget, compute_budget::ComputeBudget,
@ -14,13 +13,9 @@ use {
solana_rbpf::{ solana_rbpf::{
aligned_memory::AlignedMemory, aligned_memory::AlignedMemory,
ebpf, ebpf,
elf::Executable, elf::{Executable, FunctionRegistry},
memory_region::{MemoryMapping, MemoryRegion}, memory_region::{MemoryMapping, MemoryRegion},
verifier::RequisiteVerifier, vm::{BuiltinProgram, Config, ContextObject, EbpfVm, ProgramResult},
vm::{
BuiltinProgram, Config, ContextObject, EbpfVm, ProgramResult,
PROGRAM_ENVIRONMENT_KEY_SHIFT,
},
}, },
solana_sdk::{ solana_sdk::{
entrypoint::{HEAP_LENGTH, SUCCESS}, entrypoint::{HEAP_LENGTH, SUCCESS},
@ -86,10 +81,7 @@ pub fn create_program_runtime_environment_v2<'a>(
reject_broken_elfs: true, reject_broken_elfs: true,
noop_instruction_rate: 256, noop_instruction_rate: 256,
sanitize_user_provided_values: true, sanitize_user_provided_values: true,
runtime_environment_key: rand::thread_rng() encrypt_runtime_environment: true,
.gen::<i32>()
.checked_shr(PROGRAM_ENVIRONMENT_KEY_SHIFT)
.unwrap_or(0),
external_internal_function_hash_collision: true, external_internal_function_hash_collision: true,
reject_callx_r10: true, reject_callx_r10: true,
enable_sbpf_v1: false, enable_sbpf_v1: false,
@ -99,7 +91,7 @@ pub fn create_program_runtime_environment_v2<'a>(
aligned_memory_mapping: true, aligned_memory_mapping: true,
// Warning, do not use `Config::default()` so that configuration here is explicit. // Warning, do not use `Config::default()` so that configuration here is explicit.
}; };
BuiltinProgram::new_loader(config) BuiltinProgram::new_loader(config, FunctionRegistry::default())
} }
fn calculate_heap_cost(heap_size: u64, heap_cost: u64) -> u64 { fn calculate_heap_cost(heap_size: u64, heap_cost: u64) -> u64 {
@ -116,7 +108,7 @@ fn calculate_heap_cost(heap_size: u64, heap_cost: u64) -> u64 {
/// Create the SBF virtual machine /// Create the SBF virtual machine
pub fn create_vm<'a, 'b>( pub fn create_vm<'a, 'b>(
invoke_context: &'a mut InvokeContext<'b>, invoke_context: &'a mut InvokeContext<'b>,
program: &'a Executable<RequisiteVerifier, InvokeContext<'b>>, program: &'a Executable<InvokeContext<'b>>,
) -> Result<EbpfVm<'a, InvokeContext<'b>>, Box<dyn std::error::Error>> { ) -> Result<EbpfVm<'a, InvokeContext<'b>>, Box<dyn std::error::Error>> {
let config = program.get_config(); let config = program.get_config();
let sbpf_version = program.get_sbpf_version(); let sbpf_version = program.get_sbpf_version();
@ -152,13 +144,12 @@ pub fn create_vm<'a, 'b>(
fn execute<'a, 'b: 'a>( fn execute<'a, 'b: 'a>(
invoke_context: &'a mut InvokeContext<'b>, invoke_context: &'a mut InvokeContext<'b>,
executable: &'a Executable<RequisiteVerifier, InvokeContext<'static>>, executable: &'a Executable<InvokeContext<'static>>,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
// We dropped the lifetime tracking in the Executor by setting it to 'static, // 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. // thus we need to reintroduce the correct lifetime of InvokeContext here again.
let executable = unsafe { let executable =
std::mem::transmute::<_, &'a Executable<RequisiteVerifier, InvokeContext<'b>>>(executable) unsafe { std::mem::transmute::<_, &'a Executable<InvokeContext<'b>>>(executable) };
};
let log_collector = invoke_context.get_log_collector(); let log_collector = invoke_context.get_log_collector();
let stack_height = invoke_context.get_stack_height(); let stack_height = invoke_context.get_stack_height();
let transaction_context = &invoke_context.transaction_context; let transaction_context = &invoke_context.transaction_context;
@ -763,7 +754,11 @@ mod tests {
let transaction_accounts = vec![ let transaction_accounts = vec![
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf(authority_address, LoaderV4Status::Deployed, "noop"), load_program_account_from_elf(
authority_address,
LoaderV4Status::Deployed,
"relative_call",
),
), ),
( (
authority_address, authority_address,
@ -771,7 +766,11 @@ mod tests {
), ),
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf(authority_address, LoaderV4Status::Finalized, "noop"), load_program_account_from_elf(
authority_address,
LoaderV4Status::Finalized,
"relative_call",
),
), ),
( (
clock::id(), clock::id(),
@ -853,7 +852,11 @@ mod tests {
let transaction_accounts = vec![ let transaction_accounts = vec![
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf(authority_address, LoaderV4Status::Retracted, "noop"), load_program_account_from_elf(
authority_address,
LoaderV4Status::Retracted,
"relative_call",
),
), ),
( (
authority_address, authority_address,
@ -861,7 +864,11 @@ mod tests {
), ),
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf(authority_address, LoaderV4Status::Deployed, "noop"), load_program_account_from_elf(
authority_address,
LoaderV4Status::Deployed,
"relative_call",
),
), ),
( (
clock::id(), clock::id(),
@ -942,7 +949,11 @@ mod tests {
let mut transaction_accounts = vec![ let mut transaction_accounts = vec![
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf(authority_address, LoaderV4Status::Retracted, "noop"), load_program_account_from_elf(
authority_address,
LoaderV4Status::Retracted,
"relative_call",
),
), ),
( (
authority_address, authority_address,
@ -954,19 +965,23 @@ mod tests {
), ),
( (
Pubkey::new_unique(), Pubkey::new_unique(),
AccountSharedData::new(20000000, 0, &loader_v4::id()), AccountSharedData::new(40000000, 0, &loader_v4::id()),
), ),
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Retracted, LoaderV4Status::Retracted,
"rodata", "rodata_section",
), ),
), ),
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf(authority_address, LoaderV4Status::Deployed, "noop"), load_program_account_from_elf(
authority_address,
LoaderV4Status::Deployed,
"relative_call",
),
), ),
( (
clock::id(), clock::id(),
@ -1194,7 +1209,7 @@ mod tests {
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Retracted, LoaderV4Status::Retracted,
"rodata", "rodata_section",
), ),
), ),
( (
@ -1203,7 +1218,11 @@ mod tests {
), ),
( (
Pubkey::new_unique(), Pubkey::new_unique(),
load_program_account_from_elf(authority_address, LoaderV4Status::Retracted, "noop"), load_program_account_from_elf(
authority_address,
LoaderV4Status::Retracted,
"relative_call",
),
), ),
( (
Pubkey::new_unique(), Pubkey::new_unique(),
@ -1338,7 +1357,7 @@ mod tests {
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Deployed, LoaderV4Status::Deployed,
"rodata", "rodata_section",
), ),
), ),
( (
@ -1354,7 +1373,7 @@ mod tests {
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Retracted, LoaderV4Status::Retracted,
"rodata", "rodata_section",
), ),
), ),
(clock::id(), clock(1000)), (clock::id(), clock(1000)),
@ -1418,7 +1437,7 @@ mod tests {
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Deployed, LoaderV4Status::Deployed,
"rodata", "rodata_section",
), ),
), ),
( (
@ -1426,7 +1445,7 @@ mod tests {
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Retracted, LoaderV4Status::Retracted,
"rodata", "rodata_section",
), ),
), ),
( (
@ -1519,7 +1538,7 @@ mod tests {
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Finalized, LoaderV4Status::Finalized,
"rodata", "rodata_section",
), ),
), ),
( (
@ -1535,7 +1554,7 @@ mod tests {
load_program_account_from_elf( load_program_account_from_elf(
authority_address, authority_address,
LoaderV4Status::Retracted, LoaderV4Status::Retracted,
"rodata", "rodata_section",
), ),
), ),
( (

Binary file not shown.

Binary file not shown.

View File

@ -4623,7 +4623,6 @@ dependencies = [
"byteorder 1.4.3", "byteorder 1.4.3",
"libsecp256k1 0.6.0", "libsecp256k1 0.6.0",
"log", "log",
"rand 0.8.5",
"scopeguard", "scopeguard",
"solana-measure", "solana-measure",
"solana-program-runtime", "solana-program-runtime",
@ -5126,7 +5125,6 @@ name = "solana-loader-v4-program"
version = "1.17.0" version = "1.17.0"
dependencies = [ dependencies = [
"log", "log",
"rand 0.8.5",
"solana-measure", "solana-measure",
"solana-program-runtime", "solana-program-runtime",
"solana-sdk", "solana-sdk",
@ -6451,9 +6449,9 @@ dependencies = [
[[package]] [[package]]
name = "solana_rbpf" name = "solana_rbpf"
version = "0.6.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3082ec3a1d4ef7879eb5b84916d5acde057abd59733eec3647e0ab8885283ef" checksum = "339e8963a8e2721227e46cf7a8488957db94cde0f35d3a769e292baaebdbeb44"
dependencies = [ dependencies = [
"byteorder 1.4.3", "byteorder 1.4.3",
"combine", "combine",

View File

@ -25,7 +25,7 @@ rand = "0.8"
rustversion = "1.0.14" rustversion = "1.0.14"
serde = "1.0.112" serde = "1.0.112"
serde_json = "1.0.56" serde_json = "1.0.56"
solana_rbpf = "=0.6.0" solana_rbpf = "=0.7.0"
solana-account-decoder = { path = "../../account-decoder", version = "=1.17.0" } solana-account-decoder = { path = "../../account-decoder", version = "=1.17.0" }
solana-accounts-db = { path = "../../accounts-db", version = "=1.17.0" } solana-accounts-db = { path = "../../accounts-db", version = "=1.17.0" }
solana-address-lookup-table-program = { path = "../../programs/address-lookup-table", version = "=1.17.0" } solana-address-lookup-table-program = { path = "../../programs/address-lookup-table", version = "=1.17.0" }

View File

@ -19,11 +19,8 @@ use {
solana_measure::measure::Measure, solana_measure::measure::Measure,
solana_program_runtime::{compute_budget::ComputeBudget, invoke_context::InvokeContext}, solana_program_runtime::{compute_budget::ComputeBudget, invoke_context::InvokeContext},
solana_rbpf::{ solana_rbpf::{
ebpf::MM_INPUT_START, ebpf::MM_INPUT_START, elf::Executable, memory_region::MemoryRegion,
elf::Executable, verifier::RequisiteVerifier, vm::ContextObject,
memory_region::MemoryRegion,
verifier::{RequisiteVerifier, TautologyVerifier},
vm::ContextObject,
}, },
solana_runtime::{ solana_runtime::{
bank::Bank, bank::Bank,
@ -98,11 +95,8 @@ fn bench_program_create_executable(bencher: &mut Bencher) {
); );
let program_runtime_environment = Arc::new(program_runtime_environment.unwrap()); let program_runtime_environment = Arc::new(program_runtime_environment.unwrap());
bencher.iter(|| { bencher.iter(|| {
let _ = Executable::<TautologyVerifier, InvokeContext>::from_elf( let _ = Executable::<InvokeContext>::from_elf(&elf, program_runtime_environment.clone())
&elf, .unwrap();
program_runtime_environment.clone(),
)
.unwrap();
}); });
} }
@ -124,19 +118,16 @@ fn bench_program_alu(bencher: &mut Bencher) {
true, true,
false, false,
); );
let executable = Executable::<TautologyVerifier, InvokeContext>::from_elf( let mut executable =
&elf, Executable::<InvokeContext>::from_elf(&elf, Arc::new(program_runtime_environment.unwrap()))
Arc::new(program_runtime_environment.unwrap()), .unwrap();
)
.unwrap();
let mut verified_executable = executable.verify::<RequisiteVerifier>().unwrap();
Executable::<RequisiteVerifier, InvokeContext>::verified(executable).unwrap();
verified_executable.jit_compile().unwrap(); executable.jit_compile().unwrap();
create_vm!( create_vm!(
vm, vm,
&verified_executable, &executable,
vec![MemoryRegion::new_writable(&mut inner_iter, MM_INPUT_START)], vec![MemoryRegion::new_writable(&mut inner_iter, MM_INPUT_START)],
vec![], vec![],
&mut invoke_context, &mut invoke_context,
@ -146,7 +137,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
println!("Interpreted:"); println!("Interpreted:");
vm.context_object_pointer vm.context_object_pointer
.mock_set_remaining(std::i64::MAX as u64); .mock_set_remaining(std::i64::MAX as u64);
let (instructions, result) = vm.execute_program(&verified_executable, true); let (instructions, result) = vm.execute_program(&executable, 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));
assert_eq!( assert_eq!(
@ -157,7 +148,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
bencher.iter(|| { bencher.iter(|| {
vm.context_object_pointer vm.context_object_pointer
.mock_set_remaining(std::i64::MAX as u64); .mock_set_remaining(std::i64::MAX as u64);
vm.execute_program(&verified_executable, true).1.unwrap(); vm.execute_program(&executable, true).1.unwrap();
}); });
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap(); let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
println!(" {:?} instructions", instructions); println!(" {:?} instructions", instructions);
@ -168,10 +159,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips); println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
println!("JIT to native:"); println!("JIT to native:");
assert_eq!( assert_eq!(SUCCESS, vm.execute_program(&executable, false).1.unwrap());
SUCCESS,
vm.execute_program(&verified_executable, false).1.unwrap()
);
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter)); assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
assert_eq!( assert_eq!(
ARMSTRONG_EXPECTED, ARMSTRONG_EXPECTED,
@ -181,7 +169,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
bencher.iter(|| { bencher.iter(|| {
vm.context_object_pointer vm.context_object_pointer
.mock_set_remaining(std::i64::MAX as u64); .mock_set_remaining(std::i64::MAX as u64);
vm.execute_program(&verified_executable, false).1.unwrap(); vm.execute_program(&executable, false).1.unwrap();
}); });
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap(); let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
println!(" {:?} instructions", instructions); println!(" {:?} instructions", instructions);
@ -243,14 +231,11 @@ fn bench_create_vm(bencher: &mut Bencher) {
true, true,
false, false,
); );
let executable = Executable::<TautologyVerifier, InvokeContext>::from_elf( let executable =
&elf, Executable::<InvokeContext>::from_elf(&elf, Arc::new(program_runtime_environment.unwrap()))
Arc::new(program_runtime_environment.unwrap()), .unwrap();
)
.unwrap();
let verified_executable = executable.verify::<RequisiteVerifier>().unwrap();
Executable::<RequisiteVerifier, InvokeContext>::verified(executable).unwrap();
// Serialize account data // Serialize account data
let (_serialized, regions, account_lengths) = serialize_parameters( let (_serialized, regions, account_lengths) = serialize_parameters(
@ -267,7 +252,7 @@ fn bench_create_vm(bencher: &mut Bencher) {
bencher.iter(|| { bencher.iter(|| {
create_vm!( create_vm!(
vm, vm,
&verified_executable, &executable,
clone_regions(&regions), clone_regions(&regions),
account_lengths.clone(), account_lengths.clone(),
&mut invoke_context, &mut invoke_context,
@ -305,18 +290,15 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
true, true,
false, false,
); );
let executable = Executable::<TautologyVerifier, InvokeContext>::from_elf( let executable =
&elf, Executable::<InvokeContext>::from_elf(&elf, Arc::new(program_runtime_environment.unwrap()))
Arc::new(program_runtime_environment.unwrap()), .unwrap();
)
.unwrap();
let verified_executable = executable.verify::<RequisiteVerifier>().unwrap();
Executable::<RequisiteVerifier, InvokeContext>::verified(executable).unwrap();
create_vm!( create_vm!(
vm, vm,
&verified_executable, &executable,
regions, regions,
account_lengths, account_lengths,
&mut invoke_context, &mut invoke_context,
@ -324,7 +306,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
let mut vm = vm.unwrap(); let mut vm = vm.unwrap();
let mut measure = Measure::start("tune"); let mut measure = Measure::start("tune");
let (instructions, _result) = vm.execute_program(&verified_executable, true); let (instructions, _result) = vm.execute_program(&executable, true);
measure.stop(); measure.stop();
assert_eq!( assert_eq!(