Refactoring - Remove redundant definition of `BuiltinProgram` (#31429)
* Replaces BuiltinProgram in the program-runtime with the one from solana_rbpf. * Adjusts the runtimes built-ins to use Arc<LoadedProgram>. * Adjusts the tests and benchmarks.
This commit is contained in:
parent
9b547fe9f8
commit
ae75c7cb3f
|
@ -1809,7 +1809,7 @@ pub mod tests {
|
||||||
matches::assert_matches,
|
matches::assert_matches,
|
||||||
rand::{thread_rng, Rng},
|
rand::{thread_rng, Rng},
|
||||||
solana_entry::entry::{create_ticks, next_entry, next_entry_mut},
|
solana_entry::entry::{create_ticks, next_entry, next_entry_mut},
|
||||||
solana_program_runtime::declare_process_instruction,
|
solana_program_runtime::{builtin_program::create_builtin, declare_process_instruction},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
genesis_utils::{
|
genesis_utils::{
|
||||||
self, create_genesis_config_with_vote_accounts, ValidatorVoteKeypairs,
|
self, create_genesis_config_with_vote_accounts, ValidatorVoteKeypairs,
|
||||||
|
@ -2971,7 +2971,10 @@ pub mod tests {
|
||||||
let mock_program_id = solana_sdk::pubkey::new_rand();
|
let mock_program_id = solana_sdk::pubkey::new_rand();
|
||||||
|
|
||||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||||
bank.add_builtin("mock_processor", &mock_program_id, mock_processor_ok);
|
bank.add_builtin(
|
||||||
|
mock_program_id,
|
||||||
|
create_builtin("mockup".to_string(), mock_processor_ok),
|
||||||
|
);
|
||||||
|
|
||||||
let tx = Transaction::new_signed_with_payer(
|
let tx = Transaction::new_signed_with_payer(
|
||||||
&[Instruction::new_with_bincode(
|
&[Instruction::new_with_bincode(
|
||||||
|
@ -3012,7 +3015,10 @@ pub mod tests {
|
||||||
|
|
||||||
(0..get_instruction_errors().len()).for_each(|err| {
|
(0..get_instruction_errors().len()).for_each(|err| {
|
||||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||||
bank.add_builtin("mock_processor", &mock_program_id, mock_processor_err);
|
bank.add_builtin(
|
||||||
|
mock_program_id,
|
||||||
|
create_builtin("mockup".to_string(), mock_processor_err),
|
||||||
|
);
|
||||||
|
|
||||||
let tx = Transaction::new_signed_with_payer(
|
let tx = Transaction::new_signed_with_payer(
|
||||||
&[Instruction::new_with_bincode(
|
&[Instruction::new_with_bincode(
|
||||||
|
|
|
@ -1,44 +1,28 @@
|
||||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
use {crate::declare_process_instruction, solana_frozen_abi::abi_example::AbiExample};
|
use solana_frozen_abi::abi_example::AbiExample;
|
||||||
use {
|
use {
|
||||||
crate::invoke_context::InvokeContext, solana_rbpf::vm::BuiltInFunction,
|
crate::{invoke_context::InvokeContext, loaded_programs::LoadedProgram},
|
||||||
|
solana_rbpf::vm::{BuiltInFunction, BuiltInProgram},
|
||||||
solana_sdk::pubkey::Pubkey,
|
solana_sdk::pubkey::Pubkey,
|
||||||
|
std::sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type ProcessInstructionWithContext = BuiltInFunction<InvokeContext<'static>>;
|
pub type ProcessInstructionWithContext = BuiltInFunction<InvokeContext<'static>>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub fn create_builtin(
|
||||||
pub struct BuiltinProgram {
|
name: String,
|
||||||
pub name: String,
|
process_instruction: ProcessInstructionWithContext,
|
||||||
pub program_id: Pubkey,
|
) -> Arc<LoadedProgram> {
|
||||||
pub process_instruction: ProcessInstructionWithContext,
|
let mut program = BuiltInProgram::default();
|
||||||
}
|
program
|
||||||
|
.register_function_by_name("entrypoint", process_instruction)
|
||||||
impl std::fmt::Debug for BuiltinProgram {
|
.unwrap();
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
Arc::new(LoadedProgram::new_builtin(name, 0, program))
|
||||||
write!(f, "Builtin [name={}, id={}]", self.name, self.program_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
|
||||||
impl AbiExample for BuiltinProgram {
|
|
||||||
fn example() -> Self {
|
|
||||||
declare_process_instruction!(empty_mock_process_instruction, 1, |_invoke_context| {
|
|
||||||
// Do nothing
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
|
|
||||||
Self {
|
|
||||||
name: String::default(),
|
|
||||||
program_id: Pubkey::default(),
|
|
||||||
process_instruction: empty_mock_process_instruction,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct BuiltinPrograms {
|
pub struct BuiltinPrograms {
|
||||||
pub vec: Vec<BuiltinProgram>,
|
pub vec: Vec<(Pubkey, Arc<LoadedProgram>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
|
@ -54,11 +38,10 @@ impl BuiltinPrograms {
|
||||||
process_instruction: ProcessInstructionWithContext,
|
process_instruction: ProcessInstructionWithContext,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
vec: vec![BuiltinProgram {
|
vec: vec![(
|
||||||
name: "mock instruction processor".to_string(),
|
|
||||||
program_id,
|
program_id,
|
||||||
process_instruction,
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
}],
|
)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use {
|
||||||
compute_budget::ComputeBudget,
|
compute_budget::ComputeBudget,
|
||||||
executor_cache::TransactionExecutorCache,
|
executor_cache::TransactionExecutorCache,
|
||||||
ic_logger_msg, ic_msg,
|
ic_logger_msg, ic_msg,
|
||||||
|
loaded_programs::LoadedProgramType,
|
||||||
log_collector::LogCollector,
|
log_collector::LogCollector,
|
||||||
pre_account::PreAccount,
|
pre_account::PreAccount,
|
||||||
stable_log,
|
stable_log,
|
||||||
|
@ -40,7 +41,7 @@ use {
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
fmt::{self, Debug},
|
fmt::{self, Debug},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::Arc,
|
sync::{atomic::Ordering, Arc},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -719,19 +720,29 @@ impl<'a> InvokeContext<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
for entry in self.builtin_programs.vec.iter() {
|
for entry in self.builtin_programs.vec.iter() {
|
||||||
if entry.program_id == builtin_id {
|
if entry.0 == builtin_id {
|
||||||
|
// The Murmur3 hash value (used by RBPF) of the string "entrypoint"
|
||||||
|
const ENTRYPOINT_KEY: u32 = 0x71E3CF81;
|
||||||
|
let process_instruction = match &entry.1.program {
|
||||||
|
LoadedProgramType::Builtin(_name, program) => program
|
||||||
|
.lookup_function(ENTRYPOINT_KEY)
|
||||||
|
.map(|(_name, process_instruction)| process_instruction),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
.ok_or(InstructionError::GenericError)?;
|
||||||
|
entry.1.usage_counter.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
let program_id =
|
let program_id =
|
||||||
*instruction_context.get_last_program_key(self.transaction_context)?;
|
*instruction_context.get_last_program_key(self.transaction_context)?;
|
||||||
self.transaction_context
|
self.transaction_context
|
||||||
.set_return_data(program_id, Vec::new())?;
|
.set_return_data(program_id, Vec::new())?;
|
||||||
|
|
||||||
let logger = self.get_log_collector();
|
let logger = self.get_log_collector();
|
||||||
stable_log::program_invoke(&logger, &program_id, self.get_stack_height());
|
stable_log::program_invoke(&logger, &program_id, self.get_stack_height());
|
||||||
let pre_remaining_units = self.get_remaining();
|
let pre_remaining_units = self.get_remaining();
|
||||||
let mock_config = Config::default();
|
let mock_config = Config::default();
|
||||||
let mut mock_memory_mapping = MemoryMapping::new(Vec::new(), &mock_config).unwrap();
|
let mut mock_memory_mapping = MemoryMapping::new(Vec::new(), &mock_config).unwrap();
|
||||||
let mut result = ProgramResult::Ok(0);
|
let mut result = ProgramResult::Ok(0);
|
||||||
(entry.process_instruction)(
|
process_instruction(
|
||||||
// Removes lifetime tracking
|
// Removes lifetime tracking
|
||||||
unsafe { std::mem::transmute::<&mut InvokeContext, &mut InvokeContext>(self) },
|
unsafe { std::mem::transmute::<&mut InvokeContext, &mut InvokeContext>(self) },
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -72,7 +72,7 @@ pub enum LoadedProgramType {
|
||||||
Typed(VerifiedExecutable<RequisiteVerifier, InvokeContext<'static>>),
|
Typed(VerifiedExecutable<RequisiteVerifier, InvokeContext<'static>>),
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
TestLoaded,
|
TestLoaded,
|
||||||
BuiltIn(BuiltInProgram<InvokeContext<'static>>),
|
Builtin(String, BuiltInProgram<InvokeContext<'static>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for LoadedProgramType {
|
impl Debug for LoadedProgramType {
|
||||||
|
@ -89,7 +89,9 @@ impl Debug for LoadedProgramType {
|
||||||
LoadedProgramType::Typed(_) => write!(f, "LoadedProgramType::Typed"),
|
LoadedProgramType::Typed(_) => write!(f, "LoadedProgramType::Typed"),
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
LoadedProgramType::TestLoaded => write!(f, "LoadedProgramType::TestLoaded"),
|
LoadedProgramType::TestLoaded => write!(f, "LoadedProgramType::TestLoaded"),
|
||||||
LoadedProgramType::BuiltIn(_) => write!(f, "LoadedProgramType::BuiltIn"),
|
LoadedProgramType::Builtin(name, _) => {
|
||||||
|
write!(f, "LoadedProgramType::Builtin({name})")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +217,8 @@ impl LoadedProgram {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new built-in program
|
/// Creates a new built-in program
|
||||||
pub fn new_built_in(
|
pub fn new_builtin(
|
||||||
|
name: String,
|
||||||
deployment_slot: Slot,
|
deployment_slot: Slot,
|
||||||
program: BuiltInProgram<InvokeContext<'static>>,
|
program: BuiltInProgram<InvokeContext<'static>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -225,7 +228,7 @@ impl LoadedProgram {
|
||||||
effective_slot: deployment_slot.saturating_add(1),
|
effective_slot: deployment_slot.saturating_add(1),
|
||||||
maybe_expiration_slot: None,
|
maybe_expiration_slot: None,
|
||||||
usage_counter: AtomicU64::new(0),
|
usage_counter: AtomicU64::new(0),
|
||||||
program: LoadedProgramType::BuiltIn(program),
|
program: LoadedProgramType::Builtin(name, program),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,16 +297,6 @@ impl LoadedProgramsForTxBatch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
|
||||||
impl solana_frozen_abi::abi_example::AbiExample for LoadedPrograms {
|
|
||||||
fn example() -> Self {
|
|
||||||
// Delegate AbiExample impl to Default before going deep and stuck with
|
|
||||||
// not easily impl-able Arc<dyn Executor> due to rust's coherence issue
|
|
||||||
// This is safe because LoadedPrograms isn't serializable by definition.
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum LoadedProgramMatchCriteria {
|
pub enum LoadedProgramMatchCriteria {
|
||||||
DeployedOnOrAfterSlot(Slot),
|
DeployedOnOrAfterSlot(Slot),
|
||||||
Closed,
|
Closed,
|
||||||
|
@ -474,7 +467,7 @@ impl LoadedPrograms {
|
||||||
LoadedProgramType::FailedVerification
|
LoadedProgramType::FailedVerification
|
||||||
| LoadedProgramType::Closed
|
| LoadedProgramType::Closed
|
||||||
| LoadedProgramType::DelayVisibility
|
| LoadedProgramType::DelayVisibility
|
||||||
| LoadedProgramType::BuiltIn(_) => None,
|
| LoadedProgramType::Builtin(_, _) => None,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.sorted_by_cached_key(|(order, (_id, program))| {
|
.sorted_by_cached_key(|(order, (_id, program))| {
|
||||||
|
@ -561,6 +554,22 @@ impl LoadedPrograms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
|
impl solana_frozen_abi::abi_example::AbiExample for LoadedProgram {
|
||||||
|
fn example() -> Self {
|
||||||
|
// LoadedProgram isn't serializable by definition.
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
|
impl solana_frozen_abi::abi_example::AbiExample for LoadedPrograms {
|
||||||
|
fn example() -> Self {
|
||||||
|
// LoadedPrograms isn't serializable by definition.
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use {
|
use {
|
||||||
|
@ -582,7 +591,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("mockup".to_string(), BuiltInProgram::default()),
|
||||||
account_size: 0,
|
account_size: 0,
|
||||||
deployment_slot,
|
deployment_slot,
|
||||||
effective_slot,
|
effective_slot,
|
||||||
|
|
|
@ -11,7 +11,7 @@ use {
|
||||||
solana_banks_server::banks_server::start_local_server,
|
solana_banks_server::banks_server::start_local_server,
|
||||||
solana_bpf_loader_program::serialization::serialize_parameters,
|
solana_bpf_loader_program::serialization::serialize_parameters,
|
||||||
solana_program_runtime::{
|
solana_program_runtime::{
|
||||||
builtin_program::{BuiltinProgram, BuiltinPrograms, ProcessInstructionWithContext},
|
builtin_program::{create_builtin, BuiltinPrograms, ProcessInstructionWithContext},
|
||||||
compute_budget::ComputeBudget,
|
compute_budget::ComputeBudget,
|
||||||
ic_msg, stable_log,
|
ic_msg, stable_log,
|
||||||
timings::ExecuteTimings,
|
timings::ExecuteTimings,
|
||||||
|
@ -692,11 +692,10 @@ impl ProgramTest {
|
||||||
process_instruction: ProcessInstructionWithContext,
|
process_instruction: ProcessInstructionWithContext,
|
||||||
) {
|
) {
|
||||||
info!("\"{}\" builtin program", program_name);
|
info!("\"{}\" builtin program", program_name);
|
||||||
self.builtin_programs.vec.push(BuiltinProgram {
|
self.builtin_programs.vec.push((
|
||||||
name: program_name.to_string(),
|
|
||||||
program_id,
|
program_id,
|
||||||
process_instruction,
|
create_builtin(program_name.to_string(), process_instruction),
|
||||||
});
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deactivate a runtime feature.
|
/// Deactivate a runtime feature.
|
||||||
|
@ -791,12 +790,8 @@ impl ProgramTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// User-supplied additional builtins
|
// User-supplied additional builtins
|
||||||
for builtin in self.builtin_programs.vec.iter() {
|
for (program_id, builtin) in self.builtin_programs.vec.iter() {
|
||||||
bank.add_builtin(
|
bank.add_builtin(*program_id, builtin.clone());
|
||||||
&builtin.name,
|
|
||||||
&builtin.program_id,
|
|
||||||
builtin.process_instruction,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (address, account) in self.accounts.iter() {
|
for (address, account) in self.accounts.iter() {
|
||||||
|
|
|
@ -5,7 +5,7 @@ extern crate test;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
log::*,
|
log::*,
|
||||||
solana_program_runtime::declare_process_instruction,
|
solana_program_runtime::{builtin_program::create_builtin, declare_process_instruction},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
bank::{test_utils::goto_end_of_slot, *},
|
bank::{test_utils::goto_end_of_slot, *},
|
||||||
bank_client::BankClient,
|
bank_client::BankClient,
|
||||||
|
@ -132,9 +132,8 @@ fn do_bench_transactions(
|
||||||
|
|
||||||
let mut bank = Bank::new_from_parent(&Arc::new(bank), &Pubkey::default(), 1);
|
let mut bank = Bank::new_from_parent(&Arc::new(bank), &Pubkey::default(), 1);
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"builtin_program",
|
Pubkey::from(BUILTIN_PROGRAM_ID),
|
||||||
&Pubkey::from(BUILTIN_PROGRAM_ID),
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
process_instruction,
|
|
||||||
);
|
);
|
||||||
bank.add_builtin_account("solana_noop_program", &Pubkey::from(NOOP_PROGRAM_ID), false);
|
bank.add_builtin_account("solana_noop_program", &Pubkey::from(NOOP_PROGRAM_ID), false);
|
||||||
let bank = Arc::new(bank);
|
let bank = Arc::new(bank);
|
||||||
|
|
|
@ -94,7 +94,7 @@ use {
|
||||||
solana_perf::perf_libs,
|
solana_perf::perf_libs,
|
||||||
solana_program_runtime::{
|
solana_program_runtime::{
|
||||||
accounts_data_meter::MAX_ACCOUNTS_DATA_LEN,
|
accounts_data_meter::MAX_ACCOUNTS_DATA_LEN,
|
||||||
builtin_program::{BuiltinProgram, BuiltinPrograms, ProcessInstructionWithContext},
|
builtin_program::BuiltinPrograms,
|
||||||
compute_budget::{self, ComputeBudget},
|
compute_budget::{self, ComputeBudget},
|
||||||
executor_cache::{BankExecutorCache, TransactionExecutorCache, MAX_CACHED_EXECUTORS},
|
executor_cache::{BankExecutorCache, TransactionExecutorCache, MAX_CACHED_EXECUTORS},
|
||||||
loaded_programs::{
|
loaded_programs::{
|
||||||
|
@ -6350,12 +6350,8 @@ impl Bank {
|
||||||
.extend_from_slice(&additional_builtins.feature_transitions);
|
.extend_from_slice(&additional_builtins.feature_transitions);
|
||||||
}
|
}
|
||||||
if !debug_do_not_add_builtins {
|
if !debug_do_not_add_builtins {
|
||||||
for builtin in builtins.genesis_builtins {
|
for (program_id, builtin) in builtins.genesis_builtins {
|
||||||
self.add_builtin(
|
self.add_builtin(program_id, builtin);
|
||||||
&builtin.name,
|
|
||||||
&builtin.program_id,
|
|
||||||
builtin.process_instruction,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
for precompile in get_precompiles() {
|
for precompile in get_precompiles() {
|
||||||
if precompile.feature.is_none() {
|
if precompile.feature.is_none() {
|
||||||
|
@ -7379,27 +7375,24 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add an instruction processor to intercept instructions before the dynamic loader.
|
/// Add an instruction processor to intercept instructions before the dynamic loader.
|
||||||
pub fn add_builtin(
|
pub fn add_builtin(&mut self, program_id: Pubkey, builtin: Arc<LoadedProgram>) {
|
||||||
&mut self,
|
let name = match &builtin.program {
|
||||||
name: &str,
|
LoadedProgramType::Builtin(name, _) => name,
|
||||||
program_id: &Pubkey,
|
_ => unreachable!(),
|
||||||
process_instruction: ProcessInstructionWithContext,
|
};
|
||||||
) {
|
|
||||||
debug!("Adding program {} under {:?}", name, program_id);
|
debug!("Adding program {} under {:?}", name, program_id);
|
||||||
self.add_builtin_account(name, program_id, false);
|
self.add_builtin_account(name.as_str(), &program_id, false);
|
||||||
if let Some(entry) = self
|
if let Some(entry) = self
|
||||||
.builtin_programs
|
.builtin_programs
|
||||||
.vec
|
.vec
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|entry| entry.program_id == *program_id)
|
.find(|entry| entry.0 == program_id)
|
||||||
{
|
{
|
||||||
entry.process_instruction = process_instruction;
|
entry.1 = builtin.clone();
|
||||||
} else {
|
} else {
|
||||||
self.builtin_programs.vec.push(BuiltinProgram {
|
self.builtin_programs
|
||||||
name: name.to_string(),
|
.vec
|
||||||
program_id: *program_id,
|
.push((program_id, builtin.clone()));
|
||||||
process_instruction,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
debug!("Added program {} under {:?}", name, program_id);
|
debug!("Added program {} under {:?}", name, program_id);
|
||||||
}
|
}
|
||||||
|
@ -7413,7 +7406,7 @@ impl Bank {
|
||||||
.builtin_programs
|
.builtin_programs
|
||||||
.vec
|
.vec
|
||||||
.iter()
|
.iter()
|
||||||
.position(|entry| entry.program_id == *program_id)
|
.position(|entry| entry.0 == *program_id)
|
||||||
{
|
{
|
||||||
self.builtin_programs.vec.remove(position);
|
self.builtin_programs.vec.remove(position);
|
||||||
}
|
}
|
||||||
|
@ -7665,11 +7658,9 @@ impl Bank {
|
||||||
transition.to_action(&should_apply_action_for_feature_transition)
|
transition.to_action(&should_apply_action_for_feature_transition)
|
||||||
{
|
{
|
||||||
match builtin_action {
|
match builtin_action {
|
||||||
BuiltinAction::Add(builtin) => self.add_builtin(
|
BuiltinAction::Add(program_id, builtin) => {
|
||||||
&builtin.name,
|
self.add_builtin(program_id, builtin)
|
||||||
&builtin.program_id,
|
}
|
||||||
builtin.process_instruction,
|
|
||||||
),
|
|
||||||
BuiltinAction::Remove(program_id) => self.remove_builtin(&program_id),
|
BuiltinAction::Remove(program_id) => self.remove_builtin(&program_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ use {
|
||||||
serde::{Deserialize, Serialize},
|
serde::{Deserialize, Serialize},
|
||||||
solana_logger,
|
solana_logger,
|
||||||
solana_program_runtime::{
|
solana_program_runtime::{
|
||||||
|
builtin_program::create_builtin,
|
||||||
compute_budget::{self, ComputeBudget, MAX_COMPUTE_UNIT_LIMIT},
|
compute_budget::{self, ComputeBudget, MAX_COMPUTE_UNIT_LIMIT},
|
||||||
declare_process_instruction,
|
declare_process_instruction,
|
||||||
executor_cache::TransactionExecutorCache,
|
executor_cache::TransactionExecutorCache,
|
||||||
|
@ -1380,7 +1381,10 @@ fn test_rent_complex() {
|
||||||
root_bank.restore_old_behavior_for_fragile_tests();
|
root_bank.restore_old_behavior_for_fragile_tests();
|
||||||
let root_bank = Arc::new(root_bank);
|
let root_bank = Arc::new(root_bank);
|
||||||
let mut bank = create_child_bank_for_rent_test(&root_bank, &genesis_config);
|
let mut bank = create_child_bank_for_rent_test(&root_bank, &genesis_config);
|
||||||
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
mock_program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(bank.last_blockhash(), genesis_config.hash());
|
assert_eq!(bank.last_blockhash(), genesis_config.hash());
|
||||||
|
|
||||||
|
@ -4817,9 +4821,8 @@ fn test_add_builtin() {
|
||||||
|
|
||||||
assert!(bank.get_account(&mock_vote_program_id()).is_none());
|
assert!(bank.get_account(&mock_vote_program_id()).is_none());
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"mock_vote_program",
|
mock_vote_program_id(),
|
||||||
&mock_vote_program_id(),
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
process_instruction,
|
|
||||||
);
|
);
|
||||||
assert!(bank.get_account(&mock_vote_program_id()).is_some());
|
assert!(bank.get_account(&mock_vote_program_id()).is_some());
|
||||||
|
|
||||||
|
@ -4894,9 +4897,8 @@ fn test_add_duplicate_static_program() {
|
||||||
|
|
||||||
let vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap();
|
let vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap();
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"solana_vote_program",
|
solana_vote_program::id(),
|
||||||
&solana_vote_program::id(),
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
process_instruction,
|
|
||||||
);
|
);
|
||||||
let new_vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap();
|
let new_vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap();
|
||||||
// Vote loader account should not be updated since it was included in the genesis config.
|
// Vote loader account should not be updated since it was included in the genesis config.
|
||||||
|
@ -4948,8 +4950,14 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bank.add_builtin("mock_program1", &vote_id, process_instruction);
|
bank.add_builtin(
|
||||||
bank.add_builtin("mock_program2", &stake_id, process_instruction);
|
vote_id,
|
||||||
|
create_builtin("mock_program1".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
bank.add_builtin(
|
||||||
|
stake_id,
|
||||||
|
create_builtin("mock_program2".to_string(), process_instruction),
|
||||||
|
);
|
||||||
{
|
{
|
||||||
let stakes = bank.stakes_cache.stakes();
|
let stakes = bank.stakes_cache.stakes();
|
||||||
assert!(stakes.vote_accounts().as_ref().is_empty());
|
assert!(stakes.vote_accounts().as_ref().is_empty());
|
||||||
|
@ -4972,8 +4980,14 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
|
||||||
// Re-adding builtin programs should be no-op
|
// Re-adding builtin programs should be no-op
|
||||||
bank.update_accounts_hash_for_tests();
|
bank.update_accounts_hash_for_tests();
|
||||||
let old_hash = bank.get_accounts_hash().unwrap();
|
let old_hash = bank.get_accounts_hash().unwrap();
|
||||||
bank.add_builtin("mock_program1", &vote_id, process_instruction);
|
bank.add_builtin(
|
||||||
bank.add_builtin("mock_program2", &stake_id, process_instruction);
|
vote_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
bank.add_builtin(
|
||||||
|
stake_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
add_root_and_flush_write_cache(&bank);
|
add_root_and_flush_write_cache(&bank);
|
||||||
bank.update_accounts_hash_for_tests();
|
bank.update_accounts_hash_for_tests();
|
||||||
let new_hash = bank.get_accounts_hash().unwrap();
|
let new_hash = bank.get_accounts_hash().unwrap();
|
||||||
|
@ -6224,7 +6238,10 @@ fn test_transaction_with_duplicate_accounts_in_instruction() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mock_program_id = Pubkey::from([2u8; 32]);
|
let mock_program_id = Pubkey::from([2u8; 32]);
|
||||||
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
mock_program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let from_pubkey = solana_sdk::pubkey::new_rand();
|
let from_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let to_pubkey = solana_sdk::pubkey::new_rand();
|
let to_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
@ -6260,7 +6277,10 @@ fn test_transaction_with_program_ids_passed_to_programs() {
|
||||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||||
|
|
||||||
let mock_program_id = Pubkey::from([2u8; 32]);
|
let mock_program_id = Pubkey::from([2u8; 32]);
|
||||||
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
mock_program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let from_pubkey = solana_sdk::pubkey::new_rand();
|
let from_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let to_pubkey = solana_sdk::pubkey::new_rand();
|
let to_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
@ -6312,7 +6332,10 @@ fn test_account_ids_after_program_ids() {
|
||||||
|
|
||||||
tx.message.account_keys.push(solana_sdk::pubkey::new_rand());
|
tx.message.account_keys.push(solana_sdk::pubkey::new_rand());
|
||||||
|
|
||||||
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
|
bank.add_builtin(
|
||||||
|
solana_vote_program::id(),
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
let result = bank.process_transaction(&tx);
|
let result = bank.process_transaction(&tx);
|
||||||
assert_eq!(result, Ok(()));
|
assert_eq!(result, Ok(()));
|
||||||
let account = bank.get_account(&solana_vote_program::id()).unwrap();
|
let account = bank.get_account(&solana_vote_program::id()).unwrap();
|
||||||
|
@ -6362,7 +6385,10 @@ fn test_duplicate_account_key() {
|
||||||
AccountMeta::new(to_pubkey, false),
|
AccountMeta::new(to_pubkey, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
|
bank.add_builtin(
|
||||||
|
solana_vote_program::id(),
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||||
let mut tx = Transaction::new_signed_with_payer(
|
let mut tx = Transaction::new_signed_with_payer(
|
||||||
|
@ -6391,7 +6417,10 @@ fn test_process_transaction_with_too_many_account_locks() {
|
||||||
AccountMeta::new(to_pubkey, false),
|
AccountMeta::new(to_pubkey, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
|
bank.add_builtin(
|
||||||
|
solana_vote_program::id(),
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||||
let mut tx = Transaction::new_signed_with_payer(
|
let mut tx = Transaction::new_signed_with_payer(
|
||||||
|
@ -6424,7 +6453,10 @@ fn test_program_id_as_payer() {
|
||||||
AccountMeta::new(to_pubkey, false),
|
AccountMeta::new(to_pubkey, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
|
bank.add_builtin(
|
||||||
|
solana_vote_program::id(),
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||||
let mut tx = Transaction::new_signed_with_payer(
|
let mut tx = Transaction::new_signed_with_payer(
|
||||||
|
@ -6467,7 +6499,10 @@ fn test_ref_account_key_after_program_id() {
|
||||||
AccountMeta::new(to_pubkey, false),
|
AccountMeta::new(to_pubkey, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
bank.add_builtin("mock_vote", &solana_vote_program::id(), process_instruction);
|
bank.add_builtin(
|
||||||
|
solana_vote_program::id(),
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||||
let mut tx = Transaction::new_signed_with_payer(
|
let mut tx = Transaction::new_signed_with_payer(
|
||||||
|
@ -6498,7 +6533,7 @@ fn test_fuzz_instructions() {
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let key = solana_sdk::pubkey::new_rand();
|
let key = solana_sdk::pubkey::new_rand();
|
||||||
let name = format!("program{i:?}");
|
let name = format!("program{i:?}");
|
||||||
bank.add_builtin(&name, &key, process_instruction);
|
bank.add_builtin(key, create_builtin(name.clone(), process_instruction));
|
||||||
(key, name.as_bytes().to_vec())
|
(key, name.as_bytes().to_vec())
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -6704,7 +6739,10 @@ fn test_same_program_id_uses_unqiue_executable_accounts() {
|
||||||
|
|
||||||
// Add a new program
|
// Add a new program
|
||||||
let program1_pubkey = solana_sdk::pubkey::new_rand();
|
let program1_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
bank.add_builtin("program", &program1_pubkey, process_instruction);
|
bank.add_builtin(
|
||||||
|
program1_pubkey,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
// Add a new program owned by the first
|
// Add a new program owned by the first
|
||||||
let program2_pubkey = solana_sdk::pubkey::new_rand();
|
let program2_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
@ -6919,15 +6957,17 @@ fn test_add_builtin_no_overwrite() {
|
||||||
));
|
));
|
||||||
assert_eq!(bank.get_account_modified_slot(&program_id), None);
|
assert_eq!(bank.get_account_modified_slot(&program_id), None);
|
||||||
|
|
||||||
Arc::get_mut(&mut bank)
|
Arc::get_mut(&mut bank).unwrap().add_builtin(
|
||||||
.unwrap()
|
program_id,
|
||||||
.add_builtin("mock_program", &program_id, process_instruction);
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
|
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
|
||||||
|
|
||||||
let mut bank = Arc::new(new_from_parent(&bank));
|
let mut bank = Arc::new(new_from_parent(&bank));
|
||||||
Arc::get_mut(&mut bank)
|
Arc::get_mut(&mut bank).unwrap().add_builtin(
|
||||||
.unwrap()
|
program_id,
|
||||||
.add_builtin("mock_program", &program_id, process_instruction);
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
|
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6943,15 +6983,17 @@ fn test_add_builtin_loader_no_overwrite() {
|
||||||
));
|
));
|
||||||
assert_eq!(bank.get_account_modified_slot(&loader_id), None);
|
assert_eq!(bank.get_account_modified_slot(&loader_id), None);
|
||||||
|
|
||||||
Arc::get_mut(&mut bank)
|
Arc::get_mut(&mut bank).unwrap().add_builtin(
|
||||||
.unwrap()
|
loader_id,
|
||||||
.add_builtin("mock_program", &loader_id, process_instruction);
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
|
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
|
||||||
|
|
||||||
let mut bank = Arc::new(new_from_parent(&bank));
|
let mut bank = Arc::new(new_from_parent(&bank));
|
||||||
Arc::get_mut(&mut bank)
|
Arc::get_mut(&mut bank).unwrap().add_builtin(
|
||||||
.unwrap()
|
loader_id,
|
||||||
.add_builtin("mock_program", &loader_id, process_instruction);
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
|
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9694,7 +9736,10 @@ fn test_tx_return_data() {
|
||||||
|
|
||||||
let mock_program_id = Pubkey::from([2u8; 32]);
|
let mock_program_id = Pubkey::from([2u8; 32]);
|
||||||
let blockhash = bank.last_blockhash();
|
let blockhash = bank.last_blockhash();
|
||||||
bank.add_builtin("mock_program", &mock_program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
mock_program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
for index in [
|
for index in [
|
||||||
None,
|
None,
|
||||||
|
@ -9883,7 +9928,10 @@ fn test_transfer_sysvar() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let program_id = solana_sdk::pubkey::new_rand();
|
let program_id = solana_sdk::pubkey::new_rand();
|
||||||
bank.add_builtin("mock_program1", &program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let blockhash = bank.last_blockhash();
|
let blockhash = bank.last_blockhash();
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
@ -10095,7 +10143,10 @@ fn test_compute_budget_program_noop() {
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
let program_id = solana_sdk::pubkey::new_rand();
|
let program_id = solana_sdk::pubkey::new_rand();
|
||||||
bank.add_builtin("mock_program", &program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let message = Message::new(
|
let message = Message::new(
|
||||||
&[
|
&[
|
||||||
|
@ -10138,7 +10189,10 @@ fn test_compute_request_instruction() {
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
let program_id = solana_sdk::pubkey::new_rand();
|
let program_id = solana_sdk::pubkey::new_rand();
|
||||||
bank.add_builtin("mock_program", &program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
let message = Message::new(
|
let message = Message::new(
|
||||||
&[
|
&[
|
||||||
|
@ -10188,7 +10242,10 @@ fn test_failed_compute_request_instruction() {
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
let program_id = solana_sdk::pubkey::new_rand();
|
let program_id = solana_sdk::pubkey::new_rand();
|
||||||
bank.add_builtin("mock_program", &program_id, process_instruction);
|
bank.add_builtin(
|
||||||
|
program_id,
|
||||||
|
create_builtin("mockup".to_string(), process_instruction),
|
||||||
|
);
|
||||||
|
|
||||||
// This message will not be executed because the compute budget request is invalid
|
// This message will not be executed because the compute budget request is invalid
|
||||||
let message0 = Message::new(
|
let message0 = Message::new(
|
||||||
|
@ -10863,9 +10920,8 @@ fn test_invalid_rent_state_changes_existing_accounts() {
|
||||||
|
|
||||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"mock_program",
|
mock_program_id,
|
||||||
&mock_program_id,
|
create_builtin("mockup".to_string(), mock_transfer_process_instruction),
|
||||||
mock_transfer_process_instruction,
|
|
||||||
);
|
);
|
||||||
let recent_blockhash = bank.last_blockhash();
|
let recent_blockhash = bank.last_blockhash();
|
||||||
|
|
||||||
|
@ -10950,9 +11006,8 @@ fn test_invalid_rent_state_changes_new_accounts() {
|
||||||
|
|
||||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"mock_program",
|
mock_program_id,
|
||||||
&mock_program_id,
|
create_builtin("mockup".to_string(), mock_transfer_process_instruction),
|
||||||
mock_transfer_process_instruction,
|
|
||||||
);
|
);
|
||||||
let recent_blockhash = bank.last_blockhash();
|
let recent_blockhash = bank.last_blockhash();
|
||||||
|
|
||||||
|
@ -11013,9 +11068,8 @@ fn test_drained_created_account() {
|
||||||
|
|
||||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"mock_program",
|
mock_program_id,
|
||||||
&mock_program_id,
|
create_builtin("mockup".to_string(), mock_transfer_process_instruction),
|
||||||
mock_transfer_process_instruction,
|
|
||||||
);
|
);
|
||||||
let recent_blockhash = bank.last_blockhash();
|
let recent_blockhash = bank.last_blockhash();
|
||||||
|
|
||||||
|
@ -11668,9 +11722,8 @@ fn test_resize_and_rent() {
|
||||||
|
|
||||||
let mock_program_id = Pubkey::new_unique();
|
let mock_program_id = Pubkey::new_unique();
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"mock_realloc_program",
|
mock_program_id,
|
||||||
&mock_program_id,
|
create_builtin("mockup".to_string(), mock_realloc_process_instruction),
|
||||||
mock_realloc_process_instruction,
|
|
||||||
);
|
);
|
||||||
let recent_blockhash = bank.last_blockhash();
|
let recent_blockhash = bank.last_blockhash();
|
||||||
|
|
||||||
|
@ -11943,9 +11996,8 @@ fn test_accounts_data_size_and_resize_transactions() {
|
||||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||||
let mock_program_id = Pubkey::new_unique();
|
let mock_program_id = Pubkey::new_unique();
|
||||||
bank.add_builtin(
|
bank.add_builtin(
|
||||||
"mock_realloc_program",
|
mock_program_id,
|
||||||
&mock_program_id,
|
create_builtin("mockup".to_string(), mock_realloc_process_instruction),
|
||||||
mock_realloc_process_instruction,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let recent_blockhash = bank.last_blockhash();
|
let recent_blockhash = bank.last_blockhash();
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use {
|
use {
|
||||||
solana_program_runtime::builtin_program::BuiltinProgram,
|
solana_program_runtime::{builtin_program::create_builtin, loaded_programs::LoadedProgram},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, feature_set, pubkey::Pubkey,
|
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, feature_set, pubkey::Pubkey,
|
||||||
},
|
},
|
||||||
|
std::sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Builtins {
|
pub struct Builtins {
|
||||||
/// Builtin programs that are always available
|
/// Builtin programs that are always available
|
||||||
pub genesis_builtins: Vec<BuiltinProgram>,
|
pub genesis_builtins: Vec<(Pubkey, Arc<LoadedProgram>)>,
|
||||||
|
|
||||||
/// Dynamic feature transitions for builtin programs
|
/// Dynamic feature transitions for builtin programs
|
||||||
pub feature_transitions: Vec<BuiltinFeatureTransition>,
|
pub feature_transitions: Vec<BuiltinFeatureTransition>,
|
||||||
|
@ -17,7 +18,7 @@ pub struct Builtins {
|
||||||
/// Actions taken by a bank when managing the list of active builtin programs.
|
/// Actions taken by a bank when managing the list of active builtin programs.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum BuiltinAction {
|
pub enum BuiltinAction {
|
||||||
Add(BuiltinProgram),
|
Add(Pubkey, Arc<LoadedProgram>),
|
||||||
Remove(Pubkey),
|
Remove(Pubkey),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,13 +28,15 @@ pub enum BuiltinAction {
|
||||||
pub enum BuiltinFeatureTransition {
|
pub enum BuiltinFeatureTransition {
|
||||||
/// Add a builtin program if a feature is activated.
|
/// Add a builtin program if a feature is activated.
|
||||||
Add {
|
Add {
|
||||||
builtin: BuiltinProgram,
|
program_id: Pubkey,
|
||||||
|
builtin: Arc<LoadedProgram>,
|
||||||
feature_id: Pubkey,
|
feature_id: Pubkey,
|
||||||
},
|
},
|
||||||
/// Remove a builtin program if a feature is activated or
|
/// Remove a builtin program if a feature is activated or
|
||||||
/// retain a previously added builtin.
|
/// retain a previously added builtin.
|
||||||
RemoveOrRetain {
|
RemoveOrRetain {
|
||||||
previously_added_builtin: BuiltinProgram,
|
program_id: Pubkey,
|
||||||
|
previously_added_builtin: Arc<LoadedProgram>,
|
||||||
addition_feature_id: Pubkey,
|
addition_feature_id: Pubkey,
|
||||||
removal_feature_id: Pubkey,
|
removal_feature_id: Pubkey,
|
||||||
},
|
},
|
||||||
|
@ -46,25 +49,30 @@ impl BuiltinFeatureTransition {
|
||||||
) -> Option<BuiltinAction> {
|
) -> Option<BuiltinAction> {
|
||||||
match self {
|
match self {
|
||||||
Self::Add {
|
Self::Add {
|
||||||
|
program_id,
|
||||||
builtin,
|
builtin,
|
||||||
feature_id,
|
feature_id,
|
||||||
} => {
|
} => {
|
||||||
if should_apply_action_for_feature(feature_id) {
|
if should_apply_action_for_feature(feature_id) {
|
||||||
Some(BuiltinAction::Add(builtin.clone()))
|
Some(BuiltinAction::Add(*program_id, builtin.clone()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::RemoveOrRetain {
|
Self::RemoveOrRetain {
|
||||||
|
program_id,
|
||||||
previously_added_builtin,
|
previously_added_builtin,
|
||||||
addition_feature_id,
|
addition_feature_id,
|
||||||
removal_feature_id,
|
removal_feature_id,
|
||||||
} => {
|
} => {
|
||||||
if should_apply_action_for_feature(removal_feature_id) {
|
if should_apply_action_for_feature(removal_feature_id) {
|
||||||
Some(BuiltinAction::Remove(previously_added_builtin.program_id))
|
Some(BuiltinAction::Remove(*program_id))
|
||||||
} else if should_apply_action_for_feature(addition_feature_id) {
|
} else if should_apply_action_for_feature(addition_feature_id) {
|
||||||
// Retaining is no different from adding a new builtin.
|
// Retaining is no different from adding a new builtin.
|
||||||
Some(BuiltinAction::Add(previously_added_builtin.clone()))
|
Some(BuiltinAction::Add(
|
||||||
|
*program_id,
|
||||||
|
previously_added_builtin.clone(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -74,43 +82,57 @@ impl BuiltinFeatureTransition {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Built-in programs that are always available
|
/// Built-in programs that are always available
|
||||||
fn genesis_builtins() -> Vec<BuiltinProgram> {
|
fn genesis_builtins() -> Vec<(Pubkey, Arc<LoadedProgram>)> {
|
||||||
vec![
|
vec![
|
||||||
BuiltinProgram {
|
(
|
||||||
name: "system_program".to_string(),
|
solana_system_program::id(),
|
||||||
program_id: solana_system_program::id(),
|
create_builtin(
|
||||||
process_instruction: solana_system_program::system_processor::process_instruction,
|
"system_program".to_string(),
|
||||||
},
|
solana_system_program::system_processor::process_instruction,
|
||||||
BuiltinProgram {
|
),
|
||||||
name: "vote_program".to_string(),
|
),
|
||||||
program_id: solana_vote_program::id(),
|
(
|
||||||
process_instruction: solana_vote_program::vote_processor::process_instruction,
|
solana_vote_program::id(),
|
||||||
},
|
create_builtin(
|
||||||
BuiltinProgram {
|
"vote_program".to_string(),
|
||||||
name: "stake_program".to_string(),
|
solana_vote_program::vote_processor::process_instruction,
|
||||||
program_id: solana_stake_program::id(),
|
),
|
||||||
process_instruction: solana_stake_program::stake_instruction::process_instruction,
|
),
|
||||||
},
|
(
|
||||||
BuiltinProgram {
|
solana_stake_program::id(),
|
||||||
name: "config_program".to_string(),
|
create_builtin(
|
||||||
program_id: solana_config_program::id(),
|
"stake_program".to_string(),
|
||||||
process_instruction: solana_config_program::config_processor::process_instruction,
|
solana_stake_program::stake_instruction::process_instruction,
|
||||||
},
|
),
|
||||||
BuiltinProgram {
|
),
|
||||||
name: "solana_bpf_loader_deprecated_program".to_string(),
|
(
|
||||||
program_id: bpf_loader_deprecated::id(),
|
solana_config_program::id(),
|
||||||
process_instruction: solana_bpf_loader_program::process_instruction,
|
create_builtin(
|
||||||
},
|
"config_program".to_string(),
|
||||||
BuiltinProgram {
|
solana_config_program::config_processor::process_instruction,
|
||||||
name: "solana_bpf_loader_program".to_string(),
|
),
|
||||||
program_id: bpf_loader::id(),
|
),
|
||||||
process_instruction: solana_bpf_loader_program::process_instruction,
|
(
|
||||||
},
|
bpf_loader_deprecated::id(),
|
||||||
BuiltinProgram {
|
create_builtin(
|
||||||
name: "solana_bpf_loader_upgradeable_program".to_string(),
|
"solana_bpf_loader_deprecated_program".to_string(),
|
||||||
program_id: bpf_loader_upgradeable::id(),
|
solana_bpf_loader_program::process_instruction,
|
||||||
process_instruction: solana_bpf_loader_program::process_instruction,
|
),
|
||||||
},
|
),
|
||||||
|
(
|
||||||
|
bpf_loader::id(),
|
||||||
|
create_builtin(
|
||||||
|
"solana_bpf_loader_program".to_string(),
|
||||||
|
solana_bpf_loader_program::process_instruction,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
bpf_loader_upgradeable::id(),
|
||||||
|
create_builtin(
|
||||||
|
"solana_bpf_loader_upgradeable_program".to_string(),
|
||||||
|
solana_bpf_loader_program::process_instruction,
|
||||||
|
),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,28 +140,27 @@ fn genesis_builtins() -> Vec<BuiltinProgram> {
|
||||||
fn builtin_feature_transitions() -> Vec<BuiltinFeatureTransition> {
|
fn builtin_feature_transitions() -> Vec<BuiltinFeatureTransition> {
|
||||||
vec![
|
vec![
|
||||||
BuiltinFeatureTransition::Add {
|
BuiltinFeatureTransition::Add {
|
||||||
builtin: BuiltinProgram {
|
|
||||||
name: "compute_budget_program".to_string(),
|
|
||||||
program_id: solana_sdk::compute_budget::id(),
|
program_id: solana_sdk::compute_budget::id(),
|
||||||
process_instruction: solana_compute_budget_program::process_instruction,
|
builtin: create_builtin(
|
||||||
},
|
"compute_budget_program".to_string(),
|
||||||
|
solana_compute_budget_program::process_instruction,
|
||||||
|
),
|
||||||
feature_id: feature_set::add_compute_budget_program::id(),
|
feature_id: feature_set::add_compute_budget_program::id(),
|
||||||
},
|
},
|
||||||
BuiltinFeatureTransition::Add {
|
BuiltinFeatureTransition::Add {
|
||||||
builtin: BuiltinProgram {
|
|
||||||
name: "address_lookup_table_program".to_string(),
|
|
||||||
program_id: solana_address_lookup_table_program::id(),
|
program_id: solana_address_lookup_table_program::id(),
|
||||||
process_instruction:
|
builtin: create_builtin(
|
||||||
|
"address_lookup_table_program".to_string(),
|
||||||
solana_address_lookup_table_program::processor::process_instruction,
|
solana_address_lookup_table_program::processor::process_instruction,
|
||||||
},
|
),
|
||||||
feature_id: feature_set::versioned_tx_message_enabled::id(),
|
feature_id: feature_set::versioned_tx_message_enabled::id(),
|
||||||
},
|
},
|
||||||
BuiltinFeatureTransition::Add {
|
BuiltinFeatureTransition::Add {
|
||||||
builtin: BuiltinProgram {
|
|
||||||
name: "zk_token_proof_program".to_string(),
|
|
||||||
program_id: solana_zk_token_sdk::zk_token_proof_program::id(),
|
program_id: solana_zk_token_sdk::zk_token_proof_program::id(),
|
||||||
process_instruction: solana_zk_token_proof_program::process_instruction,
|
builtin: create_builtin(
|
||||||
},
|
"zk_token_proof_program".to_string(),
|
||||||
|
solana_zk_token_proof_program::process_instruction,
|
||||||
|
),
|
||||||
feature_id: feature_set::zk_token_sdk_enabled::id(),
|
feature_id: feature_set::zk_token_sdk_enabled::id(),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -157,9 +178,14 @@ pub fn get_pubkeys() -> Vec<Pubkey> {
|
||||||
let builtins = get();
|
let builtins = get();
|
||||||
|
|
||||||
let mut pubkeys = Vec::new();
|
let mut pubkeys = Vec::new();
|
||||||
pubkeys.extend(builtins.genesis_builtins.iter().map(|b| b.program_id));
|
pubkeys.extend(
|
||||||
|
builtins
|
||||||
|
.genesis_builtins
|
||||||
|
.iter()
|
||||||
|
.map(|(program_id, _builtin)| program_id),
|
||||||
|
);
|
||||||
pubkeys.extend(builtins.feature_transitions.iter().filter_map(|f| match f {
|
pubkeys.extend(builtins.feature_transitions.iter().filter_map(|f| match f {
|
||||||
BuiltinFeatureTransition::Add { builtin, .. } => Some(builtin.program_id),
|
BuiltinFeatureTransition::Add { program_id, .. } => Some(program_id),
|
||||||
BuiltinFeatureTransition::RemoveOrRetain { .. } => None,
|
BuiltinFeatureTransition::RemoveOrRetain { .. } => None,
|
||||||
}));
|
}));
|
||||||
pubkeys
|
pubkeys
|
||||||
|
|
Loading…
Reference in New Issue