Refactor: Remove KeyedAccount
from program runtime (#22226)
* Makes error handling in BorrowedAccount optional. Adds BorrowedAccount ::get_rent_epoch(). Exposes InstructionContext::get_index_in_transaction(). Turns accounts and account_keys into pinned boxed slices. * Introduces "unsafe" to InvokeContext::push(). * Turns &TransactionContext into &mut TransactionContext in InvokeContext. * Push and pop InstructionContext in InvokeContext. Makes test_process_cross_program and test_native_invoke symmetric. Removes the borrow check from test_invoke_context_verify. * Removes keyed_accounts from prepare_instruction() * Removes usage of invoke_stack. * Removes keyed_accounts from program-test. * Removes caller_write_privileges. * Removes keyed_accounts from BPF parameter (de-)serialization.
This commit is contained in:
committed by
GitHub
parent
672fed04cb
commit
73e6038986
@ -3561,9 +3561,9 @@ impl Bank {
|
||||
|
||||
let mut transaction_accounts = Vec::new();
|
||||
std::mem::swap(&mut loaded_transaction.accounts, &mut transaction_accounts);
|
||||
let transaction_context = TransactionContext::new(
|
||||
let mut transaction_context = TransactionContext::new(
|
||||
transaction_accounts,
|
||||
compute_budget.max_invoke_depth,
|
||||
compute_budget.max_invoke_depth.saturating_add(1),
|
||||
);
|
||||
|
||||
let instruction_recorder = if enable_cpi_recording {
|
||||
@ -3588,7 +3588,7 @@ impl Bank {
|
||||
&self.builtin_programs.vec,
|
||||
legacy_message,
|
||||
&loaded_transaction.program_indices,
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
self.rent_collector.rent,
|
||||
log_collector.clone(),
|
||||
executors.clone(),
|
||||
@ -10401,7 +10401,7 @@ pub(crate) mod tests {
|
||||
_instruction_data: &[u8],
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> std::result::Result<(), InstructionError> {
|
||||
let program_id = invoke_context.get_caller()?;
|
||||
let program_id = invoke_context.transaction_context.get_program_key()?;
|
||||
if mock_vote_program_id() != *program_id {
|
||||
return Err(InstructionError::IncorrectProgramId);
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ fn process_instruction_with_program_logging(
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> Result<(), InstructionError> {
|
||||
let logger = invoke_context.get_log_collector();
|
||||
let program_id = invoke_context.get_caller()?;
|
||||
let program_id = invoke_context.transaction_context.get_program_key()?;
|
||||
stable_log::program_invoke(&logger, program_id, invoke_context.invoke_depth());
|
||||
|
||||
let result = process_instruction(first_instruction_account, instruction_data, invoke_context);
|
||||
|
||||
let program_id = invoke_context.get_caller()?;
|
||||
let program_id = invoke_context.transaction_context.get_program_key()?;
|
||||
match &result {
|
||||
Ok(()) => stable_log::program_success(&logger, program_id),
|
||||
Err(err) => stable_log::program_failure(&logger, program_id, err),
|
||||
|
@ -53,7 +53,7 @@ impl MessageProcessor {
|
||||
builtin_programs: &[BuiltinProgram],
|
||||
message: &Message,
|
||||
program_indices: &[Vec<usize>],
|
||||
transaction_context: &TransactionContext,
|
||||
transaction_context: &mut TransactionContext,
|
||||
rent: Rent,
|
||||
log_collector: Option<Rc<RefCell<LogCollector>>>,
|
||||
executors: Rc<RefCell<Executors>>,
|
||||
@ -132,7 +132,6 @@ impl MessageProcessor {
|
||||
let result = invoke_context.process_instruction(
|
||||
&instruction.data,
|
||||
&instruction_accounts,
|
||||
None,
|
||||
program_indices,
|
||||
&mut compute_units_consumed,
|
||||
);
|
||||
@ -242,7 +241,7 @@ mod tests {
|
||||
create_loadable_account_for_test("mock_system_program"),
|
||||
),
|
||||
];
|
||||
let transaction_context = TransactionContext::new(accounts, 1);
|
||||
let mut transaction_context = TransactionContext::new(accounts, 1);
|
||||
let program_indices = vec![vec![2]];
|
||||
let executors = Rc::new(RefCell::new(Executors::default()));
|
||||
let account_metas = vec![
|
||||
@ -262,7 +261,7 @@ mod tests {
|
||||
builtin_programs,
|
||||
&message,
|
||||
&program_indices,
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
rent_collector.rent,
|
||||
None,
|
||||
executors.clone(),
|
||||
@ -303,7 +302,7 @@ mod tests {
|
||||
builtin_programs,
|
||||
&message,
|
||||
&program_indices,
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
rent_collector.rent,
|
||||
None,
|
||||
executors.clone(),
|
||||
@ -336,7 +335,7 @@ mod tests {
|
||||
builtin_programs,
|
||||
&message,
|
||||
&program_indices,
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
rent_collector.rent,
|
||||
None,
|
||||
executors,
|
||||
@ -458,7 +457,7 @@ mod tests {
|
||||
create_loadable_account_for_test("mock_system_program"),
|
||||
),
|
||||
];
|
||||
let transaction_context = TransactionContext::new(accounts, 1);
|
||||
let mut transaction_context = TransactionContext::new(accounts, 1);
|
||||
let program_indices = vec![vec![2]];
|
||||
let executors = Rc::new(RefCell::new(Executors::default()));
|
||||
let account_metas = vec![
|
||||
@ -480,7 +479,7 @@ mod tests {
|
||||
builtin_programs,
|
||||
&message,
|
||||
&program_indices,
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
rent_collector.rent,
|
||||
None,
|
||||
executors.clone(),
|
||||
@ -514,7 +513,7 @@ mod tests {
|
||||
builtin_programs,
|
||||
&message,
|
||||
&program_indices,
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
rent_collector.rent,
|
||||
None,
|
||||
executors.clone(),
|
||||
@ -545,7 +544,7 @@ mod tests {
|
||||
builtin_programs,
|
||||
&message,
|
||||
&program_indices,
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
rent_collector.rent,
|
||||
None,
|
||||
executors,
|
||||
@ -602,7 +601,7 @@ mod tests {
|
||||
(secp256k1_program::id(), secp256k1_account),
|
||||
(mock_program_id, mock_program_account),
|
||||
];
|
||||
let transaction_context = TransactionContext::new(accounts, 1);
|
||||
let mut transaction_context = TransactionContext::new(accounts, 1);
|
||||
|
||||
let message = Message::new(
|
||||
&[
|
||||
@ -618,7 +617,7 @@ mod tests {
|
||||
builtin_programs,
|
||||
&message,
|
||||
&[vec![0], vec![1]],
|
||||
&transaction_context,
|
||||
&mut transaction_context,
|
||||
RentCollector::default().rent,
|
||||
None,
|
||||
Rc::new(RefCell::new(Executors::default())),
|
||||
|
@ -334,8 +334,8 @@ mod test {
|
||||
where
|
||||
F: FnMut(&mut InvokeContext, &KeyedAccount),
|
||||
{
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let pubkey = Pubkey::new_unique();
|
||||
let account = create_account(lamports);
|
||||
let keyed_account = KeyedAccount::new(&pubkey, signer, &account);
|
||||
|
@ -675,8 +675,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_address_create_with_seed_mismatch() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let from = Pubkey::new_unique();
|
||||
let seed = "dull boy";
|
||||
let to = Pubkey::new_unique();
|
||||
@ -690,8 +690,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_account_with_seed_missing_sig() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let new_owner = Pubkey::new(&[9; 32]);
|
||||
let from = Pubkey::new_unique();
|
||||
let seed = "dull boy";
|
||||
@ -721,8 +721,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_with_zero_lamports() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
// create account with zero lamports transferred
|
||||
let new_owner = Pubkey::new(&[9; 32]);
|
||||
let from = Pubkey::new_unique();
|
||||
@ -756,8 +756,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_negative_lamports() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
// Attempt to create account with more lamports than remaining in from_account
|
||||
let new_owner = Pubkey::new(&[9; 32]);
|
||||
let from = Pubkey::new_unique();
|
||||
@ -781,8 +781,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_request_more_than_allowed_data_length() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let from_account = RefCell::new(AccountSharedData::new(100, 0, &system_program::id()));
|
||||
let from = Pubkey::new_unique();
|
||||
let to_account = RefCell::new(AccountSharedData::new(0, 0, &system_program::id()));
|
||||
@ -829,8 +829,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_already_in_use() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
// Attempt to create system account in account already owned by another program
|
||||
let new_owner = Pubkey::new(&[9; 32]);
|
||||
let from = Pubkey::new_unique();
|
||||
@ -898,8 +898,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_unsigned() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
// Attempt to create an account without signing the transfer
|
||||
let new_owner = Pubkey::new(&[9; 32]);
|
||||
let from = Pubkey::new_unique();
|
||||
@ -954,8 +954,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_sysvar_invalid_id_with_feature() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
// Attempt to create system account in account already owned by another program
|
||||
let from = Pubkey::new_unique();
|
||||
let from_account = RefCell::new(AccountSharedData::new(100, 0, &system_program::id()));
|
||||
@ -989,8 +989,8 @@ mod tests {
|
||||
feature_set
|
||||
.inactive
|
||||
.insert(feature_set::rent_for_sysvars::id());
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.feature_set = Arc::new(feature_set);
|
||||
// Attempt to create system account in account already owned by another program
|
||||
let from = Pubkey::new_unique();
|
||||
@ -1017,8 +1017,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_data_populated() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
// Attempt to create system account in account with populated data
|
||||
let new_owner = Pubkey::new(&[9; 32]);
|
||||
let from = Pubkey::new_unique();
|
||||
@ -1051,8 +1051,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_from_account_is_nonce_fail() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let nonce = Pubkey::new_unique();
|
||||
let nonce_account = RefCell::new(
|
||||
AccountSharedData::new_data(
|
||||
@ -1090,8 +1090,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_assign() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let new_owner = Pubkey::new(&[9; 32]);
|
||||
let pubkey = Pubkey::new_unique();
|
||||
let mut account = AccountSharedData::new(100, 0, &system_program::id());
|
||||
@ -1133,8 +1133,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_assign_to_sysvar_with_feature() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let new_owner = sysvar::id();
|
||||
let from = Pubkey::new_unique();
|
||||
let mut from_account = AccountSharedData::new(100, 0, &system_program::id());
|
||||
@ -1160,8 +1160,8 @@ mod tests {
|
||||
feature_set
|
||||
.inactive
|
||||
.insert(feature_set::rent_for_sysvars::id());
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.feature_set = Arc::new(feature_set);
|
||||
let new_owner = sysvar::id();
|
||||
let from = Pubkey::new_unique();
|
||||
@ -1212,8 +1212,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_transfer_lamports() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let from = Pubkey::new_unique();
|
||||
let from_account = RefCell::new(AccountSharedData::new(100, 0, &Pubkey::new(&[2; 32]))); // account owner should not matter
|
||||
let to = Pubkey::new(&[3; 32]);
|
||||
@ -1251,8 +1251,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_transfer_with_seed() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let base = Pubkey::new_unique();
|
||||
let base_account = RefCell::new(AccountSharedData::new(100, 0, &Pubkey::new(&[2; 32]))); // account owner should not matter
|
||||
let from_base_keyed_account = KeyedAccount::new(&base, true, &base_account);
|
||||
@ -1312,8 +1312,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_transfer_lamports_from_nonce_account_fail() {
|
||||
let transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
let mut transaction_context = TransactionContext::new(Vec::new(), 1);
|
||||
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
let from = Pubkey::new_unique();
|
||||
let from_account = RefCell::new(
|
||||
AccountSharedData::new_data(
|
||||
|
Reference in New Issue
Block a user