* 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.
(cherry picked from commit 7462c27d07
)
# Conflicts:
# program-test/src/lib.rs
# runtime/src/bank.rs
# runtime/src/message_processor.rs
* fix conflicts
Co-authored-by: Alexander Meißner <AlexanderMeissner@gmx.net>
Co-authored-by: Justin Starry <justin@solana.com>
This commit is contained in:
@@ -287,7 +287,7 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
|
|||||||
'outer: for key in &message.account_keys {
|
'outer: for key in &message.account_keys {
|
||||||
for account_info in account_infos {
|
for account_info in account_infos {
|
||||||
if account_info.unsigned_key() == key {
|
if account_info.unsigned_key() == key {
|
||||||
accounts.push(Rc::new(RefCell::new(ai_to_a(account_info))));
|
accounts.push((*key, Rc::new(RefCell::new(ai_to_a(account_info)))));
|
||||||
continue 'outer;
|
continue 'outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,14 +333,12 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
|
|||||||
.map_err(|err| ProgramError::try_from(err).unwrap_or_else(|err| panic!("{}", err)))?;
|
.map_err(|err| ProgramError::try_from(err).unwrap_or_else(|err| panic!("{}", err)))?;
|
||||||
|
|
||||||
// Copy writeable account modifications back into the caller's AccountInfos
|
// Copy writeable account modifications back into the caller's AccountInfos
|
||||||
for (i, account_pubkey) in message.account_keys.iter().enumerate() {
|
for (i, (pubkey, account)) in accounts.iter().enumerate().take(message.account_keys.len()) {
|
||||||
if !message.is_writable(i) {
|
if !message.is_writable(i) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for account_info in account_infos {
|
for account_info in account_infos {
|
||||||
if account_info.unsigned_key() == account_pubkey {
|
if account_info.unsigned_key() == pubkey {
|
||||||
let account = &accounts[i];
|
|
||||||
**account_info.try_borrow_mut_lamports().unwrap() = account.borrow().lamports();
|
**account_info.try_borrow_mut_lamports().unwrap() = account.borrow().lamports();
|
||||||
|
|
||||||
let mut data = account_info.try_borrow_mut_data()?;
|
let mut data = account_info.try_borrow_mut_data()?;
|
||||||
|
@@ -1343,7 +1343,7 @@ type TranslatedAccount<'a> = (
|
|||||||
Option<AccountReferences<'a>>,
|
Option<AccountReferences<'a>>,
|
||||||
);
|
);
|
||||||
type TranslatedAccounts<'a> = (
|
type TranslatedAccounts<'a> = (
|
||||||
Vec<Rc<RefCell<AccountSharedData>>>,
|
Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>,
|
||||||
Vec<Option<AccountReferences<'a>>>,
|
Vec<Option<AccountReferences<'a>>>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1988,7 +1988,7 @@ where
|
|||||||
|
|
||||||
if i == program_account_index || account.borrow().executable() {
|
if i == program_account_index || account.borrow().executable() {
|
||||||
// Use the known account
|
// Use the known account
|
||||||
accounts.push(account);
|
accounts.push((**account_key, account));
|
||||||
refs.push(None);
|
refs.push(None);
|
||||||
} else if let Some(account_info) =
|
} else if let Some(account_info) =
|
||||||
account_info_keys
|
account_info_keys
|
||||||
@@ -2003,7 +2003,7 @@ where
|
|||||||
})
|
})
|
||||||
{
|
{
|
||||||
let (account, account_ref) = do_translate(account_info, invoke_context)?;
|
let (account, account_ref) = do_translate(account_info, invoke_context)?;
|
||||||
accounts.push(account);
|
accounts.push((**account_key, account));
|
||||||
refs.push(account_ref);
|
refs.push(account_ref);
|
||||||
} else {
|
} else {
|
||||||
ic_msg!(
|
ic_msg!(
|
||||||
@@ -2188,6 +2188,7 @@ fn call<'a>(
|
|||||||
ic_msg!(invoke_context, "Unknown program {}", callee_program_id,);
|
ic_msg!(invoke_context, "Unknown program {}", callee_program_id,);
|
||||||
SyscallError::InstructionError(InstructionError::MissingAccount)
|
SyscallError::InstructionError(InstructionError::MissingAccount)
|
||||||
})?
|
})?
|
||||||
|
.1
|
||||||
.clone();
|
.clone();
|
||||||
let programdata_executable =
|
let programdata_executable =
|
||||||
get_upgradeable_executable(&callee_program_id, &program_account, &invoke_context)?;
|
get_upgradeable_executable(&callee_program_id, &program_account, &invoke_context)?;
|
||||||
@@ -2228,7 +2229,7 @@ fn call<'a>(
|
|||||||
// Copy results back to caller
|
// Copy results back to caller
|
||||||
{
|
{
|
||||||
let invoke_context = syscall.get_context()?;
|
let invoke_context = syscall.get_context()?;
|
||||||
for (i, (account, account_ref)) in accounts.iter().zip(account_refs).enumerate() {
|
for (i, ((_key, account), account_ref)) in accounts.iter().zip(account_refs).enumerate() {
|
||||||
let account = account.borrow();
|
let account = account.borrow();
|
||||||
if let Some(mut account_ref) = account_ref {
|
if let Some(mut account_ref) = account_ref {
|
||||||
if message.is_writable(i) && !account.executable() {
|
if message.is_writable(i) && !account.executable() {
|
||||||
|
@@ -3095,15 +3095,21 @@ pub mod rpc_full {
|
|||||||
accounts.push(if result.is_err() {
|
accounts.push(if result.is_err() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
transaction
|
(0..transaction.message.account_keys.len())
|
||||||
.message
|
.position(|i| {
|
||||||
.account_keys
|
post_simulation_accounts
|
||||||
.iter()
|
.get(i)
|
||||||
.position(|pubkey| *pubkey == address)
|
.map(|(key, _account)| *key == address)
|
||||||
.map(|i| post_simulation_accounts.get(i))
|
.unwrap_or(false)
|
||||||
.flatten()
|
})
|
||||||
.map(|account| {
|
.map(|i| {
|
||||||
UiAccount::encode(&address, account, accounts_encoding, None, None)
|
UiAccount::encode(
|
||||||
|
&address,
|
||||||
|
&post_simulation_accounts[i].1,
|
||||||
|
accounts_encoding,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -97,14 +97,12 @@ pub struct Accounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for the load instructions
|
// for the load instructions
|
||||||
pub type TransactionAccounts = Vec<AccountSharedData>;
|
pub type TransactionAccounts = Vec<(Pubkey, AccountSharedData)>;
|
||||||
pub type TransactionAccountDeps = Vec<(Pubkey, AccountSharedData)>;
|
|
||||||
pub type TransactionRent = u64;
|
pub type TransactionRent = u64;
|
||||||
pub type TransactionLoaders = Vec<Vec<(Pubkey, AccountSharedData)>>;
|
pub type TransactionLoaders = Vec<Vec<(Pubkey, AccountSharedData)>>;
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
pub struct LoadedTransaction {
|
pub struct LoadedTransaction {
|
||||||
pub accounts: TransactionAccounts,
|
pub accounts: TransactionAccounts,
|
||||||
pub account_deps: TransactionAccountDeps,
|
|
||||||
pub loaders: TransactionLoaders,
|
pub loaders: TransactionLoaders,
|
||||||
pub rent: TransactionRent,
|
pub rent: TransactionRent,
|
||||||
pub rent_debits: RentDebits,
|
pub rent_debits: RentDebits,
|
||||||
@@ -272,36 +270,43 @@ impl Accounts {
|
|||||||
// Fill in an empty account for the program slots.
|
// Fill in an empty account for the program slots.
|
||||||
AccountSharedData::default()
|
AccountSharedData::default()
|
||||||
};
|
};
|
||||||
accounts.push(account);
|
accounts.push((*key, account));
|
||||||
}
|
}
|
||||||
debug_assert_eq!(accounts.len(), message.account_keys.len());
|
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 let Some(payer_index) = payer_index {
|
||||||
if payer_index != 0 {
|
if payer_index != 0 {
|
||||||
warn!("Payer index should be 0! {:?}", tx);
|
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;
|
error_counters.account_not_found += 1;
|
||||||
Err(TransactionError::AccountNotFound)
|
Err(TransactionError::AccountNotFound)
|
||||||
} else {
|
} else {
|
||||||
let min_balance = match get_system_account_kind(&accounts[payer_index])
|
let min_balance =
|
||||||
.ok_or_else(|| {
|
match get_system_account_kind(payer_account).ok_or_else(|| {
|
||||||
error_counters.invalid_account_for_fee += 1;
|
error_counters.invalid_account_for_fee += 1;
|
||||||
TransactionError::InvalidAccountForFee
|
TransactionError::InvalidAccountForFee
|
||||||
})? {
|
})? {
|
||||||
SystemAccountKind::System => 0,
|
SystemAccountKind::System => 0,
|
||||||
SystemAccountKind::Nonce => {
|
SystemAccountKind::Nonce => {
|
||||||
// Should we ever allow a fees charge to zero a nonce account's
|
// Should we ever allow a fees charge to zero a nonce account's
|
||||||
// balance. The state MUST be set to uninitialized in that case
|
// balance. The state MUST be set to uninitialized in that case
|
||||||
rent_collector.rent.minimum_balance(nonce::State::size())
|
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;
|
error_counters.insufficient_funds += 1;
|
||||||
Err(TransactionError::InsufficientFundsForFee)
|
Err(TransactionError::InsufficientFundsForFee)
|
||||||
} else {
|
} else {
|
||||||
accounts[payer_index]
|
payer_account
|
||||||
.checked_sub_lamports(fee)
|
.checked_sub_lamports(fee)
|
||||||
.map_err(|_| TransactionError::InsufficientFundsForFee)?;
|
.map_err(|_| TransactionError::InsufficientFundsForFee)?;
|
||||||
|
|
||||||
@@ -324,7 +329,6 @@ impl Accounts {
|
|||||||
.collect::<Result<TransactionLoaders>>()?;
|
.collect::<Result<TransactionLoaders>>()?;
|
||||||
Ok(LoadedTransaction {
|
Ok(LoadedTransaction {
|
||||||
accounts,
|
accounts,
|
||||||
account_deps,
|
|
||||||
loaders,
|
loaders,
|
||||||
rent: tx_rent,
|
rent: tx_rent,
|
||||||
rent_debits,
|
rent_debits,
|
||||||
@@ -971,12 +975,9 @@ impl Accounts {
|
|||||||
let message = &tx.message();
|
let message = &tx.message();
|
||||||
let loaded_transaction = raccs.as_mut().unwrap();
|
let loaded_transaction = raccs.as_mut().unwrap();
|
||||||
let mut fee_payer_index = None;
|
let mut fee_payer_index = None;
|
||||||
for ((i, key), account) in message
|
for (i, (key, account)) in (0..message.account_keys.len())
|
||||||
.account_keys
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.zip(loaded_transaction.accounts.iter_mut())
|
.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(
|
let is_nonce_account = prepare_if_nonce_account(
|
||||||
account,
|
account,
|
||||||
@@ -1014,7 +1015,7 @@ impl Accounts {
|
|||||||
.rent_debits
|
.rent_debits
|
||||||
.push(key, rent, account.lamports());
|
.push(key, rent, account.lamports());
|
||||||
}
|
}
|
||||||
accounts.push((key, &*account));
|
accounts.push((&*key, &*account));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1356,7 +1357,7 @@ mod tests {
|
|||||||
assert_eq!(loaded_accounts.len(), 1);
|
assert_eq!(loaded_accounts.len(), 1);
|
||||||
let (load_res, _nonce_rollback) = &loaded_accounts[0];
|
let (load_res, _nonce_rollback) = &loaded_accounts[0];
|
||||||
let loaded_transaction = load_res.as_ref().unwrap();
|
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
|
// Fee leaves zero balance fails
|
||||||
accounts[0].1.set_lamports(min_balance);
|
accounts[0].1.set_lamports(min_balance);
|
||||||
@@ -1418,7 +1419,7 @@ mod tests {
|
|||||||
match &loaded_accounts[0] {
|
match &loaded_accounts[0] {
|
||||||
(Ok(loaded_transaction), _nonce_rollback) => {
|
(Ok(loaded_transaction), _nonce_rollback) => {
|
||||||
assert_eq!(loaded_transaction.accounts.len(), 3);
|
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.len(), 1);
|
||||||
assert_eq!(loaded_transaction.loaders[0].len(), 0);
|
assert_eq!(loaded_transaction.loaders[0].len(), 0);
|
||||||
}
|
}
|
||||||
@@ -1641,7 +1642,7 @@ mod tests {
|
|||||||
match &loaded_accounts[0] {
|
match &loaded_accounts[0] {
|
||||||
(Ok(loaded_transaction), _nonce_rollback) => {
|
(Ok(loaded_transaction), _nonce_rollback) => {
|
||||||
assert_eq!(loaded_transaction.accounts.len(), 3);
|
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.len(), 2);
|
||||||
assert_eq!(loaded_transaction.loaders[0].len(), 1);
|
assert_eq!(loaded_transaction.loaders[0].len(), 1);
|
||||||
assert_eq!(loaded_transaction.loaders[1].len(), 2);
|
assert_eq!(loaded_transaction.loaders[1].len(), 2);
|
||||||
@@ -1918,6 +1919,9 @@ mod tests {
|
|||||||
let keypair0 = Keypair::new();
|
let keypair0 = Keypair::new();
|
||||||
let keypair1 = Keypair::new();
|
let keypair1 = Keypair::new();
|
||||||
let pubkey = solana_sdk::pubkey::new_rand();
|
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();
|
let rent_collector = RentCollector::default();
|
||||||
|
|
||||||
@@ -1930,6 +1934,10 @@ mod tests {
|
|||||||
Hash::default(),
|
Hash::default(),
|
||||||
instructions,
|
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 tx0 = Transaction::new(&[&keypair0], message, Hash::default());
|
||||||
|
|
||||||
let instructions = vec![CompiledInstruction::new(2, &(), vec![0, 1])];
|
let instructions = vec![CompiledInstruction::new(2, &(), vec![0, 1])];
|
||||||
@@ -1941,22 +1949,19 @@ mod tests {
|
|||||||
Hash::default(),
|
Hash::default(),
|
||||||
instructions,
|
instructions,
|
||||||
);
|
);
|
||||||
|
let transaction_accounts1 = vec![
|
||||||
|
(message.account_keys[0], account1),
|
||||||
|
(message.account_keys[1], account2),
|
||||||
|
];
|
||||||
let tx1 = Transaction::new(&[&keypair1], message, Hash::default());
|
let tx1 = Transaction::new(&[&keypair1], message, Hash::default());
|
||||||
let txs = vec![tx0, tx1];
|
|
||||||
|
|
||||||
let loaders = vec![(Ok(()), None), (Ok(()), None)];
|
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_loaders0 = vec![];
|
||||||
let transaction_rent0 = 0;
|
let transaction_rent0 = 0;
|
||||||
let loaded0 = (
|
let loaded0 = (
|
||||||
Ok(LoadedTransaction {
|
Ok(LoadedTransaction {
|
||||||
accounts: transaction_accounts0,
|
accounts: transaction_accounts0,
|
||||||
account_deps: vec![],
|
|
||||||
loaders: transaction_loaders0,
|
loaders: transaction_loaders0,
|
||||||
rent: transaction_rent0,
|
rent: transaction_rent0,
|
||||||
rent_debits: RentDebits::default(),
|
rent_debits: RentDebits::default(),
|
||||||
@@ -1964,13 +1969,11 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let transaction_accounts1 = vec![account1, account2];
|
|
||||||
let transaction_loaders1 = vec![];
|
let transaction_loaders1 = vec![];
|
||||||
let transaction_rent1 = 0;
|
let transaction_rent1 = 0;
|
||||||
let loaded1 = (
|
let loaded1 = (
|
||||||
Ok(LoadedTransaction {
|
Ok(LoadedTransaction {
|
||||||
accounts: transaction_accounts1,
|
accounts: transaction_accounts1,
|
||||||
account_deps: vec![],
|
|
||||||
loaders: transaction_loaders1,
|
loaders: transaction_loaders1,
|
||||||
rent: transaction_rent1,
|
rent: transaction_rent1,
|
||||||
rent_debits: RentDebits::default(),
|
rent_debits: RentDebits::default(),
|
||||||
@@ -1994,6 +1997,7 @@ mod tests {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.insert_new_readonly(&pubkey);
|
.insert_new_readonly(&pubkey);
|
||||||
}
|
}
|
||||||
|
let txs = &[tx0, tx1];
|
||||||
let collected_accounts = accounts.collect_accounts_to_store(
|
let collected_accounts = accounts.collect_accounts_to_store(
|
||||||
txs.iter(),
|
txs.iter(),
|
||||||
&loaders,
|
&loaders,
|
||||||
@@ -2296,16 +2300,34 @@ mod tests {
|
|||||||
let from = keypair_from_seed(&[1; 32]).unwrap();
|
let from = keypair_from_seed(&[1; 32]).unwrap();
|
||||||
let from_address = from.pubkey();
|
let from_address = from.pubkey();
|
||||||
let to_address = Pubkey::new_unique();
|
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![
|
let instructions = vec![
|
||||||
system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()),
|
system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()),
|
||||||
system_instruction::transfer(&from_address, &to_address, 42),
|
system_instruction::transfer(&from_address, &to_address, 42),
|
||||||
];
|
];
|
||||||
let message = Message::new(&instructions, Some(&from_address));
|
let message = Message::new(&instructions, Some(&from_address));
|
||||||
let blockhash = Hash::new_unique();
|
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 tx = Transaction::new(&[&nonce_authority, &from], message, blockhash);
|
||||||
|
|
||||||
let txs = vec![tx];
|
|
||||||
|
|
||||||
let nonce_state =
|
let nonce_state =
|
||||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||||
authority: nonce_authority.pubkey(),
|
authority: nonce_authority.pubkey(),
|
||||||
@@ -2329,33 +2351,11 @@ mod tests {
|
|||||||
nonce_rollback.clone(),
|
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_loaders = vec![];
|
||||||
let transaction_rent = 0;
|
let transaction_rent = 0;
|
||||||
let loaded = (
|
let loaded = (
|
||||||
Ok(LoadedTransaction {
|
Ok(LoadedTransaction {
|
||||||
accounts: transaction_accounts,
|
accounts: transaction_accounts,
|
||||||
account_deps: vec![],
|
|
||||||
loaders: transaction_loaders,
|
loaders: transaction_loaders,
|
||||||
rent: transaction_rent,
|
rent: transaction_rent,
|
||||||
rent_debits: RentDebits::default(),
|
rent_debits: RentDebits::default(),
|
||||||
@@ -2373,6 +2373,7 @@ mod tests {
|
|||||||
false,
|
false,
|
||||||
AccountShrinkThreshold::default(),
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
|
let txs = &[tx];
|
||||||
let collected_accounts = accounts.collect_accounts_to_store(
|
let collected_accounts = accounts.collect_accounts_to_store(
|
||||||
txs.iter(),
|
txs.iter(),
|
||||||
&loaders,
|
&loaders,
|
||||||
@@ -2416,16 +2417,34 @@ mod tests {
|
|||||||
let from = keypair_from_seed(&[1; 32]).unwrap();
|
let from = keypair_from_seed(&[1; 32]).unwrap();
|
||||||
let from_address = from.pubkey();
|
let from_address = from.pubkey();
|
||||||
let to_address = Pubkey::new_unique();
|
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![
|
let instructions = vec![
|
||||||
system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()),
|
system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()),
|
||||||
system_instruction::transfer(&from_address, &to_address, 42),
|
system_instruction::transfer(&from_address, &to_address, 42),
|
||||||
];
|
];
|
||||||
let message = Message::new(&instructions, Some(&nonce_address));
|
let message = Message::new(&instructions, Some(&nonce_address));
|
||||||
let blockhash = Hash::new_unique();
|
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 tx = Transaction::new(&[&nonce_authority, &from], message, blockhash);
|
||||||
|
|
||||||
let txs = vec![tx];
|
|
||||||
|
|
||||||
let nonce_state =
|
let nonce_state =
|
||||||
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
|
||||||
authority: nonce_authority.pubkey(),
|
authority: nonce_authority.pubkey(),
|
||||||
@@ -2448,33 +2467,11 @@ mod tests {
|
|||||||
nonce_rollback.clone(),
|
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_loaders = vec![];
|
||||||
let transaction_rent = 0;
|
let transaction_rent = 0;
|
||||||
let loaded = (
|
let loaded = (
|
||||||
Ok(LoadedTransaction {
|
Ok(LoadedTransaction {
|
||||||
accounts: transaction_accounts,
|
accounts: transaction_accounts,
|
||||||
account_deps: vec![],
|
|
||||||
loaders: transaction_loaders,
|
loaders: transaction_loaders,
|
||||||
rent: transaction_rent,
|
rent: transaction_rent,
|
||||||
rent_debits: RentDebits::default(),
|
rent_debits: RentDebits::default(),
|
||||||
@@ -2492,6 +2489,7 @@ mod tests {
|
|||||||
false,
|
false,
|
||||||
AccountShrinkThreshold::default(),
|
AccountShrinkThreshold::default(),
|
||||||
);
|
);
|
||||||
|
let txs = &[tx];
|
||||||
let collected_accounts = accounts.collect_accounts_to_store(
|
let collected_accounts = accounts.collect_accounts_to_store(
|
||||||
txs.iter(),
|
txs.iter(),
|
||||||
&loaders,
|
&loaders,
|
||||||
|
@@ -35,8 +35,8 @@
|
|||||||
//! already been signed and verified.
|
//! already been signed and verified.
|
||||||
use crate::{
|
use crate::{
|
||||||
accounts::{
|
accounts::{
|
||||||
AccountAddressFilter, Accounts, TransactionAccountDeps, TransactionAccounts,
|
AccountAddressFilter, Accounts, TransactionAccounts, TransactionLoadResult,
|
||||||
TransactionLoadResult, TransactionLoaders,
|
TransactionLoaders,
|
||||||
},
|
},
|
||||||
accounts_db::{AccountShrinkThreshold, ErrorCounters, SnapshotStorages},
|
accounts_db::{AccountShrinkThreshold, ErrorCounters, SnapshotStorages},
|
||||||
accounts_index::{AccountSecondaryIndexes, IndexKey, ScanResult},
|
accounts_index::{AccountSecondaryIndexes, IndexKey, ScanResult},
|
||||||
@@ -177,8 +177,7 @@ impl ExecuteTimings {
|
|||||||
type BankStatusCache = StatusCache<Result<()>>;
|
type BankStatusCache = StatusCache<Result<()>>;
|
||||||
#[frozen_abi(digest = "HhY4tMP5KZU9fw9VLpMMUikfvNVCLksocZBUKjt8ZjYH")]
|
#[frozen_abi(digest = "HhY4tMP5KZU9fw9VLpMMUikfvNVCLksocZBUKjt8ZjYH")]
|
||||||
pub type BankSlotDelta = SlotDelta<Result<()>>;
|
pub type BankSlotDelta = SlotDelta<Result<()>>;
|
||||||
type TransactionAccountRefCells = Vec<Rc<RefCell<AccountSharedData>>>;
|
type TransactionAccountRefCells = Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>;
|
||||||
type TransactionAccountDepRefCells = Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>;
|
|
||||||
type TransactionLoaderRefCells = Vec<Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>>;
|
type TransactionLoaderRefCells = Vec<Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>>;
|
||||||
|
|
||||||
// Eager rent collection repeats in cyclic manner.
|
// Eager rent collection repeats in cyclic manner.
|
||||||
@@ -625,30 +624,32 @@ impl NonceRollbackFull {
|
|||||||
pub fn from_partial(
|
pub fn from_partial(
|
||||||
partial: NonceRollbackPartial,
|
partial: NonceRollbackPartial,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
accounts: &[AccountSharedData],
|
accounts: &[(Pubkey, AccountSharedData)],
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let NonceRollbackPartial {
|
let NonceRollbackPartial {
|
||||||
nonce_address,
|
nonce_address,
|
||||||
nonce_account,
|
nonce_account,
|
||||||
} = partial;
|
} = partial;
|
||||||
let fee_payer = message
|
let fee_payer = (0..message.account_keys.len()).find_map(|i| {
|
||||||
.account_keys
|
if let Some((k, a)) = &accounts.get(i) {
|
||||||
.iter()
|
if message.is_non_loader_key(k, i) {
|
||||||
.enumerate()
|
return Some((k, a));
|
||||||
.find(|(i, k)| message.is_non_loader_key(k, *i))
|
}
|
||||||
.and_then(|(i, k)| accounts.get(i).cloned().map(|a| (*k, a)));
|
}
|
||||||
|
None
|
||||||
|
});
|
||||||
if let Some((fee_pubkey, fee_account)) = fee_payer {
|
if let Some((fee_pubkey, fee_account)) = fee_payer {
|
||||||
if fee_pubkey == nonce_address {
|
if *fee_pubkey == nonce_address {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
nonce_address,
|
nonce_address,
|
||||||
nonce_account: fee_account,
|
nonce_account: fee_account.clone(),
|
||||||
fee_account: None,
|
fee_account: None,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
nonce_address,
|
nonce_address,
|
||||||
nonce_account,
|
nonce_account,
|
||||||
fee_account: Some(fee_account),
|
fee_account: Some(fee_account.clone()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2638,7 +2639,11 @@ impl Bank {
|
|||||||
pub fn simulate_transaction(
|
pub fn simulate_transaction(
|
||||||
&self,
|
&self,
|
||||||
transaction: &Transaction,
|
transaction: &Transaction,
|
||||||
) -> (Result<()>, TransactionLogMessages, Vec<AccountSharedData>) {
|
) -> (
|
||||||
|
Result<()>,
|
||||||
|
TransactionLogMessages,
|
||||||
|
Vec<(Pubkey, AccountSharedData)>,
|
||||||
|
) {
|
||||||
assert!(self.is_frozen(), "simulation bank must be frozen");
|
assert!(self.is_frozen(), "simulation bank must be frozen");
|
||||||
|
|
||||||
let batch = self.prepare_simulation_batch(transaction);
|
let batch = self.prepare_simulation_batch(transaction);
|
||||||
@@ -2646,7 +2651,7 @@ impl Bank {
|
|||||||
let mut timings = ExecuteTimings::default();
|
let mut timings = ExecuteTimings::default();
|
||||||
|
|
||||||
let (
|
let (
|
||||||
loaded_accounts,
|
loaded_txs,
|
||||||
executed,
|
executed,
|
||||||
_inner_instructions,
|
_inner_instructions,
|
||||||
log_messages,
|
log_messages,
|
||||||
@@ -2666,7 +2671,7 @@ impl Bank {
|
|||||||
|
|
||||||
let transaction_result = executed[0].0.clone().map(|_| ());
|
let transaction_result = executed[0].0.clone().map(|_| ());
|
||||||
let log_messages = log_messages.get(0).cloned().flatten().unwrap_or_default();
|
let log_messages = log_messages.get(0).cloned().flatten().unwrap_or_default();
|
||||||
let post_transaction_accounts = loaded_accounts
|
let post_transaction_accounts = loaded_txs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -2931,20 +2936,11 @@ impl Bank {
|
|||||||
/// ownership by draining the source
|
/// ownership by draining the source
|
||||||
fn accounts_to_refcells(
|
fn accounts_to_refcells(
|
||||||
accounts: &mut TransactionAccounts,
|
accounts: &mut TransactionAccounts,
|
||||||
account_deps: &mut TransactionAccountDeps,
|
|
||||||
loaders: &mut TransactionLoaders,
|
loaders: &mut TransactionLoaders,
|
||||||
) -> (
|
) -> (TransactionAccountRefCells, TransactionLoaderRefCells) {
|
||||||
TransactionAccountRefCells,
|
|
||||||
TransactionAccountDepRefCells,
|
|
||||||
TransactionLoaderRefCells,
|
|
||||||
) {
|
|
||||||
let account_refcells: Vec<_> = accounts
|
let account_refcells: Vec<_> = accounts
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.map(|account| Rc::new(RefCell::new(account)))
|
.map(|(pubkey, account)| (pubkey, Rc::new(RefCell::new(account))))
|
||||||
.collect();
|
|
||||||
let account_dep_refcells: Vec<_> = account_deps
|
|
||||||
.drain(..)
|
|
||||||
.map(|(pubkey, account_dep)| (pubkey, Rc::new(RefCell::new(account_dep))))
|
|
||||||
.collect();
|
.collect();
|
||||||
let loader_refcells: Vec<Vec<_>> = loaders
|
let loader_refcells: Vec<Vec<_>> = loaders
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@@ -2954,7 +2950,7 @@ impl Bank {
|
|||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
(account_refcells, account_dep_refcells, loader_refcells)
|
(account_refcells, loader_refcells)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts back from RefCell<AccountSharedData> to AccountSharedData, this involves moving
|
/// Converts back from RefCell<AccountSharedData> to AccountSharedData, this involves moving
|
||||||
@@ -2965,12 +2961,13 @@ impl Bank {
|
|||||||
mut account_refcells: TransactionAccountRefCells,
|
mut account_refcells: TransactionAccountRefCells,
|
||||||
loader_refcells: TransactionLoaderRefCells,
|
loader_refcells: TransactionLoaderRefCells,
|
||||||
) -> std::result::Result<(), TransactionError> {
|
) -> std::result::Result<(), TransactionError> {
|
||||||
for account_refcell in account_refcells.drain(..) {
|
for (pubkey, account_refcell) in account_refcells.drain(..) {
|
||||||
accounts.push(
|
accounts.push((
|
||||||
|
pubkey,
|
||||||
Rc::try_unwrap(account_refcell)
|
Rc::try_unwrap(account_refcell)
|
||||||
.map_err(|_| TransactionError::AccountBorrowOutstanding)?
|
.map_err(|_| TransactionError::AccountBorrowOutstanding)?
|
||||||
.into_inner(),
|
.into_inner(),
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
for (ls, mut lrcs) in loaders.iter_mut().zip(loader_refcells) {
|
for (ls, mut lrcs) in loaders.iter_mut().zip(loader_refcells) {
|
||||||
for (pubkey, lrc) in lrcs.drain(..) {
|
for (pubkey, lrc) in lrcs.drain(..) {
|
||||||
@@ -3102,7 +3099,7 @@ impl Bank {
|
|||||||
check_time.stop();
|
check_time.stop();
|
||||||
|
|
||||||
let mut load_time = Measure::start("accounts_load");
|
let mut load_time = Measure::start("accounts_load");
|
||||||
let mut loaded_accounts = self.rc.accounts.load_accounts(
|
let mut loaded_txs = self.rc.accounts.load_accounts(
|
||||||
&self.ancestors,
|
&self.ancestors,
|
||||||
hashed_txs.as_transactions_iter(),
|
hashed_txs.as_transactions_iter(),
|
||||||
check_results,
|
check_results,
|
||||||
@@ -3123,7 +3120,7 @@ impl Bank {
|
|||||||
.bpf_compute_budget
|
.bpf_compute_budget
|
||||||
.unwrap_or_else(BpfComputeBudget::new);
|
.unwrap_or_else(BpfComputeBudget::new);
|
||||||
|
|
||||||
let executed: Vec<TransactionExecutionResult> = loaded_accounts
|
let executed: Vec<TransactionExecutionResult> = loaded_txs
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(hashed_txs.as_transactions_iter())
|
.zip(hashed_txs.as_transactions_iter())
|
||||||
.map(|(accs, tx)| match accs {
|
.map(|(accs, tx)| match accs {
|
||||||
@@ -3136,12 +3133,10 @@ impl Bank {
|
|||||||
signature_count += u64::from(tx.message().header.num_required_signatures);
|
signature_count += u64::from(tx.message().header.num_required_signatures);
|
||||||
let executors = self.get_executors(&tx.message, &loaded_transaction.loaders);
|
let executors = self.get_executors(&tx.message, &loaded_transaction.loaders);
|
||||||
|
|
||||||
let (account_refcells, account_dep_refcells, loader_refcells) =
|
let (account_refcells, loader_refcells) = Self::accounts_to_refcells(
|
||||||
Self::accounts_to_refcells(
|
&mut loaded_transaction.accounts,
|
||||||
&mut loaded_transaction.accounts,
|
&mut loaded_transaction.loaders,
|
||||||
&mut loaded_transaction.account_deps,
|
);
|
||||||
&mut loaded_transaction.loaders,
|
|
||||||
);
|
|
||||||
|
|
||||||
let instruction_recorders = if enable_cpi_recording {
|
let instruction_recorders = if enable_cpi_recording {
|
||||||
let ix_count = tx.message.instructions.len();
|
let ix_count = tx.message.instructions.len();
|
||||||
@@ -3162,7 +3157,6 @@ impl Bank {
|
|||||||
tx.message(),
|
tx.message(),
|
||||||
&loader_refcells,
|
&loader_refcells,
|
||||||
&account_refcells,
|
&account_refcells,
|
||||||
&account_dep_refcells,
|
|
||||||
&self.rent_collector,
|
&self.rent_collector,
|
||||||
log_collector.clone(),
|
log_collector.clone(),
|
||||||
executors.clone(),
|
executors.clone(),
|
||||||
@@ -3301,7 +3295,7 @@ impl Bank {
|
|||||||
}
|
}
|
||||||
Self::update_error_counters(&error_counters);
|
Self::update_error_counters(&error_counters);
|
||||||
(
|
(
|
||||||
loaded_accounts,
|
loaded_txs,
|
||||||
executed,
|
executed,
|
||||||
inner_instructions,
|
inner_instructions,
|
||||||
transaction_log_messages,
|
transaction_log_messages,
|
||||||
@@ -3373,7 +3367,7 @@ impl Bank {
|
|||||||
pub fn commit_transactions(
|
pub fn commit_transactions(
|
||||||
&self,
|
&self,
|
||||||
hashed_txs: &[HashedTransaction],
|
hashed_txs: &[HashedTransaction],
|
||||||
loaded_accounts: &mut [TransactionLoadResult],
|
loaded_txs: &mut [TransactionLoadResult],
|
||||||
executed: &[TransactionExecutionResult],
|
executed: &[TransactionExecutionResult],
|
||||||
tx_count: u64,
|
tx_count: u64,
|
||||||
signature_count: u64,
|
signature_count: u64,
|
||||||
@@ -3412,18 +3406,15 @@ impl Bank {
|
|||||||
self.slot(),
|
self.slot(),
|
||||||
hashed_txs.as_transactions_iter(),
|
hashed_txs.as_transactions_iter(),
|
||||||
executed,
|
executed,
|
||||||
loaded_accounts,
|
loaded_txs,
|
||||||
&self.rent_collector,
|
&self.rent_collector,
|
||||||
&self.last_blockhash_with_fee_calculator(),
|
&self.last_blockhash_with_fee_calculator(),
|
||||||
self.fix_recent_blockhashes_sysvar_delay(),
|
self.fix_recent_blockhashes_sysvar_delay(),
|
||||||
);
|
);
|
||||||
let rent_debits = self.collect_rent(executed, loaded_accounts);
|
let rent_debits = self.collect_rent(executed, loaded_txs);
|
||||||
|
|
||||||
let overwritten_vote_accounts = self.update_cached_accounts(
|
let overwritten_vote_accounts =
|
||||||
hashed_txs.as_transactions_iter(),
|
self.update_cached_accounts(hashed_txs.as_transactions_iter(), executed, loaded_txs);
|
||||||
executed,
|
|
||||||
loaded_accounts,
|
|
||||||
);
|
|
||||||
|
|
||||||
// once committed there is no way to unroll
|
// once committed there is no way to unroll
|
||||||
write_time.stop();
|
write_time.stop();
|
||||||
@@ -3603,11 +3594,11 @@ impl Bank {
|
|||||||
fn collect_rent(
|
fn collect_rent(
|
||||||
&self,
|
&self,
|
||||||
res: &[TransactionExecutionResult],
|
res: &[TransactionExecutionResult],
|
||||||
loaded_accounts: &mut [TransactionLoadResult],
|
loaded_txs: &mut [TransactionLoadResult],
|
||||||
) -> Vec<RentDebits> {
|
) -> Vec<RentDebits> {
|
||||||
let mut collected_rent: u64 = 0;
|
let mut collected_rent: u64 = 0;
|
||||||
let mut rent_debits: Vec<RentDebits> = Vec::with_capacity(loaded_accounts.len());
|
let mut rent_debits: Vec<RentDebits> = Vec::with_capacity(loaded_txs.len());
|
||||||
for (i, (raccs, _nonce_rollback)) in loaded_accounts.iter_mut().enumerate() {
|
for (i, (raccs, _nonce_rollback)) in loaded_txs.iter_mut().enumerate() {
|
||||||
let (res, _nonce_rollback) = &res[i];
|
let (res, _nonce_rollback) = &res[i];
|
||||||
if res.is_err() || raccs.is_err() {
|
if res.is_err() || raccs.is_err() {
|
||||||
rent_debits.push(RentDebits::default());
|
rent_debits.push(RentDebits::default());
|
||||||
@@ -4046,7 +4037,7 @@ impl Bank {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (
|
let (
|
||||||
mut loaded_accounts,
|
mut loaded_txs,
|
||||||
executed,
|
executed,
|
||||||
inner_instructions,
|
inner_instructions,
|
||||||
transaction_logs,
|
transaction_logs,
|
||||||
@@ -4063,7 +4054,7 @@ impl Bank {
|
|||||||
|
|
||||||
let results = self.commit_transactions(
|
let results = self.commit_transactions(
|
||||||
batch.hashed_transactions(),
|
batch.hashed_transactions(),
|
||||||
&mut loaded_accounts,
|
&mut loaded_txs,
|
||||||
&executed,
|
&executed,
|
||||||
tx_count,
|
tx_count,
|
||||||
signature_count,
|
signature_count,
|
||||||
@@ -4785,10 +4776,10 @@ impl Bank {
|
|||||||
&self,
|
&self,
|
||||||
txs: impl Iterator<Item = &'a Transaction>,
|
txs: impl Iterator<Item = &'a Transaction>,
|
||||||
res: &[TransactionExecutionResult],
|
res: &[TransactionExecutionResult],
|
||||||
loaded: &[TransactionLoadResult],
|
loaded_txs: &[TransactionLoadResult],
|
||||||
) -> Vec<OverwrittenVoteAccount> {
|
) -> Vec<OverwrittenVoteAccount> {
|
||||||
let mut overwritten_vote_accounts = vec![];
|
let mut overwritten_vote_accounts = vec![];
|
||||||
for (i, ((raccs, _load_nonce_rollback), tx)) in loaded.iter().zip(txs).enumerate() {
|
for (i, ((raccs, _load_nonce_rollback), tx)) in loaded_txs.iter().zip(txs).enumerate() {
|
||||||
let (res, _res_nonce_rollback) = &res[i];
|
let (res, _res_nonce_rollback) = &res[i];
|
||||||
if res.is_err() || raccs.is_err() {
|
if res.is_err() || raccs.is_err() {
|
||||||
continue;
|
continue;
|
||||||
@@ -4797,11 +4788,9 @@ impl Bank {
|
|||||||
let message = &tx.message();
|
let message = &tx.message();
|
||||||
let loaded_transaction = raccs.as_ref().unwrap();
|
let loaded_transaction = raccs.as_ref().unwrap();
|
||||||
|
|
||||||
for (pubkey, account) in message
|
for (_i, (pubkey, account)) in (0..message.account_keys.len())
|
||||||
.account_keys
|
|
||||||
.iter()
|
|
||||||
.zip(loaded_transaction.accounts.iter())
|
.zip(loaded_transaction.accounts.iter())
|
||||||
.filter(|(_key, account)| (Stakes::is_stake(account)))
|
.filter(|(_i, (_pubkey, account))| (Stakes::is_stake(account)))
|
||||||
{
|
{
|
||||||
if Stakes::is_stake(account) {
|
if Stakes::is_stake(account) {
|
||||||
if let Some(old_vote_account) = self.stakes.write().unwrap().store(
|
if let Some(old_vote_account) = self.stakes.write().unwrap().store(
|
||||||
@@ -5425,10 +5414,13 @@ pub(crate) mod tests {
|
|||||||
let to_account = AccountSharedData::new(45, 0, &Pubkey::default());
|
let to_account = AccountSharedData::new(45, 0, &Pubkey::default());
|
||||||
let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default());
|
let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default());
|
||||||
let accounts = [
|
let accounts = [
|
||||||
from_account.clone(),
|
(message.account_keys[0], from_account.clone()),
|
||||||
nonce_account.clone(),
|
(message.account_keys[1], nonce_account.clone()),
|
||||||
to_account.clone(),
|
(message.account_keys[2], to_account.clone()),
|
||||||
recent_blockhashes_sysvar_account.clone(),
|
(
|
||||||
|
message.account_keys[3],
|
||||||
|
recent_blockhashes_sysvar_account.clone(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
// NonceRollbackFull create + NonceRollbackInfo impl
|
// NonceRollbackFull create + NonceRollbackInfo impl
|
||||||
@@ -5440,10 +5432,10 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
let message = Message::new(&instructions, Some(&nonce_address));
|
let message = Message::new(&instructions, Some(&nonce_address));
|
||||||
let accounts = [
|
let accounts = [
|
||||||
nonce_account,
|
(message.account_keys[0], nonce_account),
|
||||||
from_account,
|
(message.account_keys[1], from_account),
|
||||||
to_account,
|
(message.account_keys[2], to_account),
|
||||||
recent_blockhashes_sysvar_account,
|
(message.account_keys[3], recent_blockhashes_sysvar_account),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Nonce account is fee-payer
|
// Nonce account is fee-payer
|
||||||
|
@@ -253,9 +253,8 @@ impl ComputeMeter for ThisComputeMeter {
|
|||||||
pub struct ThisInvokeContext<'a> {
|
pub struct ThisInvokeContext<'a> {
|
||||||
invoke_stack: Vec<InvokeContextStackFrame<'a>>,
|
invoke_stack: Vec<InvokeContextStackFrame<'a>>,
|
||||||
rent: Rent,
|
rent: Rent,
|
||||||
message: &'a Message,
|
|
||||||
pre_accounts: Vec<PreAccount>,
|
pre_accounts: Vec<PreAccount>,
|
||||||
account_deps: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||||
logger: Rc<RefCell<dyn Logger>>,
|
logger: Rc<RefCell<dyn Logger>>,
|
||||||
bpf_compute_budget: BpfComputeBudget,
|
bpf_compute_budget: BpfComputeBudget,
|
||||||
@@ -277,8 +276,7 @@ impl<'a> ThisInvokeContext<'a> {
|
|||||||
message: &'a Message,
|
message: &'a Message,
|
||||||
instruction: &'a CompiledInstruction,
|
instruction: &'a CompiledInstruction,
|
||||||
executable_accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
executable_accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
accounts: &'a [Rc<RefCell<AccountSharedData>>],
|
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
account_deps: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
|
||||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||||
log_collector: Option<Rc<LogCollector>>,
|
log_collector: Option<Rc<LogCollector>>,
|
||||||
bpf_compute_budget: BpfComputeBudget,
|
bpf_compute_budget: BpfComputeBudget,
|
||||||
@@ -298,9 +296,8 @@ impl<'a> ThisInvokeContext<'a> {
|
|||||||
let mut invoke_context = Self {
|
let mut invoke_context = Self {
|
||||||
invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth),
|
invoke_stack: Vec::with_capacity(bpf_compute_budget.max_invoke_depth),
|
||||||
rent,
|
rent,
|
||||||
message,
|
|
||||||
pre_accounts,
|
pre_accounts,
|
||||||
account_deps,
|
accounts,
|
||||||
programs,
|
programs,
|
||||||
logger: Rc::new(RefCell::new(ThisLogger { log_collector })),
|
logger: Rc::new(RefCell::new(ThisLogger { log_collector })),
|
||||||
bpf_compute_budget,
|
bpf_compute_budget,
|
||||||
@@ -353,25 +350,21 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
let keyed_accounts = keyed_accounts
|
let keyed_accounts = keyed_accounts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(is_signer, is_writable, search_key, account)| {
|
.map(|(is_signer, is_writable, search_key, account)| {
|
||||||
self.account_deps
|
self.accounts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(key, _account)| key)
|
.position(|(key, _account)| key == *search_key)
|
||||||
.chain(self.message.account_keys.iter())
|
.map(|index| {
|
||||||
.position(|key| key == *search_key)
|
|
||||||
.map(|mut index| {
|
|
||||||
// TODO
|
// TODO
|
||||||
// Currently we are constructing new accounts on the stack
|
// Currently we are constructing new accounts on the stack
|
||||||
// before calling MessageProcessor::process_cross_program_instruction
|
// before calling MessageProcessor::process_cross_program_instruction
|
||||||
// Ideally we would recycle the existing accounts here.
|
// Ideally we would recycle the existing accounts here.
|
||||||
let key = if index < self.account_deps.len() {
|
(
|
||||||
&self.account_deps[index].0
|
*is_signer,
|
||||||
// &self.account_deps[index].1 as &RefCell<AccountSharedData>,
|
*is_writable,
|
||||||
} else {
|
&self.accounts[index].0,
|
||||||
index = index.saturating_sub(self.account_deps.len());
|
// &self.accounts[index] as &RefCell<AccountSharedData>
|
||||||
&self.message.account_keys[index]
|
transmute_lifetime(*account),
|
||||||
// &self.accounts[index] as &RefCell<AccountSharedData>,
|
)
|
||||||
};
|
|
||||||
(*is_signer, *is_writable, key, transmute_lifetime(*account))
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Option<Vec<_>>>()
|
.collect::<Option<Vec<_>>>()
|
||||||
@@ -392,7 +385,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
caller_write_privileges: Option<&[bool]>,
|
caller_write_privileges: Option<&[bool]>,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let stack_frame = self
|
let stack_frame = self
|
||||||
@@ -460,16 +453,7 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
|||||||
self.feature_set.is_active(feature_id)
|
self.feature_set.is_active(feature_id)
|
||||||
}
|
}
|
||||||
fn get_account(&self, pubkey: &Pubkey) -> Option<Rc<RefCell<AccountSharedData>>> {
|
fn get_account(&self, pubkey: &Pubkey) -> Option<Rc<RefCell<AccountSharedData>>> {
|
||||||
if let Some(account) = self.pre_accounts.iter().find_map(|pre| {
|
self.accounts.iter().find_map(|(key, account)| {
|
||||||
if pre.key == *pubkey {
|
|
||||||
Some(pre.account.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
return Some(account);
|
|
||||||
}
|
|
||||||
self.account_deps.iter().find_map(|(key, account)| {
|
|
||||||
if key == pubkey {
|
if key == pubkey {
|
||||||
Some(account.clone())
|
Some(account.clone())
|
||||||
} else {
|
} else {
|
||||||
@@ -619,7 +603,7 @@ impl MessageProcessor {
|
|||||||
message: &'a Message,
|
message: &'a Message,
|
||||||
instruction: &'a CompiledInstruction,
|
instruction: &'a CompiledInstruction,
|
||||||
executable_accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
executable_accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
accounts: &'a [Rc<RefCell<AccountSharedData>>],
|
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
) -> Vec<(bool, bool, &'a Pubkey, &'a RefCell<AccountSharedData>)> {
|
) -> Vec<(bool, bool, &'a Pubkey, &'a RefCell<AccountSharedData>)> {
|
||||||
executable_accounts
|
executable_accounts
|
||||||
.iter()
|
.iter()
|
||||||
@@ -629,8 +613,8 @@ impl MessageProcessor {
|
|||||||
(
|
(
|
||||||
message.is_signer(index),
|
message.is_signer(index),
|
||||||
message.is_writable(index),
|
message.is_writable(index),
|
||||||
&message.account_keys[index],
|
&accounts[index].0,
|
||||||
&accounts[index] as &RefCell<AccountSharedData>,
|
&accounts[index].1 as &RefCell<AccountSharedData>,
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
@@ -789,7 +773,7 @@ impl MessageProcessor {
|
|||||||
for keyed_account_index in keyed_account_indices {
|
for keyed_account_index in keyed_account_indices {
|
||||||
let keyed_account = &keyed_accounts[*keyed_account_index];
|
let keyed_account = &keyed_accounts[*keyed_account_index];
|
||||||
if account_key == keyed_account.unsigned_key() {
|
if account_key == keyed_account.unsigned_key() {
|
||||||
accounts.push(Rc::new(keyed_account.account.clone()));
|
accounts.push((*account_key, Rc::new(keyed_account.account.clone())));
|
||||||
keyed_account_indices_reordered.push(*keyed_account_index);
|
keyed_account_indices_reordered.push(*keyed_account_index);
|
||||||
continue 'root;
|
continue 'root;
|
||||||
}
|
}
|
||||||
@@ -874,7 +858,7 @@ impl MessageProcessor {
|
|||||||
{
|
{
|
||||||
let invoke_context = invoke_context.borrow();
|
let invoke_context = invoke_context.borrow();
|
||||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||||
for (src_keyed_account_index, (account, dst_keyed_account_index)) in accounts
|
for (src_keyed_account_index, ((_key, account), dst_keyed_account_index)) in accounts
|
||||||
.iter()
|
.iter()
|
||||||
.zip(keyed_account_indices_reordered)
|
.zip(keyed_account_indices_reordered)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@@ -914,7 +898,7 @@ impl MessageProcessor {
|
|||||||
pub fn process_cross_program_instruction(
|
pub fn process_cross_program_instruction(
|
||||||
message: &Message,
|
message: &Message,
|
||||||
executable_accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
executable_accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
caller_write_privileges: &[bool],
|
caller_write_privileges: &[bool],
|
||||||
invoke_context: &mut dyn InvokeContext,
|
invoke_context: &mut dyn InvokeContext,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
@@ -965,15 +949,17 @@ impl MessageProcessor {
|
|||||||
pub fn create_pre_accounts(
|
pub fn create_pre_accounts(
|
||||||
message: &Message,
|
message: &Message,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
) -> Vec<PreAccount> {
|
) -> Vec<PreAccount> {
|
||||||
let mut pre_accounts = Vec::with_capacity(instruction.accounts.len());
|
let mut pre_accounts = Vec::with_capacity(instruction.accounts.len());
|
||||||
{
|
{
|
||||||
let mut work = |_unique_index: usize, account_index: usize| {
|
let mut work = |_unique_index: usize, account_index: usize| {
|
||||||
let key = &message.account_keys[account_index];
|
if account_index < message.account_keys.len() && account_index < accounts.len() {
|
||||||
let account = accounts[account_index].borrow();
|
let account = accounts[account_index].1.borrow();
|
||||||
pre_accounts.push(PreAccount::new(key, &account));
|
pre_accounts.push(PreAccount::new(&accounts[account_index].0, &account));
|
||||||
Ok(())
|
return Ok(());
|
||||||
|
}
|
||||||
|
Err(InstructionError::MissingAccount)
|
||||||
};
|
};
|
||||||
let _ = instruction.visit_each_account(&mut work);
|
let _ = instruction.visit_each_account(&mut work);
|
||||||
}
|
}
|
||||||
@@ -998,7 +984,7 @@ impl MessageProcessor {
|
|||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
pre_accounts: &[PreAccount],
|
pre_accounts: &[PreAccount],
|
||||||
executable_accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
executable_accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
rent: &Rent,
|
rent: &Rent,
|
||||||
timings: &mut ExecuteDetailsTimings,
|
timings: &mut ExecuteDetailsTimings,
|
||||||
logger: Rc<RefCell<dyn Logger>>,
|
logger: Rc<RefCell<dyn Logger>>,
|
||||||
@@ -1014,10 +1000,11 @@ impl MessageProcessor {
|
|||||||
{
|
{
|
||||||
// Verify account has no outstanding references
|
// Verify account has no outstanding references
|
||||||
let _ = accounts[account_index]
|
let _ = accounts[account_index]
|
||||||
|
.1
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.map_err(|_| InstructionError::AccountBorrowOutstanding)?;
|
.map_err(|_| InstructionError::AccountBorrowOutstanding)?;
|
||||||
}
|
}
|
||||||
let account = accounts[account_index].borrow();
|
let account = accounts[account_index].1.borrow();
|
||||||
pre_accounts[unique_index]
|
pre_accounts[unique_index]
|
||||||
.verify(
|
.verify(
|
||||||
program_id,
|
program_id,
|
||||||
@@ -1056,7 +1043,7 @@ impl MessageProcessor {
|
|||||||
message: &Message,
|
message: &Message,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
pre_accounts: &mut [PreAccount],
|
pre_accounts: &mut [PreAccount],
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
rent: &Rent,
|
rent: &Rent,
|
||||||
caller_write_privileges: Option<&[bool]>,
|
caller_write_privileges: Option<&[bool]>,
|
||||||
@@ -1067,8 +1054,7 @@ impl MessageProcessor {
|
|||||||
let (mut pre_sum, mut post_sum) = (0_u128, 0_u128);
|
let (mut pre_sum, mut post_sum) = (0_u128, 0_u128);
|
||||||
let mut work = |_unique_index: usize, account_index: usize| {
|
let mut work = |_unique_index: usize, account_index: usize| {
|
||||||
if account_index < message.account_keys.len() && account_index < accounts.len() {
|
if account_index < message.account_keys.len() && account_index < accounts.len() {
|
||||||
let key = &message.account_keys[account_index];
|
let (key, account) = &accounts[account_index];
|
||||||
let account = &accounts[account_index];
|
|
||||||
let is_writable = if let Some(caller_write_privileges) = caller_write_privileges {
|
let is_writable = if let Some(caller_write_privileges) = caller_write_privileges {
|
||||||
caller_write_privileges[account_index]
|
caller_write_privileges[account_index]
|
||||||
} else {
|
} else {
|
||||||
@@ -1121,8 +1107,7 @@ impl MessageProcessor {
|
|||||||
message: &Message,
|
message: &Message,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
executable_accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
executable_accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
account_deps: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
|
||||||
rent_collector: &RentCollector,
|
rent_collector: &RentCollector,
|
||||||
log_collector: Option<Rc<LogCollector>>,
|
log_collector: Option<Rc<LogCollector>>,
|
||||||
executors: Rc<RefCell<Executors>>,
|
executors: Rc<RefCell<Executors>>,
|
||||||
@@ -1137,9 +1122,9 @@ impl MessageProcessor {
|
|||||||
// Fixup the special instructions key if present
|
// Fixup the special instructions key if present
|
||||||
// before the account pre-values are taken care of
|
// before the account pre-values are taken care of
|
||||||
if feature_set.is_active(&instructions_sysvar_enabled::id()) {
|
if feature_set.is_active(&instructions_sysvar_enabled::id()) {
|
||||||
for (i, key) in message.account_keys.iter().enumerate() {
|
for (pubkey, accont) in accounts.iter().take(message.account_keys.len()) {
|
||||||
if instructions::check_id(key) {
|
if instructions::check_id(pubkey) {
|
||||||
let mut mut_account_ref = accounts[i].borrow_mut();
|
let mut mut_account_ref = accont.borrow_mut();
|
||||||
instructions::store_current_index(
|
instructions::store_current_index(
|
||||||
mut_account_ref.data_as_mut_slice(),
|
mut_account_ref.data_as_mut_slice(),
|
||||||
instruction_index as u16,
|
instruction_index as u16,
|
||||||
@@ -1157,7 +1142,6 @@ impl MessageProcessor {
|
|||||||
instruction,
|
instruction,
|
||||||
executable_accounts,
|
executable_accounts,
|
||||||
accounts,
|
accounts,
|
||||||
account_deps,
|
|
||||||
&self.programs,
|
&self.programs,
|
||||||
log_collector,
|
log_collector,
|
||||||
bpf_compute_budget,
|
bpf_compute_budget,
|
||||||
@@ -1193,8 +1177,7 @@ impl MessageProcessor {
|
|||||||
&self,
|
&self,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
loaders: &[Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>],
|
loaders: &[Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>],
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
account_deps: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
|
||||||
rent_collector: &RentCollector,
|
rent_collector: &RentCollector,
|
||||||
log_collector: Option<Rc<LogCollector>>,
|
log_collector: Option<Rc<LogCollector>>,
|
||||||
executors: Rc<RefCell<Executors>>,
|
executors: Rc<RefCell<Executors>>,
|
||||||
@@ -1214,7 +1197,6 @@ impl MessageProcessor {
|
|||||||
instruction,
|
instruction,
|
||||||
&loaders[instruction_index],
|
&loaders[instruction_index],
|
||||||
accounts,
|
accounts,
|
||||||
account_deps,
|
|
||||||
rent_collector,
|
rent_collector,
|
||||||
log_collector.clone(),
|
log_collector.clone(),
|
||||||
executors.clone(),
|
executors.clone(),
|
||||||
@@ -1246,25 +1228,29 @@ mod tests {
|
|||||||
fn test_invoke_context() {
|
fn test_invoke_context() {
|
||||||
const MAX_DEPTH: usize = 10;
|
const MAX_DEPTH: usize = 10;
|
||||||
let mut invoke_stack = vec![];
|
let mut invoke_stack = vec![];
|
||||||
let mut keys = vec![];
|
|
||||||
let mut accounts = vec![];
|
let mut accounts = vec![];
|
||||||
let mut metas = vec![];
|
let mut metas = vec![];
|
||||||
for i in 0..MAX_DEPTH {
|
for i in 0..MAX_DEPTH {
|
||||||
invoke_stack.push(solana_sdk::pubkey::new_rand());
|
invoke_stack.push(solana_sdk::pubkey::new_rand());
|
||||||
keys.push(solana_sdk::pubkey::new_rand());
|
accounts.push((
|
||||||
accounts.push(Rc::new(RefCell::new(AccountSharedData::new(
|
solana_sdk::pubkey::new_rand(),
|
||||||
i as u64,
|
Rc::new(RefCell::new(AccountSharedData::new(
|
||||||
1,
|
i as u64,
|
||||||
&invoke_stack[i],
|
1,
|
||||||
))));
|
&invoke_stack[i],
|
||||||
metas.push(AccountMeta::new(keys[i], false));
|
))),
|
||||||
|
));
|
||||||
|
metas.push(AccountMeta::new(accounts[i].0, false));
|
||||||
}
|
}
|
||||||
for program_id in invoke_stack.iter() {
|
for program_id in invoke_stack.iter() {
|
||||||
accounts.push(Rc::new(RefCell::new(AccountSharedData::new(
|
accounts.push((
|
||||||
1,
|
*program_id,
|
||||||
1,
|
Rc::new(RefCell::new(AccountSharedData::new(
|
||||||
&solana_sdk::pubkey::Pubkey::default(),
|
1,
|
||||||
))));
|
1,
|
||||||
|
&solana_sdk::pubkey::Pubkey::default(),
|
||||||
|
))),
|
||||||
|
));
|
||||||
metas.push(AccountMeta::new(*program_id, false));
|
metas.push(AccountMeta::new(*program_id, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1281,7 +1267,6 @@ mod tests {
|
|||||||
&[],
|
&[],
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
&[],
|
||||||
&[],
|
|
||||||
None,
|
None,
|
||||||
BpfComputeBudget::default(),
|
BpfComputeBudget::default(),
|
||||||
Rc::new(RefCell::new(Executors::default())),
|
Rc::new(RefCell::new(Executors::default())),
|
||||||
@@ -1306,8 +1291,8 @@ mod tests {
|
|||||||
for owned_index in (1..depth_reached).rev() {
|
for owned_index in (1..depth_reached).rev() {
|
||||||
let not_owned_index = owned_index - 1;
|
let not_owned_index = owned_index - 1;
|
||||||
let metas = vec![
|
let metas = vec![
|
||||||
AccountMeta::new(keys[not_owned_index], false),
|
AccountMeta::new(accounts[not_owned_index].0, false),
|
||||||
AccountMeta::new(keys[owned_index], false),
|
AccountMeta::new(accounts[owned_index].0, false),
|
||||||
];
|
];
|
||||||
let message = Message::new(
|
let message = Message::new(
|
||||||
&[Instruction::new_with_bytes(
|
&[Instruction::new_with_bytes(
|
||||||
@@ -1319,14 +1304,17 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// modify account owned by the program
|
// modify account owned by the program
|
||||||
accounts[owned_index].borrow_mut().data_as_mut_slice()[0] =
|
accounts[owned_index].1.borrow_mut().data_as_mut_slice()[0] =
|
||||||
(MAX_DEPTH + owned_index) as u8;
|
(MAX_DEPTH + owned_index) as u8;
|
||||||
let mut these_accounts = accounts[not_owned_index..owned_index + 1].to_vec();
|
let mut these_accounts = accounts[not_owned_index..owned_index + 1].to_vec();
|
||||||
these_accounts.push(Rc::new(RefCell::new(AccountSharedData::new(
|
these_accounts.push((
|
||||||
1,
|
message.account_keys[2],
|
||||||
1,
|
Rc::new(RefCell::new(AccountSharedData::new(
|
||||||
&solana_sdk::pubkey::Pubkey::default(),
|
1,
|
||||||
))));
|
1,
|
||||||
|
&solana_sdk::pubkey::Pubkey::default(),
|
||||||
|
))),
|
||||||
|
));
|
||||||
invoke_context
|
invoke_context
|
||||||
.verify_and_update(&message, &message.instructions[0], &these_accounts, None)
|
.verify_and_update(&message, &message.instructions[0], &these_accounts, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -1339,8 +1327,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// modify account not owned by the program
|
// modify account not owned by the program
|
||||||
let data = accounts[not_owned_index].borrow_mut().data()[0];
|
let data = accounts[not_owned_index].1.borrow_mut().data()[0];
|
||||||
accounts[not_owned_index].borrow_mut().data_as_mut_slice()[0] =
|
accounts[not_owned_index].1.borrow_mut().data_as_mut_slice()[0] =
|
||||||
(MAX_DEPTH + not_owned_index) as u8;
|
(MAX_DEPTH + not_owned_index) as u8;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
invoke_context.verify_and_update(
|
invoke_context.verify_and_update(
|
||||||
@@ -1358,7 +1346,7 @@ mod tests {
|
|||||||
.data()[0],
|
.data()[0],
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
accounts[not_owned_index].borrow_mut().data_as_mut_slice()[0] = data;
|
accounts[not_owned_index].1.borrow_mut().data_as_mut_slice()[0] = data;
|
||||||
|
|
||||||
invoke_context.pop();
|
invoke_context.pop();
|
||||||
}
|
}
|
||||||
@@ -1834,26 +1822,28 @@ mod tests {
|
|||||||
let mut message_processor = MessageProcessor::default();
|
let mut message_processor = MessageProcessor::default();
|
||||||
message_processor.add_program(mock_system_program_id, mock_system_process_instruction);
|
message_processor.add_program(mock_system_program_id, mock_system_process_instruction);
|
||||||
|
|
||||||
let mut accounts: Vec<Rc<RefCell<AccountSharedData>>> = Vec::new();
|
let accounts = vec![
|
||||||
let account = AccountSharedData::new_ref(100, 1, &mock_system_program_id);
|
(
|
||||||
accounts.push(account);
|
solana_sdk::pubkey::new_rand(),
|
||||||
let account = AccountSharedData::new_ref(0, 1, &mock_system_program_id);
|
AccountSharedData::new_ref(100, 1, &mock_system_program_id),
|
||||||
accounts.push(account);
|
),
|
||||||
|
(
|
||||||
|
solana_sdk::pubkey::new_rand(),
|
||||||
|
AccountSharedData::new_ref(0, 1, &mock_system_program_id),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
let mut loaders: Vec<Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>> = Vec::new();
|
|
||||||
let account = Rc::new(RefCell::new(create_loadable_account_for_test(
|
let account = Rc::new(RefCell::new(create_loadable_account_for_test(
|
||||||
"mock_system_program",
|
"mock_system_program",
|
||||||
)));
|
)));
|
||||||
loaders.push(vec![(mock_system_program_id, account)]);
|
let loaders = vec![vec![(mock_system_program_id, account)]];
|
||||||
|
|
||||||
let executors = Rc::new(RefCell::new(Executors::default()));
|
let executors = Rc::new(RefCell::new(Executors::default()));
|
||||||
let ancestors = Ancestors::default();
|
let ancestors = Ancestors::default();
|
||||||
|
|
||||||
let from_pubkey = solana_sdk::pubkey::new_rand();
|
|
||||||
let to_pubkey = solana_sdk::pubkey::new_rand();
|
|
||||||
let account_metas = vec![
|
let account_metas = vec![
|
||||||
AccountMeta::new(from_pubkey, true),
|
AccountMeta::new(accounts[0].0, true),
|
||||||
AccountMeta::new_readonly(to_pubkey, false),
|
AccountMeta::new_readonly(accounts[1].0, false),
|
||||||
];
|
];
|
||||||
let message = Message::new(
|
let message = Message::new(
|
||||||
&[Instruction::new_with_bincode(
|
&[Instruction::new_with_bincode(
|
||||||
@@ -1861,14 +1851,13 @@ mod tests {
|
|||||||
&MockSystemInstruction::Correct,
|
&MockSystemInstruction::Correct,
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
)],
|
)],
|
||||||
Some(&from_pubkey),
|
Some(&accounts[0].0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = message_processor.process_message(
|
let result = message_processor.process_message(
|
||||||
&message,
|
&message,
|
||||||
&loaders,
|
&loaders,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
&rent_collector,
|
&rent_collector,
|
||||||
None,
|
None,
|
||||||
executors.clone(),
|
executors.clone(),
|
||||||
@@ -1880,8 +1869,8 @@ mod tests {
|
|||||||
&ancestors,
|
&ancestors,
|
||||||
);
|
);
|
||||||
assert_eq!(result, Ok(()));
|
assert_eq!(result, Ok(()));
|
||||||
assert_eq!(accounts[0].borrow().lamports(), 100);
|
assert_eq!(accounts[0].1.borrow().lamports(), 100);
|
||||||
assert_eq!(accounts[1].borrow().lamports(), 0);
|
assert_eq!(accounts[1].1.borrow().lamports(), 0);
|
||||||
|
|
||||||
let message = Message::new(
|
let message = Message::new(
|
||||||
&[Instruction::new_with_bincode(
|
&[Instruction::new_with_bincode(
|
||||||
@@ -1889,14 +1878,13 @@ mod tests {
|
|||||||
&MockSystemInstruction::AttemptCredit { lamports: 50 },
|
&MockSystemInstruction::AttemptCredit { lamports: 50 },
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
)],
|
)],
|
||||||
Some(&from_pubkey),
|
Some(&accounts[0].0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = message_processor.process_message(
|
let result = message_processor.process_message(
|
||||||
&message,
|
&message,
|
||||||
&loaders,
|
&loaders,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
&rent_collector,
|
&rent_collector,
|
||||||
None,
|
None,
|
||||||
executors.clone(),
|
executors.clone(),
|
||||||
@@ -1921,14 +1909,13 @@ mod tests {
|
|||||||
&MockSystemInstruction::AttemptDataChange { data: 50 },
|
&MockSystemInstruction::AttemptDataChange { data: 50 },
|
||||||
account_metas,
|
account_metas,
|
||||||
)],
|
)],
|
||||||
Some(&from_pubkey),
|
Some(&accounts[0].0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = message_processor.process_message(
|
let result = message_processor.process_message(
|
||||||
&message,
|
&message,
|
||||||
&loaders,
|
&loaders,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
&rent_collector,
|
&rent_collector,
|
||||||
None,
|
None,
|
||||||
executors,
|
executors,
|
||||||
@@ -2014,28 +2001,29 @@ mod tests {
|
|||||||
let mut message_processor = MessageProcessor::default();
|
let mut message_processor = MessageProcessor::default();
|
||||||
message_processor.add_program(mock_program_id, mock_system_process_instruction);
|
message_processor.add_program(mock_program_id, mock_system_process_instruction);
|
||||||
|
|
||||||
let mut accounts: Vec<Rc<RefCell<AccountSharedData>>> = Vec::new();
|
let accounts = vec![
|
||||||
let account = AccountSharedData::new_ref(100, 1, &mock_program_id);
|
(
|
||||||
accounts.push(account);
|
solana_sdk::pubkey::new_rand(),
|
||||||
let account = AccountSharedData::new_ref(0, 1, &mock_program_id);
|
AccountSharedData::new_ref(100, 1, &mock_program_id),
|
||||||
accounts.push(account);
|
),
|
||||||
|
(
|
||||||
|
solana_sdk::pubkey::new_rand(),
|
||||||
|
AccountSharedData::new_ref(0, 1, &mock_program_id),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
let mut loaders: Vec<Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>> = Vec::new();
|
|
||||||
let account = Rc::new(RefCell::new(create_loadable_account_for_test(
|
let account = Rc::new(RefCell::new(create_loadable_account_for_test(
|
||||||
"mock_system_program",
|
"mock_system_program",
|
||||||
)));
|
)));
|
||||||
loaders.push(vec![(mock_program_id, account)]);
|
let loaders = vec![vec![(mock_program_id, account)]];
|
||||||
|
|
||||||
let executors = Rc::new(RefCell::new(Executors::default()));
|
let executors = Rc::new(RefCell::new(Executors::default()));
|
||||||
let ancestors = Ancestors::default();
|
let ancestors = Ancestors::default();
|
||||||
|
|
||||||
let from_pubkey = solana_sdk::pubkey::new_rand();
|
|
||||||
let to_pubkey = solana_sdk::pubkey::new_rand();
|
|
||||||
let dup_pubkey = from_pubkey;
|
|
||||||
let account_metas = vec![
|
let account_metas = vec![
|
||||||
AccountMeta::new(from_pubkey, true),
|
AccountMeta::new(accounts[0].0, true),
|
||||||
AccountMeta::new(to_pubkey, false),
|
AccountMeta::new(accounts[1].0, false),
|
||||||
AccountMeta::new(dup_pubkey, false),
|
AccountMeta::new(accounts[0].0, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Try to borrow mut the same account
|
// Try to borrow mut the same account
|
||||||
@@ -2045,13 +2033,12 @@ mod tests {
|
|||||||
&MockSystemInstruction::BorrowFail,
|
&MockSystemInstruction::BorrowFail,
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
)],
|
)],
|
||||||
Some(&from_pubkey),
|
Some(&accounts[0].0),
|
||||||
);
|
);
|
||||||
let result = message_processor.process_message(
|
let result = message_processor.process_message(
|
||||||
&message,
|
&message,
|
||||||
&loaders,
|
&loaders,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
&rent_collector,
|
&rent_collector,
|
||||||
None,
|
None,
|
||||||
executors.clone(),
|
executors.clone(),
|
||||||
@@ -2077,13 +2064,12 @@ mod tests {
|
|||||||
&MockSystemInstruction::MultiBorrowMut,
|
&MockSystemInstruction::MultiBorrowMut,
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
)],
|
)],
|
||||||
Some(&from_pubkey),
|
Some(&accounts[0].0),
|
||||||
);
|
);
|
||||||
let result = message_processor.process_message(
|
let result = message_processor.process_message(
|
||||||
&message,
|
&message,
|
||||||
&loaders,
|
&loaders,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
&rent_collector,
|
&rent_collector,
|
||||||
None,
|
None,
|
||||||
executors.clone(),
|
executors.clone(),
|
||||||
@@ -2106,14 +2092,13 @@ mod tests {
|
|||||||
},
|
},
|
||||||
account_metas,
|
account_metas,
|
||||||
)],
|
)],
|
||||||
Some(&from_pubkey),
|
Some(&accounts[0].0),
|
||||||
);
|
);
|
||||||
let ancestors = Ancestors::default();
|
let ancestors = Ancestors::default();
|
||||||
let result = message_processor.process_message(
|
let result = message_processor.process_message(
|
||||||
&message,
|
&message,
|
||||||
&loaders,
|
&loaders,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
&rent_collector,
|
&rent_collector,
|
||||||
None,
|
None,
|
||||||
executors,
|
executors,
|
||||||
@@ -2125,9 +2110,9 @@ mod tests {
|
|||||||
&ancestors,
|
&ancestors,
|
||||||
);
|
);
|
||||||
assert_eq!(result, Ok(()));
|
assert_eq!(result, Ok(()));
|
||||||
assert_eq!(accounts[0].borrow().lamports(), 80);
|
assert_eq!(accounts[0].1.borrow().lamports(), 80);
|
||||||
assert_eq!(accounts[1].borrow().lamports(), 20);
|
assert_eq!(accounts[1].1.borrow().lamports(), 20);
|
||||||
assert_eq!(accounts[0].borrow().data(), &vec![42]);
|
assert_eq!(accounts[0].1.borrow().data(), &vec![42]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -2179,25 +2164,28 @@ mod tests {
|
|||||||
Rc::new(RefCell::new(program_account.clone())),
|
Rc::new(RefCell::new(program_account.clone())),
|
||||||
)];
|
)];
|
||||||
|
|
||||||
let owned_key = solana_sdk::pubkey::new_rand();
|
|
||||||
let owned_account = AccountSharedData::new(42, 1, &callee_program_id);
|
let owned_account = AccountSharedData::new(42, 1, &callee_program_id);
|
||||||
|
|
||||||
let not_owned_key = solana_sdk::pubkey::new_rand();
|
|
||||||
let not_owned_account = AccountSharedData::new(84, 1, &solana_sdk::pubkey::new_rand());
|
let not_owned_account = AccountSharedData::new(84, 1, &solana_sdk::pubkey::new_rand());
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut accounts = vec![
|
let accounts = vec![
|
||||||
Rc::new(RefCell::new(owned_account)),
|
(
|
||||||
Rc::new(RefCell::new(not_owned_account)),
|
solana_sdk::pubkey::new_rand(),
|
||||||
Rc::new(RefCell::new(program_account)),
|
Rc::new(RefCell::new(owned_account)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
solana_sdk::pubkey::new_rand(),
|
||||||
|
Rc::new(RefCell::new(not_owned_account)),
|
||||||
|
),
|
||||||
|
(callee_program_id, Rc::new(RefCell::new(program_account))),
|
||||||
];
|
];
|
||||||
|
|
||||||
let compiled_instruction = CompiledInstruction::new(2, &(), vec![0, 1, 2]);
|
let compiled_instruction = CompiledInstruction::new(2, &(), vec![0, 1, 2]);
|
||||||
let programs: Vec<(_, ProcessInstructionWithContext)> =
|
let programs: Vec<(_, ProcessInstructionWithContext)> =
|
||||||
vec![(callee_program_id, mock_process_instruction)];
|
vec![(callee_program_id, mock_process_instruction)];
|
||||||
let metas = vec![
|
let metas = vec![
|
||||||
AccountMeta::new(owned_key, false),
|
AccountMeta::new(accounts[0].0, false),
|
||||||
AccountMeta::new(not_owned_key, false),
|
AccountMeta::new(accounts[1].0, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
let instruction = Instruction::new_with_bincode(
|
let instruction = Instruction::new_with_bincode(
|
||||||
@@ -2215,7 +2203,6 @@ mod tests {
|
|||||||
&compiled_instruction,
|
&compiled_instruction,
|
||||||
&executable_accounts,
|
&executable_accounts,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
programs.as_slice(),
|
programs.as_slice(),
|
||||||
None,
|
None,
|
||||||
BpfComputeBudget::default(),
|
BpfComputeBudget::default(),
|
||||||
@@ -2233,7 +2220,7 @@ mod tests {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, _)| message.is_writable(i))
|
.map(|(i, _)| message.is_writable(i))
|
||||||
.collect::<Vec<bool>>();
|
.collect::<Vec<bool>>();
|
||||||
accounts[0].borrow_mut().data_as_mut_slice()[0] = 1;
|
accounts[0].1.borrow_mut().data_as_mut_slice()[0] = 1;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MessageProcessor::process_cross_program_instruction(
|
MessageProcessor::process_cross_program_instruction(
|
||||||
&message,
|
&message,
|
||||||
@@ -2244,7 +2231,7 @@ mod tests {
|
|||||||
),
|
),
|
||||||
Err(InstructionError::ExternalAccountDataModified)
|
Err(InstructionError::ExternalAccountDataModified)
|
||||||
);
|
);
|
||||||
accounts[0].borrow_mut().data_as_mut_slice()[0] = 0;
|
accounts[0].1.borrow_mut().data_as_mut_slice()[0] = 0;
|
||||||
|
|
||||||
let cases = vec![
|
let cases = vec![
|
||||||
(MockInstruction::NoopSuccess, Ok(())),
|
(MockInstruction::NoopSuccess, Ok(())),
|
||||||
@@ -2272,7 +2259,6 @@ mod tests {
|
|||||||
&compiled_instruction,
|
&compiled_instruction,
|
||||||
&executable_accounts,
|
&executable_accounts,
|
||||||
&accounts,
|
&accounts,
|
||||||
&[],
|
|
||||||
programs.as_slice(),
|
programs.as_slice(),
|
||||||
None,
|
None,
|
||||||
BpfComputeBudget::default(),
|
BpfComputeBudget::default(),
|
||||||
|
@@ -64,7 +64,7 @@ pub trait InvokeContext {
|
|||||||
&mut self,
|
&mut self,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
instruction: &CompiledInstruction,
|
instruction: &CompiledInstruction,
|
||||||
accounts: &[Rc<RefCell<AccountSharedData>>],
|
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
caller_pivileges: Option<&[bool]>,
|
caller_pivileges: Option<&[bool]>,
|
||||||
) -> Result<(), InstructionError>;
|
) -> Result<(), InstructionError>;
|
||||||
/// Get the program ID of the currently executing program
|
/// Get the program ID of the currently executing program
|
||||||
@@ -90,7 +90,7 @@ pub trait InvokeContext {
|
|||||||
fn record_instruction(&self, instruction: &Instruction);
|
fn record_instruction(&self, instruction: &Instruction);
|
||||||
/// Get the bank's active feature set
|
/// Get the bank's active feature set
|
||||||
fn is_feature_active(&self, feature_id: &Pubkey) -> bool;
|
fn is_feature_active(&self, feature_id: &Pubkey) -> bool;
|
||||||
/// Get an account from a pre-account
|
/// Get an account by its key
|
||||||
fn get_account(&self, pubkey: &Pubkey) -> Option<Rc<RefCell<AccountSharedData>>>;
|
fn get_account(&self, pubkey: &Pubkey) -> Option<Rc<RefCell<AccountSharedData>>>;
|
||||||
/// Update timing
|
/// Update timing
|
||||||
fn update_timing(
|
fn update_timing(
|
||||||
@@ -395,7 +395,7 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_message: &Message,
|
_message: &Message,
|
||||||
_instruction: &CompiledInstruction,
|
_instruction: &CompiledInstruction,
|
||||||
_accounts: &[Rc<RefCell<AccountSharedData>>],
|
_accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
_caller_pivileges: Option<&[bool]>,
|
_caller_pivileges: Option<&[bool]>,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Reference in New Issue
Block a user