Refactor: Remove Rc from PreAccount and InvokeContext::get_account() (#21882)
* Removes Rc and RefCell from PreAccount * Splits get_account() into find_index_of_account() and get_account_at_index() in order to remove Rc from return type.
This commit is contained in:
parent
c92c09a8be
commit
4adc8b133f
|
@ -17,7 +17,7 @@ fn bench_verify_account_changes_data(bencher: &mut Bencher) {
|
||||||
let non_owner = pubkey::new_rand();
|
let non_owner = pubkey::new_rand();
|
||||||
let pre = PreAccount::new(
|
let pre = PreAccount::new(
|
||||||
&pubkey::new_rand(),
|
&pubkey::new_rand(),
|
||||||
&AccountSharedData::new(0, BUFSIZE, &owner),
|
AccountSharedData::new(0, BUFSIZE, &owner),
|
||||||
);
|
);
|
||||||
let post = AccountSharedData::new(0, BUFSIZE, &owner);
|
let post = AccountSharedData::new(0, BUFSIZE, &owner);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -57,7 +57,7 @@ fn bench_verify_account_changes_data(bencher: &mut Bencher) {
|
||||||
|
|
||||||
let pre = PreAccount::new(
|
let pre = PreAccount::new(
|
||||||
&pubkey::new_rand(),
|
&pubkey::new_rand(),
|
||||||
&AccountSharedData::new(0, BUFSIZE, &owner),
|
AccountSharedData::new(0, BUFSIZE, &owner),
|
||||||
);
|
);
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
pre.verify(
|
pre.verify(
|
||||||
|
|
|
@ -257,9 +257,9 @@ impl<'a> InvokeContext<'a> {
|
||||||
self.pre_accounts = Vec::with_capacity(instruction.accounts.len());
|
self.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| {
|
||||||
if account_index < self.accounts.len() {
|
if account_index < self.accounts.len() {
|
||||||
let account = self.accounts[account_index].1.borrow();
|
let account = self.accounts[account_index].1.borrow().clone();
|
||||||
self.pre_accounts
|
self.pre_accounts
|
||||||
.push(PreAccount::new(&self.accounts[account_index].0, &account));
|
.push(PreAccount::new(&self.accounts[account_index].0, account));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(InstructionError::MissingAccount)
|
Err(InstructionError::MissingAccount)
|
||||||
|
@ -461,7 +461,7 @@ impl<'a> InvokeContext<'a> {
|
||||||
.checked_add(u128::from(account.lamports()))
|
.checked_add(u128::from(account.lamports()))
|
||||||
.ok_or(InstructionError::UnbalancedInstruction)?;
|
.ok_or(InstructionError::UnbalancedInstruction)?;
|
||||||
if is_writable && !pre_account.executable() {
|
if is_writable && !pre_account.executable() {
|
||||||
pre_account.update(&account);
|
pre_account.update(account.clone());
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -489,12 +489,12 @@ impl<'a> InvokeContext<'a> {
|
||||||
let mut account_indices = Vec::with_capacity(message.account_keys.len());
|
let mut account_indices = Vec::with_capacity(message.account_keys.len());
|
||||||
let mut prev_account_sizes = Vec::with_capacity(message.account_keys.len());
|
let mut prev_account_sizes = Vec::with_capacity(message.account_keys.len());
|
||||||
for account_key in message.account_keys.iter() {
|
for account_key in message.account_keys.iter() {
|
||||||
let (account_index, account) = self
|
let account_index = self
|
||||||
.get_account(account_key)
|
.find_index_of_account(account_key)
|
||||||
.ok_or(InstructionError::MissingAccount)?;
|
.ok_or(InstructionError::MissingAccount)?;
|
||||||
let account_length = account.borrow().data().len();
|
let account_length = self.accounts[account_index].1.borrow().data().len();
|
||||||
account_indices.push(account_index);
|
account_indices.push(account_index);
|
||||||
prev_account_sizes.push((account, account_length));
|
prev_account_sizes.push((account_index, account_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(instruction_recorder) = &self.instruction_recorder {
|
if let Some(instruction_recorder) = &self.instruction_recorder {
|
||||||
|
@ -510,8 +510,10 @@ impl<'a> InvokeContext<'a> {
|
||||||
|
|
||||||
// Verify the called program has not misbehaved
|
// Verify the called program has not misbehaved
|
||||||
let do_support_realloc = self.feature_set.is_active(&do_support_realloc::id());
|
let do_support_realloc = self.feature_set.is_active(&do_support_realloc::id());
|
||||||
for (account, prev_size) in prev_account_sizes.iter() {
|
for (account_index, prev_size) in prev_account_sizes.into_iter() {
|
||||||
if !do_support_realloc && *prev_size != account.borrow().data().len() && *prev_size != 0
|
if !do_support_realloc
|
||||||
|
&& prev_size != self.accounts[account_index].1.borrow().data().len()
|
||||||
|
&& prev_size != 0
|
||||||
{
|
{
|
||||||
// Only support for `CreateAccount` at this time.
|
// Only support for `CreateAccount` at this time.
|
||||||
// Need a way to limit total realloc size across multiple CPI calls
|
// Need a way to limit total realloc size across multiple CPI calls
|
||||||
|
@ -595,26 +597,27 @@ impl<'a> InvokeContext<'a> {
|
||||||
|
|
||||||
// Find and validate executables / program accounts
|
// Find and validate executables / program accounts
|
||||||
let callee_program_id = instruction.program_id;
|
let callee_program_id = instruction.program_id;
|
||||||
let (program_account_index, program_account) = callee_keyed_accounts
|
let program_account_index = callee_keyed_accounts
|
||||||
.iter()
|
.iter()
|
||||||
.find(|keyed_account| &callee_program_id == keyed_account.unsigned_key())
|
.find(|keyed_account| &callee_program_id == keyed_account.unsigned_key())
|
||||||
.and_then(|_keyed_account| self.get_account(&callee_program_id))
|
.and_then(|_keyed_account| self.find_index_of_account(&callee_program_id))
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
ic_msg!(self, "Unknown program {}", callee_program_id);
|
ic_msg!(self, "Unknown program {}", callee_program_id);
|
||||||
InstructionError::MissingAccount
|
InstructionError::MissingAccount
|
||||||
})?;
|
})?;
|
||||||
if !program_account.borrow().executable() {
|
let program_account = self.accounts[program_account_index].1.borrow();
|
||||||
|
if !program_account.executable() {
|
||||||
ic_msg!(self, "Account {} is not executable", callee_program_id);
|
ic_msg!(self, "Account {} is not executable", callee_program_id);
|
||||||
return Err(InstructionError::AccountNotExecutable);
|
return Err(InstructionError::AccountNotExecutable);
|
||||||
}
|
}
|
||||||
let mut program_indices = vec![];
|
let mut program_indices = vec![];
|
||||||
if program_account.borrow().owner() == &bpf_loader_upgradeable::id() {
|
if program_account.owner() == &bpf_loader_upgradeable::id() {
|
||||||
if let UpgradeableLoaderState::Program {
|
if let UpgradeableLoaderState::Program {
|
||||||
programdata_address,
|
programdata_address,
|
||||||
} = program_account.borrow().state()?
|
} = program_account.state()?
|
||||||
{
|
{
|
||||||
if let Some((programdata_account_index, _programdata_account)) =
|
if let Some(programdata_account_index) =
|
||||||
self.get_account(&programdata_address)
|
self.find_index_of_account(&programdata_address)
|
||||||
{
|
{
|
||||||
program_indices.push(programdata_account_index);
|
program_indices.push(programdata_account_index);
|
||||||
} else {
|
} else {
|
||||||
|
@ -797,16 +800,21 @@ impl<'a> InvokeContext<'a> {
|
||||||
self.executors.borrow().get(pubkey)
|
self.executors.borrow().get(pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find an account_index and account by its key
|
/// Finds an account_index by its key
|
||||||
pub fn get_account(&self, pubkey: &Pubkey) -> Option<(usize, Rc<RefCell<AccountSharedData>>)> {
|
pub fn find_index_of_account(&self, pubkey: &Pubkey) -> Option<usize> {
|
||||||
for (index, (key, account)) in self.accounts.iter().enumerate().rev() {
|
for (index, (key, _account)) in self.accounts.iter().enumerate().rev() {
|
||||||
if key == pubkey {
|
if key == pubkey {
|
||||||
return Some((index, account.clone()));
|
return Some(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an account by its account_index
|
||||||
|
pub fn get_account_at_index(&self, account_index: usize) -> &RefCell<AccountSharedData> {
|
||||||
|
&self.accounts[account_index].1
|
||||||
|
}
|
||||||
|
|
||||||
/// Get this invocation's compute budget
|
/// Get this invocation's compute budget
|
||||||
pub fn get_compute_budget(&self) -> &ComputeBudget {
|
pub fn get_compute_budget(&self) -> &ComputeBudget {
|
||||||
&self.current_compute_budget
|
&self.current_compute_budget
|
||||||
|
|
|
@ -8,11 +8,7 @@ use {
|
||||||
system_instruction::MAX_PERMITTED_DATA_LENGTH,
|
system_instruction::MAX_PERMITTED_DATA_LENGTH,
|
||||||
system_program,
|
system_program,
|
||||||
},
|
},
|
||||||
std::{
|
std::fmt::Debug,
|
||||||
cell::{Ref, RefCell},
|
|
||||||
fmt::Debug,
|
|
||||||
rc::Rc,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The relevant state of an account before an Instruction executes, used
|
// The relevant state of an account before an Instruction executes, used
|
||||||
|
@ -20,14 +16,14 @@ use {
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct PreAccount {
|
pub struct PreAccount {
|
||||||
key: Pubkey,
|
key: Pubkey,
|
||||||
account: Rc<RefCell<AccountSharedData>>,
|
account: AccountSharedData,
|
||||||
changed: bool,
|
changed: bool,
|
||||||
}
|
}
|
||||||
impl PreAccount {
|
impl PreAccount {
|
||||||
pub fn new(key: &Pubkey, account: &AccountSharedData) -> Self {
|
pub fn new(key: &Pubkey, account: AccountSharedData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key: *key,
|
key: *key,
|
||||||
account: Rc::new(RefCell::new(account.clone())),
|
account,
|
||||||
changed: false,
|
changed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +38,7 @@ impl PreAccount {
|
||||||
outermost_call: bool,
|
outermost_call: bool,
|
||||||
do_support_realloc: bool,
|
do_support_realloc: bool,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let pre = self.account.borrow();
|
let pre = &self.account;
|
||||||
|
|
||||||
// Only the owner of the account may change owner and
|
// Only the owner of the account may change owner and
|
||||||
// only if the account is writable and
|
// only if the account is writable and
|
||||||
|
@ -157,11 +153,10 @@ impl PreAccount {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, account: &AccountSharedData) {
|
pub fn update(&mut self, account: AccountSharedData) {
|
||||||
let mut pre = self.account.borrow_mut();
|
let rent_epoch = self.account.rent_epoch();
|
||||||
let rent_epoch = pre.rent_epoch();
|
self.account = account;
|
||||||
*pre = account.clone();
|
self.account.set_rent_epoch(rent_epoch);
|
||||||
pre.set_rent_epoch(rent_epoch);
|
|
||||||
|
|
||||||
self.changed = true;
|
self.changed = true;
|
||||||
}
|
}
|
||||||
|
@ -170,16 +165,16 @@ impl PreAccount {
|
||||||
&self.key
|
&self.key
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(&self) -> Ref<[u8]> {
|
pub fn data(&self) -> &[u8] {
|
||||||
Ref::map(self.account.borrow(), |account| account.data())
|
self.account.data()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lamports(&self) -> u64 {
|
pub fn lamports(&self) -> u64 {
|
||||||
self.account.borrow().lamports()
|
self.account.lamports()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn executable(&self) -> bool {
|
pub fn executable(&self) -> bool {
|
||||||
self.account.borrow().executable()
|
self.account.executable()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_zeroed(buf: &[u8]) -> bool {
|
pub fn is_zeroed(buf: &[u8]) -> bool {
|
||||||
|
@ -236,10 +231,9 @@ mod tests {
|
||||||
is_writable: true,
|
is_writable: true,
|
||||||
pre: PreAccount::new(
|
pre: PreAccount::new(
|
||||||
&solana_sdk::pubkey::new_rand(),
|
&solana_sdk::pubkey::new_rand(),
|
||||||
&AccountSharedData::from(Account {
|
AccountSharedData::from(Account {
|
||||||
owner: *owner,
|
owner: *owner,
|
||||||
lamports: std::u64::MAX,
|
lamports: std::u64::MAX,
|
||||||
data: vec![],
|
|
||||||
..Account::default()
|
..Account::default()
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -255,12 +249,12 @@ mod tests {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn executable(mut self, pre: bool, post: bool) -> Self {
|
pub fn executable(mut self, pre: bool, post: bool) -> Self {
|
||||||
self.pre.account.borrow_mut().set_executable(pre);
|
self.pre.account.set_executable(pre);
|
||||||
self.post.set_executable(post);
|
self.post.set_executable(post);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn lamports(mut self, pre: u64, post: u64) -> Self {
|
pub fn lamports(mut self, pre: u64, post: u64) -> Self {
|
||||||
self.pre.account.borrow_mut().set_lamports(pre);
|
self.pre.account.set_lamports(pre);
|
||||||
self.post.set_lamports(post);
|
self.post.set_lamports(post);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -269,12 +263,12 @@ mod tests {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn data(mut self, pre: Vec<u8>, post: Vec<u8>) -> Self {
|
pub fn data(mut self, pre: Vec<u8>, post: Vec<u8>) -> Self {
|
||||||
self.pre.account.borrow_mut().set_data(pre);
|
self.pre.account.set_data(pre);
|
||||||
self.post.set_data(post);
|
self.post.set_data(post);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn rent_epoch(mut self, pre: u64, post: u64) -> Self {
|
pub fn rent_epoch(mut self, pre: u64, post: u64) -> Self {
|
||||||
self.pre.account.borrow_mut().set_rent_epoch(pre);
|
self.pre.account.set_rent_epoch(pre);
|
||||||
self.post.set_rent_epoch(post);
|
self.post.set_rent_epoch(post);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,8 +261,8 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
|
||||||
let mut account_indices = Vec::with_capacity(message.account_keys.len());
|
let mut account_indices = Vec::with_capacity(message.account_keys.len());
|
||||||
let mut accounts = Vec::with_capacity(message.account_keys.len());
|
let mut accounts = Vec::with_capacity(message.account_keys.len());
|
||||||
for (i, account_key) in message.account_keys.iter().enumerate() {
|
for (i, account_key) in message.account_keys.iter().enumerate() {
|
||||||
let ((account_index, account), account_info) = invoke_context
|
let (account_index, account_info) = invoke_context
|
||||||
.get_account(account_key)
|
.find_index_of_account(account_key)
|
||||||
.zip(
|
.zip(
|
||||||
account_infos
|
account_infos
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -271,7 +271,9 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
|
||||||
.ok_or(InstructionError::MissingAccount)
|
.ok_or(InstructionError::MissingAccount)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
{
|
{
|
||||||
let mut account = account.borrow_mut();
|
let mut account = invoke_context
|
||||||
|
.get_account_at_index(account_index)
|
||||||
|
.borrow_mut();
|
||||||
account.copy_into_owner_from_slice(account_info.owner.as_ref());
|
account.copy_into_owner_from_slice(account_info.owner.as_ref());
|
||||||
account.set_data_from_slice(&account_info.try_borrow_data().unwrap());
|
account.set_data_from_slice(&account_info.try_borrow_data().unwrap());
|
||||||
account.set_lamports(account_info.lamports());
|
account.set_lamports(account_info.lamports());
|
||||||
|
@ -284,10 +286,9 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
account_indices.push(account_index);
|
account_indices.push(account_index);
|
||||||
accounts.push((account, account_info));
|
accounts.push((account_index, account_info));
|
||||||
}
|
}
|
||||||
let (program_account_index, _program_account) =
|
let program_account_index = invoke_context.find_index_of_account(&program_id).unwrap();
|
||||||
invoke_context.get_account(&program_id).unwrap();
|
|
||||||
let program_indices = vec![program_account_index];
|
let program_indices = vec![program_account_index];
|
||||||
|
|
||||||
// Check Signers
|
// Check Signers
|
||||||
|
@ -329,19 +330,20 @@ 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 (account, account_info) in accounts.iter() {
|
for (account_index, account_info) in accounts.into_iter() {
|
||||||
if let Some(account_info) = account_info {
|
if let Some(account_info) = account_info {
|
||||||
**account_info.try_borrow_mut_lamports().unwrap() = account.borrow().lamports();
|
let account = invoke_context.get_account_at_index(account_index);
|
||||||
let mut data = account_info.try_borrow_mut_data()?;
|
|
||||||
let account_borrow = account.borrow();
|
let account_borrow = account.borrow();
|
||||||
|
**account_info.try_borrow_mut_lamports().unwrap() = account_borrow.lamports();
|
||||||
|
let mut data = account_info.try_borrow_mut_data()?;
|
||||||
let new_data = account_borrow.data();
|
let new_data = account_borrow.data();
|
||||||
if account_info.owner != account.borrow().owner() {
|
if account_info.owner != account_borrow.owner() {
|
||||||
// TODO Figure out a better way to allow the System Program to set the account owner
|
// TODO Figure out a better way to allow the System Program to set the account owner
|
||||||
#[allow(clippy::transmute_ptr_to_ptr)]
|
#[allow(clippy::transmute_ptr_to_ptr)]
|
||||||
#[allow(mutable_transmutes)]
|
#[allow(mutable_transmutes)]
|
||||||
let account_info_mut =
|
let account_info_mut =
|
||||||
unsafe { transmute::<&Pubkey, &mut Pubkey>(account_info.owner) };
|
unsafe { transmute::<&Pubkey, &mut Pubkey>(account_info.owner) };
|
||||||
*account_info_mut = *account.borrow().owner();
|
*account_info_mut = *account_borrow.owner();
|
||||||
}
|
}
|
||||||
// TODO: Figure out how to allow the System Program to resize the account data
|
// TODO: Figure out how to allow the System Program to resize the account data
|
||||||
assert!(
|
assert!(
|
||||||
|
|
|
@ -17,7 +17,7 @@ use {
|
||||||
vm::{EbpfVm, SyscallObject, SyscallRegistry},
|
vm::{EbpfVm, SyscallObject, SyscallRegistry},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{AccountSharedData, ReadableAccount, WritableAccount},
|
account::{ReadableAccount, WritableAccount},
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
blake3, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
|
blake3, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
|
||||||
clock::Clock,
|
clock::Clock,
|
||||||
|
@ -1667,10 +1667,7 @@ struct CallerAccount<'a> {
|
||||||
executable: bool,
|
executable: bool,
|
||||||
rent_epoch: u64,
|
rent_epoch: u64,
|
||||||
}
|
}
|
||||||
type TranslatedAccounts<'a> = (
|
type TranslatedAccounts<'a> = (Vec<usize>, Vec<(usize, Option<CallerAccount<'a>>)>);
|
||||||
Vec<usize>,
|
|
||||||
Vec<(Rc<RefCell<AccountSharedData>>, Option<CallerAccount<'a>>)>,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Implemented by language specific data structure translators
|
/// Implemented by language specific data structure translators
|
||||||
trait SyscallInvokeSigned<'a, 'b> {
|
trait SyscallInvokeSigned<'a, 'b> {
|
||||||
|
@ -2210,13 +2207,14 @@ where
|
||||||
let mut account_indices = Vec::with_capacity(message.account_keys.len());
|
let mut account_indices = Vec::with_capacity(message.account_keys.len());
|
||||||
let mut accounts = Vec::with_capacity(message.account_keys.len());
|
let mut accounts = Vec::with_capacity(message.account_keys.len());
|
||||||
for (i, account_key) in message.account_keys.iter().enumerate() {
|
for (i, account_key) in message.account_keys.iter().enumerate() {
|
||||||
if let Some((account_index, account)) = invoke_context.get_account(account_key) {
|
if let Some(account_index) = invoke_context.find_index_of_account(account_key) {
|
||||||
|
let account = invoke_context.get_account_at_index(account_index);
|
||||||
if i == message.instructions[0].program_id_index as usize
|
if i == message.instructions[0].program_id_index as usize
|
||||||
|| account.borrow().executable()
|
|| account.borrow().executable()
|
||||||
{
|
{
|
||||||
// Use the known account
|
// Use the known account
|
||||||
account_indices.push(account_index);
|
account_indices.push(account_index);
|
||||||
accounts.push((account, None));
|
accounts.push((account_index, None));
|
||||||
continue;
|
continue;
|
||||||
} else if let Some(caller_account_index) =
|
} else if let Some(caller_account_index) =
|
||||||
account_info_keys.iter().position(|key| *key == account_key)
|
account_info_keys.iter().position(|key| *key == account_key)
|
||||||
|
@ -2265,7 +2263,7 @@ where
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
account_indices.push(account_index);
|
account_indices.push(account_index);
|
||||||
accounts.push((account, caller_account));
|
accounts.push((account_index, caller_account));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2400,9 +2398,11 @@ fn call<'a, 'b: 'a>(
|
||||||
.map_err(SyscallError::InstructionError)?;
|
.map_err(SyscallError::InstructionError)?;
|
||||||
|
|
||||||
// Copy results back to caller
|
// Copy results back to caller
|
||||||
for (callee_account, caller_account) in accounts.iter_mut() {
|
for (callee_account_index, caller_account) in accounts.iter_mut() {
|
||||||
if let Some(caller_account) = caller_account {
|
if let Some(caller_account) = caller_account {
|
||||||
let callee_account = callee_account.borrow();
|
let callee_account = invoke_context
|
||||||
|
.get_account_at_index(*callee_account_index)
|
||||||
|
.borrow();
|
||||||
*caller_account.lamports = callee_account.lamports();
|
*caller_account.lamports = callee_account.lamports();
|
||||||
*caller_account.owner = *callee_account.owner();
|
*caller_account.owner = *callee_account.owner();
|
||||||
let new_len = callee_account.data().len();
|
let new_len = callee_account.data().len();
|
||||||
|
@ -2672,7 +2672,9 @@ mod tests {
|
||||||
solana_rbpf::{
|
solana_rbpf::{
|
||||||
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
|
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
|
||||||
},
|
},
|
||||||
solana_sdk::{bpf_loader, fee_calculator::FeeCalculator, hash::hashv},
|
solana_sdk::{
|
||||||
|
account::AccountSharedData, bpf_loader, fee_calculator::FeeCalculator, hash::hashv,
|
||||||
|
},
|
||||||
std::str::FromStr,
|
std::str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue