sdk: Add new version of `StakeState` to avoid breaking downstream users (#32736)
* sdk: Rename `StakeState` -> `StakeStateWithFlags` * Add back `StakeFlags` with a deprecation warning
This commit is contained in:
parent
ef318c23ae
commit
8e4a9a94ed
|
@ -6,24 +6,24 @@ use {
|
|||
bincode::deserialize,
|
||||
solana_sdk::{
|
||||
clock::{Epoch, UnixTimestamp},
|
||||
stake::state::{Authorized, Delegation, Lockup, Meta, Stake, StakeState},
|
||||
stake::state::{Authorized, Delegation, Lockup, Meta, Stake, StakeStateWithFlags},
|
||||
},
|
||||
};
|
||||
|
||||
pub fn parse_stake(data: &[u8]) -> Result<StakeAccountType, ParseAccountError> {
|
||||
let stake_state: StakeState = deserialize(data)
|
||||
let stake_state: StakeStateWithFlags = deserialize(data)
|
||||
.map_err(|_| ParseAccountError::AccountNotParsable(ParsableAccount::Stake))?;
|
||||
let parsed_account = match stake_state {
|
||||
StakeState::Uninitialized => StakeAccountType::Uninitialized,
|
||||
StakeState::Initialized(meta) => StakeAccountType::Initialized(UiStakeAccount {
|
||||
StakeStateWithFlags::Uninitialized => StakeAccountType::Uninitialized,
|
||||
StakeStateWithFlags::Initialized(meta) => StakeAccountType::Initialized(UiStakeAccount {
|
||||
meta: meta.into(),
|
||||
stake: None,
|
||||
}),
|
||||
StakeState::Stake(meta, stake, _) => StakeAccountType::Delegated(UiStakeAccount {
|
||||
StakeStateWithFlags::Stake(meta, stake, _) => StakeAccountType::Delegated(UiStakeAccount {
|
||||
meta: meta.into(),
|
||||
stake: Some(stake.into()),
|
||||
}),
|
||||
StakeState::RewardsPool => StakeAccountType::RewardsPool,
|
||||
StakeStateWithFlags::RewardsPool => StakeAccountType::RewardsPool,
|
||||
};
|
||||
Ok(parsed_account)
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ mod test {
|
|||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_parse_stake() {
|
||||
let stake_state = StakeState::Uninitialized;
|
||||
let stake_state = StakeStateWithFlags::Uninitialized;
|
||||
let stake_data = serialize(&stake_state).unwrap();
|
||||
assert_eq!(
|
||||
parse_stake(&stake_data).unwrap(),
|
||||
|
@ -167,7 +167,7 @@ mod test {
|
|||
lockup,
|
||||
};
|
||||
|
||||
let stake_state = StakeState::Initialized(meta);
|
||||
let stake_state = StakeStateWithFlags::Initialized(meta);
|
||||
let stake_data = serialize(&stake_state).unwrap();
|
||||
assert_eq!(
|
||||
parse_stake(&stake_data).unwrap(),
|
||||
|
@ -200,7 +200,7 @@ mod test {
|
|||
credits_observed: 10,
|
||||
};
|
||||
|
||||
let stake_state = StakeState::Stake(meta, stake, StakeFlags::empty());
|
||||
let stake_state = StakeStateWithFlags::Stake(meta, stake, StakeFlags::empty());
|
||||
let stake_data = serialize(&stake_state).unwrap();
|
||||
assert_eq!(
|
||||
parse_stake(&stake_data).unwrap(),
|
||||
|
@ -230,7 +230,7 @@ mod test {
|
|||
})
|
||||
);
|
||||
|
||||
let stake_state = StakeState::RewardsPool;
|
||||
let stake_state = StakeStateWithFlags::RewardsPool;
|
||||
let stake_data = serialize(&stake_state).unwrap();
|
||||
assert_eq!(
|
||||
parse_stake(&stake_data).unwrap(),
|
||||
|
|
|
@ -54,7 +54,7 @@ use {
|
|||
rpc_port::DEFAULT_RPC_PORT_STR,
|
||||
signature::Signature,
|
||||
slot_history,
|
||||
stake::{self, state::StakeState},
|
||||
stake::{self, state::StakeStateWithFlags},
|
||||
system_instruction,
|
||||
sysvar::{
|
||||
self,
|
||||
|
@ -1768,7 +1768,7 @@ pub fn process_show_stakes(
|
|||
// Use server-side filtering if only one vote account is provided
|
||||
if vote_account_pubkeys.len() == 1 {
|
||||
program_accounts_config.filters = Some(vec![
|
||||
// Filter by `StakeState::Stake(_, _)`
|
||||
// Filter by `StakeStateWithFlags::Stake(_, _)`
|
||||
RpcFilterType::Memcmp(Memcmp::new_base58_encoded(0, &[2, 0, 0, 0])),
|
||||
// Filter by `Delegation::voter_pubkey`, which begins at byte offset 124
|
||||
RpcFilterType::Memcmp(Memcmp::new_base58_encoded(
|
||||
|
@ -1809,7 +1809,7 @@ pub fn process_show_stakes(
|
|||
for (stake_pubkey, stake_account) in all_stake_accounts {
|
||||
if let Ok(stake_state) = stake_account.state() {
|
||||
match stake_state {
|
||||
StakeState::Initialized(_) => {
|
||||
StakeStateWithFlags::Initialized(_) => {
|
||||
if vote_account_pubkeys.is_none() {
|
||||
stake_accounts.push(CliKeyedStakeState {
|
||||
stake_pubkey: stake_pubkey.to_string(),
|
||||
|
@ -1824,7 +1824,7 @@ pub fn process_show_stakes(
|
|||
});
|
||||
}
|
||||
}
|
||||
StakeState::Stake(_, stake, _) => {
|
||||
StakeStateWithFlags::Stake(_, stake, _) => {
|
||||
if vote_account_pubkeys.is_none()
|
||||
|| vote_account_pubkeys
|
||||
.unwrap()
|
||||
|
@ -2157,7 +2157,7 @@ impl RentLengthValue {
|
|||
pub fn length(&self) -> usize {
|
||||
match self {
|
||||
Self::Nonce => NonceState::size(),
|
||||
Self::Stake => StakeState::size_of(),
|
||||
Self::Stake => StakeStateWithFlags::size_of(),
|
||||
Self::System => 0,
|
||||
Self::Vote => VoteState::size_of(),
|
||||
Self::Bytes(l) => *l,
|
||||
|
|
|
@ -47,7 +47,10 @@ use {
|
|||
stake::{
|
||||
self,
|
||||
instruction::{self as stake_instruction, LockupArgs, StakeError},
|
||||
state::{Authorized, Lockup, Meta, StakeActivationStatus, StakeAuthorize, StakeState},
|
||||
state::{
|
||||
Authorized, Lockup, Meta, StakeActivationStatus, StakeAuthorize,
|
||||
StakeStateWithFlags,
|
||||
},
|
||||
tools::{acceptable_reference_epoch_credits, eligible_for_deactivate_delinquent},
|
||||
},
|
||||
stake_history::{Epoch, StakeHistory},
|
||||
|
@ -1422,7 +1425,7 @@ pub fn process_create_stake_account(
|
|||
}
|
||||
|
||||
let minimum_balance =
|
||||
rpc_client.get_minimum_balance_for_rent_exemption(StakeState::size_of())?;
|
||||
rpc_client.get_minimum_balance_for_rent_exemption(StakeStateWithFlags::size_of())?;
|
||||
|
||||
if lamports < minimum_balance {
|
||||
return Err(CliError::BadParameter(format!(
|
||||
|
@ -1500,8 +1503,8 @@ pub fn process_stake_authorize(
|
|||
let authority = config.signers[*authority];
|
||||
if let Some(current_stake_account) = current_stake_account {
|
||||
let authorized = match current_stake_account {
|
||||
StakeState::Stake(Meta { authorized, .. }, ..) => Some(authorized),
|
||||
StakeState::Initialized(Meta { authorized, .. }) => Some(authorized),
|
||||
StakeStateWithFlags::Stake(Meta { authorized, .. }, ..) => Some(authorized),
|
||||
StakeStateWithFlags::Initialized(Meta { authorized, .. }) => Some(authorized),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(authorized) = authorized {
|
||||
|
@ -1630,7 +1633,7 @@ pub fn process_deactivate_stake_account(
|
|||
|
||||
let vote_account_address = match stake_account.state() {
|
||||
Ok(stake_state) => match stake_state {
|
||||
StakeState::Stake(_, stake, _) => stake.delegation.voter_pubkey,
|
||||
StakeStateWithFlags::Stake(_, stake, _) => stake.delegation.voter_pubkey,
|
||||
_ => {
|
||||
return Err(CliError::BadParameter(format!(
|
||||
"{stake_account_address} is not a delegated stake account",
|
||||
|
@ -1895,7 +1898,7 @@ pub fn process_split_stake(
|
|||
}
|
||||
|
||||
let minimum_balance =
|
||||
rpc_client.get_minimum_balance_for_rent_exemption(StakeState::size_of())?;
|
||||
rpc_client.get_minimum_balance_for_rent_exemption(StakeStateWithFlags::size_of())?;
|
||||
|
||||
if lamports < minimum_balance {
|
||||
return Err(CliError::BadParameter(format!(
|
||||
|
@ -2116,8 +2119,8 @@ pub fn process_stake_set_lockup(
|
|||
if !sign_only {
|
||||
let state = get_stake_account_state(rpc_client, stake_account_pubkey, config.commitment)?;
|
||||
let lockup = match state {
|
||||
StakeState::Stake(Meta { lockup, .. }, ..) => Some(lockup),
|
||||
StakeState::Initialized(Meta { lockup, .. }) => Some(lockup),
|
||||
StakeStateWithFlags::Stake(Meta { lockup, .. }, ..) => Some(lockup),
|
||||
StakeStateWithFlags::Initialized(Meta { lockup, .. }) => Some(lockup),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(lockup) = lockup {
|
||||
|
@ -2184,14 +2187,14 @@ fn u64_some_if_not_zero(n: u64) -> Option<u64> {
|
|||
|
||||
pub fn build_stake_state(
|
||||
account_balance: u64,
|
||||
stake_state: &StakeState,
|
||||
stake_state: &StakeStateWithFlags,
|
||||
use_lamports_unit: bool,
|
||||
stake_history: &StakeHistory,
|
||||
clock: &Clock,
|
||||
new_rate_activation_epoch: Option<Epoch>,
|
||||
) -> CliStakeState {
|
||||
match stake_state {
|
||||
StakeState::Stake(
|
||||
StakeStateWithFlags::Stake(
|
||||
Meta {
|
||||
rent_exempt_reserve,
|
||||
authorized,
|
||||
|
@ -2248,16 +2251,16 @@ pub fn build_stake_state(
|
|||
..CliStakeState::default()
|
||||
}
|
||||
}
|
||||
StakeState::RewardsPool => CliStakeState {
|
||||
StakeStateWithFlags::RewardsPool => CliStakeState {
|
||||
stake_type: CliStakeType::RewardsPool,
|
||||
account_balance,
|
||||
..CliStakeState::default()
|
||||
},
|
||||
StakeState::Uninitialized => CliStakeState {
|
||||
StakeStateWithFlags::Uninitialized => CliStakeState {
|
||||
account_balance,
|
||||
..CliStakeState::default()
|
||||
},
|
||||
StakeState::Initialized(Meta {
|
||||
StakeStateWithFlags::Initialized(Meta {
|
||||
rent_exempt_reserve,
|
||||
authorized,
|
||||
lockup,
|
||||
|
@ -2285,7 +2288,7 @@ fn get_stake_account_state(
|
|||
rpc_client: &RpcClient,
|
||||
stake_account_pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<StakeState, Box<dyn std::error::Error>> {
|
||||
) -> Result<StakeStateWithFlags, Box<dyn std::error::Error>> {
|
||||
let stake_account = rpc_client
|
||||
.get_account_with_commitment(stake_account_pubkey, commitment_config)?
|
||||
.value
|
||||
|
|
|
@ -26,7 +26,7 @@ use {
|
|||
stake::{
|
||||
self,
|
||||
instruction::LockupArgs,
|
||||
state::{Lockup, StakeAuthorize, StakeState},
|
||||
state::{Lockup, StakeAuthorize, StakeStateWithFlags},
|
||||
},
|
||||
},
|
||||
solana_streamer::socket::SocketAddrSpace,
|
||||
|
@ -162,10 +162,10 @@ fn test_stake_redelegation() {
|
|||
|
||||
// `stake_keypair` should now be delegated to `vote_keypair` and fully activated
|
||||
let stake_account = rpc_client.get_account(&stake_keypair.pubkey()).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
|
||||
let rent_exempt_reserve = match stake_state {
|
||||
StakeState::Stake(meta, stake, _) => {
|
||||
StakeStateWithFlags::Stake(meta, stake, _) => {
|
||||
assert_eq!(stake.delegation.voter_pubkey, vote_keypair.pubkey());
|
||||
meta.rent_exempt_reserve
|
||||
}
|
||||
|
@ -268,10 +268,10 @@ fn test_stake_redelegation() {
|
|||
|
||||
// `stake2_keypair` should now be delegated to `vote2_keypair` and fully activated
|
||||
let stake2_account = rpc_client.get_account(&stake2_keypair.pubkey()).unwrap();
|
||||
let stake2_state: StakeState = stake2_account.state().unwrap();
|
||||
let stake2_state: StakeStateWithFlags = stake2_account.state().unwrap();
|
||||
|
||||
match stake2_state {
|
||||
StakeState::Stake(_meta, stake, _) => {
|
||||
StakeStateWithFlags::Stake(_meta, stake, _) => {
|
||||
assert_eq!(stake.delegation.voter_pubkey, vote2_keypair.pubkey());
|
||||
}
|
||||
_ => panic!("Unexpected stake2 state!"),
|
||||
|
@ -966,9 +966,9 @@ fn test_stake_authorize() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_authority = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.authorized.staker,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.authorized.staker,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(current_authority, online_authority_pubkey);
|
||||
|
@ -1008,9 +1008,11 @@ fn test_stake_authorize() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let (current_staker, current_withdrawer) = match stake_state {
|
||||
StakeState::Initialized(meta) => (meta.authorized.staker, meta.authorized.withdrawer),
|
||||
StakeStateWithFlags::Initialized(meta) => {
|
||||
(meta.authorized.staker, meta.authorized.withdrawer)
|
||||
}
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(current_staker, online_authority2_pubkey);
|
||||
|
@ -1040,9 +1042,9 @@ fn test_stake_authorize() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_authority = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.authorized.staker,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.authorized.staker,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(current_authority, offline_authority_pubkey);
|
||||
|
@ -1097,9 +1099,9 @@ fn test_stake_authorize() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_authority = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.authorized.staker,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.authorized.staker,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(current_authority, nonced_authority_pubkey);
|
||||
|
@ -1184,9 +1186,9 @@ fn test_stake_authorize() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_authority = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.authorized.staker,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.authorized.staker,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(current_authority, online_authority_pubkey);
|
||||
|
@ -1434,7 +1436,7 @@ fn test_stake_split() {
|
|||
|
||||
// Create stake account, identity is authority
|
||||
let stake_balance = rpc_client
|
||||
.get_minimum_balance_for_rent_exemption(StakeState::size_of())
|
||||
.get_minimum_balance_for_rent_exemption(StakeStateWithFlags::size_of())
|
||||
.unwrap()
|
||||
+ 10_000_000_000;
|
||||
let stake_keypair = keypair_from_seed(&[0u8; 32]).unwrap();
|
||||
|
@ -1587,7 +1589,7 @@ fn test_stake_set_lockup() {
|
|||
|
||||
// Create stake account, identity is authority
|
||||
let stake_balance = rpc_client
|
||||
.get_minimum_balance_for_rent_exemption(StakeState::size_of())
|
||||
.get_minimum_balance_for_rent_exemption(StakeStateWithFlags::size_of())
|
||||
.unwrap()
|
||||
+ 10_000_000_000;
|
||||
|
||||
|
@ -1645,9 +1647,9 @@ fn test_stake_set_lockup() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_lockup = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.lockup,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.lockup,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(
|
||||
|
@ -1704,9 +1706,9 @@ fn test_stake_set_lockup() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_lockup = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.lockup,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.lockup,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(
|
||||
|
@ -1811,9 +1813,9 @@ fn test_stake_set_lockup() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_lockup = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.lockup,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.lockup,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(
|
||||
|
@ -2187,9 +2189,9 @@ fn test_stake_checked_instructions() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_authority = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.authorized.staker,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.authorized.staker,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(current_authority, staker_pubkey);
|
||||
|
@ -2244,9 +2246,9 @@ fn test_stake_checked_instructions() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_authority = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.authorized.withdrawer,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.authorized.withdrawer,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(current_authority, new_withdrawer_pubkey);
|
||||
|
@ -2293,9 +2295,9 @@ fn test_stake_checked_instructions() {
|
|||
};
|
||||
process_command(&config).unwrap();
|
||||
let stake_account = rpc_client.get_account(&stake_account_pubkey).unwrap();
|
||||
let stake_state: StakeState = stake_account.state().unwrap();
|
||||
let stake_state: StakeStateWithFlags = stake_account.state().unwrap();
|
||||
let current_lockup = match stake_state {
|
||||
StakeState::Initialized(meta) => meta.lockup,
|
||||
StakeStateWithFlags::Initialized(meta) => meta.lockup,
|
||||
_ => panic!("Unexpected stake state!"),
|
||||
};
|
||||
assert_eq!(
|
||||
|
|
|
@ -11,8 +11,8 @@ msc {
|
|||
|
||||
VoteSigner <:> Validator [label="register\n\n(optional)"];
|
||||
Validator => Cluster [label="VoteState::Initialize(VoteSigner)"];
|
||||
StakerX => Cluster [label="StakeState::Delegate(Validator)"];
|
||||
StakerY => Cluster [label="StakeState::Delegate(Validator)"];
|
||||
StakerX => Cluster [label="StakeStateWithFlags::Delegate(Validator)"];
|
||||
StakerY => Cluster [label="StakeStateWithFlags::Delegate(Validator)"];
|
||||
|
||||
|||;
|
||||
Validator box Cluster [label="\nvalidate\n"];
|
||||
|
|
|
@ -14,7 +14,7 @@ A separate Stake account \(created by a staker\) names a Vote account to which t
|
|||
|
||||
Any number of Stake accounts can delegate to a single Vote account without an interactive action from the identity controlling the Vote account or submitting votes to the account.
|
||||
|
||||
The total stake allocated to a Vote account can be calculated by the sum of all the Stake accounts that have the Vote account pubkey as the `StakeState::Stake::voter_pubkey`.
|
||||
The total stake allocated to a Vote account can be calculated by the sum of all the Stake accounts that have the Vote account pubkey as the `StakeStateWithFlags::Stake::voter_pubkey`.
|
||||
|
||||
## Vote and Stake accounts
|
||||
|
||||
|
@ -62,13 +62,13 @@ Updates the account with a new authorized voter or withdrawer, according to the
|
|||
- `account[1]` - RO - `sysvar::slot_hashes` A list of some N most recent slots and their hashes for the vote to be verified against.
|
||||
- `account[2]` - RO - `sysvar::clock` The current network time, expressed in slots, epochs.
|
||||
|
||||
### StakeState
|
||||
### StakeStateWithFlags
|
||||
|
||||
A StakeState takes one of four forms, StakeState::Uninitialized, StakeState::Initialized, StakeState::Stake, and StakeState::RewardsPool. Only the first three forms are used in staking, but only StakeState::Stake is interesting. All RewardsPools are created at genesis.
|
||||
A StakeStateWithFlags takes one of four forms, StakeStateWithFlags::Uninitialized, StakeStateWithFlags::Initialized, StakeStateWithFlags::Stake, and StakeStateWithFlags::RewardsPool. Only the first three forms are used in staking, but only StakeStateWithFlags::Stake is interesting. All RewardsPools are created at genesis.
|
||||
|
||||
### StakeState::Stake
|
||||
### StakeStateWithFlags::Stake
|
||||
|
||||
StakeState::Stake is the current delegation preference of the **staker** and contains the following state information:
|
||||
StakeStateWithFlags::Stake is the current delegation preference of the **staker** and contains the following state information:
|
||||
|
||||
- Account::lamports - The lamports available for staking.
|
||||
- `stake` - the staked amount \(subject to warmup and cooldown\) for generating rewards, always less than or equal to Account::lamports.
|
||||
|
@ -79,7 +79,7 @@ StakeState::Stake is the current delegation preference of the **staker** and con
|
|||
- `authorized_staker` - the pubkey of the entity that must sign delegation, activation, and deactivation transactions.
|
||||
- `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's address, and the authorized staker.
|
||||
|
||||
### StakeState::RewardsPool
|
||||
### StakeStateWithFlags::RewardsPool
|
||||
|
||||
To avoid a single network-wide lock or contention in redemption, 256 RewardsPools are part of genesis under pre-determined keys, each with std::u64::MAX credits to be able to satisfy redemptions according to point value.
|
||||
|
||||
|
@ -87,9 +87,9 @@ The Stakes and the RewardsPool are accounts that are owned by the same `Stake` p
|
|||
|
||||
### StakeInstruction::DelegateStake
|
||||
|
||||
The Stake account is moved from Initialized to StakeState::Stake form, or from a deactivated (i.e. fully cooled-down) StakeState::Stake to activated StakeState::Stake. This is how stakers choose the vote account and validator node to which their stake account lamports are delegated. The transaction must be signed by the stake's `authorized_staker`.
|
||||
The Stake account is moved from Initialized to StakeStateWithFlags::Stake form, or from a deactivated (i.e. fully cooled-down) StakeStateWithFlags::Stake to activated StakeStateWithFlags::Stake. This is how stakers choose the vote account and validator node to which their stake account lamports are delegated. The transaction must be signed by the stake's `authorized_staker`.
|
||||
|
||||
- `account[0]` - RW - The StakeState::Stake instance. `StakeState::Stake::credits_observed` is initialized to `VoteState::credits`, `StakeState::Stake::voter_pubkey` is initialized to `account[1]`. If this is the initial delegation of stake, `StakeState::Stake::stake` is initialized to the account's balance in lamports, `StakeState::Stake::activated` is initialized to the current Bank epoch, and `StakeState::Stake::deactivated` is initialized to std::u64::MAX
|
||||
- `account[0]` - RW - The StakeStateWithFlags::Stake instance. `StakeStateWithFlags::Stake::credits_observed` is initialized to `VoteState::credits`, `StakeStateWithFlags::Stake::voter_pubkey` is initialized to `account[1]`. If this is the initial delegation of stake, `StakeStateWithFlags::Stake::stake` is initialized to the account's balance in lamports, `StakeStateWithFlags::Stake::activated` is initialized to the current Bank epoch, and `StakeStateWithFlags::Stake::deactivated` is initialized to std::u64::MAX
|
||||
- `account[1]` - R - The VoteState instance.
|
||||
- `account[2]` - R - sysvar::clock account, carries information about current Bank epoch.
|
||||
- `account[3]` - R - sysvar::stakehistory account, carries information about stake history.
|
||||
|
@ -99,25 +99,25 @@ The Stake account is moved from Initialized to StakeState::Stake form, or from a
|
|||
|
||||
Updates the account with a new authorized staker or withdrawer, according to the StakeAuthorize parameter \(`Staker` or `Withdrawer`\). The transaction must be by signed by the Stakee account's current `authorized_staker` or `authorized_withdrawer`. Any stake lock-up must have expired, or the lock-up custodian must also sign the transaction.
|
||||
|
||||
- `account[0]` - RW - The StakeState.
|
||||
- `account[0]` - RW - The StakeStateWithFlags.
|
||||
|
||||
`StakeState::authorized_staker` or `authorized_withdrawer` is set to to `Pubkey`.
|
||||
`StakeStateWithFlags::authorized_staker` or `authorized_withdrawer` is set to to `Pubkey`.
|
||||
|
||||
### StakeInstruction::Deactivate
|
||||
|
||||
A staker may wish to withdraw from the network. To do so he must first deactivate his stake, and wait for cooldown.
|
||||
The transaction must be signed by the stake's `authorized_staker`.
|
||||
|
||||
- `account[0]` - RW - The StakeState::Stake instance that is deactivating.
|
||||
- `account[0]` - RW - The StakeStateWithFlags::Stake instance that is deactivating.
|
||||
- `account[1]` - R - sysvar::clock account from the Bank that carries current epoch.
|
||||
|
||||
StakeState::Stake::deactivated is set to the current epoch + cooldown. The account's stake will ramp down to zero by that epoch, and Account::lamports will be available for withdrawal.
|
||||
StakeStateWithFlags::Stake::deactivated is set to the current epoch + cooldown. The account's stake will ramp down to zero by that epoch, and Account::lamports will be available for withdrawal.
|
||||
|
||||
### StakeInstruction::Withdraw\(u64\)
|
||||
|
||||
Lamports build up over time in a Stake account and any excess over activated stake can be withdrawn. The transaction must be signed by the stake's `authorized_withdrawer`.
|
||||
|
||||
- `account[0]` - RW - The StakeState::Stake from which to withdraw.
|
||||
- `account[0]` - RW - The StakeStateWithFlags::Stake from which to withdraw.
|
||||
- `account[1]` - RW - Account that should be credited with the withdrawn lamports.
|
||||
- `account[2]` - R - sysvar::clock account from the Bank that carries current epoch, to calculate stake.
|
||||
- `account[3]` - R - sysvar::stake_history account from the Bank that carries stake warmup/cooldown history.
|
||||
|
|
|
@ -31,7 +31,7 @@ use {
|
|||
rent::Rent,
|
||||
signature::{Keypair, Signer},
|
||||
signer::keypair::read_keypair_file,
|
||||
stake::state::StakeState,
|
||||
stake::state::StakeStateWithFlags,
|
||||
system_program, timing,
|
||||
},
|
||||
solana_stake_program::stake_state,
|
||||
|
@ -141,7 +141,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||
.to_string();
|
||||
// stake account
|
||||
let default_bootstrap_validator_stake_lamports = &sol_to_lamports(0.5)
|
||||
.max(rent.minimum_balance(StakeState::size_of()))
|
||||
.max(rent.minimum_balance(StakeStateWithFlags::size_of()))
|
||||
.to_string();
|
||||
|
||||
let default_target_tick_duration =
|
||||
|
@ -444,7 +444,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||
let bootstrap_validator_stake_lamports = rent_exempt_check(
|
||||
&matches,
|
||||
"bootstrap_validator_stake_lamports",
|
||||
rent.minimum_balance(StakeState::size_of()),
|
||||
rent.minimum_balance(StakeStateWithFlags::size_of()),
|
||||
)?;
|
||||
|
||||
let bootstrap_stake_authorized_pubkey =
|
||||
|
|
|
@ -11,7 +11,7 @@ use {
|
|||
pubkey::Pubkey,
|
||||
stake::{
|
||||
self,
|
||||
state::{Authorized, Lockup, StakeState},
|
||||
state::{Authorized, Lockup, StakeStateWithFlags},
|
||||
},
|
||||
system_program,
|
||||
timing::years_as_slots,
|
||||
|
@ -107,7 +107,9 @@ pub fn create_and_add_stakes(
|
|||
|
||||
let mut address_generator = AddressGenerator::new(&authorized.staker, &stake::program::id());
|
||||
|
||||
let stake_rent_reserve = genesis_config.rent.minimum_balance(StakeState::size_of());
|
||||
let stake_rent_reserve = genesis_config
|
||||
.rent
|
||||
.minimum_balance(StakeStateWithFlags::size_of());
|
||||
|
||||
for unlock in unlocks {
|
||||
let lamports = unlock.amount(stakes_lamports);
|
||||
|
@ -193,7 +195,9 @@ mod tests {
|
|||
.iter()
|
||||
.all(|(_pubkey, account)| account.lamports <= granularity
|
||||
|| account.lamports - granularity
|
||||
<= genesis_config.rent.minimum_balance(StakeState::size_of())));
|
||||
<= genesis_config
|
||||
.rent
|
||||
.minimum_balance(StakeStateWithFlags::size_of())));
|
||||
}
|
||||
|
||||
// #[ignore]
|
||||
|
@ -238,7 +242,7 @@ mod tests {
|
|||
..Rent::default()
|
||||
};
|
||||
|
||||
let reserve = rent.minimum_balance(StakeState::size_of());
|
||||
let reserve = rent.minimum_balance(StakeStateWithFlags::size_of());
|
||||
let staker_reserve = rent.minimum_balance(0);
|
||||
|
||||
// verify that a small remainder ends up in the last stake
|
||||
|
|
|
@ -74,7 +74,7 @@ use {
|
|||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
shred_version::compute_shred_version,
|
||||
stake::{self, state::StakeState},
|
||||
stake::{self, state::StakeStateWithFlags},
|
||||
system_program,
|
||||
transaction::{
|
||||
MessageHash, SanitizedTransaction, SimpleAddressLoader, VersionedTransaction,
|
||||
|
@ -1293,7 +1293,7 @@ fn main() {
|
|||
.max(VoteState::get_rent_exempt_reserve(&rent))
|
||||
.to_string();
|
||||
let default_bootstrap_validator_stake_lamports = &sol_to_lamports(0.5)
|
||||
.max(rent.minimum_balance(StakeState::size_of()))
|
||||
.max(rent.minimum_balance(StakeStateWithFlags::size_of()))
|
||||
.to_string();
|
||||
let default_graph_vote_account_mode = GraphVoteAccountMode::default();
|
||||
|
||||
|
@ -2768,7 +2768,7 @@ fn main() {
|
|||
value_t_or_exit!(arg_matches, "bootstrap_validator_lamports", u64);
|
||||
let bootstrap_validator_stake_lamports =
|
||||
value_t_or_exit!(arg_matches, "bootstrap_validator_stake_lamports", u64);
|
||||
let minimum_stake_lamports = rent.minimum_balance(StakeState::size_of());
|
||||
let minimum_stake_lamports = rent.minimum_balance(StakeStateWithFlags::size_of());
|
||||
if bootstrap_validator_stake_lamports < minimum_stake_lamports {
|
||||
eprintln!(
|
||||
"Error: insufficient --bootstrap-validator-stake-lamports. \
|
||||
|
@ -2996,7 +2996,9 @@ fn main() {
|
|||
.unwrap()
|
||||
.into_iter()
|
||||
{
|
||||
if let Ok(StakeState::Stake(meta, stake, _)) = account.state() {
|
||||
if let Ok(StakeStateWithFlags::Stake(meta, stake, _)) =
|
||||
account.state()
|
||||
{
|
||||
if vote_accounts_to_destake
|
||||
.contains(&stake.delegation.voter_pubkey)
|
||||
{
|
||||
|
@ -3006,7 +3008,9 @@ fn main() {
|
|||
address, stake.delegation.voter_pubkey,
|
||||
);
|
||||
}
|
||||
account.set_state(&StakeState::Initialized(meta)).unwrap();
|
||||
account
|
||||
.set_state(&StakeStateWithFlags::Initialized(meta))
|
||||
.unwrap();
|
||||
bank.store_account(&address, &account);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use {
|
|||
signature::{Keypair, Signer},
|
||||
stake::{
|
||||
instruction as stake_instruction,
|
||||
state::{Authorized, Lockup, StakeActivationStatus, StakeState},
|
||||
state::{Authorized, Lockup, StakeActivationStatus, StakeStateWithFlags},
|
||||
},
|
||||
system_instruction, system_program,
|
||||
sysvar::{
|
||||
|
@ -271,7 +271,7 @@ async fn stake_rewards_from_warp() {
|
|||
.expect("account exists")
|
||||
.unwrap();
|
||||
|
||||
let stake_state: StakeState = deserialize(&account.data).unwrap();
|
||||
let stake_state: StakeStateWithFlags = deserialize(&account.data).unwrap();
|
||||
let stake_history: StakeHistory = deserialize(&stake_history_account.data).unwrap();
|
||||
let clock: Clock = deserialize(&clock_account.data).unwrap();
|
||||
let stake = stake_state.stake().unwrap();
|
||||
|
@ -387,7 +387,7 @@ async fn stake_rewards_filter_bench_core(num_stake_accounts: u64) {
|
|||
.expect("account exists")
|
||||
.unwrap();
|
||||
|
||||
let stake_state: StakeState = deserialize(&account.data).unwrap();
|
||||
let stake_state: StakeStateWithFlags = deserialize(&account.data).unwrap();
|
||||
let stake_history: StakeHistory = deserialize(&stake_history_account.data).unwrap();
|
||||
let clock: Clock = deserialize(&clock_account.data).unwrap();
|
||||
let stake = stake_state.stake().unwrap();
|
||||
|
@ -409,7 +409,7 @@ async fn check_credits_observed(
|
|||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let stake_state: StakeState = deserialize(&stake_account.data).unwrap();
|
||||
let stake_state: StakeStateWithFlags = deserialize(&stake_account.data).unwrap();
|
||||
assert_eq!(
|
||||
stake_state.stake().unwrap().credits_observed,
|
||||
expected_credits
|
||||
|
@ -465,7 +465,7 @@ async fn stake_merge_immediately_after_activation() {
|
|||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let stake_state: StakeState = deserialize(&stake_account.data).unwrap();
|
||||
let stake_state: StakeStateWithFlags = deserialize(&stake_account.data).unwrap();
|
||||
assert_eq!(stake_state.stake().unwrap().credits_observed, 300);
|
||||
assert!(stake_account.lamports > stake_lamports);
|
||||
|
||||
|
@ -476,7 +476,7 @@ async fn stake_merge_immediately_after_activation() {
|
|||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let stake_state: StakeState = deserialize(&stake_account.data).unwrap();
|
||||
let stake_state: StakeStateWithFlags = deserialize(&stake_account.data).unwrap();
|
||||
assert_eq!(stake_state.stake().unwrap().credits_observed, 300);
|
||||
assert_eq!(stake_account.lamports, stake_lamports);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -73,28 +73,34 @@ pub(crate) fn null_tracer() -> Option<impl Fn(&InflationPointCalculationEvent)>
|
|||
}
|
||||
|
||||
// utility function, used by Stakes, tests
|
||||
pub fn from<T: ReadableAccount + StateMut<StakeState>>(account: &T) -> Option<StakeState> {
|
||||
pub fn from<T: ReadableAccount + StateMut<StakeStateWithFlags>>(
|
||||
account: &T,
|
||||
) -> Option<StakeStateWithFlags> {
|
||||
account.state().ok()
|
||||
}
|
||||
|
||||
pub fn stake_from<T: ReadableAccount + StateMut<StakeState>>(account: &T) -> Option<Stake> {
|
||||
from(account).and_then(|state: StakeState| state.stake())
|
||||
pub fn stake_from<T: ReadableAccount + StateMut<StakeStateWithFlags>>(
|
||||
account: &T,
|
||||
) -> Option<Stake> {
|
||||
from(account).and_then(|state: StakeStateWithFlags| state.stake())
|
||||
}
|
||||
|
||||
pub fn delegation_from(account: &AccountSharedData) -> Option<Delegation> {
|
||||
from(account).and_then(|state: StakeState| state.delegation())
|
||||
from(account).and_then(|state: StakeStateWithFlags| state.delegation())
|
||||
}
|
||||
|
||||
pub fn authorized_from(account: &AccountSharedData) -> Option<Authorized> {
|
||||
from(account).and_then(|state: StakeState| state.authorized())
|
||||
from(account).and_then(|state: StakeStateWithFlags| state.authorized())
|
||||
}
|
||||
|
||||
pub fn lockup_from<T: ReadableAccount + StateMut<StakeState>>(account: &T) -> Option<Lockup> {
|
||||
from(account).and_then(|state: StakeState| state.lockup())
|
||||
pub fn lockup_from<T: ReadableAccount + StateMut<StakeStateWithFlags>>(
|
||||
account: &T,
|
||||
) -> Option<Lockup> {
|
||||
from(account).and_then(|state: StakeStateWithFlags| state.lockup())
|
||||
}
|
||||
|
||||
pub fn meta_from(account: &AccountSharedData) -> Option<Meta> {
|
||||
from(account).and_then(|state: StakeState| state.meta())
|
||||
from(account).and_then(|state: StakeStateWithFlags| state.meta())
|
||||
}
|
||||
|
||||
pub(crate) fn new_warmup_cooldown_rate_epoch(invoke_context: &InvokeContext) -> Option<Epoch> {
|
||||
|
@ -470,13 +476,13 @@ pub fn initialize(
|
|||
lockup: &Lockup,
|
||||
rent: &Rent,
|
||||
) -> Result<(), InstructionError> {
|
||||
if stake_account.get_data().len() != StakeState::size_of() {
|
||||
if stake_account.get_data().len() != StakeStateWithFlags::size_of() {
|
||||
return Err(InstructionError::InvalidAccountData);
|
||||
}
|
||||
if let StakeState::Uninitialized = stake_account.get_state()? {
|
||||
if let StakeStateWithFlags::Uninitialized = stake_account.get_state()? {
|
||||
let rent_exempt_reserve = rent.minimum_balance(stake_account.get_data().len());
|
||||
if stake_account.get_lamports() >= rent_exempt_reserve {
|
||||
stake_account.set_state(&StakeState::Initialized(Meta {
|
||||
stake_account.set_state(&StakeStateWithFlags::Initialized(Meta {
|
||||
rent_exempt_reserve,
|
||||
authorized: *authorized,
|
||||
lockup: *lockup,
|
||||
|
@ -502,7 +508,7 @@ pub fn authorize(
|
|||
custodian: Option<&Pubkey>,
|
||||
) -> Result<(), InstructionError> {
|
||||
match stake_account.get_state()? {
|
||||
StakeState::Stake(mut meta, stake, stake_flags) => {
|
||||
StakeStateWithFlags::Stake(mut meta, stake, stake_flags) => {
|
||||
meta.authorized.authorize(
|
||||
signers,
|
||||
new_authority,
|
||||
|
@ -513,9 +519,9 @@ pub fn authorize(
|
|||
None
|
||||
},
|
||||
)?;
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, stake_flags))
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(meta, stake, stake_flags))
|
||||
}
|
||||
StakeState::Initialized(mut meta) => {
|
||||
StakeStateWithFlags::Initialized(mut meta) => {
|
||||
meta.authorized.authorize(
|
||||
signers,
|
||||
new_authority,
|
||||
|
@ -526,7 +532,7 @@ pub fn authorize(
|
|||
None
|
||||
},
|
||||
)?;
|
||||
stake_account.set_state(&StakeState::Initialized(meta))
|
||||
stake_account.set_state(&StakeStateWithFlags::Initialized(meta))
|
||||
}
|
||||
_ => Err(InstructionError::InvalidAccountData),
|
||||
}
|
||||
|
@ -593,7 +599,7 @@ pub fn delegate(
|
|||
let mut stake_account = instruction_context
|
||||
.try_borrow_instruction_account(transaction_context, stake_account_index)?;
|
||||
match stake_account.get_state()? {
|
||||
StakeState::Initialized(meta) => {
|
||||
StakeStateWithFlags::Initialized(meta) => {
|
||||
meta.authorized.check(signers, StakeAuthorize::Staker)?;
|
||||
let ValidatedDelegatedInfo { stake_amount } =
|
||||
validate_delegated_amount(&stake_account, &meta, feature_set)?;
|
||||
|
@ -603,9 +609,13 @@ pub fn delegate(
|
|||
&vote_state?.convert_to_current(),
|
||||
clock.epoch,
|
||||
);
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, StakeFlags::empty()))
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(
|
||||
meta,
|
||||
stake,
|
||||
StakeFlags::empty(),
|
||||
))
|
||||
}
|
||||
StakeState::Stake(meta, mut stake, stake_flags) => {
|
||||
StakeStateWithFlags::Stake(meta, mut stake, stake_flags) => {
|
||||
meta.authorized.check(signers, StakeAuthorize::Staker)?;
|
||||
let ValidatedDelegatedInfo { stake_amount } =
|
||||
validate_delegated_amount(&stake_account, &meta, feature_set)?;
|
||||
|
@ -618,7 +628,7 @@ pub fn delegate(
|
|||
clock,
|
||||
stake_history,
|
||||
)?;
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, stake_flags))
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(meta, stake, stake_flags))
|
||||
}
|
||||
_ => Err(InstructionError::InvalidAccountData),
|
||||
}
|
||||
|
@ -629,11 +639,11 @@ pub fn deactivate(
|
|||
clock: &Clock,
|
||||
signers: &HashSet<Pubkey>,
|
||||
) -> Result<(), InstructionError> {
|
||||
if let StakeState::Stake(meta, mut stake, stake_flags) = stake_account.get_state()? {
|
||||
if let StakeStateWithFlags::Stake(meta, mut stake, stake_flags) = stake_account.get_state()? {
|
||||
meta.authorized.check(signers, StakeAuthorize::Staker)?;
|
||||
stake.deactivate(clock.epoch)?;
|
||||
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, stake_flags))
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(meta, stake, stake_flags))
|
||||
} else {
|
||||
Err(InstructionError::InvalidAccountData)
|
||||
}
|
||||
|
@ -646,13 +656,13 @@ pub fn set_lockup(
|
|||
clock: &Clock,
|
||||
) -> Result<(), InstructionError> {
|
||||
match stake_account.get_state()? {
|
||||
StakeState::Initialized(mut meta) => {
|
||||
StakeStateWithFlags::Initialized(mut meta) => {
|
||||
meta.set_lockup(lockup, signers, clock)?;
|
||||
stake_account.set_state(&StakeState::Initialized(meta))
|
||||
stake_account.set_state(&StakeStateWithFlags::Initialized(meta))
|
||||
}
|
||||
StakeState::Stake(mut meta, stake, stake_flags) => {
|
||||
StakeStateWithFlags::Stake(mut meta, stake, stake_flags) => {
|
||||
meta.set_lockup(lockup, signers, clock)?;
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, stake_flags))
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(meta, stake, stake_flags))
|
||||
}
|
||||
_ => Err(InstructionError::InvalidAccountData),
|
||||
}
|
||||
|
@ -672,10 +682,10 @@ pub fn split(
|
|||
if *split.get_owner() != id() {
|
||||
return Err(InstructionError::IncorrectProgramId);
|
||||
}
|
||||
if split.get_data().len() != StakeState::size_of() {
|
||||
if split.get_data().len() != StakeStateWithFlags::size_of() {
|
||||
return Err(InstructionError::InvalidAccountData);
|
||||
}
|
||||
if !matches!(split.get_state()?, StakeState::Uninitialized) {
|
||||
if !matches!(split.get_state()?, StakeStateWithFlags::Uninitialized) {
|
||||
return Err(InstructionError::InvalidAccountData);
|
||||
}
|
||||
let split_lamport_balance = split.get_lamports();
|
||||
|
@ -689,7 +699,7 @@ pub fn split(
|
|||
drop(stake_account);
|
||||
|
||||
match stake_state {
|
||||
StakeState::Stake(meta, mut stake, stake_flags) => {
|
||||
StakeStateWithFlags::Stake(meta, mut stake, stake_flags) => {
|
||||
meta.authorized.check(signers, StakeAuthorize::Staker)?;
|
||||
let minimum_delegation = crate::get_minimum_delegation(&invoke_context.feature_set);
|
||||
let validated_split_info = validate_split_amount(
|
||||
|
@ -759,13 +769,17 @@ pub fn split(
|
|||
|
||||
let mut stake_account = instruction_context
|
||||
.try_borrow_instruction_account(transaction_context, stake_account_index)?;
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, stake_flags))?;
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(meta, stake, stake_flags))?;
|
||||
drop(stake_account);
|
||||
let mut split = instruction_context
|
||||
.try_borrow_instruction_account(transaction_context, split_index)?;
|
||||
split.set_state(&StakeState::Stake(split_meta, split_stake, stake_flags))?;
|
||||
split.set_state(&StakeStateWithFlags::Stake(
|
||||
split_meta,
|
||||
split_stake,
|
||||
stake_flags,
|
||||
))?;
|
||||
}
|
||||
StakeState::Initialized(meta) => {
|
||||
StakeStateWithFlags::Initialized(meta) => {
|
||||
meta.authorized.check(signers, StakeAuthorize::Staker)?;
|
||||
let validated_split_info = validate_split_amount(
|
||||
invoke_context,
|
||||
|
@ -782,9 +796,9 @@ pub fn split(
|
|||
split_meta.rent_exempt_reserve = validated_split_info.destination_rent_exempt_reserve;
|
||||
let mut split = instruction_context
|
||||
.try_borrow_instruction_account(transaction_context, split_index)?;
|
||||
split.set_state(&StakeState::Initialized(split_meta))?;
|
||||
split.set_state(&StakeStateWithFlags::Initialized(split_meta))?;
|
||||
}
|
||||
StakeState::Uninitialized => {
|
||||
StakeStateWithFlags::Uninitialized => {
|
||||
let stake_pubkey = transaction_context.get_key_of_account_at_index(
|
||||
instruction_context
|
||||
.get_index_of_instruction_account_in_transaction(stake_account_index)?,
|
||||
|
@ -800,7 +814,7 @@ pub fn split(
|
|||
let mut stake_account = instruction_context
|
||||
.try_borrow_instruction_account(transaction_context, stake_account_index)?;
|
||||
if lamports == stake_account.get_lamports() {
|
||||
stake_account.set_state(&StakeState::Uninitialized)?;
|
||||
stake_account.set_state(&StakeStateWithFlags::Uninitialized)?;
|
||||
}
|
||||
drop(stake_account);
|
||||
|
||||
|
@ -870,7 +884,7 @@ pub fn merge(
|
|||
}
|
||||
|
||||
// Source is about to be drained, deinitialize its state
|
||||
source_account.set_state(&StakeState::Uninitialized)?;
|
||||
source_account.set_state(&StakeStateWithFlags::Uninitialized)?;
|
||||
|
||||
// Drain the source stake account
|
||||
let lamports = source_account.get_lamports();
|
||||
|
@ -902,18 +916,18 @@ pub fn redelegate(
|
|||
);
|
||||
return Err(InstructionError::IncorrectProgramId);
|
||||
}
|
||||
if uninitialized_stake_account.get_data().len() != StakeState::size_of() {
|
||||
if uninitialized_stake_account.get_data().len() != StakeStateWithFlags::size_of() {
|
||||
ic_msg!(
|
||||
invoke_context,
|
||||
"expected uninitialized stake account data len to be {}, not {}",
|
||||
StakeState::size_of(),
|
||||
StakeStateWithFlags::size_of(),
|
||||
uninitialized_stake_account.get_data().len()
|
||||
);
|
||||
return Err(InstructionError::InvalidAccountData);
|
||||
}
|
||||
if !matches!(
|
||||
uninitialized_stake_account.get_state()?,
|
||||
StakeState::Uninitialized
|
||||
StakeStateWithFlags::Uninitialized
|
||||
) {
|
||||
ic_msg!(
|
||||
invoke_context,
|
||||
|
@ -938,7 +952,7 @@ pub fn redelegate(
|
|||
let vote_state = vote_account.get_state::<VoteStateVersions>()?;
|
||||
|
||||
let (stake_meta, effective_stake) =
|
||||
if let StakeState::Stake(meta, stake, _stake_flags) = stake_account.get_state()? {
|
||||
if let StakeStateWithFlags::Stake(meta, stake, _stake_flags) = stake_account.get_state()? {
|
||||
let stake_history = invoke_context.get_sysvar_cache().get_stake_history()?;
|
||||
let status = stake.delegation.stake_activating_and_deactivating(
|
||||
clock.epoch,
|
||||
|
@ -987,7 +1001,7 @@ pub fn redelegate(
|
|||
&uninitialized_stake_meta,
|
||||
&invoke_context.feature_set,
|
||||
)?;
|
||||
uninitialized_stake_account.set_state(&StakeState::Stake(
|
||||
uninitialized_stake_account.set_state(&StakeStateWithFlags::Stake(
|
||||
uninitialized_stake_meta,
|
||||
new_stake(
|
||||
stake_amount,
|
||||
|
@ -1027,7 +1041,7 @@ pub fn withdraw(
|
|||
let mut stake_account = instruction_context
|
||||
.try_borrow_instruction_account(transaction_context, stake_account_index)?;
|
||||
let (lockup, reserve, is_staked) = match stake_account.get_state()? {
|
||||
StakeState::Stake(meta, stake, _stake_flag) => {
|
||||
StakeStateWithFlags::Stake(meta, stake, _stake_flag) => {
|
||||
meta.authorized
|
||||
.check(&signers, StakeAuthorize::Withdrawer)?;
|
||||
// if we have a deactivation epoch and we're in cooldown
|
||||
|
@ -1045,13 +1059,13 @@ pub fn withdraw(
|
|||
let staked_and_reserve = checked_add(staked, meta.rent_exempt_reserve)?;
|
||||
(meta.lockup, staked_and_reserve, staked != 0)
|
||||
}
|
||||
StakeState::Initialized(meta) => {
|
||||
StakeStateWithFlags::Initialized(meta) => {
|
||||
meta.authorized
|
||||
.check(&signers, StakeAuthorize::Withdrawer)?;
|
||||
// stake accounts must have a balance >= rent_exempt_reserve
|
||||
(meta.lockup, meta.rent_exempt_reserve, false)
|
||||
}
|
||||
StakeState::Uninitialized => {
|
||||
StakeStateWithFlags::Uninitialized => {
|
||||
if !signers.contains(stake_account.get_key()) {
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
}
|
||||
|
@ -1097,7 +1111,7 @@ pub fn withdraw(
|
|||
|
||||
// Deinitialize state upon zero balance
|
||||
if lamports == stake_account.get_lamports() {
|
||||
stake_account.set_state(&StakeState::Uninitialized)?;
|
||||
stake_account.set_state(&StakeStateWithFlags::Uninitialized)?;
|
||||
}
|
||||
|
||||
stake_account.checked_sub_lamports(lamports)?;
|
||||
|
@ -1142,7 +1156,7 @@ pub(crate) fn deactivate_delinquent(
|
|||
return Err(StakeError::InsufficientReferenceVotes.into());
|
||||
}
|
||||
|
||||
if let StakeState::Stake(meta, mut stake, stake_flags) = stake_account.get_state()? {
|
||||
if let StakeStateWithFlags::Stake(meta, mut stake, stake_flags) = stake_account.get_state()? {
|
||||
if stake.delegation.voter_pubkey != *delinquent_vote_account_pubkey {
|
||||
return Err(StakeError::VoteAddressMismatch.into());
|
||||
}
|
||||
|
@ -1151,7 +1165,7 @@ pub(crate) fn deactivate_delinquent(
|
|||
// voted in the last `MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION`
|
||||
if eligible_for_deactivate_delinquent(&delinquent_vote_state.epoch_credits, current_epoch) {
|
||||
stake.deactivate(current_epoch)?;
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, stake_flags))
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(meta, stake, stake_flags))
|
||||
} else {
|
||||
Err(StakeError::MinimumDelinquentEpochsForDeactivationNotMet.into())
|
||||
}
|
||||
|
@ -1312,13 +1326,13 @@ impl MergeKind {
|
|||
|
||||
fn get_if_mergeable(
|
||||
invoke_context: &InvokeContext,
|
||||
stake_state: &StakeState,
|
||||
stake_state: &StakeStateWithFlags,
|
||||
stake_lamports: u64,
|
||||
clock: &Clock,
|
||||
stake_history: &StakeHistory,
|
||||
) -> Result<Self, InstructionError> {
|
||||
match stake_state {
|
||||
StakeState::Stake(meta, stake, stake_flags) => {
|
||||
StakeStateWithFlags::Stake(meta, stake, stake_flags) => {
|
||||
// stake must not be in a transient state. Transient here meaning
|
||||
// activating or deactivating with non-zero effective stake.
|
||||
let status = stake.delegation.stake_activating_and_deactivating(
|
||||
|
@ -1338,7 +1352,7 @@ impl MergeKind {
|
|||
}
|
||||
}
|
||||
}
|
||||
StakeState::Initialized(meta) => {
|
||||
StakeStateWithFlags::Initialized(meta) => {
|
||||
Ok(Self::Inactive(*meta, stake_lamports, StakeFlags::empty()))
|
||||
}
|
||||
_ => Err(InstructionError::InvalidAccountData),
|
||||
|
@ -1412,7 +1426,7 @@ impl MergeKind {
|
|||
invoke_context: &InvokeContext,
|
||||
source: Self,
|
||||
clock: &Clock,
|
||||
) -> Result<Option<StakeState>, InstructionError> {
|
||||
) -> Result<Option<StakeStateWithFlags>, InstructionError> {
|
||||
Self::metas_can_merge(invoke_context, self.meta(), source.meta(), clock)?;
|
||||
self.active_stake()
|
||||
.zip(source.active_stake())
|
||||
|
@ -1439,7 +1453,7 @@ impl MergeKind {
|
|||
Self::Inactive(_, source_lamports, source_stake_flags),
|
||||
) => {
|
||||
stake.delegation.stake = checked_add(stake.delegation.stake, source_lamports)?;
|
||||
Some(StakeState::Stake(
|
||||
Some(StakeStateWithFlags::Stake(
|
||||
meta,
|
||||
stake,
|
||||
stake_flags.union(source_stake_flags),
|
||||
|
@ -1459,7 +1473,7 @@ impl MergeKind {
|
|||
source_lamports,
|
||||
source_stake.credits_observed,
|
||||
)?;
|
||||
Some(StakeState::Stake(
|
||||
Some(StakeStateWithFlags::Stake(
|
||||
meta,
|
||||
stake,
|
||||
stake_flags.union(source_stake_flags),
|
||||
|
@ -1476,7 +1490,7 @@ impl MergeKind {
|
|||
source_stake.delegation.stake,
|
||||
source_stake.credits_observed,
|
||||
)?;
|
||||
Some(StakeState::Stake(meta, stake, StakeFlags::empty()))
|
||||
Some(StakeStateWithFlags::Stake(meta, stake, StakeFlags::empty()))
|
||||
}
|
||||
_ => return Err(StakeError::MergeMismatch.into()),
|
||||
};
|
||||
|
@ -1555,7 +1569,7 @@ fn stake_weighted_credits_observed(
|
|||
#[doc(hidden)]
|
||||
pub fn redeem_rewards(
|
||||
rewarded_epoch: Epoch,
|
||||
stake_state: StakeState,
|
||||
stake_state: StakeStateWithFlags,
|
||||
stake_account: &mut AccountSharedData,
|
||||
vote_state: &VoteState,
|
||||
point_value: &PointValue,
|
||||
|
@ -1563,7 +1577,7 @@ pub fn redeem_rewards(
|
|||
inflation_point_calc_tracer: Option<impl Fn(&InflationPointCalculationEvent)>,
|
||||
new_rate_activation_epoch: Option<Epoch>,
|
||||
) -> Result<(u64, u64), InstructionError> {
|
||||
if let StakeState::Stake(meta, mut stake, stake_flags) = stake_state {
|
||||
if let StakeStateWithFlags::Stake(meta, mut stake, stake_flags) = stake_state {
|
||||
if let Some(inflation_point_calc_tracer) = inflation_point_calc_tracer.as_ref() {
|
||||
inflation_point_calc_tracer(
|
||||
&InflationPointCalculationEvent::EffectiveStakeAtRewardedEpoch(stake.stake(
|
||||
|
@ -1590,7 +1604,7 @@ pub fn redeem_rewards(
|
|||
new_rate_activation_epoch,
|
||||
) {
|
||||
stake_account.checked_add_lamports(stakers_reward)?;
|
||||
stake_account.set_state(&StakeState::Stake(meta, stake, stake_flags))?;
|
||||
stake_account.set_state(&StakeStateWithFlags::Stake(meta, stake, stake_flags))?;
|
||||
|
||||
Ok((stakers_reward, voters_reward))
|
||||
} else {
|
||||
|
@ -1604,12 +1618,12 @@ pub fn redeem_rewards(
|
|||
// utility function, used by runtime
|
||||
#[doc(hidden)]
|
||||
pub fn calculate_points(
|
||||
stake_state: &StakeState,
|
||||
stake_state: &StakeStateWithFlags,
|
||||
vote_state: &VoteState,
|
||||
stake_history: Option<&StakeHistory>,
|
||||
new_rate_activation_epoch: Option<Epoch>,
|
||||
) -> Result<u128, InstructionError> {
|
||||
if let StakeState::Stake(_meta, stake, _stake_flags) = stake_state {
|
||||
if let StakeStateWithFlags::Stake(_meta, stake, _stake_flags) = stake_state {
|
||||
Ok(calculate_stake_points(
|
||||
stake,
|
||||
vote_state,
|
||||
|
@ -1678,7 +1692,7 @@ pub fn create_lockup_stake_account(
|
|||
rent: &Rent,
|
||||
lamports: u64,
|
||||
) -> AccountSharedData {
|
||||
let mut stake_account = AccountSharedData::new(lamports, StakeState::size_of(), &id());
|
||||
let mut stake_account = AccountSharedData::new(lamports, StakeStateWithFlags::size_of(), &id());
|
||||
|
||||
let rent_exempt_reserve = rent.minimum_balance(stake_account.data().len());
|
||||
assert!(
|
||||
|
@ -1687,7 +1701,7 @@ pub fn create_lockup_stake_account(
|
|||
);
|
||||
|
||||
stake_account
|
||||
.set_state(&StakeState::Initialized(Meta {
|
||||
.set_state(&StakeStateWithFlags::Initialized(Meta {
|
||||
authorized: *authorized,
|
||||
lockup: *lockup,
|
||||
rent_exempt_reserve,
|
||||
|
@ -1742,14 +1756,14 @@ fn do_create_account(
|
|||
lamports: u64,
|
||||
activation_epoch: Epoch,
|
||||
) -> AccountSharedData {
|
||||
let mut stake_account = AccountSharedData::new(lamports, StakeState::size_of(), &id());
|
||||
let mut stake_account = AccountSharedData::new(lamports, StakeStateWithFlags::size_of(), &id());
|
||||
|
||||
let vote_state = vote_state::from(vote_account).expect("vote_state");
|
||||
|
||||
let rent_exempt_reserve = rent.minimum_balance(stake_account.data().len());
|
||||
|
||||
stake_account
|
||||
.set_state(&StakeState::Stake(
|
||||
.set_state(&StakeStateWithFlags::Stake(
|
||||
Meta {
|
||||
authorized: Authorized::auto(authorized),
|
||||
rent_exempt_reserve,
|
||||
|
@ -1925,10 +1939,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_stake_state_stake_from_fail() {
|
||||
let mut stake_account = AccountSharedData::new(0, StakeState::size_of(), &id());
|
||||
let mut stake_account = AccountSharedData::new(0, StakeStateWithFlags::size_of(), &id());
|
||||
|
||||
stake_account
|
||||
.set_state(&StakeState::default())
|
||||
.set_state(&StakeStateWithFlags::default())
|
||||
.expect("set_state");
|
||||
|
||||
assert_eq!(stake_from(&stake_account), None);
|
||||
|
@ -2985,7 +2999,7 @@ mod tests {
|
|||
#[ignore]
|
||||
#[should_panic]
|
||||
fn test_dbg_stake_minimum_balance() {
|
||||
let minimum_balance = Rent::default().minimum_balance(StakeState::size_of());
|
||||
let minimum_balance = Rent::default().minimum_balance(StakeStateWithFlags::size_of());
|
||||
panic!(
|
||||
"stake minimum_balance: {} lamports, {} SOL",
|
||||
minimum_balance,
|
||||
|
@ -3230,7 +3244,7 @@ mod tests {
|
|||
let authority_pubkey = Pubkey::new_unique();
|
||||
let initial_lamports = 4242424242;
|
||||
let rent = Rent::default();
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeStateWithFlags::size_of());
|
||||
let stake_lamports = rent_exempt_reserve + initial_lamports;
|
||||
let new_rate_activation_epoch = Some(0);
|
||||
|
||||
|
@ -3240,8 +3254,8 @@ mod tests {
|
|||
};
|
||||
let mut stake_account = AccountSharedData::new_data_with_space(
|
||||
stake_lamports,
|
||||
&StakeState::Uninitialized,
|
||||
StakeState::size_of(),
|
||||
&StakeStateWithFlags::Uninitialized,
|
||||
StakeStateWithFlags::size_of(),
|
||||
&id(),
|
||||
)
|
||||
.expect("stake_account");
|
||||
|
@ -3262,7 +3276,9 @@ mod tests {
|
|||
);
|
||||
|
||||
// RewardsPool state fails
|
||||
stake_account.set_state(&StakeState::RewardsPool).unwrap();
|
||||
stake_account
|
||||
.set_state(&StakeStateWithFlags::RewardsPool)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
MergeKind::get_if_mergeable(
|
||||
&invoke_context,
|
||||
|
@ -3277,7 +3293,7 @@ mod tests {
|
|||
|
||||
// Initialized state succeeds
|
||||
stake_account
|
||||
.set_state(&StakeState::Initialized(meta))
|
||||
.set_state(&StakeStateWithFlags::Initialized(meta))
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
MergeKind::get_if_mergeable(
|
||||
|
@ -3325,7 +3341,11 @@ mod tests {
|
|||
..Stake::default()
|
||||
};
|
||||
stake_account
|
||||
.set_state(&StakeState::Stake(meta, stake, StakeFlags::empty()))
|
||||
.set_state(&StakeStateWithFlags::Stake(
|
||||
meta,
|
||||
stake,
|
||||
StakeFlags::empty(),
|
||||
))
|
||||
.unwrap();
|
||||
// activation_epoch succeeds
|
||||
assert_eq!(
|
||||
|
|
|
@ -68,7 +68,7 @@ use {
|
|||
message::SanitizedMessage,
|
||||
pubkey::{Pubkey, PUBKEY_BYTES},
|
||||
signature::{Keypair, Signature, Signer},
|
||||
stake::state::{StakeActivationStatus, StakeState},
|
||||
stake::state::{StakeActivationStatus, StakeStateWithFlags},
|
||||
stake_history::StakeHistory,
|
||||
system_instruction,
|
||||
sysvar::stake_history,
|
||||
|
@ -1731,7 +1731,7 @@ impl JsonRpcRequestProcessor {
|
|||
let stake_account = bank
|
||||
.get_account(pubkey)
|
||||
.ok_or_else(|| Error::invalid_params("Invalid param: account not found".to_string()))?;
|
||||
let stake_state: StakeState = stake_account
|
||||
let stake_state: StakeStateWithFlags = stake_account
|
||||
.state()
|
||||
.map_err(|_| Error::invalid_params("Invalid param: not a stake account".to_string()))?;
|
||||
let delegation = stake_state.delegation();
|
||||
|
|
|
@ -635,7 +635,7 @@ mod tests {
|
|||
signature::{Keypair, Signer},
|
||||
stake::{
|
||||
self, instruction as stake_instruction,
|
||||
state::{Authorized, Lockup, StakeAuthorize, StakeState},
|
||||
state::{Authorized, Lockup, StakeAuthorize, StakeStateWithFlags},
|
||||
},
|
||||
system_instruction, system_program, system_transaction,
|
||||
transaction::{self, Transaction},
|
||||
|
@ -907,7 +907,7 @@ mod tests {
|
|||
let balance = {
|
||||
let bank = bank_forks.read().unwrap().working_bank();
|
||||
let rent = &bank.rent_collector().rent;
|
||||
rent.minimum_balance(StakeState::size_of())
|
||||
rent.minimum_balance(StakeStateWithFlags::size_of())
|
||||
};
|
||||
|
||||
let tx = system_transaction::transfer(&alice, &from.pubkey(), balance, blockhash);
|
||||
|
|
|
@ -174,7 +174,7 @@ use {
|
|||
},
|
||||
},
|
||||
solana_stake_program::stake_state::{
|
||||
self, InflationPointCalculationEvent, PointValue, StakeState,
|
||||
self, InflationPointCalculationEvent, PointValue, StakeStateWithFlags,
|
||||
},
|
||||
solana_system_program::{get_system_account_kind, SystemAccountKind},
|
||||
solana_vote_program::vote_state::VoteState,
|
||||
|
@ -3122,7 +3122,7 @@ impl Bank {
|
|||
|
||||
let delegation = stake_account.delegation();
|
||||
let (mut stake_account, stake_state) =
|
||||
<(AccountSharedData, StakeState)>::from(stake_account);
|
||||
<(AccountSharedData, StakeStateWithFlags)>::from(stake_account);
|
||||
let vote_pubkey = delegation.voter_pubkey;
|
||||
let Some(vote_account) = get_vote_account(&vote_pubkey) else {
|
||||
return None;
|
||||
|
@ -3253,7 +3253,7 @@ impl Bank {
|
|||
}
|
||||
});
|
||||
let (mut stake_account, stake_state) =
|
||||
<(AccountSharedData, StakeState)>::from(stake_account);
|
||||
<(AccountSharedData, StakeStateWithFlags)>::from(stake_account);
|
||||
let redeemed = stake_state::redeem_rewards(
|
||||
rewarded_epoch,
|
||||
stake_state,
|
||||
|
|
|
@ -96,7 +96,7 @@ use {
|
|||
},
|
||||
transaction_context::{TransactionAccount, TransactionContext},
|
||||
},
|
||||
solana_stake_program::stake_state::{self, StakeState},
|
||||
solana_stake_program::stake_state::{self, StakeStateWithFlags},
|
||||
solana_vote_program::{
|
||||
vote_instruction,
|
||||
vote_state::{
|
||||
|
@ -4417,7 +4417,7 @@ fn test_bank_cloned_stake_delegations() {
|
|||
let (vote_balance, stake_balance) = {
|
||||
let rent = &bank.rent_collector().rent;
|
||||
let vote_rent_exempt_reserve = rent.minimum_balance(VoteState::size_of());
|
||||
let stake_rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
|
||||
let stake_rent_exempt_reserve = rent.minimum_balance(StakeStateWithFlags::size_of());
|
||||
let minimum_delegation = solana_stake_program::get_minimum_delegation(&bank.feature_set);
|
||||
(
|
||||
vote_rent_exempt_reserve,
|
||||
|
|
|
@ -10,7 +10,7 @@ use {
|
|||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
signature::{Keypair, Signer},
|
||||
stake::state::StakeState,
|
||||
stake::state::StakeStateWithFlags,
|
||||
system_program,
|
||||
},
|
||||
solana_stake_program::stake_state,
|
||||
|
@ -23,7 +23,7 @@ const VALIDATOR_LAMPORTS: u64 = 42;
|
|||
|
||||
// fun fact: rustc is very close to make this const fn.
|
||||
pub fn bootstrap_validator_stake_lamports() -> u64 {
|
||||
Rent::default().minimum_balance(StakeState::size_of())
|
||||
Rent::default().minimum_balance(StakeStateWithFlags::size_of())
|
||||
}
|
||||
|
||||
// Number of lamports automatically used for genesis accounts
|
||||
|
|
|
@ -7,7 +7,7 @@ use {
|
|||
solana_sdk::{
|
||||
account::ReadableAccount,
|
||||
pubkey::Pubkey,
|
||||
stake::{self, state::StakeState},
|
||||
stake::{self, state::StakeStateWithFlags},
|
||||
},
|
||||
solana_stake_program::stake_state,
|
||||
std::{collections::HashSet, sync::Arc},
|
||||
|
@ -53,14 +53,14 @@ pub fn calculate_non_circulating_supply(bank: &Arc<Bank>) -> ScanResult<NonCircu
|
|||
for (pubkey, account) in stake_accounts.iter() {
|
||||
let stake_account = stake_state::from(account).unwrap_or_default();
|
||||
match stake_account {
|
||||
StakeState::Initialized(meta) => {
|
||||
StakeStateWithFlags::Initialized(meta) => {
|
||||
if meta.lockup.is_in_force(&clock, None)
|
||||
|| withdraw_authority_list.contains(&meta.authorized.withdrawer)
|
||||
{
|
||||
non_circulating_accounts_set.insert(*pubkey);
|
||||
}
|
||||
}
|
||||
StakeState::Stake(meta, _stake, _stake_flags) => {
|
||||
StakeStateWithFlags::Stake(meta, _stake, _stake_flags) => {
|
||||
if meta.lockup.is_in_force(&clock, None)
|
||||
|| withdraw_authority_list.contains(&meta.authorized.withdrawer)
|
||||
{
|
||||
|
@ -264,8 +264,8 @@ mod tests {
|
|||
};
|
||||
let stake_account = Account::new_data_with_space(
|
||||
balance,
|
||||
&StakeState::Initialized(meta),
|
||||
StakeState::size_of(),
|
||||
&StakeStateWithFlags::Initialized(meta),
|
||||
StakeStateWithFlags::size_of(),
|
||||
&stake::program::id(),
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -6,7 +6,7 @@ use {
|
|||
account_utils::StateMut,
|
||||
instruction::InstructionError,
|
||||
pubkey::Pubkey,
|
||||
stake::state::{Delegation, StakeState},
|
||||
stake::state::{Delegation, StakeStateWithFlags},
|
||||
},
|
||||
std::marker::PhantomData,
|
||||
thiserror::Error,
|
||||
|
@ -19,7 +19,7 @@ use {
|
|||
#[derive(Clone, Debug, Default)]
|
||||
pub struct StakeAccount<T> {
|
||||
account: AccountSharedData,
|
||||
stake_state: StakeState,
|
||||
stake_state: StakeStateWithFlags,
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ pub enum Error {
|
|||
#[error(transparent)]
|
||||
InstructionError(#[from] InstructionError),
|
||||
#[error("Invalid delegation: {0:?}")]
|
||||
InvalidDelegation(Box<StakeState>),
|
||||
InvalidDelegation(Box<StakeStateWithFlags>),
|
||||
#[error("Invalid stake account owner: {0}")]
|
||||
InvalidOwner(/*owner:*/ Pubkey),
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ impl<T> StakeAccount<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn stake_state(&self) -> &StakeState {
|
||||
pub(crate) fn stake_state(&self) -> &StakeStateWithFlags {
|
||||
&self.stake_state
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ impl TryFrom<AccountSharedData> for StakeAccount<Delegation> {
|
|||
if account.owner() != &solana_stake_program::id() {
|
||||
return Err(Error::InvalidOwner(*account.owner()));
|
||||
}
|
||||
let stake_state: StakeState = account.state()?;
|
||||
let stake_state: StakeStateWithFlags = account.state()?;
|
||||
if stake_state.delegation().is_none() {
|
||||
return Err(Error::InvalidDelegation(Box::new(stake_state)));
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ impl TryFrom<AccountSharedData> for StakeAccount<Delegation> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> From<StakeAccount<T>> for (AccountSharedData, StakeState) {
|
||||
impl<T> From<StakeAccount<T>> for (AccountSharedData, StakeStateWithFlags) {
|
||||
#[inline]
|
||||
fn from(stake_account: StakeAccount<T>) -> Self {
|
||||
(stake_account.account, stake_account.stake_state)
|
||||
|
@ -102,7 +102,7 @@ impl AbiExample for StakeAccount<Delegation> {
|
|||
},
|
||||
};
|
||||
let stake_state =
|
||||
StakeState::Stake(Meta::example(), Stake::example(), StakeFlags::example());
|
||||
StakeStateWithFlags::Stake(Meta::example(), Stake::example(), StakeFlags::example());
|
||||
let mut account = Account::example();
|
||||
account.data.resize(200, 0u8);
|
||||
account.owner = solana_stake_program::id();
|
||||
|
|
|
@ -179,7 +179,7 @@ impl StakesCache {
|
|||
/// [`Stakes<Delegation>`] is equivalent to the old code and is used for backward
|
||||
/// compatibility in [`crate::bank::BankFieldsToDeserialize`].
|
||||
/// But banks cache [`Stakes<StakeAccount>`] which includes the entire stake
|
||||
/// account and StakeState deserialized from the account. Doing so, will remove
|
||||
/// account and StakeStateWithFlags deserialized from the account. Doing so, will remove
|
||||
/// the need to load the stake account from accounts-db when working with
|
||||
/// stake-delegations.
|
||||
#[derive(Default, Clone, PartialEq, Debug, Deserialize, Serialize, AbiExample)]
|
||||
|
|
|
@ -19,7 +19,7 @@ use {
|
|||
signature::{Keypair, Signer},
|
||||
stake::{
|
||||
self, instruction as stake_instruction,
|
||||
state::{Authorized, Lockup, StakeState},
|
||||
state::{Authorized, Lockup, StakeStateWithFlags},
|
||||
},
|
||||
sysvar::{self, stake_history::StakeHistory},
|
||||
},
|
||||
|
@ -145,7 +145,7 @@ fn test_stake_create_and_split_single_signature() {
|
|||
|
||||
let lamports = {
|
||||
let rent = &bank.rent_collector().rent;
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeStateWithFlags::size_of());
|
||||
let minimum_delegation = solana_stake_program::get_minimum_delegation(&bank.feature_set);
|
||||
2 * (rent_exempt_reserve + minimum_delegation)
|
||||
};
|
||||
|
@ -221,7 +221,7 @@ fn test_stake_create_and_split_to_existing_system_account() {
|
|||
|
||||
let lamports = {
|
||||
let rent = &bank.rent_collector().rent;
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeStateWithFlags::size_of());
|
||||
let minimum_delegation = solana_stake_program::get_minimum_delegation(&bank.feature_set);
|
||||
2 * (rent_exempt_reserve + minimum_delegation)
|
||||
};
|
||||
|
@ -314,7 +314,7 @@ fn test_stake_account_lifetime() {
|
|||
let rent = &bank.rent_collector().rent;
|
||||
(
|
||||
rent.minimum_balance(VoteState::size_of()),
|
||||
rent.minimum_balance(StakeState::size_of()),
|
||||
rent.minimum_balance(StakeStateWithFlags::size_of()),
|
||||
solana_stake_program::get_minimum_delegation(&bank.feature_set),
|
||||
)
|
||||
};
|
||||
|
@ -367,7 +367,7 @@ fn test_stake_account_lifetime() {
|
|||
// Test that correct lamports are staked
|
||||
let account = bank.get_account(&stake_pubkey).expect("account not found");
|
||||
let stake_state = account.state().expect("couldn't unpack account data");
|
||||
if let StakeState::Stake(_meta, stake, _stake_flags) = stake_state {
|
||||
if let StakeStateWithFlags::Stake(_meta, stake, _stake_flags) = stake_state {
|
||||
assert_eq!(stake.delegation.stake, stake_starting_delegation,);
|
||||
} else {
|
||||
panic!("wrong account type found")
|
||||
|
@ -391,7 +391,7 @@ fn test_stake_account_lifetime() {
|
|||
// Test that lamports are still staked
|
||||
let account = bank.get_account(&stake_pubkey).expect("account not found");
|
||||
let stake_state = account.state().expect("couldn't unpack account data");
|
||||
if let StakeState::Stake(_meta, stake, _stake_flags) = stake_state {
|
||||
if let StakeStateWithFlags::Stake(_meta, stake, _stake_flags) = stake_state {
|
||||
assert_eq!(stake.delegation.stake, stake_starting_delegation,);
|
||||
} else {
|
||||
panic!("wrong account type found")
|
||||
|
@ -615,7 +615,7 @@ fn test_create_stake_account_from_seed() {
|
|||
let authorized = Authorized::auto(&mint_pubkey);
|
||||
let (balance, delegation) = {
|
||||
let rent = &bank.rent_collector().rent;
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeStateWithFlags::size_of());
|
||||
let minimum_delegation = solana_stake_program::get_minimum_delegation(&bank.feature_set);
|
||||
(rent_exempt_reserve + minimum_delegation, minimum_delegation)
|
||||
};
|
||||
|
@ -641,7 +641,7 @@ fn test_create_stake_account_from_seed() {
|
|||
// Test that correct lamports are staked
|
||||
let account = bank.get_account(&stake_pubkey).expect("account not found");
|
||||
let stake_state = account.state().expect("couldn't unpack account data");
|
||||
if let StakeState::Stake(_meta, stake, _) = stake_state {
|
||||
if let StakeStateWithFlags::Stake(_meta, stake, _) = stake_state {
|
||||
assert_eq!(stake.delegation.stake, delegation);
|
||||
} else {
|
||||
panic!("wrong account type found")
|
||||
|
|
|
@ -8,7 +8,7 @@ use {
|
|||
pubkey::Pubkey,
|
||||
stake::{
|
||||
program::id,
|
||||
state::{Authorized, Lockup, StakeAuthorize, StakeState},
|
||||
state::{Authorized, Lockup, StakeAuthorize, StakeStateWithFlags},
|
||||
},
|
||||
system_instruction, sysvar,
|
||||
},
|
||||
|
@ -364,7 +364,7 @@ pub fn create_account_with_seed(
|
|||
base,
|
||||
seed,
|
||||
lamports,
|
||||
StakeState::size_of() as u64,
|
||||
StakeStateWithFlags::size_of() as u64,
|
||||
&id(),
|
||||
),
|
||||
initialize(stake_pubkey, authorized, lockup),
|
||||
|
@ -383,7 +383,7 @@ pub fn create_account(
|
|||
from_pubkey,
|
||||
stake_pubkey,
|
||||
lamports,
|
||||
StakeState::size_of() as u64,
|
||||
StakeStateWithFlags::size_of() as u64,
|
||||
&id(),
|
||||
),
|
||||
initialize(stake_pubkey, authorized, lockup),
|
||||
|
@ -405,7 +405,7 @@ pub fn create_account_with_seed_checked(
|
|||
base,
|
||||
seed,
|
||||
lamports,
|
||||
StakeState::size_of() as u64,
|
||||
StakeStateWithFlags::size_of() as u64,
|
||||
&id(),
|
||||
),
|
||||
initialize_checked(stake_pubkey, authorized),
|
||||
|
@ -423,7 +423,7 @@ pub fn create_account_checked(
|
|||
from_pubkey,
|
||||
stake_pubkey,
|
||||
lamports,
|
||||
StakeState::size_of() as u64,
|
||||
StakeStateWithFlags::size_of() as u64,
|
||||
&id(),
|
||||
),
|
||||
initialize_checked(stake_pubkey, authorized),
|
||||
|
@ -452,7 +452,7 @@ pub fn split(
|
|||
split_stake_pubkey: &Pubkey,
|
||||
) -> Vec<Instruction> {
|
||||
vec![
|
||||
system_instruction::allocate(split_stake_pubkey, StakeState::size_of() as u64),
|
||||
system_instruction::allocate(split_stake_pubkey, StakeStateWithFlags::size_of() as u64),
|
||||
system_instruction::assign(split_stake_pubkey, &id()),
|
||||
_split(
|
||||
stake_pubkey,
|
||||
|
@ -476,7 +476,7 @@ pub fn split_with_seed(
|
|||
split_stake_pubkey,
|
||||
base,
|
||||
seed,
|
||||
StakeState::size_of() as u64,
|
||||
StakeStateWithFlags::size_of() as u64,
|
||||
&id(),
|
||||
),
|
||||
_split(
|
||||
|
@ -796,7 +796,10 @@ pub fn redelegate(
|
|||
uninitialized_stake_pubkey: &Pubkey,
|
||||
) -> Vec<Instruction> {
|
||||
vec![
|
||||
system_instruction::allocate(uninitialized_stake_pubkey, StakeState::size_of() as u64),
|
||||
system_instruction::allocate(
|
||||
uninitialized_stake_pubkey,
|
||||
StakeStateWithFlags::size_of() as u64,
|
||||
),
|
||||
system_instruction::assign(uninitialized_stake_pubkey, &id()),
|
||||
_redelegate(
|
||||
stake_pubkey,
|
||||
|
@ -820,7 +823,7 @@ pub fn redelegate_with_seed(
|
|||
uninitialized_stake_pubkey,
|
||||
base,
|
||||
seed,
|
||||
StakeState::size_of() as u64,
|
||||
StakeStateWithFlags::size_of() as u64,
|
||||
&id(),
|
||||
),
|
||||
_redelegate(
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
// Remove the following `allow` when `StakeState` is removed, required to avoid
|
||||
// warnings from uses of deprecated types during trait derivations.
|
||||
#![allow(deprecated)]
|
||||
|
||||
use {
|
||||
crate::{
|
||||
|
@ -33,14 +36,17 @@ pub fn warmup_cooldown_rate(current_epoch: Epoch, new_rate_activation_epoch: Opt
|
|||
|
||||
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[deprecated(
|
||||
since = "1.17.0",
|
||||
note = "Please use `StakeStateWithFlags` instead, and match the third `StakeFlags` field when matching `StakeStateWithFlags::Stake` to resolve any breakage. For example, `if let StakeState::Stake(meta, stake)` becomes `if let StakeStateWithFlags::Stake(meta, stake, _stake_flags)`."
|
||||
)]
|
||||
pub enum StakeState {
|
||||
#[default]
|
||||
Uninitialized,
|
||||
Initialized(Meta),
|
||||
Stake(Meta, Stake, StakeFlags),
|
||||
Stake(Meta, Stake),
|
||||
RewardsPool,
|
||||
}
|
||||
|
||||
impl BorshDeserialize for StakeState {
|
||||
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||
let enum_value = u32::deserialize_reader(reader)?;
|
||||
|
@ -53,8 +59,7 @@ impl BorshDeserialize for StakeState {
|
|||
2 => {
|
||||
let meta: Meta = BorshDeserialize::deserialize_reader(reader)?;
|
||||
let stake: Stake = BorshDeserialize::deserialize_reader(reader)?;
|
||||
let stake_flags: StakeFlags = BorshDeserialize::deserialize_reader(reader)?;
|
||||
Ok(StakeState::Stake(meta, stake, stake_flags))
|
||||
Ok(StakeState::Stake(meta, stake))
|
||||
}
|
||||
3 => Ok(StakeState::RewardsPool),
|
||||
_ => Err(io::Error::new(
|
||||
|
@ -64,7 +69,6 @@ impl BorshDeserialize for StakeState {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BorshSerialize for StakeState {
|
||||
fn serialize<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
match self {
|
||||
|
@ -73,17 +77,15 @@ impl BorshSerialize for StakeState {
|
|||
writer.write_all(&1u32.to_le_bytes())?;
|
||||
meta.serialize(writer)
|
||||
}
|
||||
StakeState::Stake(meta, stake, stake_flags) => {
|
||||
StakeState::Stake(meta, stake) => {
|
||||
writer.write_all(&2u32.to_le_bytes())?;
|
||||
meta.serialize(writer)?;
|
||||
stake.serialize(writer)?;
|
||||
stake_flags.serialize(writer)
|
||||
stake.serialize(writer)
|
||||
}
|
||||
StakeState::RewardsPool => writer.write_all(&3u32.to_le_bytes()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StakeState {
|
||||
/// The fixed number of bytes used to serialize each stake account
|
||||
pub const fn size_of() -> usize {
|
||||
|
@ -92,21 +94,21 @@ impl StakeState {
|
|||
|
||||
pub fn stake(&self) -> Option<Stake> {
|
||||
match self {
|
||||
StakeState::Stake(_meta, stake, _stake_flags) => Some(*stake),
|
||||
StakeState::Stake(_meta, stake) => Some(*stake),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delegation(&self) -> Option<Delegation> {
|
||||
match self {
|
||||
StakeState::Stake(_meta, stake, _stake_flags) => Some(stake.delegation),
|
||||
StakeState::Stake(_meta, stake) => Some(stake.delegation),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn authorized(&self) -> Option<Authorized> {
|
||||
match self {
|
||||
StakeState::Stake(meta, _stake, _stake_flags) => Some(meta.authorized),
|
||||
StakeState::Stake(meta, _stake) => Some(meta.authorized),
|
||||
StakeState::Initialized(meta) => Some(meta.authorized),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -118,13 +120,107 @@ impl StakeState {
|
|||
|
||||
pub fn meta(&self) -> Option<Meta> {
|
||||
match self {
|
||||
StakeState::Stake(meta, _stake, _stake_flags) => Some(*meta),
|
||||
StakeState::Stake(meta, _stake) => Some(*meta),
|
||||
StakeState::Initialized(meta) => Some(*meta),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy, AbiExample)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum StakeStateWithFlags {
|
||||
#[default]
|
||||
Uninitialized,
|
||||
Initialized(Meta),
|
||||
Stake(Meta, Stake, StakeFlags),
|
||||
RewardsPool,
|
||||
}
|
||||
|
||||
impl BorshDeserialize for StakeStateWithFlags {
|
||||
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||
let enum_value = u32::deserialize_reader(reader)?;
|
||||
match enum_value {
|
||||
0 => Ok(StakeStateWithFlags::Uninitialized),
|
||||
1 => {
|
||||
let meta = Meta::deserialize_reader(reader)?;
|
||||
Ok(StakeStateWithFlags::Initialized(meta))
|
||||
}
|
||||
2 => {
|
||||
let meta: Meta = BorshDeserialize::deserialize_reader(reader)?;
|
||||
let stake: Stake = BorshDeserialize::deserialize_reader(reader)?;
|
||||
let stake_flags: StakeFlags = BorshDeserialize::deserialize_reader(reader)?;
|
||||
Ok(StakeStateWithFlags::Stake(meta, stake, stake_flags))
|
||||
}
|
||||
3 => Ok(StakeStateWithFlags::RewardsPool),
|
||||
_ => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Invalid enum value",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BorshSerialize for StakeStateWithFlags {
|
||||
fn serialize<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
match self {
|
||||
StakeStateWithFlags::Uninitialized => writer.write_all(&0u32.to_le_bytes()),
|
||||
StakeStateWithFlags::Initialized(meta) => {
|
||||
writer.write_all(&1u32.to_le_bytes())?;
|
||||
meta.serialize(writer)
|
||||
}
|
||||
StakeStateWithFlags::Stake(meta, stake, stake_flags) => {
|
||||
writer.write_all(&2u32.to_le_bytes())?;
|
||||
meta.serialize(writer)?;
|
||||
stake.serialize(writer)?;
|
||||
stake_flags.serialize(writer)
|
||||
}
|
||||
StakeStateWithFlags::RewardsPool => writer.write_all(&3u32.to_le_bytes()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StakeStateWithFlags {
|
||||
/// The fixed number of bytes used to serialize each stake account
|
||||
pub const fn size_of() -> usize {
|
||||
200 // see test_size_of
|
||||
}
|
||||
|
||||
pub fn stake(&self) -> Option<Stake> {
|
||||
match self {
|
||||
StakeStateWithFlags::Stake(_meta, stake, _stake_flags) => Some(*stake),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delegation(&self) -> Option<Delegation> {
|
||||
match self {
|
||||
StakeStateWithFlags::Stake(_meta, stake, _stake_flags) => Some(stake.delegation),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn authorized(&self) -> Option<Authorized> {
|
||||
match self {
|
||||
StakeStateWithFlags::Stake(meta, _stake, _stake_flags) => Some(meta.authorized),
|
||||
StakeStateWithFlags::Initialized(meta) => Some(meta.authorized),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lockup(&self) -> Option<Lockup> {
|
||||
self.meta().map(|meta| meta.lockup)
|
||||
}
|
||||
|
||||
pub fn meta(&self) -> Option<Meta> {
|
||||
match self {
|
||||
StakeStateWithFlags::Stake(meta, _stake, _stake_flags) => Some(*meta),
|
||||
StakeStateWithFlags::Initialized(meta) => Some(*meta),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy, AbiExample)]
|
||||
pub enum StakeAuthorize {
|
||||
Staker,
|
||||
|
@ -615,28 +711,31 @@ mod test {
|
|||
bincode::serialize,
|
||||
};
|
||||
|
||||
fn check_borsh_deserialization(stake: StakeState) {
|
||||
fn check_borsh_deserialization(stake: StakeStateWithFlags) {
|
||||
let serialized = serialize(&stake).unwrap();
|
||||
let deserialized = StakeState::try_from_slice(&serialized).unwrap();
|
||||
let deserialized = StakeStateWithFlags::try_from_slice(&serialized).unwrap();
|
||||
assert_eq!(stake, deserialized);
|
||||
}
|
||||
|
||||
fn check_borsh_serialization(stake: StakeState) {
|
||||
fn check_borsh_serialization(stake: StakeStateWithFlags) {
|
||||
let bincode_serialized = serialize(&stake).unwrap();
|
||||
let borsh_serialized = StakeState::try_to_vec(&stake).unwrap();
|
||||
let borsh_serialized = StakeStateWithFlags::try_to_vec(&stake).unwrap();
|
||||
assert_eq!(bincode_serialized, borsh_serialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_size_of() {
|
||||
assert_eq!(StakeState::size_of(), std::mem::size_of::<StakeState>());
|
||||
assert_eq!(
|
||||
StakeStateWithFlags::size_of(),
|
||||
std::mem::size_of::<StakeStateWithFlags>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bincode_vs_borsh_deserialization() {
|
||||
check_borsh_deserialization(StakeState::Uninitialized);
|
||||
check_borsh_deserialization(StakeState::RewardsPool);
|
||||
check_borsh_deserialization(StakeState::Initialized(Meta {
|
||||
check_borsh_deserialization(StakeStateWithFlags::Uninitialized);
|
||||
check_borsh_deserialization(StakeStateWithFlags::RewardsPool);
|
||||
check_borsh_deserialization(StakeStateWithFlags::Initialized(Meta {
|
||||
rent_exempt_reserve: u64::MAX,
|
||||
authorized: Authorized {
|
||||
staker: Pubkey::new_unique(),
|
||||
|
@ -644,7 +743,7 @@ mod test {
|
|||
},
|
||||
lockup: Lockup::default(),
|
||||
}));
|
||||
check_borsh_deserialization(StakeState::Stake(
|
||||
check_borsh_deserialization(StakeStateWithFlags::Stake(
|
||||
Meta {
|
||||
rent_exempt_reserve: 1,
|
||||
authorized: Authorized {
|
||||
|
@ -669,9 +768,9 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn bincode_vs_borsh_serialization() {
|
||||
check_borsh_serialization(StakeState::Uninitialized);
|
||||
check_borsh_serialization(StakeState::RewardsPool);
|
||||
check_borsh_serialization(StakeState::Initialized(Meta {
|
||||
check_borsh_serialization(StakeStateWithFlags::Uninitialized);
|
||||
check_borsh_serialization(StakeStateWithFlags::RewardsPool);
|
||||
check_borsh_serialization(StakeStateWithFlags::Initialized(Meta {
|
||||
rent_exempt_reserve: u64::MAX,
|
||||
authorized: Authorized {
|
||||
staker: Pubkey::new_unique(),
|
||||
|
@ -679,7 +778,7 @@ mod test {
|
|||
},
|
||||
lockup: Lockup::default(),
|
||||
}));
|
||||
check_borsh_serialization(StakeState::Stake(
|
||||
check_borsh_serialization(StakeStateWithFlags::Stake(
|
||||
Meta {
|
||||
rent_exempt_reserve: 1,
|
||||
authorized: Authorized {
|
||||
|
@ -717,13 +816,126 @@ mod test {
|
|||
];
|
||||
// As long as we get the 4-byte enum and the first field right, then
|
||||
// we're sure the rest works out
|
||||
let deserialized = try_from_slice_unchecked::<StakeState>(&data).unwrap();
|
||||
let deserialized = try_from_slice_unchecked::<StakeStateWithFlags>(&data).unwrap();
|
||||
assert_matches!(
|
||||
deserialized,
|
||||
StakeState::Initialized(Meta {
|
||||
StakeStateWithFlags::Initialized(Meta {
|
||||
rent_exempt_reserve: 2282880,
|
||||
..
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
mod deprecated {
|
||||
use super::*;
|
||||
fn check_borsh_deserialization(stake: StakeState) {
|
||||
let serialized = serialize(&stake).unwrap();
|
||||
let deserialized = StakeState::try_from_slice(&serialized).unwrap();
|
||||
assert_eq!(stake, deserialized);
|
||||
}
|
||||
|
||||
fn check_borsh_serialization(stake: StakeState) {
|
||||
let bincode_serialized = serialize(&stake).unwrap();
|
||||
let borsh_serialized = StakeState::try_to_vec(&stake).unwrap();
|
||||
assert_eq!(bincode_serialized, borsh_serialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_size_of() {
|
||||
assert_eq!(StakeState::size_of(), std::mem::size_of::<StakeState>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bincode_vs_borsh_deserialization() {
|
||||
check_borsh_deserialization(StakeState::Uninitialized);
|
||||
check_borsh_deserialization(StakeState::RewardsPool);
|
||||
check_borsh_deserialization(StakeState::Initialized(Meta {
|
||||
rent_exempt_reserve: u64::MAX,
|
||||
authorized: Authorized {
|
||||
staker: Pubkey::new_unique(),
|
||||
withdrawer: Pubkey::new_unique(),
|
||||
},
|
||||
lockup: Lockup::default(),
|
||||
}));
|
||||
check_borsh_deserialization(StakeState::Stake(
|
||||
Meta {
|
||||
rent_exempt_reserve: 1,
|
||||
authorized: Authorized {
|
||||
staker: Pubkey::new_unique(),
|
||||
withdrawer: Pubkey::new_unique(),
|
||||
},
|
||||
lockup: Lockup::default(),
|
||||
},
|
||||
Stake {
|
||||
delegation: Delegation {
|
||||
voter_pubkey: Pubkey::new_unique(),
|
||||
stake: u64::MAX,
|
||||
activation_epoch: Epoch::MAX,
|
||||
deactivation_epoch: Epoch::MAX,
|
||||
warmup_cooldown_rate: f64::MAX,
|
||||
},
|
||||
credits_observed: 1,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bincode_vs_borsh_serialization() {
|
||||
check_borsh_serialization(StakeState::Uninitialized);
|
||||
check_borsh_serialization(StakeState::RewardsPool);
|
||||
check_borsh_serialization(StakeState::Initialized(Meta {
|
||||
rent_exempt_reserve: u64::MAX,
|
||||
authorized: Authorized {
|
||||
staker: Pubkey::new_unique(),
|
||||
withdrawer: Pubkey::new_unique(),
|
||||
},
|
||||
lockup: Lockup::default(),
|
||||
}));
|
||||
check_borsh_serialization(StakeState::Stake(
|
||||
Meta {
|
||||
rent_exempt_reserve: 1,
|
||||
authorized: Authorized {
|
||||
staker: Pubkey::new_unique(),
|
||||
withdrawer: Pubkey::new_unique(),
|
||||
},
|
||||
lockup: Lockup::default(),
|
||||
},
|
||||
Stake {
|
||||
delegation: Delegation {
|
||||
voter_pubkey: Pubkey::new_unique(),
|
||||
stake: u64::MAX,
|
||||
activation_epoch: Epoch::MAX,
|
||||
deactivation_epoch: Epoch::MAX,
|
||||
warmup_cooldown_rate: f64::MAX,
|
||||
},
|
||||
credits_observed: 1,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn borsh_deserialization_live_data() {
|
||||
let data = [
|
||||
1, 0, 0, 0, 128, 213, 34, 0, 0, 0, 0, 0, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35,
|
||||
119, 124, 168, 12, 120, 216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246,
|
||||
149, 224, 109, 52, 100, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35, 119, 124, 168,
|
||||
12, 120, 216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246, 149, 224, 109, 52,
|
||||
100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
// As long as we get the 4-byte enum and the first field right, then
|
||||
// we're sure the rest works out
|
||||
let deserialized = try_from_slice_unchecked::<StakeState>(&data).unwrap();
|
||||
assert_matches!(
|
||||
deserialized,
|
||||
StakeState::Initialized(Meta {
|
||||
rent_exempt_reserve: 2282880,
|
||||
..
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ mod tests {
|
|||
client::SyncClient,
|
||||
genesis_config::create_genesis_config,
|
||||
signature::{Keypair, Signer},
|
||||
stake::state::StakeState,
|
||||
stake::state::StakeStateWithFlags,
|
||||
},
|
||||
solana_stake_program::stake_state,
|
||||
};
|
||||
|
@ -297,7 +297,8 @@ mod tests {
|
|||
fn create_bank(lamports: u64) -> (Bank, Keypair, u64, u64) {
|
||||
let (genesis_config, mint_keypair) = create_genesis_config(lamports);
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
let stake_rent = bank.get_minimum_balance_for_rent_exemption(StakeState::size_of());
|
||||
let stake_rent =
|
||||
bank.get_minimum_balance_for_rent_exemption(StakeStateWithFlags::size_of());
|
||||
let system_rent = bank.get_minimum_balance_for_rent_exemption(0);
|
||||
(bank, mint_keypair, stake_rent, system_rent)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue