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