Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVM: add new bootstrap method #3203

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions program-runtime/src/loaded_programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,19 @@ impl<FG: ForkGraph> ProgramCache<FG> {
self.fork_graph = Some(fork_graph);
}

pub fn set_environments(
&mut self,
latest_root_slot: Slot,
latest_root_epoch: Epoch,
program_runtime_environment_v1: ProgramRuntimeEnvironment,
program_runtime_environment_v2: ProgramRuntimeEnvironment,
) {
self.latest_root_slot = latest_root_slot;
self.latest_root_epoch = latest_root_epoch;
self.environments.program_runtime_v1 = program_runtime_environment_v1;
self.environments.program_runtime_v2 = program_runtime_environment_v2;
}

/// Returns the current environments depending on the given epoch
pub fn get_environments_for_epoch(&self, epoch: Epoch) -> ProgramRuntimeEnvironments {
if epoch != self.latest_root_epoch {
Expand Down
35 changes: 18 additions & 17 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5103,23 +5103,24 @@ impl Bank {
}
}

let mut program_cache = self.transaction_processor.program_cache.write().unwrap();
program_cache.latest_root_slot = self.slot();
program_cache.latest_root_epoch = self.epoch();
program_cache.environments.program_runtime_v1 = Arc::new(
create_program_runtime_environment_v1(
&self.feature_set,
&self.compute_budget().unwrap_or_default(),
false, /* deployment */
false, /* debugging_features */
)
.unwrap(),
);
program_cache.environments.program_runtime_v2 =
Arc::new(create_program_runtime_environment_v2(
&self.compute_budget().unwrap_or_default(),
false, /* debugging_features */
));
self.transaction_processor
.configure_program_runtime_environments(
self.slot(),
self.epoch(),
Arc::new(
create_program_runtime_environment_v1(
&self.feature_set,
&self.compute_budget().unwrap_or_default(),
false, /* deployment */
false, /* debugging_features */
)
.unwrap(),
),
Arc::new(create_program_runtime_environment_v2(
&self.compute_budget().unwrap_or_default(),
false, /* debugging_features */
)),
);
}

pub fn set_inflation(&self, inflation: Inflation) {
Expand Down
34 changes: 18 additions & 16 deletions svm/examples/paytube/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
use {
solana_bpf_loader_program::syscalls::create_program_runtime_environment_v1,
solana_compute_budget::compute_budget::ComputeBudget,
solana_program_runtime::loaded_programs::{BlockRelation, ForkGraph, ProgramCacheEntry},
solana_program_runtime::{
loaded_programs::{BlockRelation, ForkGraph, ProgramCacheEntry},
solana_rbpf::{
program::{BuiltinProgram, FunctionRegistry},
vm::Config,
},
},
solana_sdk::{clock::Slot, feature_set::FeatureSet, transaction},
solana_svm::{
account_loader::CheckedTransactionDetails,
Expand Down Expand Up @@ -47,23 +53,19 @@ pub(crate) fn create_transaction_batch_processor<CB: TransactionProcessingCallba
// marked as "depoyed" in slot 0.
// See `solana_svm::program_loader::load_program_with_pubkey` for more
// details.
let processor = TransactionBatchProcessor::<PayTubeForkGraph>::new_uninitialized(
/* slot */ 1, /* epoch */ 1,
);

{
let mut cache = processor.program_cache.write().unwrap();

// Initialize the mocked fork graph.
cache.fork_graph = Some(Arc::downgrade(&fork_graph));

// Initialize a proper cache environment.
// (Use Loader v4 program to initialize runtime v2 if desired)
cache.environments.program_runtime_v1 = Arc::new(
let processor = TransactionBatchProcessor::<PayTubeForkGraph>::new(
/* slot */ 1,
/* epoch */ 1,
Arc::downgrade(&fork_graph),
Arc::new(
create_program_runtime_environment_v1(feature_set, compute_budget, false, false)
.unwrap(),
);
}
),
Arc::new(BuiltinProgram::new_loader(
Config::default(),
FunctionRegistry::default(),
)),
);

// Add the system program builtin.
processor.add_builtin(
Expand Down
72 changes: 65 additions & 7 deletions svm/src/transaction_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use {
invoke_context::{EnvironmentConfig, InvokeContext},
loaded_programs::{
ForkGraph, ProgramCache, ProgramCacheEntry, ProgramCacheForTxBatch,
ProgramCacheMatchCriteria,
ProgramCacheMatchCriteria, ProgramRuntimeEnvironment,
},
sysvar_cache::SysvarCache,
},
Expand All @@ -60,6 +60,7 @@ use {
collections::{hash_map::Entry, HashMap, HashSet},
fmt::{Debug, Formatter},
rc::Rc,
sync::Weak,
},
};

Expand Down Expand Up @@ -207,6 +208,34 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
}
}

/// Create a new `TransactionBatchProcessor`.
///
/// The created processor's program cache is initialized with the provided
/// fork graph and loaders.
///
/// The cache will still not contain any builtin programs. It's advisable to
/// call `add_builtin` to add the required builtins before using the processor.
pub fn new(
slot: Slot,
epoch: Epoch,
fork_graph: Weak<RwLock<FG>>,
program_runtime_environment_v1: ProgramRuntimeEnvironment,
program_runtime_environment_v2: ProgramRuntimeEnvironment,
) -> Self {
let processor = Self::new_uninitialized(slot, epoch);
{
let mut program_cache = processor.program_cache.write().unwrap();
program_cache.set_fork_graph(fork_graph);
program_cache.set_environments(
slot,
epoch,
program_runtime_environment_v1,
program_runtime_environment_v2,
);
}
processor
}

/// Create a new `TransactionBatchProcessor` from the current instance, but
/// with the provided slot and epoch.
///
Expand All @@ -223,6 +252,26 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
}
}

/// Configures the program runtime environment for the transaction
/// processor's program cache.
///
/// Use this method to register loaders for the processor's program cache.
pub fn configure_program_runtime_environments(
&self,
latest_root_slot: Slot,
latest_root_epoch: Epoch,
program_runtime_environment_v1: ProgramRuntimeEnvironment,
program_runtime_environment_v2: ProgramRuntimeEnvironment,
) {
let mut program_cache = self.program_cache.write().unwrap();
program_cache.set_environments(
latest_root_slot,
latest_root_epoch,
program_runtime_environment_v1,
program_runtime_environment_v2,
);
}

/// Returns the current environments depending on the given epoch
/// Returns None if the call could result in a deadlock
#[cfg(feature = "dev-context-only-utils")]
Expand Down Expand Up @@ -1314,8 +1363,11 @@ mod tests {
let mock_bank = MockBankCallback::default();
let batch_processor = TransactionBatchProcessor::<TestForkGraph>::default();
let fork_graph = Arc::new(RwLock::new(TestForkGraph {}));
batch_processor.program_cache.write().unwrap().fork_graph =
Some(Arc::downgrade(&fork_graph));
batch_processor
.program_cache
.write()
.unwrap()
.set_fork_graph(Arc::downgrade(&fork_graph));
let key = Pubkey::new_unique();

let mut account_maps: HashMap<Pubkey, u64> = HashMap::new();
Expand All @@ -1329,8 +1381,11 @@ mod tests {
let mock_bank = MockBankCallback::default();
let batch_processor = TransactionBatchProcessor::<TestForkGraph>::default();
let fork_graph = Arc::new(RwLock::new(TestForkGraph {}));
batch_processor.program_cache.write().unwrap().fork_graph =
Some(Arc::downgrade(&fork_graph));
batch_processor
.program_cache
.write()
.unwrap()
.set_fork_graph(Arc::downgrade(&fork_graph));
let key = Pubkey::new_unique();

let mut account_data = AccountSharedData::default();
Expand Down Expand Up @@ -1817,8 +1872,11 @@ mod tests {
let mock_bank = MockBankCallback::default();
let batch_processor = TransactionBatchProcessor::<TestForkGraph>::default();
let fork_graph = Arc::new(RwLock::new(TestForkGraph {}));
batch_processor.program_cache.write().unwrap().fork_graph =
Some(Arc::downgrade(&fork_graph));
batch_processor
.program_cache
.write()
.unwrap()
.set_fork_graph(Arc::downgrade(&fork_graph));

let key = Pubkey::new_unique();
let name = "a_builtin_name";
Expand Down
6 changes: 5 additions & 1 deletion svm/tests/concurrent_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ fn program_cache_execution(threads: usize) {
let mut mock_bank = MockBankCallback::default();
let batch_processor = TransactionBatchProcessor::<MockForkGraph>::new_uninitialized(5, 5);
let fork_graph = Arc::new(RwLock::new(MockForkGraph {}));
batch_processor.program_cache.write().unwrap().fork_graph = Some(Arc::downgrade(&fork_graph));
batch_processor
.program_cache
.write()
.unwrap()
.set_fork_graph(Arc::downgrade(&fork_graph));

let programs = vec![
deploy_program("hello-solana".to_string(), 0, &mut mock_bank),
Expand Down
24 changes: 11 additions & 13 deletions svm/tests/conformance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
solana_log_collector::LogCollector,
solana_program_runtime::{
invoke_context::{EnvironmentConfig, InvokeContext},
loaded_programs::{ProgramCacheEntry, ProgramCacheForTxBatch, ProgramRuntimeEnvironments},
loaded_programs::{ProgramCacheEntry, ProgramCacheForTxBatch},
solana_rbpf::{
program::{BuiltinProgram, FunctionRegistry},
vm::Config,
Expand Down Expand Up @@ -244,20 +244,18 @@ fn run_fixture(fixture: InstrFixture, filename: OsString, execute_as_instr: bool
create_program_runtime_environment_v1(&feature_set, &compute_budget, false, false).unwrap();

mock_bank.override_feature_set(feature_set);
let batch_processor = TransactionBatchProcessor::<MockForkGraph>::new_uninitialized(42, 2);

let fork_graph = Arc::new(RwLock::new(MockForkGraph {}));
{
let mut program_cache = batch_processor.program_cache.write().unwrap();
program_cache.environments = ProgramRuntimeEnvironments {
program_runtime_v1: Arc::new(v1_environment),
program_runtime_v2: Arc::new(BuiltinProgram::new_loader(
Config::default(),
FunctionRegistry::default(),
)),
};
program_cache.fork_graph = Some(Arc::downgrade(&fork_graph.clone()));
}
let batch_processor = TransactionBatchProcessor::new(
42,
2,
Arc::downgrade(&fork_graph),
Arc::new(v1_environment),
Arc::new(BuiltinProgram::new_loader(
Config::default(),
FunctionRegistry::default(),
)),
);

batch_processor.fill_missing_sysvar_cache_entries(&mock_bank);
register_builtins(&batch_processor, &mock_bank);
Expand Down
Loading