Feature: TransactionContext, InstructionContext and BorrowedAccount (#21706)
* Adds TransactionContext, InstructionContext and BorrowedAccount. * Redirects the usage of accounts in InvokeContext through TransactionContext. Also use the types declared in transaction_context.rs everywhere. * Adjusts all affected tests.
This commit is contained in:
committed by
GitHub
parent
bb97c8fdcd
commit
a06646631c
@ -323,6 +323,7 @@ mod tests {
|
||||
bpf_loader,
|
||||
entrypoint::deserialize,
|
||||
instruction::AccountMeta,
|
||||
transaction_context::TransactionContext,
|
||||
},
|
||||
std::{
|
||||
cell::RefCell,
|
||||
@ -452,7 +453,8 @@ mod tests {
|
||||
let program_indices = [0];
|
||||
let preparation =
|
||||
prepare_mock_invoke_context(transaction_accounts.clone(), instruction_accounts);
|
||||
let mut invoke_context = InvokeContext::new_mock(&preparation.transaction_accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(preparation.transaction_accounts, 1);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context
|
||||
.push(&preparation.instruction_accounts, &program_indices)
|
||||
.unwrap();
|
||||
|
@ -5,7 +5,7 @@ use {
|
||||
alloc::Alloc,
|
||||
solana_program_runtime::{
|
||||
ic_logger_msg, ic_msg,
|
||||
invoke_context::{ComputeMeter, InstructionAccount, InvokeContext},
|
||||
invoke_context::{ComputeMeter, InvokeContext},
|
||||
stable_log,
|
||||
},
|
||||
solana_rbpf::{
|
||||
@ -41,6 +41,7 @@ use {
|
||||
Secp256k1RecoverError, SECP256K1_PUBLIC_KEY_LENGTH, SECP256K1_SIGNATURE_LENGTH,
|
||||
},
|
||||
sysvar::{self, Sysvar, SysvarId},
|
||||
transaction_context::InstructionAccount,
|
||||
},
|
||||
std::{
|
||||
alloc::Layout,
|
||||
@ -2214,8 +2215,12 @@ where
|
||||
accounts.push((*program_account_index, None));
|
||||
|
||||
for instruction_account in instruction_accounts.iter() {
|
||||
let account = invoke_context.get_account_at_index(instruction_account.index);
|
||||
let account_key = invoke_context.get_account_key_at_index(instruction_account.index);
|
||||
let account = invoke_context
|
||||
.transaction_context
|
||||
.get_account_at_index(instruction_account.index);
|
||||
let account_key = invoke_context
|
||||
.transaction_context
|
||||
.get_key_of_account_at_index(instruction_account.index);
|
||||
if account.borrow().executable() {
|
||||
// Use the known account
|
||||
accounts.push((instruction_account.index, None));
|
||||
@ -2396,6 +2401,7 @@ fn call<'a, 'b: 'a>(
|
||||
for (callee_account_index, caller_account) in accounts.iter_mut() {
|
||||
if let Some(caller_account) = caller_account {
|
||||
let callee_account = invoke_context
|
||||
.transaction_context
|
||||
.get_account_at_index(*callee_account_index)
|
||||
.borrow();
|
||||
*caller_account.lamports = callee_account.lamports();
|
||||
@ -2669,6 +2675,7 @@ mod tests {
|
||||
},
|
||||
solana_sdk::{
|
||||
account::AccountSharedData, bpf_loader, fee_calculator::FeeCalculator, hash::hashv,
|
||||
transaction_context::TransactionContext,
|
||||
},
|
||||
std::str::FromStr,
|
||||
};
|
||||
@ -2979,9 +2986,11 @@ mod tests {
|
||||
#[should_panic(expected = "UserError(SyscallError(Panic(\"Gaggablaghblagh!\", 42, 84)))")]
|
||||
fn test_syscall_sol_panic() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let mut syscall_panic = SyscallPanic {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
@ -3050,9 +3059,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_syscall_sol_log() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let mut syscall_sol_log = SyscallLog {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
@ -3148,9 +3159,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_syscall_sol_log_u64() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let cost = invoke_context.get_compute_budget().log_64_units;
|
||||
let mut syscall_sol_log_u64 = SyscallLogU64 {
|
||||
@ -3184,9 +3197,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_syscall_sol_pubkey() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let cost = invoke_context.get_compute_budget().log_pubkey_units;
|
||||
let mut syscall_sol_pubkey = SyscallLogPubkey {
|
||||
@ -3390,10 +3405,14 @@ mod tests {
|
||||
fn test_syscall_sha256() {
|
||||
let config = Config::default();
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account =
|
||||
RefCell::new(AccountSharedData::new(0, 0, &bpf_loader_deprecated::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(
|
||||
program_id,
|
||||
AccountSharedData::new(0, 0, &bpf_loader_deprecated::id()),
|
||||
)],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
|
||||
let bytes1 = "Gaggablaghblagh!";
|
||||
@ -3511,11 +3530,55 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_syscall_get_sysvar() {
|
||||
let config = Config::default();
|
||||
let src_clock = Clock {
|
||||
slot: 1,
|
||||
epoch_start_timestamp: 2,
|
||||
epoch: 3,
|
||||
leader_schedule_epoch: 4,
|
||||
unix_timestamp: 5,
|
||||
};
|
||||
let mut data_clock = vec![];
|
||||
bincode::serialize_into(&mut data_clock, &src_clock).unwrap();
|
||||
let src_epochschedule = EpochSchedule {
|
||||
slots_per_epoch: 1,
|
||||
leader_schedule_slot_offset: 2,
|
||||
warmup: false,
|
||||
first_normal_epoch: 3,
|
||||
first_normal_slot: 4,
|
||||
};
|
||||
let mut data_epochschedule = vec![];
|
||||
bincode::serialize_into(&mut data_epochschedule, &src_epochschedule).unwrap();
|
||||
let src_fees = Fees {
|
||||
fee_calculator: FeeCalculator {
|
||||
lamports_per_signature: 1,
|
||||
},
|
||||
};
|
||||
let mut data_fees = vec![];
|
||||
bincode::serialize_into(&mut data_fees, &src_fees).unwrap();
|
||||
let src_rent = Rent {
|
||||
lamports_per_byte_year: 1,
|
||||
exemption_threshold: 2.0,
|
||||
burn_percent: 3,
|
||||
};
|
||||
let mut data_rent = vec![];
|
||||
bincode::serialize_into(&mut data_rent, &src_rent).unwrap();
|
||||
let sysvars = [
|
||||
(sysvar::clock::id(), data_clock),
|
||||
(sysvar::epoch_schedule::id(), data_epochschedule),
|
||||
(sysvar::fees::id(), data_fees),
|
||||
(sysvar::rent::id(), data_rent),
|
||||
];
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.sysvars = &sysvars;
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
|
||||
// Test clock sysvar
|
||||
{
|
||||
@ -3536,20 +3599,6 @@ mod tests {
|
||||
&config,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let src_clock = Clock {
|
||||
slot: 1,
|
||||
epoch_start_timestamp: 2,
|
||||
epoch: 3,
|
||||
leader_schedule_epoch: 4,
|
||||
unix_timestamp: 5,
|
||||
};
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_clock).unwrap();
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let sysvars = [(sysvar::clock::id(), data)];
|
||||
invoke_context.sysvars = &sysvars;
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let mut syscall = SyscallGetClockSysvar {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
};
|
||||
@ -3579,20 +3628,6 @@ mod tests {
|
||||
&config,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let src_epochschedule = EpochSchedule {
|
||||
slots_per_epoch: 1,
|
||||
leader_schedule_slot_offset: 2,
|
||||
warmup: false,
|
||||
first_normal_epoch: 3,
|
||||
first_normal_slot: 4,
|
||||
};
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let sysvars = [(sysvar::epoch_schedule::id(), data)];
|
||||
invoke_context.sysvars = &sysvars;
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let mut syscall = SyscallGetEpochScheduleSysvar {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
};
|
||||
@ -3612,7 +3647,6 @@ mod tests {
|
||||
}
|
||||
|
||||
// Test fees sysvar
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
let got_fees = Fees::default();
|
||||
let got_fees_va = 0x100000000;
|
||||
@ -3631,18 +3665,6 @@ mod tests {
|
||||
&config,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let src_fees = Fees {
|
||||
fee_calculator: FeeCalculator {
|
||||
lamports_per_signature: 1,
|
||||
},
|
||||
};
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_fees).unwrap();
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let sysvars = [(sysvar::fees::id(), data)];
|
||||
invoke_context.sysvars = &sysvars;
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let mut syscall = SyscallGetFeesSysvar {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
};
|
||||
@ -3672,18 +3694,6 @@ mod tests {
|
||||
&config,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let src_rent = Rent {
|
||||
lamports_per_byte_year: 1,
|
||||
exemption_threshold: 2.0,
|
||||
burn_percent: 3,
|
||||
};
|
||||
let mut data = vec![];
|
||||
bincode::serialize_into(&mut data, &src_rent).unwrap();
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let sysvars = [(sysvar::rent::id(), data)];
|
||||
invoke_context.sysvars = &sysvars;
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let mut syscall = SyscallGetRentSysvar {
|
||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||
};
|
||||
@ -3812,9 +3822,11 @@ mod tests {
|
||||
// These tests duplicate the direct tests in solana_program::pubkey
|
||||
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let address = bpf_loader_upgradeable::id();
|
||||
|
||||
@ -3922,9 +3934,11 @@ mod tests {
|
||||
#[test]
|
||||
fn test_find_program_address() {
|
||||
let program_id = Pubkey::new_unique();
|
||||
let program_account = RefCell::new(AccountSharedData::new(0, 0, &bpf_loader::id()));
|
||||
let accounts = [(program_id, program_account)];
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
let transaction_context = TransactionContext::new(
|
||||
vec![(program_id, AccountSharedData::new(0, 0, &bpf_loader::id()))],
|
||||
1,
|
||||
);
|
||||
let mut invoke_context = InvokeContext::new_mock(&transaction_context, &[]);
|
||||
invoke_context.push(&[], &[0]).unwrap();
|
||||
let cost = invoke_context
|
||||
.get_compute_budget()
|
||||
|
Reference in New Issue
Block a user