Skip to content

runtime/Optimize accounts loading (one pass) #1157

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6735,6 +6735,17 @@ impl TransactionProcessingCallback for Bank {
.ok()
}

fn load_account_with(
&self,
pubkey: &Pubkey,
callback: impl for<'a> Fn(&'a AccountSharedData) -> bool,
) -> Option<(AccountSharedData, Slot)> {
self.rc
.accounts
.accounts_db
.load_account_with(&self.ancestors, pubkey, callback)
}

fn get_account_shared_data(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
self.rc
.accounts
Expand Down
8 changes: 7 additions & 1 deletion runtime/src/bank/builtins/core_bpf_migration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ impl Bank {
let source = SourceBuffer::new_checked(self, &config.source_buffer_address)?;

// Attempt serialization first before modifying the bank.
let new_target_program_account = self.new_target_program_account(&target)?;
let mut new_target_program_account = self.new_target_program_account(&target)?;
let new_target_program_data_account =
self.new_target_program_data_account(&source, config.upgrade_authority_address)?;

Expand All @@ -268,6 +268,12 @@ impl Bank {
new_target_program_data_account.data(),
)?;

// After successfully deployed the `Builtin` program, we need to mark
// the builtin program account as executable. This is required for
// transaction account loading, when "fake program account" optimization
// is disabled.
new_target_program_account.set_executable(true);

// Calculate the lamports to burn.
// The target program account will be replaced, so burn its lamports.
// The source buffer account will be cleared, so burn its lamports.
Expand Down
16 changes: 8 additions & 8 deletions runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7135,12 +7135,10 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() {
invocation_message.clone(),
bank.last_blockhash(),
);
// See comments below for Test buffer invocation.
assert_eq!(
bank.process_transaction(&transaction),
Err(TransactionError::InstructionError(
0,
InstructionError::InvalidAccountData
)),
Err(TransactionError::InvalidProgramForExecution),
);
{
let program_cache = bank.transaction_processor.program_cache.read().unwrap();
Expand All @@ -7159,12 +7157,14 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() {
let instruction = Instruction::new_with_bytes(buffer_address, &[], Vec::new());
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
let transaction = Transaction::new(&[&binding], message, bank.last_blockhash());
// This is a slightly change of behavior for this PR. In the old code, we
// short-circuit buffer account to fake it and mark it executable. So it
// passed program execution check but failed with `Err(InstructionError(0, InvalidAccountData))`.
// With this PR, we don't do that. The buffer account will NOT be executable. A different error is throw `Err(InvalidProgramForExecution)`.
// This will NOT break consensus fortunately! Changing to `Err(InvalidProgramForExecution)` won't affect bank hash!
assert_eq!(
bank.process_transaction(&transaction),
Err(TransactionError::InstructionError(
0,
InstructionError::InvalidAccountData,
)),
Err(TransactionError::InvalidProgramForExecution),
);
{
let program_cache = bank.transaction_processor.program_cache.read().unwrap();
Expand Down
Loading