Revert "Updates rbpf to v0.2.0, (#12951)"
This reverts commit 6606590b81
.
This commit is contained in:
parent
7d686b72a0
commit
da361afbb9
|
@ -4637,7 +4637,6 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"hmac",
|
"hmac",
|
||||||
"itertools 0.9.0",
|
"itertools 0.9.0",
|
||||||
"lazy_static",
|
|
||||||
"libsecp256k1",
|
"libsecp256k1",
|
||||||
"log 0.4.8",
|
"log 0.4.8",
|
||||||
"memmap",
|
"memmap",
|
||||||
|
@ -4678,6 +4677,7 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"hmac",
|
"hmac",
|
||||||
"itertools 0.9.0",
|
"itertools 0.9.0",
|
||||||
|
"lazy_static",
|
||||||
"libsecp256k1",
|
"libsecp256k1",
|
||||||
"log 0.4.8",
|
"log 0.4.8",
|
||||||
"memmap",
|
"memmap",
|
||||||
|
@ -5077,9 +5077,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana_rbpf"
|
name = "solana_rbpf"
|
||||||
version = "0.2.0"
|
version = "0.1.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09e18fa1e1b6cac20a5f2571882b7580a65ae685b1413fc498f975d07d4c968f"
|
checksum = "9a95dbe2b00920ac4e1524b7442cf5319f01e8fa5742930ac60148882fd7738b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"combine",
|
"combine",
|
||||||
|
|
|
@ -37,7 +37,7 @@ solana-config-program = { path = "../programs/config", version = "1.5.0" }
|
||||||
solana-faucet = { path = "../faucet", version = "1.5.0" }
|
solana-faucet = { path = "../faucet", version = "1.5.0" }
|
||||||
solana-logger = { path = "../logger", version = "1.5.0" }
|
solana-logger = { path = "../logger", version = "1.5.0" }
|
||||||
solana-net-utils = { path = "../net-utils", version = "1.5.0" }
|
solana-net-utils = { path = "../net-utils", version = "1.5.0" }
|
||||||
solana_rbpf = "=0.2.0"
|
solana_rbpf = "=0.1.32"
|
||||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.5.0" }
|
solana-remote-wallet = { path = "../remote-wallet", version = "1.5.0" }
|
||||||
solana-sdk = { path = "../sdk", version = "1.5.0" }
|
solana-sdk = { path = "../sdk", version = "1.5.0" }
|
||||||
solana-stake-program = { path = "../programs/stake", version = "1.5.0" }
|
solana-stake-program = { path = "../programs/stake", version = "1.5.0" }
|
||||||
|
|
|
@ -9,7 +9,7 @@ use log::*;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use serde_json::{self, json, Value};
|
use serde_json::{self, json, Value};
|
||||||
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
||||||
use solana_bpf_loader_program::{bpf_verifier, BPFError};
|
use solana_bpf_loader_program::bpf_verifier;
|
||||||
use solana_clap_utils::{
|
use solana_clap_utils::{
|
||||||
self,
|
self,
|
||||||
commitment::commitment_arg_with_default,
|
commitment::commitment_arg_with_default,
|
||||||
|
@ -39,7 +39,7 @@ use solana_client::{
|
||||||
use solana_faucet::faucet::request_airdrop_transaction;
|
use solana_faucet::faucet::request_airdrop_transaction;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use solana_faucet::faucet_mock::request_airdrop_transaction;
|
use solana_faucet::faucet_mock::request_airdrop_transaction;
|
||||||
use solana_rbpf::vm::Executable;
|
use solana_rbpf::vm::EbpfVm;
|
||||||
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
bpf_loader, bpf_loader_deprecated,
|
bpf_loader, bpf_loader_deprecated,
|
||||||
|
@ -1217,7 +1217,7 @@ fn do_process_deploy(
|
||||||
CliError::DynamicProgramError(format!("Unable to read program file: {}", err))
|
CliError::DynamicProgramError(format!("Unable to read program file: {}", err))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Executable::<BPFError>::from_elf(&program_data, Some(|x| bpf_verifier::check(x, true)))
|
EbpfVm::create_executable_from_elf(&program_data, Some(|x| bpf_verifier::check(x, true)))
|
||||||
.map_err(|err| CliError::DynamicProgramError(format!("ELF error: {}", err)))?;
|
.map_err(|err| CliError::DynamicProgramError(format!("ELF error: {}", err)))?;
|
||||||
|
|
||||||
let loader_id = if use_deprecated_loader {
|
let loader_id = if use_deprecated_loader {
|
||||||
|
|
|
@ -2302,9 +2302,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana_rbpf"
|
name = "solana_rbpf"
|
||||||
version = "0.2.0"
|
version = "0.1.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09e18fa1e1b6cac20a5f2571882b7580a65ae685b1413fc498f975d07d4c968f"
|
checksum = "9a95dbe2b00920ac4e1524b7442cf5319f01e8fa5742930ac60148882fd7738b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.3.4",
|
"byteorder 1.3.4",
|
||||||
"combine",
|
"combine",
|
||||||
|
|
|
@ -27,7 +27,7 @@ solana-logger = { path = "../../logger", version = "1.5.0" }
|
||||||
solana-measure = { path = "../../measure", version = "1.5.0" }
|
solana-measure = { path = "../../measure", version = "1.5.0" }
|
||||||
solana-runtime = { path = "../../runtime", version = "1.5.0" }
|
solana-runtime = { path = "../../runtime", version = "1.5.0" }
|
||||||
solana-sdk = { path = "../../sdk", version = "1.5.0" }
|
solana-sdk = { path = "../../sdk", version = "1.5.0" }
|
||||||
solana_rbpf = "=0.2.0"
|
solana_rbpf = "=0.1.32"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "bpf_loader"
|
name = "bpf_loader"
|
||||||
|
|
|
@ -6,9 +6,8 @@ extern crate test;
|
||||||
extern crate solana_bpf_loader_program;
|
extern crate solana_bpf_loader_program;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
||||||
use solana_bpf_loader_program::ThisInstructionMeter;
|
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_rbpf::vm::{Executable, InstructionMeter};
|
use solana_rbpf::vm::{EbpfVm, InstructionMeter};
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_client::BankClient,
|
bank_client::BankClient,
|
||||||
|
@ -22,11 +21,11 @@ use solana_sdk::{
|
||||||
entrypoint::SUCCESS,
|
entrypoint::SUCCESS,
|
||||||
instruction::{AccountMeta, Instruction},
|
instruction::{AccountMeta, Instruction},
|
||||||
message::Message,
|
message::Message,
|
||||||
process_instruction::{InvokeContext, MockInvokeContext},
|
process_instruction::{ComputeMeter, InvokeContext, MockInvokeContext},
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, env, fs::File, io::Read, mem, path::PathBuf, sync::Arc};
|
use std::{cell::RefCell, env, fs::File, io::Read, mem, path::PathBuf, rc::Rc, sync::Arc};
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
/// BPF program file extension
|
/// BPF program file extension
|
||||||
|
@ -72,7 +71,9 @@ fn bench_program_create_executable(bencher: &mut Bencher) {
|
||||||
let elf = load_elf("bench_alu").unwrap();
|
let elf = load_elf("bench_alu").unwrap();
|
||||||
|
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
let _ = Executable::<solana_bpf_loader_program::BPFError>::from_elf(&elf, None).unwrap();
|
let _ =
|
||||||
|
EbpfVm::<solana_bpf_loader_program::BPFError>::create_executable_from_elf(&elf, None)
|
||||||
|
.unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,13 +91,11 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
|
|
||||||
let elf = load_elf("bench_alu").unwrap();
|
let elf = load_elf("bench_alu").unwrap();
|
||||||
let executable =
|
let executable =
|
||||||
Executable::<solana_bpf_loader_program::BPFError>::from_elf(&elf, None).unwrap();
|
EbpfVm::<solana_bpf_loader_program::BPFError>::create_executable_from_elf(&elf, None)
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
.unwrap();
|
||||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
let (mut vm, _) = solana_bpf_loader_program::create_vm(
|
||||||
let mut vm = solana_bpf_loader_program::create_vm(
|
|
||||||
&loader_id,
|
&loader_id,
|
||||||
executable.as_ref(),
|
executable.as_ref(),
|
||||||
&mut inner_iter,
|
|
||||||
&[],
|
&[],
|
||||||
&mut invoke_context,
|
&mut invoke_context,
|
||||||
)
|
)
|
||||||
|
@ -105,8 +104,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
println!("Interpreted:");
|
println!("Interpreted:");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
vm.execute_program_interpreted(&mut instruction_meter)
|
vm.execute_program(&mut inner_iter, &[], &[]).unwrap()
|
||||||
.unwrap()
|
|
||||||
);
|
);
|
||||||
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -115,8 +113,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
);
|
);
|
||||||
|
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
vm.execute_program_interpreted(&mut instruction_meter)
|
vm.execute_program(&mut inner_iter, &[], &[]).unwrap();
|
||||||
.unwrap();
|
|
||||||
});
|
});
|
||||||
let instructions = vm.get_total_instruction_count();
|
let instructions = vm.get_total_instruction_count();
|
||||||
let summary = bencher.bench(|_bencher| {}).unwrap();
|
let summary = bencher.bench(|_bencher| {}).unwrap();
|
||||||
|
@ -127,30 +124,31 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||||
println!(" {:?} MIPS", mips);
|
println!(" {:?} MIPS", mips);
|
||||||
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:");
|
// JIT disabled until address translation support is added
|
||||||
vm.jit_compile().unwrap();
|
// println!("JIT to native:");
|
||||||
unsafe {
|
// vm.jit_compile().unwrap();
|
||||||
assert_eq!(
|
// unsafe {
|
||||||
SUCCESS,
|
// assert_eq!(
|
||||||
vm.execute_program_jit(&mut instruction_meter).unwrap()
|
// 0, /*success*/
|
||||||
);
|
// vm.execute_program_jit(&mut inner_iter).unwrap()
|
||||||
}
|
// );
|
||||||
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
// }
|
||||||
assert_eq!(
|
// assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||||
ARMSTRONG_EXPECTED,
|
// assert_eq!(
|
||||||
LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
|
// ARMSTRONG_EXPECTED,
|
||||||
);
|
// LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
|
||||||
|
// );
|
||||||
|
|
||||||
bencher.iter(|| unsafe {
|
// bencher.iter(|| unsafe {
|
||||||
vm.execute_program_jit(&mut instruction_meter).unwrap();
|
// vm.execute_program_jit(&mut inner_iter).unwrap();
|
||||||
});
|
// });
|
||||||
let summary = bencher.bench(|_bencher| {}).unwrap();
|
// let summary = bencher.bench(|_bencher| {}).unwrap();
|
||||||
println!(" {:?} instructions", instructions);
|
// println!(" {:?} instructions", instructions);
|
||||||
println!(" {:?} ns/iter median", summary.median as u64);
|
// println!(" {:?} ns/iter median", summary.median as u64);
|
||||||
assert!(0f64 != summary.median);
|
// assert!(0f64 != summary.median);
|
||||||
let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
|
// let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
|
||||||
println!(" {:?} MIPS", mips);
|
// println!(" {:?} MIPS", mips);
|
||||||
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
|
// println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
@ -193,6 +191,22 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
let loader_id = bpf_loader::id();
|
let loader_id = bpf_loader::id();
|
||||||
let mut invoke_context = MockInvokeContext::default();
|
let mut invoke_context = MockInvokeContext::default();
|
||||||
invoke_context.compute_meter.remaining = BUDGET;
|
invoke_context.compute_meter.remaining = BUDGET;
|
||||||
|
let compute_meter = invoke_context.get_compute_meter();
|
||||||
|
|
||||||
|
let elf = load_elf("tuner").unwrap();
|
||||||
|
let executable =
|
||||||
|
EbpfVm::<solana_bpf_loader_program::BPFError>::create_executable_from_elf(&elf, None)
|
||||||
|
.unwrap();
|
||||||
|
let (mut vm, _) = solana_bpf_loader_program::create_vm(
|
||||||
|
&loader_id,
|
||||||
|
executable.as_ref(),
|
||||||
|
&[],
|
||||||
|
&mut invoke_context,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let instruction_meter = MockInstructionMeter { compute_meter };
|
||||||
|
|
||||||
|
let mut measure = Measure::start("tune");
|
||||||
|
|
||||||
let accounts = [RefCell::new(Account::new(
|
let accounts = [RefCell::new(Account::new(
|
||||||
1,
|
1,
|
||||||
|
@ -208,7 +222,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
let instruction_data = vec![0u8];
|
let instruction_data = vec![0u8];
|
||||||
|
|
||||||
// Serialize account data
|
// Serialize account data
|
||||||
let serialized = solana_bpf_loader_program::serialization::serialize_parameters(
|
let mut serialized = solana_bpf_loader_program::serialization::serialize_parameters(
|
||||||
&bpf_loader::id(),
|
&bpf_loader::id(),
|
||||||
&solana_sdk::pubkey::new_rand(),
|
&solana_sdk::pubkey::new_rand(),
|
||||||
&keyed_accounts,
|
&keyed_accounts,
|
||||||
|
@ -216,24 +230,8 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let elf = load_elf("tuner").unwrap();
|
let _ = vm.execute_program_metered(&mut serialized, &[], &[], instruction_meter.clone());
|
||||||
let executable =
|
|
||||||
Executable::<solana_bpf_loader_program::BPFError>::from_elf(&elf, None).unwrap();
|
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
|
||||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
|
||||||
let mut vm = solana_bpf_loader_program::create_vm(
|
|
||||||
&loader_id,
|
|
||||||
executable.as_ref(),
|
|
||||||
&serialized,
|
|
||||||
&[],
|
|
||||||
&mut invoke_context,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut measure = Measure::start("tune");
|
|
||||||
let _ = vm.execute_program_interpreted(&mut instruction_meter);
|
|
||||||
measure.stop();
|
measure.stop();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
0,
|
0,
|
||||||
instruction_meter.get_remaining(),
|
instruction_meter.get_remaining(),
|
||||||
|
@ -246,3 +244,19 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
vm.get_total_instruction_count(),
|
vm.get_total_instruction_count(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Passed to the VM to enforce the compute budget
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct MockInstructionMeter {
|
||||||
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
|
}
|
||||||
|
impl InstructionMeter for MockInstructionMeter {
|
||||||
|
fn consume(&mut self, amount: u64) {
|
||||||
|
// 1 to 1 instruction to compute unit mapping
|
||||||
|
// ignore error, Ebpf will bail if exceeded
|
||||||
|
let _ = self.compute_meter.borrow_mut().consume(amount);
|
||||||
|
}
|
||||||
|
fn get_remaining(&self) -> u64 {
|
||||||
|
self.compute_meter.borrow().get_remaining()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,9 +6,8 @@ extern crate solana_bpf_loader_program;
|
||||||
use solana_bpf_loader_program::{
|
use solana_bpf_loader_program::{
|
||||||
create_vm,
|
create_vm,
|
||||||
serialization::{deserialize_parameters, serialize_parameters},
|
serialization::{deserialize_parameters, serialize_parameters},
|
||||||
ThisInstructionMeter,
|
|
||||||
};
|
};
|
||||||
use solana_rbpf::vm::Executable;
|
use solana_rbpf::vm::EbpfVm;
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_client::BankClient,
|
bank_client::BankClient,
|
||||||
|
@ -24,7 +23,7 @@ use solana_sdk::{
|
||||||
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
|
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
|
||||||
keyed_account::KeyedAccount,
|
keyed_account::KeyedAccount,
|
||||||
message::Message,
|
message::Message,
|
||||||
process_instruction::{BpfComputeBudget, InvokeContext, MockInvokeContext},
|
process_instruction::{BpfComputeBudget, MockInvokeContext},
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
sysvar::{clock, fees, rent, slot_hashes, stake_history},
|
sysvar::{clock, fees, rent, slot_hashes, stake_history},
|
||||||
|
@ -75,29 +74,25 @@ fn run_program(
|
||||||
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();
|
||||||
let mut invoke_context = MockInvokeContext::default();
|
let mut invoke_context = MockInvokeContext::default();
|
||||||
let parameter_bytes = serialize_parameters(
|
|
||||||
|
let executable = EbpfVm::create_executable_from_elf(&data, None).unwrap();
|
||||||
|
let (mut vm, heap_region) = create_vm(
|
||||||
|
&loader_id,
|
||||||
|
executable.as_ref(),
|
||||||
|
parameter_accounts,
|
||||||
|
&mut invoke_context,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let mut parameter_bytes = serialize_parameters(
|
||||||
&bpf_loader::id(),
|
&bpf_loader::id(),
|
||||||
program_id,
|
program_id,
|
||||||
parameter_accounts,
|
parameter_accounts,
|
||||||
&instruction_data,
|
&instruction_data,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
|
||||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
|
||||||
|
|
||||||
let executable = Executable::from_elf(&data, None).unwrap();
|
|
||||||
let mut vm = create_vm(
|
|
||||||
&loader_id,
|
|
||||||
executable.as_ref(),
|
|
||||||
¶meter_bytes,
|
|
||||||
parameter_accounts,
|
|
||||||
&mut invoke_context,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
vm.execute_program_interpreted(&mut instruction_meter)
|
vm.execute_program(parameter_bytes.as_mut_slice(), &[], &[heap_region.clone()])
|
||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
deserialize_parameters(&bpf_loader::id(), parameter_accounts, ¶meter_bytes).unwrap();
|
deserialize_parameters(&bpf_loader::id(), parameter_accounts, ¶meter_bytes).unwrap();
|
||||||
|
@ -816,6 +811,7 @@ fn test_program_bpf_instruction_introspection() {
|
||||||
Some(&mint_keypair.pubkey()),
|
Some(&mint_keypair.pubkey()),
|
||||||
);
|
);
|
||||||
let result = bank_client.send_and_confirm_message(&[&mint_keypair], message);
|
let result = bank_client.send_and_confirm_message(&[&mint_keypair], message);
|
||||||
|
println!("result: {:?}", result);
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
|
||||||
// writable special instructions11111 key, should not be allowed
|
// writable special instructions11111 key, should not be allowed
|
||||||
|
|
|
@ -16,7 +16,7 @@ num-derive = "0.3"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
solana-runtime = { path = "../../runtime", version = "1.5.0" }
|
solana-runtime = { path = "../../runtime", version = "1.5.0" }
|
||||||
solana-sdk = { path = "../../sdk", version = "1.5.0" }
|
solana-sdk = { path = "../../sdk", version = "1.5.0" }
|
||||||
solana_rbpf = "=0.2.0"
|
solana_rbpf = "=0.1.32"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -12,7 +12,6 @@ use crate::{
|
||||||
};
|
};
|
||||||
use num_derive::{FromPrimitive, ToPrimitive};
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
use solana_rbpf::{
|
use solana_rbpf::{
|
||||||
ebpf::MM_HEAP_START,
|
|
||||||
error::{EbpfError, UserDefinedError},
|
error::{EbpfError, UserDefinedError},
|
||||||
memory_region::MemoryRegion,
|
memory_region::MemoryRegion,
|
||||||
vm::{Config, EbpfVm, Executable, InstructionMeter},
|
vm::{Config, EbpfVm, Executable, InstructionMeter},
|
||||||
|
@ -21,7 +20,7 @@ use solana_sdk::{
|
||||||
bpf_loader, bpf_loader_deprecated,
|
bpf_loader, bpf_loader_deprecated,
|
||||||
decode_error::DecodeError,
|
decode_error::DecodeError,
|
||||||
entrypoint::SUCCESS,
|
entrypoint::SUCCESS,
|
||||||
feature_set::{bpf_compute_budget_balancing, bpf_just_in_time_compilation},
|
feature_set::bpf_compute_budget_balancing,
|
||||||
instruction::InstructionError,
|
instruction::InstructionError,
|
||||||
keyed_account::{is_executable, next_keyed_account, KeyedAccount},
|
keyed_account::{is_executable, next_keyed_account, KeyedAccount},
|
||||||
loader_instruction::LoaderInstruction,
|
loader_instruction::LoaderInstruction,
|
||||||
|
@ -93,7 +92,7 @@ pub fn create_and_cache_executor(
|
||||||
program: &KeyedAccount,
|
program: &KeyedAccount,
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut dyn InvokeContext,
|
||||||
) -> Result<Arc<BPFExecutor>, InstructionError> {
|
) -> Result<Arc<BPFExecutor>, InstructionError> {
|
||||||
let executable = Executable::from_elf(&program.try_account_ref()?.data, None)
|
let executable = EbpfVm::create_executable_from_elf(&program.try_account_ref()?.data, None)
|
||||||
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
||||||
let (_, elf_bytes) = executable
|
let (_, elf_bytes) = executable
|
||||||
.get_text_bytes()
|
.get_text_bytes()
|
||||||
|
@ -108,20 +107,13 @@ pub fn create_and_cache_executor(
|
||||||
Ok(executor)
|
Ok(executor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default program heap size, allocators
|
|
||||||
/// are expected to enforce this
|
|
||||||
const DEFAULT_HEAP_SIZE: usize = 32 * 1024;
|
|
||||||
|
|
||||||
/// Create the BPF virtual machine
|
/// Create the BPF virtual machine
|
||||||
pub fn create_vm<'a>(
|
pub fn create_vm<'a>(
|
||||||
loader_id: &'a Pubkey,
|
loader_id: &'a Pubkey,
|
||||||
executable: &'a dyn Executable<BPFError>,
|
executable: &'a dyn Executable<BPFError>,
|
||||||
parameter_bytes: &[u8],
|
|
||||||
parameter_accounts: &'a [KeyedAccount<'a>],
|
parameter_accounts: &'a [KeyedAccount<'a>],
|
||||||
invoke_context: &'a mut dyn InvokeContext,
|
invoke_context: &'a mut dyn InvokeContext,
|
||||||
) -> Result<EbpfVm<'a, BPFError, ThisInstructionMeter>, EbpfError<BPFError>> {
|
) -> Result<(EbpfVm<'a, BPFError>, MemoryRegion), EbpfError<BPFError>> {
|
||||||
let heap = vec![0_u8; DEFAULT_HEAP_SIZE];
|
|
||||||
let heap_region = MemoryRegion::new_from_slice(&heap, MM_HEAP_START, true);
|
|
||||||
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
|
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
|
||||||
let mut vm = EbpfVm::new(
|
let mut vm = EbpfVm::new(
|
||||||
executable,
|
executable,
|
||||||
|
@ -129,11 +121,10 @@ pub fn create_vm<'a>(
|
||||||
max_call_depth: bpf_compute_budget.max_call_depth,
|
max_call_depth: bpf_compute_budget.max_call_depth,
|
||||||
stack_frame_size: bpf_compute_budget.stack_frame_size,
|
stack_frame_size: bpf_compute_budget.stack_frame_size,
|
||||||
},
|
},
|
||||||
parameter_bytes,
|
|
||||||
&[heap_region],
|
|
||||||
)?;
|
)?;
|
||||||
syscalls::register_syscalls(loader_id, &mut vm, parameter_accounts, invoke_context, heap)?;
|
let heap_region =
|
||||||
Ok(vm)
|
syscalls::register_syscalls(loader_id, &mut vm, parameter_accounts, invoke_context)?;
|
||||||
|
Ok((vm, heap_region))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
|
@ -198,8 +189,8 @@ pub fn process_instruction(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Passed to the VM to enforce the compute budget
|
/// Passed to the VM to enforce the compute budget
|
||||||
pub struct ThisInstructionMeter {
|
struct ThisInstructionMeter {
|
||||||
pub compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
}
|
}
|
||||||
impl ThisInstructionMeter {
|
impl ThisInstructionMeter {
|
||||||
fn new(compute_meter: Rc<RefCell<dyn ComputeMeter>>) -> Self {
|
fn new(compute_meter: Rc<RefCell<dyn ComputeMeter>>) -> Self {
|
||||||
|
@ -251,12 +242,9 @@ impl Executor for BPFExecutor {
|
||||||
)?;
|
)?;
|
||||||
{
|
{
|
||||||
let compute_meter = invoke_context.get_compute_meter();
|
let compute_meter = invoke_context.get_compute_meter();
|
||||||
let is_jit_enabled =
|
let (mut vm, heap_region) = match create_vm(
|
||||||
invoke_context.is_feature_active(&bpf_just_in_time_compilation::id());
|
|
||||||
let mut vm = match create_vm(
|
|
||||||
program_id,
|
program_id,
|
||||||
self.executable.as_ref(),
|
self.executable.as_ref(),
|
||||||
parameter_bytes.as_slice(),
|
|
||||||
¶meter_accounts,
|
¶meter_accounts,
|
||||||
invoke_context,
|
invoke_context,
|
||||||
) {
|
) {
|
||||||
|
@ -268,16 +256,14 @@ impl Executor for BPFExecutor {
|
||||||
};
|
};
|
||||||
|
|
||||||
log!(logger, "Call BPF program {}", program.unsigned_key());
|
log!(logger, "Call BPF program {}", program.unsigned_key());
|
||||||
let mut instruction_meter = ThisInstructionMeter::new(compute_meter.clone());
|
let instruction_meter = ThisInstructionMeter::new(compute_meter.clone());
|
||||||
let before = compute_meter.borrow().get_remaining();
|
let before = compute_meter.borrow().get_remaining();
|
||||||
let result = if is_jit_enabled {
|
let result = vm.execute_program_metered(
|
||||||
if vm.jit_compile().is_err() {
|
parameter_bytes.as_slice(),
|
||||||
return Err(BPFLoaderError::VirtualMachineCreationFailed.into());
|
&[],
|
||||||
}
|
&[heap_region],
|
||||||
unsafe { vm.execute_program_jit(&mut instruction_meter) }
|
instruction_meter,
|
||||||
} else {
|
);
|
||||||
vm.execute_program_interpreted(&mut instruction_meter)
|
|
||||||
};
|
|
||||||
let after = compute_meter.borrow().get_remaining();
|
let after = compute_meter.borrow().get_remaining();
|
||||||
log!(
|
log!(
|
||||||
logger,
|
logger,
|
||||||
|
@ -347,7 +333,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "ExceededMaxInstructions(31, 10)")]
|
#[should_panic(expected = "ExceededMaxInstructions(10)")]
|
||||||
fn test_bpf_loader_non_terminating_program() {
|
fn test_bpf_loader_non_terminating_program() {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let program = &[
|
let program = &[
|
||||||
|
@ -357,16 +343,10 @@ mod tests {
|
||||||
];
|
];
|
||||||
let input = &mut [0x00];
|
let input = &mut [0x00];
|
||||||
|
|
||||||
let executable = Executable::<BPFError>::from_text_bytes(program, None).unwrap();
|
let executable = EbpfVm::create_executable_from_text_bytes(program, None).unwrap();
|
||||||
let mut vm = EbpfVm::<BPFError, TestInstructionMeter>::new(
|
let mut vm = EbpfVm::<BPFError>::new(executable.as_ref(), Config::default()).unwrap();
|
||||||
executable.as_ref(),
|
let instruction_meter = TestInstructionMeter { remaining: 10 };
|
||||||
Config::default(),
|
vm.execute_program_metered(input, &[], &[], instruction_meter)
|
||||||
input,
|
|
||||||
&[],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut instruction_meter = TestInstructionMeter { remaining: 10 };
|
|
||||||
vm.execute_program_interpreted(&mut instruction_meter)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -78,10 +78,6 @@ pub mod pull_request_ping_pong_check {
|
||||||
solana_sdk::declare_id!("5RzEHTnf6D7JPZCvwEzjM19kzBsyjSU3HoMfXaQmVgnZ");
|
solana_sdk::declare_id!("5RzEHTnf6D7JPZCvwEzjM19kzBsyjSU3HoMfXaQmVgnZ");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod bpf_just_in_time_compilation {
|
|
||||||
solana_sdk::declare_id!("3bZhti6PMmsdkPxqPT8TPNzB3n9NYbKtnwqEpUDnFuPi");
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
|
@ -103,7 +99,6 @@ lazy_static! {
|
||||||
(sol_log_compute_units_syscall::id(), "sol_log_compute_units syscall (#13243)"),
|
(sol_log_compute_units_syscall::id(), "sol_log_compute_units syscall (#13243)"),
|
||||||
(pubkey_log_syscall_enabled::id(), "pubkey log syscall"),
|
(pubkey_log_syscall_enabled::id(), "pubkey log syscall"),
|
||||||
(pull_request_ping_pong_check::id(), "ping-pong packet check #12794"),
|
(pull_request_ping_pong_check::id(), "ping-pong packet check #12794"),
|
||||||
(bpf_just_in_time_compilation::id(), "bpf just-in-time compilation #12951"),
|
|
||||||
/*************** ADD NEW FEATURES HERE ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
|
Loading…
Reference in New Issue