Refactor stake program into solana_program (#17906)

* Move stake state / instructions into solana_program

* Update account-decoder

* Update cli and runtime

* Update all other parts

* Commit Cargo.lock changes in programs/bpf

* Update cli stake instruction import

* Allow integer arithmetic

* Update ABI digest

* Bump rust mem instruction count

* Remove useless structs

* Move stake::id() -> stake::program::id()

* Re-export from solana_sdk and mark deprecated

* Address feedback

* Run cargo fmt
This commit is contained in:
Jon Cinque
2021-06-15 18:04:00 +02:00
committed by GitHub
parent 36b09db2d1
commit 1b1d34da59
59 changed files with 1765 additions and 1711 deletions

View File

@ -2730,7 +2730,6 @@ dependencies = [
"serde_json",
"solana-config-program",
"solana-sdk",
"solana-stake-program",
"solana-vote-program",
"spl-token",
"thiserror",
@ -3143,7 +3142,6 @@ dependencies = [
"solana-clap-utils",
"solana-client",
"solana-sdk",
"solana-stake-program",
"solana-transaction-status",
"solana-vote-program",
"spl-memo",
@ -3643,7 +3641,6 @@ dependencies = [
"solana-account-decoder",
"solana-runtime",
"solana-sdk",
"solana-stake-program",
"solana-vote-program",
"spl-associated-token-account",
"spl-memo",

View File

@ -1297,7 +1297,7 @@ fn assert_instruction_count() {
("solana_bpf_rust_external_spend", 504),
("solana_bpf_rust_iter", 724),
("solana_bpf_rust_many_args", 233),
("solana_bpf_rust_mem", 3096),
("solana_bpf_rust_mem", 3117),
("solana_bpf_rust_membuiltins", 4065),
("solana_bpf_rust_noop", 478),
("solana_bpf_rust_param_passing", 46),

View File

@ -9,6 +9,7 @@ use solana_sdk::{
account::{Account, AccountSharedData},
pubkey::Pubkey,
short_vec,
stake::config::Config as StakeConfig,
};
solana_sdk::declare_id!("Config1111111111111111111111111111111111111");
@ -18,6 +19,13 @@ pub trait ConfigState: serde::Serialize + Default {
fn max_space() -> u64;
}
// TODO move ConfigState into `solana_program` to implement trait locally
impl ConfigState for StakeConfig {
fn max_space() -> u64 {
serialized_size(&StakeConfig::default()).unwrap()
}
}
/// A collection of keys to be stored in Config account data.
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct ConfigKeys {

View File

@ -1,52 +1,36 @@
//! config for staking
//! carries variables that the stake program cares about
use bincode::{deserialize, serialized_size};
use serde_derive::{Deserialize, Serialize};
use solana_config_program::{create_config_account, get_config_data, ConfigState};
use bincode::deserialize;
use solana_config_program::{create_config_account, get_config_data};
use solana_sdk::{
account::{AccountSharedData, ReadableAccount, WritableAccount},
genesis_config::GenesisConfig,
instruction::InstructionError,
keyed_account::KeyedAccount,
stake::config::{self, Config},
};
// stake config ID
solana_sdk::declare_id!("StakeConfig11111111111111111111111111111111");
#[deprecated(
since = "1.8.0",
note = "Please use `solana_sdk::stake::config` or `solana_program::stake::config` instead"
)]
pub use solana_sdk::stake::config::*;
// means that no more than RATE of current effective stake may be added or subtracted per
// epoch
pub const DEFAULT_WARMUP_COOLDOWN_RATE: f64 = 0.25;
pub const DEFAULT_SLASH_PENALTY: u8 = ((5 * std::u8::MAX as usize) / 100) as u8;
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)]
pub struct Config {
/// how much stake we can activate/deactivate per-epoch as a fraction of currently effective stake
pub warmup_cooldown_rate: f64,
/// percentage of stake lost when slash, expressed as a portion of std::u8::MAX
pub slash_penalty: u8,
pub fn from<T: ReadableAccount>(account: &T) -> Option<Config> {
get_config_data(&account.data())
.ok()
.and_then(|data| deserialize(data).ok())
}
impl Config {
pub fn from<T: ReadableAccount>(account: &T) -> Option<Self> {
get_config_data(&account.data())
.ok()
.and_then(|data| deserialize(data).ok())
pub fn from_keyed_account(account: &KeyedAccount) -> Result<Config, InstructionError> {
if !config::check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
}
from(&*account.try_account_ref()?).ok_or(InstructionError::InvalidArgument)
}
impl Default for Config {
fn default() -> Self {
Self {
warmup_cooldown_rate: DEFAULT_WARMUP_COOLDOWN_RATE,
slash_penalty: DEFAULT_SLASH_PENALTY,
}
}
}
impl ConfigState for Config {
fn max_space() -> u64 {
serialized_size(&Config::default()).unwrap()
}
pub fn create_account(lamports: u64, config: &Config) -> AccountSharedData {
create_config_account(vec![], config, lamports)
}
pub fn add_genesis_account(genesis_config: &mut GenesisConfig) -> u64 {
@ -55,22 +39,11 @@ pub fn add_genesis_account(genesis_config: &mut GenesisConfig) -> u64 {
account.set_lamports(lamports.max(1));
genesis_config.add_account(id(), account);
genesis_config.add_account(config::id(), account);
lamports
}
pub fn create_account(lamports: u64, config: &Config) -> AccountSharedData {
create_config_account(vec![], config, lamports)
}
pub fn from_keyed_account(account: &KeyedAccount) -> Result<Config, InstructionError> {
if !check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
}
Config::from(&*account.try_account_ref()?).ok_or(InstructionError::InvalidArgument)
}
#[cfg(test)]
mod tests {
use super::*;
@ -80,7 +53,7 @@ mod tests {
#[test]
fn test() {
let account = RefCell::new(create_account(0, &Config::default()));
assert_eq!(Config::from(&account.borrow()), Some(Config::default()));
assert_eq!(from(&account.borrow()), Some(Config::default()));
assert_eq!(
from_keyed_account(&KeyedAccount::new(&Pubkey::default(), false, &account)),
Err(InstructionError::InvalidArgument)

View File

@ -2,15 +2,16 @@
#![allow(clippy::integer_arithmetic)]
use solana_sdk::genesis_config::GenesisConfig;
#[deprecated(
since = "1.8.0",
note = "Please use `solana_sdk::stake::program::id` or `solana_program::stake::program::id` instead"
)]
pub use solana_sdk::stake::program::{check_id, id};
pub mod config;
pub mod stake_instruction;
pub mod stake_state;
solana_sdk::declare_id!("Stake11111111111111111111111111111111111111");
pub fn add_genesis_accounts(genesis_config: &mut GenesisConfig) -> u64 {
config::add_genesis_account(genesis_config)
}
#[macro_use]
extern crate solana_frozen_abi_macro;

View File

@ -1,481 +1,23 @@
use crate::{
config, id,
stake_state::{Authorized, Lockup, StakeAccount, StakeAuthorize, StakeState},
use {
crate::{config, stake_state::StakeAccount},
log::*,
solana_sdk::{
feature_set,
instruction::InstructionError,
keyed_account::{from_keyed_account, get_signers, keyed_account_at_index},
process_instruction::{get_sysvar, InvokeContext},
program_utils::limited_deserialize,
pubkey::Pubkey,
stake::{instruction::StakeInstruction, program::id},
sysvar::{self, clock::Clock, rent::Rent, stake_history::StakeHistory},
},
};
use log::*;
use num_derive::{FromPrimitive, ToPrimitive};
use serde_derive::{Deserialize, Serialize};
use solana_sdk::{
clock::{Epoch, UnixTimestamp},
decode_error::DecodeError,
feature_set,
instruction::{AccountMeta, Instruction, InstructionError},
keyed_account::{from_keyed_account, get_signers, keyed_account_at_index},
process_instruction::{get_sysvar, InvokeContext},
program_utils::limited_deserialize,
pubkey::Pubkey,
system_instruction,
sysvar::{self, clock::Clock, rent::Rent, stake_history::StakeHistory},
};
use thiserror::Error;
/// Reasons the stake might have had an error
#[derive(Error, Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)]
pub enum StakeError {
#[error("not enough credits to redeem")]
NoCreditsToRedeem,
#[error("lockup has not yet expired")]
LockupInForce,
#[error("stake already deactivated")]
AlreadyDeactivated,
#[error("one re-delegation permitted per epoch")]
TooSoonToRedelegate,
#[error("split amount is more than is staked")]
InsufficientStake,
#[error("stake account with transient stake cannot be merged")]
MergeTransientStake,
#[error("stake account merge failed due to different authority, lockups or state")]
MergeMismatch,
#[error("custodian address not present")]
CustodianMissing,
#[error("custodian signature not present")]
CustodianSignatureMissing,
}
impl<E> DecodeError<E> for StakeError {
fn type_of() -> &'static str {
"StakeError"
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum StakeInstruction {
/// Initialize a stake with lockup and authorization information
///
/// # Account references
/// 0. [WRITE] Uninitialized stake account
/// 1. [] Rent sysvar
///
/// Authorized carries pubkeys that must sign staker transactions
/// and withdrawer transactions.
/// Lockup carries information about withdrawal restrictions
Initialize(Authorized, Lockup),
/// Authorize a key to manage stake or withdrawal
///
/// # Account references
/// 0. [WRITE] Stake account to be updated
/// 1. [] Clock sysvar
/// 2. [SIGNER] The stake or withdraw authority
/// 3. Optional: [SIGNER] Lockup authority, if updating StakeAuthorize::Withdrawer before
/// lockup expiration
Authorize(Pubkey, StakeAuthorize),
/// Delegate a stake to a particular vote account
///
/// # Account references
/// 0. [WRITE] Initialized stake account to be delegated
/// 1. [] Vote account to which this stake will be delegated
/// 2. [] Clock sysvar
/// 3. [] Stake history sysvar that carries stake warmup/cooldown history
/// 4. [] Address of config account that carries stake config
/// 5. [SIGNER] Stake authority
///
/// The entire balance of the staking account is staked. DelegateStake
/// can be called multiple times, but re-delegation is delayed
/// by one epoch
DelegateStake,
/// Split u64 tokens and stake off a stake account into another stake account.
///
/// # Account references
/// 0. [WRITE] Stake account to be split; must be in the Initialized or Stake state
/// 1. [WRITE] Uninitialized stake account that will take the split-off amount
/// 2. [SIGNER] Stake authority
Split(u64),
/// Withdraw unstaked lamports from the stake account
///
/// # Account references
/// 0. [WRITE] Stake account from which to withdraw
/// 1. [WRITE] Recipient account
/// 2. [] Clock sysvar
/// 3. [] Stake history sysvar that carries stake warmup/cooldown history
/// 4. [SIGNER] Withdraw authority
/// 5. Optional: [SIGNER] Lockup authority, if before lockup expiration
///
/// The u64 is the portion of the stake account balance to be withdrawn,
/// must be `<= StakeAccount.lamports - staked_lamports`.
Withdraw(u64),
/// Deactivates the stake in the account
///
/// # Account references
/// 0. [WRITE] Delegated stake account
/// 1. [] Clock sysvar
/// 2. [SIGNER] Stake authority
Deactivate,
/// Set stake lockup
///
/// If a lockup is not active, the withdraw authority may set a new lockup
/// If a lockup is active, the lockup custodian may update the lockup parameters
///
/// # Account references
/// 0. [WRITE] Initialized stake account
/// 1. [SIGNER] Lockup authority or withdraw authority
SetLockup(LockupArgs),
/// Merge two stake accounts.
///
/// Both accounts must have identical lockup and authority keys. A merge
/// is possible between two stakes in the following states with no additional
/// conditions:
///
/// * two deactivated stakes
/// * an inactive stake into an activating stake during its activation epoch
///
/// For the following cases, the voter pubkey and vote credits observed must match:
///
/// * two activated stakes
/// * two activating accounts that share an activation epoch, during the activation epoch
///
/// All other combinations of stake states will fail to merge, including all
/// "transient" states, where a stake is activating or deactivating with a
/// non-zero effective stake.
///
/// # Account references
/// 0. [WRITE] Destination stake account for the merge
/// 1. [WRITE] Source stake account for to merge. This account will be drained
/// 2. [] Clock sysvar
/// 3. [] Stake history sysvar that carries stake warmup/cooldown history
/// 4. [SIGNER] Stake authority
Merge,
/// Authorize a key to manage stake or withdrawal with a derived key
///
/// # Account references
/// 0. [WRITE] Stake account to be updated
/// 1. [SIGNER] Base key of stake or withdraw authority
/// 2. [] Clock sysvar
/// 3. Optional: [SIGNER] Lockup authority, if updating StakeAuthorize::Withdrawer before
/// lockup expiration
AuthorizeWithSeed(AuthorizeWithSeedArgs),
}
#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
pub struct LockupArgs {
pub unix_timestamp: Option<UnixTimestamp>,
pub epoch: Option<Epoch>,
pub custodian: Option<Pubkey>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct AuthorizeWithSeedArgs {
pub new_authorized_pubkey: Pubkey,
pub stake_authorize: StakeAuthorize,
pub authority_seed: String,
pub authority_owner: Pubkey,
}
pub fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) -> Instruction {
Instruction::new_with_bincode(
id(),
&StakeInstruction::Initialize(*authorized, *lockup),
vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new_readonly(sysvar::rent::id(), false),
],
)
}
pub fn create_account_with_seed(
from_pubkey: &Pubkey,
stake_pubkey: &Pubkey,
base: &Pubkey,
seed: &str,
authorized: &Authorized,
lockup: &Lockup,
lamports: u64,
) -> Vec<Instruction> {
vec![
system_instruction::create_account_with_seed(
from_pubkey,
stake_pubkey,
base,
seed,
lamports,
std::mem::size_of::<StakeState>() as u64,
&id(),
),
initialize(stake_pubkey, authorized, lockup),
]
}
pub fn create_account(
from_pubkey: &Pubkey,
stake_pubkey: &Pubkey,
authorized: &Authorized,
lockup: &Lockup,
lamports: u64,
) -> Vec<Instruction> {
vec![
system_instruction::create_account(
from_pubkey,
stake_pubkey,
lamports,
std::mem::size_of::<StakeState>() as u64,
&id(),
),
initialize(stake_pubkey, authorized, lockup),
]
}
fn _split(
stake_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
lamports: u64,
split_stake_pubkey: &Pubkey,
) -> Instruction {
let account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new(*split_stake_pubkey, false),
AccountMeta::new_readonly(*authorized_pubkey, true),
];
Instruction::new_with_bincode(id(), &StakeInstruction::Split(lamports), account_metas)
}
pub fn split(
stake_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
lamports: u64,
split_stake_pubkey: &Pubkey,
) -> Vec<Instruction> {
vec![
system_instruction::allocate(split_stake_pubkey, std::mem::size_of::<StakeState>() as u64),
system_instruction::assign(split_stake_pubkey, &id()),
_split(
stake_pubkey,
authorized_pubkey,
lamports,
split_stake_pubkey,
),
]
}
pub fn split_with_seed(
stake_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
lamports: u64,
split_stake_pubkey: &Pubkey, // derived using create_with_seed()
base: &Pubkey, // base
seed: &str, // seed
) -> Vec<Instruction> {
vec![
system_instruction::allocate_with_seed(
split_stake_pubkey,
base,
seed,
std::mem::size_of::<StakeState>() as u64,
&id(),
),
_split(
stake_pubkey,
authorized_pubkey,
lamports,
split_stake_pubkey,
),
]
}
pub fn merge(
destination_stake_pubkey: &Pubkey,
source_stake_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
) -> Vec<Instruction> {
let account_metas = vec![
AccountMeta::new(*destination_stake_pubkey, false),
AccountMeta::new(*source_stake_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(*authorized_pubkey, true),
];
vec![Instruction::new_with_bincode(
id(),
&StakeInstruction::Merge,
account_metas,
)]
}
pub fn create_account_and_delegate_stake(
from_pubkey: &Pubkey,
stake_pubkey: &Pubkey,
vote_pubkey: &Pubkey,
authorized: &Authorized,
lockup: &Lockup,
lamports: u64,
) -> Vec<Instruction> {
let mut instructions = create_account(from_pubkey, stake_pubkey, authorized, lockup, lamports);
instructions.push(delegate_stake(
stake_pubkey,
&authorized.staker,
vote_pubkey,
));
instructions
}
pub fn create_account_with_seed_and_delegate_stake(
from_pubkey: &Pubkey,
stake_pubkey: &Pubkey,
base: &Pubkey,
seed: &str,
vote_pubkey: &Pubkey,
authorized: &Authorized,
lockup: &Lockup,
lamports: u64,
) -> Vec<Instruction> {
let mut instructions = create_account_with_seed(
from_pubkey,
stake_pubkey,
base,
seed,
authorized,
lockup,
lamports,
);
instructions.push(delegate_stake(
stake_pubkey,
&authorized.staker,
vote_pubkey,
));
instructions
}
pub fn authorize(
stake_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
new_authorized_pubkey: &Pubkey,
stake_authorize: StakeAuthorize,
custodian_pubkey: Option<&Pubkey>,
) -> Instruction {
let mut account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(*authorized_pubkey, true),
];
if let Some(custodian_pubkey) = custodian_pubkey {
account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
}
Instruction::new_with_bincode(
id(),
&StakeInstruction::Authorize(*new_authorized_pubkey, stake_authorize),
account_metas,
)
}
pub fn authorize_with_seed(
stake_pubkey: &Pubkey,
authority_base: &Pubkey,
authority_seed: String,
authority_owner: &Pubkey,
new_authorized_pubkey: &Pubkey,
stake_authorize: StakeAuthorize,
custodian_pubkey: Option<&Pubkey>,
) -> Instruction {
let mut account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new_readonly(*authority_base, true),
AccountMeta::new_readonly(sysvar::clock::id(), false),
];
if let Some(custodian_pubkey) = custodian_pubkey {
account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
}
let args = AuthorizeWithSeedArgs {
new_authorized_pubkey: *new_authorized_pubkey,
stake_authorize,
authority_seed,
authority_owner: *authority_owner,
};
Instruction::new_with_bincode(
id(),
&StakeInstruction::AuthorizeWithSeed(args),
account_metas,
)
}
pub fn delegate_stake(
stake_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
vote_pubkey: &Pubkey,
) -> Instruction {
let account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new_readonly(*vote_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(crate::config::id(), false),
AccountMeta::new_readonly(*authorized_pubkey, true),
];
Instruction::new_with_bincode(id(), &StakeInstruction::DelegateStake, account_metas)
}
pub fn withdraw(
stake_pubkey: &Pubkey,
withdrawer_pubkey: &Pubkey,
to_pubkey: &Pubkey,
lamports: u64,
custodian_pubkey: Option<&Pubkey>,
) -> Instruction {
let mut account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new(*to_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(*withdrawer_pubkey, true),
];
if let Some(custodian_pubkey) = custodian_pubkey {
account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
}
Instruction::new_with_bincode(id(), &StakeInstruction::Withdraw(lamports), account_metas)
}
pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction {
let account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(*authorized_pubkey, true),
];
Instruction::new_with_bincode(id(), &StakeInstruction::Deactivate, account_metas)
}
pub fn set_lockup(
stake_pubkey: &Pubkey,
lockup: &LockupArgs,
custodian_pubkey: &Pubkey,
) -> Instruction {
let account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new_readonly(*custodian_pubkey, true),
];
Instruction::new_with_bincode(id(), &StakeInstruction::SetLockup(*lockup), account_metas)
}
#[deprecated(
since = "1.8.0",
note = "Please use `solana_sdk::stake::instruction` or `solana_program::stake::instruction` instead"
)]
pub use solana_sdk::stake::instruction::*;
pub fn process_instruction(
_program_id: &Pubkey,
@ -637,9 +179,15 @@ mod tests {
use bincode::serialize;
use solana_sdk::{
account::{self, Account, AccountSharedData, WritableAccount},
instruction::Instruction,
keyed_account::KeyedAccount,
process_instruction::{mock_set_sysvar, MockInvokeContext},
rent::Rent,
stake::{
config as stake_config,
instruction::{self, LockupArgs},
state::{Authorized, Lockup, StakeAuthorize},
},
sysvar::stake_history::StakeHistory,
};
use std::cell::RefCell;
@ -685,8 +233,8 @@ mod tests {
))
} else if sysvar::stake_history::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&StakeHistory::default())
} else if config::check_id(&meta.pubkey) {
config::create_account(0, &config::Config::default())
} else if stake_config::check_id(&meta.pubkey) {
config::create_account(0, &stake_config::Config::default())
} else if sysvar::rent::check_id(&meta.pubkey) {
account::create_account_shared_data_for_test(&Rent::default())
} else if meta.pubkey == invalid_stake_state_pubkey() {
@ -735,7 +283,7 @@ mod tests {
#[test]
fn test_stake_process_instruction() {
assert_eq!(
process_instruction(&initialize(
process_instruction(&instruction::initialize(
&Pubkey::default(),
&Authorized::default(),
&Lockup::default()
@ -743,7 +291,7 @@ mod tests {
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction(&authorize(
process_instruction(&instruction::authorize(
&Pubkey::default(),
&Pubkey::default(),
&Pubkey::default(),
@ -754,7 +302,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&split(
&instruction::split(
&Pubkey::default(),
&Pubkey::default(),
100,
@ -765,7 +313,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&merge(
&instruction::merge(
&Pubkey::default(),
&invalid_stake_state_pubkey(),
&Pubkey::default(),
@ -775,7 +323,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&split_with_seed(
&instruction::split_with_seed(
&Pubkey::default(),
&Pubkey::default(),
100,
@ -787,7 +335,7 @@ mod tests {
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction(&delegate_stake(
process_instruction(&instruction::delegate_stake(
&Pubkey::default(),
&Pubkey::default(),
&invalid_vote_state_pubkey(),
@ -795,7 +343,7 @@ mod tests {
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction(&withdraw(
process_instruction(&instruction::withdraw(
&Pubkey::default(),
&Pubkey::default(),
&solana_sdk::pubkey::new_rand(),
@ -805,11 +353,14 @@ mod tests {
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction(&deactivate_stake(&Pubkey::default(), &Pubkey::default())),
process_instruction(&instruction::deactivate_stake(
&Pubkey::default(),
&Pubkey::default()
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction(&set_lockup(
process_instruction(&instruction::set_lockup(
&Pubkey::default(),
&LockupArgs::default(),
&Pubkey::default()
@ -821,7 +372,7 @@ mod tests {
#[test]
fn test_spoofed_stake_accounts() {
assert_eq!(
process_instruction(&initialize(
process_instruction(&instruction::initialize(
&spoofed_stake_state_pubkey(),
&Authorized::default(),
&Lockup::default()
@ -829,7 +380,7 @@ mod tests {
Err(InstructionError::InvalidAccountOwner),
);
assert_eq!(
process_instruction(&authorize(
process_instruction(&instruction::authorize(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::default(),
@ -840,7 +391,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&split(
&instruction::split(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
100,
@ -851,7 +402,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&split(
&instruction::split(
&Pubkey::default(),
&Pubkey::default(),
100,
@ -862,7 +413,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&merge(
&instruction::merge(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::default(),
@ -872,7 +423,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&merge(
&instruction::merge(
&Pubkey::default(),
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
@ -882,7 +433,7 @@ mod tests {
);
assert_eq!(
process_instruction(
&split_with_seed(
&instruction::split_with_seed(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
100,
@ -894,7 +445,7 @@ mod tests {
Err(InstructionError::InvalidAccountOwner),
);
assert_eq!(
process_instruction(&delegate_stake(
process_instruction(&instruction::delegate_stake(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&Pubkey::default(),
@ -902,7 +453,7 @@ mod tests {
Err(InstructionError::InvalidAccountOwner),
);
assert_eq!(
process_instruction(&withdraw(
process_instruction(&instruction::withdraw(
&spoofed_stake_state_pubkey(),
&Pubkey::default(),
&solana_sdk::pubkey::new_rand(),
@ -912,14 +463,14 @@ mod tests {
Err(InstructionError::InvalidAccountOwner),
);
assert_eq!(
process_instruction(&deactivate_stake(
process_instruction(&instruction::deactivate_stake(
&spoofed_stake_state_pubkey(),
&Pubkey::default()
)),
Err(InstructionError::InvalidAccountOwner),
);
assert_eq!(
process_instruction(&set_lockup(
process_instruction(&instruction::set_lockup(
&spoofed_stake_state_pubkey(),
&LockupArgs::default(),
&Pubkey::default()
@ -1051,8 +602,9 @@ mod tests {
let stake_history_account = RefCell::new(account::create_account_shared_data_for_test(
&sysvar::stake_history::StakeHistory::default(),
));
let config_address = config::id();
let config_account = RefCell::new(config::create_account(0, &config::Config::default()));
let config_address = stake_config::id();
let config_account =
RefCell::new(config::create_account(0, &stake_config::Config::default()));
let keyed_accounts = vec![
KeyedAccount::new(&stake_address, true, &stake_account),
KeyedAccount::new(&vote_address, false, &bad_vote_account),
@ -1140,30 +692,4 @@ mod tests {
Err(InstructionError::NotEnoughAccountKeys),
);
}
#[test]
fn test_custom_error_decode() {
use num_traits::FromPrimitive;
fn pretty_err<T>(err: InstructionError) -> String
where
T: 'static + std::error::Error + DecodeError<T> + FromPrimitive,
{
if let InstructionError::Custom(code) = err {
let specific_error: T = T::decode_custom_error_to_enum(code).unwrap();
format!(
"{:?}: {}::{:?} - {}",
err,
T::type_of(),
specific_error,
specific_error,
)
} else {
"".to_string()
}
}
assert_eq!(
"Custom(0): StakeError::NoCreditsToRedeem - not enough credits to redeem",
pretty_err::<StakeError>(StakeError::NoCreditsToRedeem.into())
)
}
}

File diff suppressed because it is too large Load Diff