Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
Refactor: Rename load_transaction to load_transaction_accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarry committed Nov 4, 2022
1 parent 064cfc7 commit 1fc0bf1
Showing 1 changed file with 125 additions and 127 deletions.
252 changes: 125 additions & 127 deletions runtime/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ impl Accounts {
})
}

fn load_transaction(
fn load_transaction_accounts(
&self,
ancestors: &Ancestors,
tx: &SanitizedTransaction,
Expand All @@ -258,147 +258,145 @@ impl Accounts {
feature_set: &FeatureSet,
account_overrides: Option<&AccountOverrides>,
) -> Result<LoadedTransaction> {
// Copy all the accounts
let message = tx.message();
// NOTE: this check will never fail because `tx` is sanitized
if tx.signatures().is_empty() && fee != 0 {
Err(TransactionError::MissingSignatureForFee)
} else {
// There is no way to predict what program will execute without an error
// If a fee can pay for execution then the program will be scheduled
let mut validated_fee_payer = false;
let mut tx_rent: TransactionRent = 0;
let account_keys = message.account_keys();
let mut accounts = Vec::with_capacity(account_keys.len());
let mut account_deps = Vec::with_capacity(account_keys.len());
let mut rent_debits = RentDebits::default();
for (i, key) in account_keys.iter().enumerate() {
let account = if !message.is_non_loader_key(i) {
// Fill in an empty account for the program slots.
AccountSharedData::default()
return Err(TransactionError::MissingSignatureForFee);
}

// There is no way to predict what program will execute without an error
// If a fee can pay for execution then the program will be scheduled
let mut validated_fee_payer = false;
let mut tx_rent: TransactionRent = 0;
let message = tx.message();
let account_keys = message.account_keys();
let mut accounts = Vec::with_capacity(account_keys.len());
let mut account_deps = Vec::with_capacity(account_keys.len());
let mut rent_debits = RentDebits::default();
for (i, key) in account_keys.iter().enumerate() {
let account = if !message.is_non_loader_key(i) {
// Fill in an empty account for the program slots.
AccountSharedData::default()
} else {
#[allow(clippy::collapsible_else_if)]
if solana_sdk::sysvar::instructions::check_id(key) {
Self::construct_instructions_account(
message,
feature_set
.is_active(&feature_set::instructions_sysvar_owned_by_sysvar::id()),
)
} else {
#[allow(clippy::collapsible_else_if)]
if solana_sdk::sysvar::instructions::check_id(key) {
Self::construct_instructions_account(
message,
feature_set
.is_active(&feature_set::instructions_sysvar_owned_by_sysvar::id()),
)
let (mut account, rent) = if let Some(account_override) =
account_overrides.and_then(|overrides| overrides.get(key))
{
(account_override.clone(), 0)
} else {
let (mut account, rent) = if let Some(account_override) =
account_overrides.and_then(|overrides| overrides.get(key))
{
(account_override.clone(), 0)
} else {
self.accounts_db
.load_with_fixed_root(ancestors, key)
.map(|(mut account, _)| {
if message.is_writable(i) {
let rent_due = rent_collector
.collect_from_existing_account(
key,
&mut account,
self.accounts_db.filler_account_suffix.as_ref(),
)
.rent_amount;
(account, rent_due)
} else {
(account, 0)
}
})
.unwrap_or_default()
};

if !validated_fee_payer {
if i != 0 {
warn!("Payer index should be 0! {:?}", tx);
}
self.accounts_db
.load_with_fixed_root(ancestors, key)
.map(|(mut account, _)| {
if message.is_writable(i) {
let rent_due = rent_collector
.collect_from_existing_account(
key,
&mut account,
self.accounts_db.filler_account_suffix.as_ref(),
)
.rent_amount;
(account, rent_due)
} else {
(account, 0)
}
})
.unwrap_or_default()
};

Self::validate_fee_payer(
key,
&mut account,
i as IndexOfAccount,
error_counters,
rent_collector,
feature_set,
fee,
)?;

validated_fee_payer = true;
if !validated_fee_payer {
if i != 0 {
warn!("Payer index should be 0! {:?}", tx);
}

if bpf_loader_upgradeable::check_id(account.owner()) {
if message.is_writable(i) && !message.is_upgradeable_loader_present() {
error_counters.invalid_writable_account += 1;
return Err(TransactionError::InvalidWritableAccount);
}
Self::validate_fee_payer(
key,
&mut account,
i as IndexOfAccount,
error_counters,
rent_collector,
feature_set,
fee,
)?;

validated_fee_payer = true;
}

if account.executable() {
// The upgradeable loader requires the derived ProgramData account
if let Ok(UpgradeableLoaderState::Program {
programdata_address,
}) = account.state()
if bpf_loader_upgradeable::check_id(account.owner()) {
if message.is_writable(i) && !message.is_upgradeable_loader_present() {
error_counters.invalid_writable_account += 1;
return Err(TransactionError::InvalidWritableAccount);
}

if account.executable() {
// The upgradeable loader requires the derived ProgramData account
if let Ok(UpgradeableLoaderState::Program {
programdata_address,
}) = account.state()
{
if let Some((programdata_account, _)) = self
.accounts_db
.load_with_fixed_root(ancestors, &programdata_address)
{
if let Some((programdata_account, _)) = self
.accounts_db
.load_with_fixed_root(ancestors, &programdata_address)
{
account_deps
.push((programdata_address, programdata_account));
} else {
error_counters.account_not_found += 1;
return Err(TransactionError::ProgramAccountNotFound);
}
account_deps.push((programdata_address, programdata_account));
} else {
error_counters.invalid_program_for_execution += 1;
return Err(TransactionError::InvalidProgramForExecution);
error_counters.account_not_found += 1;
return Err(TransactionError::ProgramAccountNotFound);
}
} else {
error_counters.invalid_program_for_execution += 1;
return Err(TransactionError::InvalidProgramForExecution);
}
} else if account.executable() && message.is_writable(i) {
error_counters.invalid_writable_account += 1;
return Err(TransactionError::InvalidWritableAccount);
}

tx_rent += rent;
rent_debits.insert(key, rent, account.lamports());

account
} else if account.executable() && message.is_writable(i) {
error_counters.invalid_writable_account += 1;
return Err(TransactionError::InvalidWritableAccount);
}
};
accounts.push((*key, account));
}
debug_assert_eq!(accounts.len(), account_keys.len());
// Appends the account_deps at the end of the accounts,
// this way they can be accessed in a uniform way.
// At places where only the accounts are needed,
// the account_deps are truncated using e.g:
// accounts.iter().take(message.account_keys.len())
accounts.append(&mut account_deps);

if validated_fee_payer {
let program_indices = message
.instructions()
.iter()
.map(|instruction| {
self.load_executable_accounts(
ancestors,
&mut accounts,
instruction.program_id_index as IndexOfAccount,
error_counters,
)
})
.collect::<Result<Vec<Vec<IndexOfAccount>>>>()?;

Ok(LoadedTransaction {
accounts,
program_indices,
rent: tx_rent,
rent_debits,
tx_rent += rent;
rent_debits.insert(key, rent, account.lamports());

account
}
};
accounts.push((*key, account));
}
debug_assert_eq!(accounts.len(), account_keys.len());
// Appends the account_deps at the end of the accounts,
// this way they can be accessed in a uniform way.
// At places where only the accounts are needed,
// the account_deps are truncated using e.g:
// accounts.iter().take(message.account_keys.len())
accounts.append(&mut account_deps);

if validated_fee_payer {
let program_indices = message
.instructions()
.iter()
.map(|instruction| {
self.load_executable_accounts(
ancestors,
&mut accounts,
instruction.program_id_index as IndexOfAccount,
error_counters,
)
})
} else {
error_counters.account_not_found += 1;
Err(TransactionError::AccountNotFound)
}
.collect::<Result<Vec<Vec<IndexOfAccount>>>>()?;

Ok(LoadedTransaction {
accounts,
program_indices,
rent: tx_rent,
rent_debits,
})
} else {
error_counters.account_not_found += 1;
Err(TransactionError::AccountNotFound)
}
}

Expand Down Expand Up @@ -563,7 +561,7 @@ impl Accounts {
return (Err(TransactionError::BlockhashNotFound), None);
};

let loaded_transaction = match self.load_transaction(
let loaded_transaction = match self.load_transaction_accounts(
ancestors,
tx,
fee,
Expand Down

0 comments on commit 1fc0bf1

Please sign in to comment.