Refactoring: Unify account_deps and accounts (#17898)
* Changes ThisInvokeContext::get_account() to use accounts instead of pre_accounts. * Adds explicit keys to accounts to make them symmetric to account_deps. * Appends account_deps to accounts in transaction loading and removes account_deps everywhere else.
This commit is contained in:
committed by
GitHub
parent
ffb1f3932a
commit
7462c27d07
@@ -97,14 +97,12 @@ pub struct Accounts {
|
||||
}
|
||||
|
||||
// for the load instructions
|
||||
pub type TransactionAccounts = Vec<AccountSharedData>;
|
||||
pub type TransactionAccountDeps = Vec<(Pubkey, AccountSharedData)>;
|
||||
pub type TransactionAccounts = Vec<(Pubkey, AccountSharedData)>;
|
||||
pub type TransactionRent = u64;
|
||||
pub type TransactionLoaders = Vec<Vec<(Pubkey, AccountSharedData)>>;
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct LoadedTransaction {
|
||||
pub accounts: TransactionAccounts,
|
||||
pub account_deps: TransactionAccountDeps,
|
||||
pub loaders: TransactionLoaders,
|
||||
pub rent: TransactionRent,
|
||||
pub rent_debits: RentDebits,
|
||||
@@ -277,36 +275,43 @@ impl Accounts {
|
||||
// Fill in an empty account for the program slots.
|
||||
AccountSharedData::default()
|
||||
};
|
||||
accounts.push(account);
|
||||
accounts.push((*key, account));
|
||||
}
|
||||
debug_assert_eq!(accounts.len(), message.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 let Some(payer_index) = payer_index {
|
||||
if payer_index != 0 {
|
||||
warn!("Payer index should be 0! {:?}", tx);
|
||||
}
|
||||
if accounts[payer_index].lamports() == 0 {
|
||||
let payer_account = &mut accounts[payer_index].1;
|
||||
if payer_account.lamports() == 0 {
|
||||
error_counters.account_not_found += 1;
|
||||
Err(TransactionError::AccountNotFound)
|
||||
} else {
|
||||
let min_balance = match get_system_account_kind(&accounts[payer_index])
|
||||
.ok_or_else(|| {
|
||||
let min_balance =
|
||||
match get_system_account_kind(payer_account).ok_or_else(|| {
|
||||
error_counters.invalid_account_for_fee += 1;
|
||||
TransactionError::InvalidAccountForFee
|
||||
})? {
|
||||
SystemAccountKind::System => 0,
|
||||
SystemAccountKind::Nonce => {
|
||||
// Should we ever allow a fees charge to zero a nonce account's
|
||||
// balance. The state MUST be set to uninitialized in that case
|
||||
rent_collector.rent.minimum_balance(nonce::State::size())
|
||||
}
|
||||
};
|
||||
SystemAccountKind::System => 0,
|
||||
SystemAccountKind::Nonce => {
|
||||
// Should we ever allow a fees charge to zero a nonce account's
|
||||
// balance. The state MUST be set to uninitialized in that case
|
||||
rent_collector.rent.minimum_balance(nonce::State::size())
|
||||
}
|
||||
};
|
||||
|
||||
if accounts[payer_index].lamports() < fee + min_balance {
|
||||
if payer_account.lamports() < fee + min_balance {
|
||||
error_counters.insufficient_funds += 1;
|
||||
Err(TransactionError::InsufficientFundsForFee)
|
||||
} else {
|
||||
accounts[payer_index]
|
||||
payer_account
|
||||
.checked_sub_lamports(fee)
|
||||
.map_err(|_| TransactionError::InsufficientFundsForFee)?;
|
||||
|
||||
@@ -329,7 +334,6 @@ impl Accounts {
|
||||
.collect::<Result<TransactionLoaders>>()?;
|
||||
Ok(LoadedTransaction {
|
||||
accounts,
|
||||
account_deps,
|
||||
loaders,
|
||||
rent: tx_rent,
|
||||
rent_debits,
|
||||
@@ -992,12 +996,9 @@ impl Accounts {
|
||||
let message = &tx.message();
|
||||
let loaded_transaction = raccs.as_mut().unwrap();
|
||||
let mut fee_payer_index = None;
|
||||
for ((i, key), account) in message
|
||||
.account_keys
|
||||
.iter()
|
||||
.enumerate()
|
||||
for (i, (key, account)) in (0..message.account_keys.len())
|
||||
.zip(loaded_transaction.accounts.iter_mut())
|
||||
.filter(|((i, key), _account)| message.is_non_loader_key(key, *i))
|
||||
.filter(|(i, (key, _account))| message.is_non_loader_key(key, *i))
|
||||
{
|
||||
let is_nonce_account = prepare_if_nonce_account(
|
||||
account,
|
||||
@@ -1035,7 +1036,7 @@ impl Accounts {
|
||||
.rent_debits
|
||||
.push(key, rent, account.lamports());
|
||||
}
|
||||
accounts.push((key, &*account));
|
||||
accounts.push((&*key, &*account));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1377,7 +1378,7 @@ mod tests {
|
||||
assert_eq!(loaded_accounts.len(), 1);
|
||||
let (load_res, _nonce_rollback) = &loaded_accounts[0];
|
||||
let loaded_transaction = load_res.as_ref().unwrap();
|
||||
assert_eq!(loaded_transaction.accounts[0].lamports(), min_balance);
|
||||
assert_eq!(loaded_transaction.accounts[0].1.lamports(), min_balance);
|
||||
|
||||
// Fee leaves zero balance fails
|
||||
accounts[0].1.set_lamports(min_balance);
|
||||
@@ -1439,7 +1440,7 @@ mod tests {
|
||||
match &loaded_accounts[0] {
|
||||
(Ok(loaded_transaction), _nonce_rollback) => {
|
||||
assert_eq!(loaded_transaction.accounts.len(), 3);
|
||||
assert_eq!(loaded_transaction.accounts[0], accounts[0].1);
|
||||
assert_eq!(loaded_transaction.accounts[0].1, accounts[0].1);
|
||||
assert_eq!(loaded_transaction.loaders.len(), 1);
|
||||
assert_eq!(loaded_transaction.loaders[0].len(), 0);
|
||||
}
|
||||
@@ -1662,7 +1663,7 @@ mod tests {
|
||||
match &loaded_accounts[0] {
|
||||
(Ok(loaded_transaction), _nonce_rollback) => {
|
||||
assert_eq!(loaded_transaction.accounts.len(), 3);
|
||||
assert_eq!(loaded_transaction.accounts[0], accounts[0].1);
|
||||
assert_eq!(loaded_transaction.accounts[0].1, accounts[0].1);
|
||||
assert_eq!(loaded_transaction.loaders.len(), 2);
|
||||
assert_eq!(loaded_transaction.loaders[0].len(), 1);
|
||||
assert_eq!(loaded_transaction.loaders[1].len(), 2);
|
||||
@@ -1970,6 +1971,9 @@ mod tests {
|
||||
let keypair0 = Keypair::new();
|
||||
let keypair1 = Keypair::new();
|
||||
let pubkey = solana_sdk::pubkey::new_rand();
|
||||
let account0 = AccountSharedData::new(1, 0, &Pubkey::default());
|
||||
let account1 = AccountSharedData::new(2, 0, &Pubkey::default());
|
||||
let account2 = AccountSharedData::new(3, 0, &Pubkey::default());
|
||||
|
||||
let rent_collector = RentCollector::default();
|
||||
|
||||
@@ -1982,6 +1986,10 @@ mod tests {
|
||||
Hash::default(),
|
||||
instructions,
|
||||
);
|
||||
let transaction_accounts0 = vec![
|
||||
(message.account_keys[0], account0),
|
||||
(message.account_keys[1], account2.clone()),
|
||||
];
|
||||
let tx0 = Transaction::new(&[&keypair0], message, Hash::default());
|
||||
|
||||
let instructions = vec![CompiledInstruction::new(2, &(), vec![0, 1])];
|
||||
@@ -1993,22 +2001,19 @@ mod tests {
|
||||
Hash::default(),
|
||||
instructions,
|
||||
);
|
||||
let transaction_accounts1 = vec![
|
||||
(message.account_keys[0], account1),
|
||||
(message.account_keys[1], account2),
|
||||
];
|
||||
let tx1 = Transaction::new(&[&keypair1], message, Hash::default());
|
||||
let txs = vec![tx0, tx1];
|
||||
|
||||
let loaders = vec![(Ok(()), None), (Ok(()), None)];
|
||||
|
||||
let account0 = AccountSharedData::new(1, 0, &Pubkey::default());
|
||||
let account1 = AccountSharedData::new(2, 0, &Pubkey::default());
|
||||
let account2 = AccountSharedData::new(3, 0, &Pubkey::default());
|
||||
|
||||
let transaction_accounts0 = vec![account0, account2.clone()];
|
||||
let transaction_loaders0 = vec![];
|
||||
let transaction_rent0 = 0;
|
||||
let loaded0 = (
|
||||
Ok(LoadedTransaction {
|
||||
accounts: transaction_accounts0,
|
||||
account_deps: vec![],
|
||||
loaders: transaction_loaders0,
|
||||
rent: transaction_rent0,
|
||||
rent_debits: RentDebits::default(),
|
||||
@@ -2016,13 +2021,11 @@ mod tests {
|
||||
None,
|
||||
);
|
||||
|
||||
let transaction_accounts1 = vec![account1, account2];
|
||||
let transaction_loaders1 = vec![];
|
||||
let transaction_rent1 = 0;
|
||||
let loaded1 = (
|
||||
Ok(LoadedTransaction {
|
||||
accounts: transaction_accounts1,
|
||||
account_deps: vec![],
|
||||
loaders: transaction_loaders1,
|
||||
rent: transaction_rent1,
|
||||
rent_debits: RentDebits::default(),
|
||||
@@ -2046,6 +2049,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.insert_new_readonly(&pubkey);
|
||||
}
|
||||
let txs = &[tx0, tx1];
|
||||
let collected_accounts = accounts.collect_accounts_to_store(
|
||||
txs.iter(),
|
||||
&loaders,
|
||||
@@ -2349,16 +2353,34 @@ mod tests {
|
||||
let from = keypair_from_seed(&[1; 32]).unwrap();
|
||||
let from_address = from.pubkey();
|
||||
let to_address = Pubkey::new_unique();
|
||||
let nonce_state =
|
||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||
authority: nonce_authority.pubkey(),
|
||||
blockhash: Hash::new_unique(),
|
||||
fee_calculator: FeeCalculator::default(),
|
||||
}));
|
||||
let nonce_account_post =
|
||||
AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap();
|
||||
let from_account_post = AccountSharedData::new(4199, 0, &Pubkey::default());
|
||||
let to_account = AccountSharedData::new(2, 0, &Pubkey::default());
|
||||
let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default());
|
||||
let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default());
|
||||
|
||||
let instructions = vec![
|
||||
system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()),
|
||||
system_instruction::transfer(&from_address, &to_address, 42),
|
||||
];
|
||||
let message = Message::new(&instructions, Some(&from_address));
|
||||
let blockhash = Hash::new_unique();
|
||||
let transaction_accounts = vec![
|
||||
(message.account_keys[0], from_account_post),
|
||||
(message.account_keys[1], nonce_authority_account),
|
||||
(message.account_keys[2], nonce_account_post),
|
||||
(message.account_keys[3], to_account),
|
||||
(message.account_keys[4], recent_blockhashes_sysvar_account),
|
||||
];
|
||||
let tx = Transaction::new(&[&nonce_authority, &from], message, blockhash);
|
||||
|
||||
let txs = vec![tx];
|
||||
|
||||
let nonce_state =
|
||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||
authority: nonce_authority.pubkey(),
|
||||
@@ -2382,33 +2404,11 @@ mod tests {
|
||||
nonce_rollback.clone(),
|
||||
)];
|
||||
|
||||
let nonce_state =
|
||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||
authority: nonce_authority.pubkey(),
|
||||
blockhash: Hash::new_unique(),
|
||||
fee_calculator: FeeCalculator::default(),
|
||||
}));
|
||||
let nonce_account_post =
|
||||
AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap();
|
||||
|
||||
let from_account_post = AccountSharedData::new(4199, 0, &Pubkey::default());
|
||||
let to_account = AccountSharedData::new(2, 0, &Pubkey::default());
|
||||
let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default());
|
||||
let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default());
|
||||
|
||||
let transaction_accounts = vec![
|
||||
from_account_post,
|
||||
nonce_authority_account,
|
||||
nonce_account_post,
|
||||
to_account,
|
||||
recent_blockhashes_sysvar_account,
|
||||
];
|
||||
let transaction_loaders = vec![];
|
||||
let transaction_rent = 0;
|
||||
let loaded = (
|
||||
Ok(LoadedTransaction {
|
||||
accounts: transaction_accounts,
|
||||
account_deps: vec![],
|
||||
loaders: transaction_loaders,
|
||||
rent: transaction_rent,
|
||||
rent_debits: RentDebits::default(),
|
||||
@@ -2426,6 +2426,7 @@ mod tests {
|
||||
false,
|
||||
AccountShrinkThreshold::default(),
|
||||
);
|
||||
let txs = &[tx];
|
||||
let collected_accounts = accounts.collect_accounts_to_store(
|
||||
txs.iter(),
|
||||
&loaders,
|
||||
@@ -2470,16 +2471,34 @@ mod tests {
|
||||
let from = keypair_from_seed(&[1; 32]).unwrap();
|
||||
let from_address = from.pubkey();
|
||||
let to_address = Pubkey::new_unique();
|
||||
let nonce_state =
|
||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||
authority: nonce_authority.pubkey(),
|
||||
blockhash: Hash::new_unique(),
|
||||
fee_calculator: FeeCalculator::default(),
|
||||
}));
|
||||
let nonce_account_post =
|
||||
AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap();
|
||||
let from_account_post = AccountSharedData::new(4200, 0, &Pubkey::default());
|
||||
let to_account = AccountSharedData::new(2, 0, &Pubkey::default());
|
||||
let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default());
|
||||
let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default());
|
||||
|
||||
let instructions = vec![
|
||||
system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()),
|
||||
system_instruction::transfer(&from_address, &to_address, 42),
|
||||
];
|
||||
let message = Message::new(&instructions, Some(&nonce_address));
|
||||
let blockhash = Hash::new_unique();
|
||||
let transaction_accounts = vec![
|
||||
(message.account_keys[0], from_account_post),
|
||||
(message.account_keys[1], nonce_authority_account),
|
||||
(message.account_keys[2], nonce_account_post),
|
||||
(message.account_keys[3], to_account),
|
||||
(message.account_keys[4], recent_blockhashes_sysvar_account),
|
||||
];
|
||||
let tx = Transaction::new(&[&nonce_authority, &from], message, blockhash);
|
||||
|
||||
let txs = vec![tx];
|
||||
|
||||
let nonce_state =
|
||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||
authority: nonce_authority.pubkey(),
|
||||
@@ -2502,33 +2521,11 @@ mod tests {
|
||||
nonce_rollback.clone(),
|
||||
)];
|
||||
|
||||
let nonce_state =
|
||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||
authority: nonce_authority.pubkey(),
|
||||
blockhash: Hash::new_unique(),
|
||||
fee_calculator: FeeCalculator::default(),
|
||||
}));
|
||||
let nonce_account_post =
|
||||
AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap();
|
||||
|
||||
let from_account_post = AccountSharedData::new(4200, 0, &Pubkey::default());
|
||||
let to_account = AccountSharedData::new(2, 0, &Pubkey::default());
|
||||
let nonce_authority_account = AccountSharedData::new(3, 0, &Pubkey::default());
|
||||
let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default());
|
||||
|
||||
let transaction_accounts = vec![
|
||||
from_account_post,
|
||||
nonce_authority_account,
|
||||
nonce_account_post,
|
||||
to_account,
|
||||
recent_blockhashes_sysvar_account,
|
||||
];
|
||||
let transaction_loaders = vec![];
|
||||
let transaction_rent = 0;
|
||||
let loaded = (
|
||||
Ok(LoadedTransaction {
|
||||
accounts: transaction_accounts,
|
||||
account_deps: vec![],
|
||||
loaders: transaction_loaders,
|
||||
rent: transaction_rent,
|
||||
rent_debits: RentDebits::default(),
|
||||
@@ -2546,6 +2543,7 @@ mod tests {
|
||||
false,
|
||||
AccountShrinkThreshold::default(),
|
||||
);
|
||||
let txs = &[tx];
|
||||
let collected_accounts = accounts.collect_accounts_to_store(
|
||||
txs.iter(),
|
||||
&loaders,
|
||||
|
Reference in New Issue
Block a user