Skip to content

Commit

Permalink
Add AccountOverrides explicit type
Browse files Browse the repository at this point in the history
  • Loading branch information
joncinque committed Apr 21, 2022
1 parent ddc2808 commit 46b291f
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 39 deletions.
25 changes: 25 additions & 0 deletions runtime/src/account_overrides.rs
@@ -0,0 +1,25 @@
use solana_sdk::{account::AccountSharedData, pubkey::Pubkey, sysvar};

/// Encapsulates overridden accounts, typically used for transaction simulations
#[derive(Default)]
pub struct AccountOverrides {
pub slot_history: Option<AccountSharedData>,
}

impl AccountOverrides {
/// Sets in the slot history
///
/// Note: no checks are performed on the correctness of the contained data
pub fn set_slot_history(&mut self, slot_history: Option<AccountSharedData>) {
self.slot_history = slot_history;
}

/// Gets the account if it's found in the list of overrides
pub fn get(&self, pubkey: &Pubkey) -> Option<&AccountSharedData> {
if pubkey == &sysvar::slot_history::id() {
self.slot_history.as_ref()
} else {
None
}
}
}
62 changes: 34 additions & 28 deletions runtime/src/accounts.rs
@@ -1,5 +1,6 @@
use {
crate::{
account_overrides::AccountOverrides,
account_rent_state::{check_rent_state_with_account, RentState},
accounts_db::{
AccountShrinkThreshold, AccountsAddRootTiming, AccountsDb, AccountsDbConfig,
Expand Down Expand Up @@ -126,7 +127,6 @@ pub struct LoadedTransaction {
}

pub type TransactionLoadResult = (Result<LoadedTransaction>, Option<NonceFull>);
pub type AccountOverrides = HashMap<Pubkey, AccountSharedData>;

pub enum AccountAddressFilter {
Exclude, // exclude all addresses matching the filter
Expand Down Expand Up @@ -266,35 +266,36 @@ impl Accounts {
payer_index = Some(i);
}

if let Some(account_override) =
account_overrides.and_then(|overrides| overrides.get(key))
{
account_override.clone()
} else if solana_sdk::sysvar::instructions::check_id(key) {
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 {
let (account, rent) = 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();
let (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 bpf_loader_upgradeable::check_id(account.owner()) {
if message.is_writable(i) && !message.is_upgradeable_loader_present() {
Expand Down Expand Up @@ -3096,16 +3097,19 @@ mod tests {
false,
AccountShrinkThreshold::default(),
);
let mut account_overrides = AccountOverrides::new();
let mut account_overrides = AccountOverrides::default();
let slot_history_id = sysvar::slot_history::id();
let account = AccountSharedData::new(42, 0, &Pubkey::default());
account_overrides.set_slot_history(Some(account));

let keypair = Keypair::new();
let account = AccountSharedData::new(1_000_000, 0, &Pubkey::default());
account_overrides.insert(keypair.pubkey(), account);
accounts.store_slow_uncached(0, &keypair.pubkey(), &account);

let instructions = vec![CompiledInstruction::new(1, &(), vec![0])];
let instructions = vec![CompiledInstruction::new(2, &(), vec![0])];
let tx = Transaction::new_with_compiled_instructions(
&[&keypair],
&[],
&[slot_history_id],
Hash::default(),
vec![native_loader::id()],
instructions,
Expand All @@ -3115,6 +3119,8 @@ mod tests {
assert_eq!(loaded_accounts.len(), 1);
let loaded_transaction = loaded_accounts[0].0.as_ref().unwrap();
assert_eq!(loaded_transaction.accounts[0].0, keypair.pubkey());
assert_eq!(loaded_transaction.accounts[1].0, slot_history_id);
assert_eq!(loaded_transaction.accounts[1].1.lamports(), 42);
}

fn create_accounts_prepare_if_nonce_account() -> (
Expand Down
27 changes: 16 additions & 11 deletions runtime/src/bank.rs
Expand Up @@ -37,8 +37,9 @@
use solana_sdk::recent_blockhashes_account;
use {
crate::{
account_overrides::AccountOverrides,
accounts::{
AccountAddressFilter, AccountOverrides, Accounts, LoadedTransaction, PubkeyAccountSlot,
AccountAddressFilter, Accounts, LoadedTransaction, PubkeyAccountSlot,
TransactionLoadResult,
},
accounts_db::{
Expand Down Expand Up @@ -116,7 +117,7 @@ use {
inflation::Inflation,
instruction::CompiledInstruction,
lamports::LamportsError,
message::SanitizedMessage,
message::{AccountKeys, SanitizedMessage},
native_loader,
native_token::sol_to_lamports,
nonce, nonce_account,
Expand Down Expand Up @@ -3587,11 +3588,12 @@ impl Bank {
&self,
transaction: SanitizedTransaction,
) -> TransactionSimulationResult {
let number_of_accounts = transaction.message().account_keys().len();
let account_keys = transaction.message().account_keys();
let number_of_accounts = account_keys.len();
let account_overrides = self.get_account_overrides_for_simulation(&account_keys);
let batch = self.prepare_simulation_batch(transaction);
let mut timings = ExecuteTimings::default();

let account_overrides = self.get_account_overrides_for_simulation();
let LoadAndExecuteTransactionsOutput {
loaded_transactions,
mut execution_results,
Expand Down Expand Up @@ -3653,19 +3655,22 @@ impl Bank {
}
}

fn get_account_overrides_for_simulation(&self) -> AccountOverrides {
let mut account_overrides = AccountOverrides::new();
{
let account_pubkey = sysvar::slot_history::id();
let current_account = self.get_account_with_fixed_root(&account_pubkey);
fn get_account_overrides_for_simulation(&self, account_keys: &AccountKeys) -> AccountOverrides {
let mut account_overrides = AccountOverrides::default();
let slot_history_id = sysvar::slot_history::id();
if account_keys.iter().any(|pubkey| *pubkey == slot_history_id) {
let current_account = self.get_account_with_fixed_root(&slot_history_id);
let slot_history = current_account
.as_ref()
.map(|account| from_account::<SlotHistory, _>(account).unwrap())
.unwrap_or_default();
if slot_history.check(self.slot()) == Check::Found {
let ancestors = Ancestors::from(self.proper_ancestors().collect::<Vec<_>>());
self.load_slow_with_fixed_root(&ancestors, &account_pubkey)
.and_then(|(account, _)| account_overrides.insert(account_pubkey, account));
if let Some((account, _)) =
self.load_slow_with_fixed_root(&ancestors, &slot_history_id)
{
account_overrides.set_slot_history(Some(account));
}
}
}
account_overrides
Expand Down
1 change: 1 addition & 0 deletions runtime/src/lib.rs
Expand Up @@ -5,6 +5,7 @@
extern crate lazy_static;

pub mod account_info;
pub mod account_overrides;
pub mod account_rent_state;
pub mod accounts;
pub mod accounts_background_service;
Expand Down

0 comments on commit 46b291f

Please sign in to comment.