Remove the deprecated `KeyedAccount` interface (#27147)

* Removes the deprecated KeyedAccount interface.

* Removes outdated example code.
This commit is contained in:
Alexander Meißner 2022-08-15 20:41:46 +02:00 committed by GitHub
parent b6762fc2f9
commit f61f63c19b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1 additions and 406 deletions

View File

@ -1,5 +1,3 @@
#[allow(deprecated)]
use solana_sdk::keyed_account::{create_keyed_accounts_unified, KeyedAccount};
use {
crate::{
accounts_data_meter::AccountsDataMeter,
@ -175,38 +173,6 @@ impl fmt::Display for AllocErr {
}
}
#[deprecated(
since = "1.11.0",
note = "Please use InstructionContext instead of StackFrame"
)]
#[allow(deprecated)]
pub struct StackFrame<'a> {
pub number_of_program_accounts: usize,
pub keyed_accounts: Vec<KeyedAccount<'a>>,
pub keyed_accounts_range: std::ops::Range<usize>,
}
#[allow(deprecated)]
impl<'a> StackFrame<'a> {
pub fn new(number_of_program_accounts: usize, keyed_accounts: Vec<KeyedAccount<'a>>) -> Self {
let keyed_accounts_range = std::ops::Range {
start: 0,
end: keyed_accounts.len(),
};
Self {
number_of_program_accounts,
keyed_accounts,
keyed_accounts_range,
}
}
pub fn program_id(&self) -> Option<&Pubkey> {
self.keyed_accounts
.get(self.number_of_program_accounts.saturating_sub(1))
.map(|keyed_account| keyed_account.unsigned_key())
}
}
struct SyscallContext {
check_aligned: bool,
check_size: bool,
@ -216,8 +182,6 @@ struct SyscallContext {
pub struct InvokeContext<'a> {
pub transaction_context: &'a mut TransactionContext,
#[allow(deprecated)]
invoke_stack: Vec<StackFrame<'a>>,
rent: Rent,
pre_accounts: Vec<PreAccount>,
builtin_programs: &'a [BuiltinProgram],
@ -252,7 +216,6 @@ impl<'a> InvokeContext<'a> {
) -> Self {
Self {
transaction_context,
invoke_stack: Vec::with_capacity(compute_budget.max_invoke_depth),
rent,
pre_accounts: Vec::new(),
builtin_programs,
@ -384,40 +347,6 @@ impl<'a> InvokeContext<'a> {
}
}
// Create the KeyedAccounts that will be passed to the program
#[allow(deprecated)]
let keyed_accounts = program_indices
.iter()
.map(|account_index| {
Ok((
false,
false,
self.transaction_context
.get_key_of_account_at_index(*account_index)?,
self.transaction_context
.get_account_at_index(*account_index)?,
))
})
.chain(instruction_accounts.iter().map(|instruction_account| {
Ok((
instruction_account.is_signer,
instruction_account.is_writable,
self.transaction_context
.get_key_of_account_at_index(instruction_account.index_in_transaction)?,
self.transaction_context
.get_account_at_index(instruction_account.index_in_transaction)?,
))
}))
.collect::<Result<Vec<_>, InstructionError>>()?;
// Unsafe will be removed together with the keyed_accounts
#[allow(deprecated)]
self.invoke_stack.push(StackFrame::new(
program_indices.len(),
create_keyed_accounts_unified(unsafe {
std::mem::transmute(keyed_accounts.as_slice())
}),
));
self.syscall_context.push(None);
self.transaction_context
.push(program_indices, instruction_accounts, instruction_data)
@ -426,7 +355,6 @@ impl<'a> InvokeContext<'a> {
/// Pop a stack frame from the invocation stack
pub fn pop(&mut self) -> Result<(), InstructionError> {
self.syscall_context.pop();
self.invoke_stack.pop();
self.transaction_context.pop()
}
@ -915,19 +843,6 @@ impl<'a> InvokeContext<'a> {
Err(InstructionError::UnsupportedProgramId)
}
#[deprecated(
since = "1.11.0",
note = "Please use BorrowedAccount instead of KeyedAccount"
)]
#[allow(deprecated)]
/// Get the list of keyed accounts including the chain of program accounts
pub fn get_keyed_accounts(&self) -> Result<&[KeyedAccount], InstructionError> {
self.invoke_stack
.last()
.and_then(|frame| frame.keyed_accounts.get(frame.keyed_accounts_range.clone()))
.ok_or(InstructionError::CallDepth)
}
/// Get this invocation's LogCollector
pub fn get_log_collector(&self) -> Option<Rc<RefCell<LogCollector>>> {
self.log_collector.clone()

View File

@ -65,67 +65,6 @@ macro_rules! declare_builtin_name {
/// entrypoint: Program's entrypoint, must be of `type Entrypoint`
/// id: Path to the program id access function, used if this macro is not
/// called in `src/lib`
///
/// # Examples
///
/// ```
/// use std::str::FromStr;
/// // wrapper is used so that the macro invocation occurs in the item position
/// // rather than in the statement position which isn't allowed.
/// mod item_wrapper {
/// use solana_sdk::keyed_account::KeyedAccount;
/// use solana_sdk::instruction::InstructionError;
/// use solana_sdk::pubkey::Pubkey;
/// use solana_sdk::declare_builtin;
///
/// fn my_process_instruction(
/// first_instruction_account: usize,
/// keyed_accounts: &[KeyedAccount],
/// ) -> Result<(), InstructionError> {
/// // Process an instruction
/// Ok(())
/// }
///
/// declare_builtin!(
/// "My11111111111111111111111111111111111111111",
/// solana_my_program,
/// my_process_instruction
/// );
///
/// # }
/// # use solana_sdk::pubkey::Pubkey;
/// # use item_wrapper::id;
/// let my_id = Pubkey::from_str("My11111111111111111111111111111111111111111").unwrap();
/// assert_eq!(id(), my_id);
/// ```
/// ```
/// use std::str::FromStr;
/// # // wrapper is used so that the macro invocation occurs in the item position
/// # // rather than in the statement position which isn't allowed.
/// # mod item_wrapper {
/// use solana_sdk::keyed_account::KeyedAccount;
/// use solana_sdk::instruction::InstructionError;
/// use solana_sdk::pubkey::Pubkey;
/// use solana_sdk::declare_builtin;
///
/// fn my_process_instruction(
/// first_instruction_account: usize,
/// keyed_accounts: &[KeyedAccount],
/// ) -> Result<(), InstructionError> {
/// // Process an instruction
/// Ok(())
/// }
///
/// declare_builtin!(
/// solana_sdk::system_program::ID,
/// solana_my_program,
/// my_process_instruction
/// );
/// }
///
/// # use item_wrapper::id;
/// assert_eq!(id(), solana_sdk::system_program::ID);
/// ```
#[macro_export]
macro_rules! declare_builtin {
($bs58_string:expr, $name:ident, $entrypoint:expr) => {

View File

@ -1,258 +0,0 @@
#![deprecated(
since = "1.11.0",
note = "Please use BorrowedAccount instead of KeyedAccount"
)]
#![allow(deprecated)]
use {
crate::{
account::{AccountSharedData, ReadableAccount},
account_utils::{State, StateMut},
},
solana_program::{clock::Epoch, instruction::InstructionError, pubkey::Pubkey},
std::{
cell::{Ref, RefCell, RefMut},
iter::FromIterator,
rc::Rc,
},
};
#[repr(C)]
#[derive(Debug, Clone)]
pub struct KeyedAccount<'a> {
is_signer: bool, // Transaction was signed by this account's key
is_writable: bool,
key: &'a Pubkey,
pub account: &'a RefCell<AccountSharedData>,
}
impl<'a> KeyedAccount<'a> {
pub fn signer_key(&self) -> Option<&Pubkey> {
if self.is_signer {
Some(self.key)
} else {
None
}
}
pub fn unsigned_key(&self) -> &Pubkey {
self.key
}
pub fn is_writable(&self) -> bool {
self.is_writable
}
pub fn lamports(&self) -> Result<u64, InstructionError> {
Ok(self.try_borrow()?.lamports())
}
pub fn data_len(&self) -> Result<usize, InstructionError> {
Ok(self.try_borrow()?.data().len())
}
pub fn data_is_empty(&self) -> Result<bool, InstructionError> {
Ok(self.try_borrow()?.data().is_empty())
}
pub fn owner(&self) -> Result<Pubkey, InstructionError> {
Ok(*self.try_borrow()?.owner())
}
pub fn executable(&self) -> Result<bool, InstructionError> {
Ok(self.try_borrow()?.executable())
}
pub fn rent_epoch(&self) -> Result<Epoch, InstructionError> {
Ok(self.try_borrow()?.rent_epoch())
}
pub fn try_account_ref(&'a self) -> Result<Ref<AccountSharedData>, InstructionError> {
self.try_borrow()
}
pub fn try_account_ref_mut(&'a self) -> Result<RefMut<AccountSharedData>, InstructionError> {
self.try_borrow_mut()
}
fn try_borrow(&self) -> Result<Ref<AccountSharedData>, InstructionError> {
self.account
.try_borrow()
.map_err(|_| InstructionError::AccountBorrowFailed)
}
fn try_borrow_mut(&self) -> Result<RefMut<AccountSharedData>, InstructionError> {
self.account
.try_borrow_mut()
.map_err(|_| InstructionError::AccountBorrowFailed)
}
pub fn new(key: &'a Pubkey, is_signer: bool, account: &'a RefCell<AccountSharedData>) -> Self {
Self {
is_signer,
is_writable: true,
key,
account,
}
}
pub fn new_readonly(
key: &'a Pubkey,
is_signer: bool,
account: &'a RefCell<AccountSharedData>,
) -> Self {
Self {
is_signer,
is_writable: false,
key,
account,
}
}
}
impl<'a> PartialEq for KeyedAccount<'a> {
fn eq(&self, other: &Self) -> bool {
self.key == other.key
}
}
impl<'a> From<(&'a Pubkey, &'a RefCell<AccountSharedData>)> for KeyedAccount<'a> {
fn from((key, account): (&'a Pubkey, &'a RefCell<AccountSharedData>)) -> Self {
Self {
is_signer: false,
is_writable: true,
key,
account,
}
}
}
impl<'a> From<(&'a Pubkey, bool, &'a RefCell<AccountSharedData>)> for KeyedAccount<'a> {
fn from((key, is_signer, account): (&'a Pubkey, bool, &'a RefCell<AccountSharedData>)) -> Self {
Self {
is_signer,
is_writable: true,
key,
account,
}
}
}
impl<'a> From<&'a (&'a Pubkey, &'a RefCell<AccountSharedData>)> for KeyedAccount<'a> {
fn from((key, account): &'a (&'a Pubkey, &'a RefCell<AccountSharedData>)) -> Self {
Self {
is_signer: false,
is_writable: true,
key,
account,
}
}
}
pub fn create_keyed_accounts<'a>(
accounts: &'a [(&'a Pubkey, &'a RefCell<AccountSharedData>)],
) -> Vec<KeyedAccount<'a>> {
accounts.iter().map(Into::into).collect()
}
#[deprecated(
since = "1.7.0",
note = "Please use create_keyed_accounts_unified instead"
)]
pub fn create_keyed_is_signer_accounts<'a>(
accounts: &'a [(&'a Pubkey, bool, &'a RefCell<AccountSharedData>)],
) -> Vec<KeyedAccount<'a>> {
accounts
.iter()
.map(|(key, is_signer, account)| KeyedAccount {
is_signer: *is_signer,
is_writable: false,
key,
account,
})
.collect()
}
#[deprecated(
since = "1.7.0",
note = "Please use create_keyed_accounts_unified instead"
)]
pub fn create_keyed_readonly_accounts(
accounts: &[(Pubkey, Rc<RefCell<AccountSharedData>>)],
) -> Vec<KeyedAccount> {
accounts
.iter()
.map(|(key, account)| KeyedAccount {
is_signer: false,
is_writable: false,
key,
account,
})
.collect()
}
pub fn create_keyed_accounts_unified<'a>(
accounts: &[(bool, bool, &'a Pubkey, &'a RefCell<AccountSharedData>)],
) -> Vec<KeyedAccount<'a>> {
accounts
.iter()
.map(|(is_signer, is_writable, key, account)| KeyedAccount {
is_signer: *is_signer,
is_writable: *is_writable,
key,
account,
})
.collect()
}
#[deprecated(
since = "1.11.0",
note = "Please use InstructionContext::get_signers() instead"
)]
/// Return all the signers from a set of KeyedAccounts
pub fn get_signers<A>(keyed_accounts: &[KeyedAccount]) -> A
where
A: FromIterator<Pubkey>,
{
keyed_accounts
.iter()
.filter_map(|keyed_account| keyed_account.signer_key())
.cloned()
.collect::<A>()
}
#[deprecated(since = "1.7.0", note = "Please use keyed_account_at_index instead")]
/// Return the next KeyedAccount or a NotEnoughAccountKeys error
pub fn next_keyed_account<'a, 'b, I: Iterator<Item = &'a KeyedAccount<'b>>>(
iter: &mut I,
) -> Result<I::Item, InstructionError> {
iter.next().ok_or(InstructionError::NotEnoughAccountKeys)
}
/// Return the KeyedAccount at the specified index or a NotEnoughAccountKeys error
///
/// Index zero starts at the chain of program accounts, followed by the instruction accounts.
pub fn keyed_account_at_index<'a>(
keyed_accounts: &'a [KeyedAccount],
index: usize,
) -> Result<&'a KeyedAccount<'a>, InstructionError> {
keyed_accounts
.get(index)
.ok_or(InstructionError::NotEnoughAccountKeys)
}
/// Return true if the first keyed_account is executable, used to determine if
/// the loader should call a program's 'main'
pub fn is_executable(keyed_accounts: &[KeyedAccount]) -> Result<bool, InstructionError> {
Ok(!keyed_accounts.is_empty() && keyed_accounts[0].executable()?)
}
impl<'a, T> State<T> for crate::keyed_account::KeyedAccount<'a>
where
T: serde::Serialize + serde::de::DeserializeOwned,
{
fn state(&self) -> Result<T, InstructionError> {
self.try_account_ref()?.state()
}
fn set_state(&self, state: &T) -> Result<(), InstructionError> {
self.try_account_ref_mut()?.set_state(state)
}
}

View File

@ -44,7 +44,6 @@ pub mod genesis_config;
pub mod hard_forks;
pub mod hash;
pub mod inflation;
pub mod keyed_account;
pub mod log;
pub mod native_loader;
pub mod nonce_account;

View File

@ -1,4 +1,4 @@
//! Successors of instruction_context_context::StackFrame, KeyedAccount and AccountInfo
//! Data shared between program runtime and built-in programs as well as SBF programs
use {
crate::{