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:
Alexander Meißner
2022-01-03 23:30:56 +01:00
committed by GitHub
parent 672fed04cb
commit 73e6038986
18 changed files with 847 additions and 805 deletions

View File

@@ -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(