Repository navigation
Conversation
9fc637b to
759f64b
Compare
| /// Deserialize a Vote Program-owned account as [`VoteStateV4`]. | ||
| #[cfg(feature = "bincode")] | ||
| pub fn get_vote_state(vote_account_info: &AccountInfo) -> Result<Box<VoteStateV4>, ProgramError> { | ||
| if *vote_account_info.owner != solana_vote_interface::program::id() { | ||
| return Err(ProgramError::IncorrectProgramId); | ||
| } | ||
|
|
||
| let mut vote_state = Box::new(MaybeUninit::uninit()); | ||
| VoteStateV4::deserialize_into_uninit( | ||
| &vote_account_info.try_borrow_data()?, | ||
| vote_state.as_mut(), | ||
| vote_account_info.key, | ||
| ) | ||
| .map_err(|_| ProgramError::InvalidAccountData)?; | ||
| let vote_state = unsafe { Box::from_raw(Box::into_raw(vote_state).cast::<VoteStateV4>()) }; | ||
|
|
||
| Ok(vote_state) | ||
| } | ||
|
|
There was a problem hiding this comment.
Moved from program/src/processor.rs so helpers here can use it
| if let StakeStateV2::Stake(meta, mut stake, stake_flags) = | ||
| let StakeStateV2::Stake(meta, mut stake, stake_flags) = | ||
| get_stake_state(stake_account_info)? | ||
| { | ||
| if stake.delegation.voter_pubkey != *delinquent_vote_account_info.key { | ||
| return Err(StakeError::VoteAddressMismatch.into()); | ||
| } | ||
| else { | ||
| return Err(ProgramError::InvalidAccountData); | ||
| }; | ||
|
|
||
| // Deactivate the stake account if its delegated vote account has never voted or | ||
| // has not voted in the last | ||
| // `MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION` | ||
| if eligible_for_deactivate_delinquent(&delinquent_vote_state.epoch_credits, clock.epoch) | ||
| { | ||
| stake.deactivate(clock.epoch)?; | ||
| if stake.delegation.voter_pubkey != *delinquent_vote_account_info.key { | ||
| return Err(StakeError::VoteAddressMismatch.into()); | ||
| } | ||
|
|
||
| set_stake_state( | ||
| stake_account_info, | ||
| &StakeStateV2::Stake(meta, stake, stake_flags), | ||
| ) | ||
| } else { | ||
| Err(StakeError::MinimumDelinquentEpochsForDeactivationNotMet.into()) | ||
| } | ||
| } else { | ||
| Err(ProgramError::InvalidAccountData) | ||
| }?; |
There was a problem hiding this comment.
Inverted some of this control flow for easier reading
759f64b to
522e6bc
Compare
| &Pubkey::new_unique(), | ||
| ), | ||
| Err(ProgramError::IncorrectProgramId), | ||
| ); | ||
| process_instruction_as_one_arg( | ||
| &mollusk, | ||
| &instruction::deactivate_delinquent_stake( | ||
| &Pubkey::new_unique(), | ||
| &invalid_vote_state_pubkey(), | ||
| &Pubkey::new_unique(), | ||
| &invalid_vote_state_pubkey(), |
There was a problem hiding this comment.
The error order changes because the reference vote account is now checked before the delinquent account in the processor.
joncinque
left a comment
There was a problem hiding this comment.
Looks great overall! Just a few small questions
522e6bc to
95e11c1
Compare
joncinque
left a comment
There was a problem hiding this comment.
Sorry, just a couple more things that I noticed
76106c0 to
3787289
Compare
|
Given my upcoming leave and need to shepherd the feature gate in, moving this to draft until beginning of Nov |
3787289 to
171adf5
Compare
171adf5 to
ddf7128
Compare
|
A few updates since returning on this:
|
| address: &Pubkey, | ||
| owner: &Pubkey, | ||
| data: &[u8], | ||
| ) -> Result<Box<VoteStateV4>, ProgramError> { |
There was a problem hiding this comment.
With VoteStateV5, we'll have to have a v2 of this fn. Given the breaking change, I suspect we'll need to have a custom type that handles both the v4 and v5 deserialization and differing field accessing cases for us.
Implements SIMD-0608. The
DeactivateDelinquentinstruction now also accepts stake delegated to a closed vote account, restoring a cleanup path for delegations orphaned in this edge case.New Behavior
The delinquency condition is satisfied when the delegated vote account:
All other Vote owned data goes through the existing vote-state decoding and five-epoch credit checks.