diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 9104f5b855d00e..bac5875bc431f0 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -3248,7 +3248,7 @@ mod tests { }, ]; - // should pass, withdrawing account down to minimum balance + // should pass, withdrawing initialized account down to minimum balance process_instruction( &serialize(&StakeInstruction::Withdraw(stake_lamports)).unwrap(), transaction_accounts.clone(), @@ -3765,10 +3765,7 @@ mod tests { ]; for (stake_delegation, expected_result) in [ (minimum_delegation, Ok(())), - ( - minimum_delegation - 1, - Err(InstructionError::InsufficientStakeDelegation), - ), + (minimum_delegation - 1, Err(StakeError::InsufficientStake)), ] { for stake_state in &[ StakeState::Initialized(meta), @@ -3800,7 +3797,7 @@ mod tests { ), ], instruction_accounts.clone(), - expected_result.clone(), + expected_result.clone().map_err(|e| e.into()), ); } } diff --git a/programs/stake/src/stake_state.rs b/programs/stake/src/stake_state.rs index ea0447d4930086..936110ff49136c 100644 --- a/programs/stake/src/stake_state.rs +++ b/programs/stake/src/stake_state.rs @@ -1027,10 +1027,16 @@ fn validate_delegated_amount( let stake_amount = account .get_lamports() .saturating_sub(meta.rent_exempt_reserve); // can't stake the rent + + // Previously, `initialize` checked that the stake account balance met + // the minimum delegation amount. + // With the `stake_allow_zero_undelegated_amount` feature, stake accounts + // may be initialized with a lower balance, so check the minimum in this + // function, on delegation. if feature_set.is_active(&stake_allow_zero_undelegated_amount::id()) && stake_amount < crate::get_minimum_delegation(feature_set) { - return Err(InstructionError::InsufficientStakeDelegation); + return Err(StakeError::InsufficientStake.into()); } Ok(ValidatedDelegatedInfo { stake_amount }) } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index fc311c96cae63e..1ef3761d749e4b 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -239,7 +239,7 @@ impl RentDebits { } type BankStatusCache = StatusCache>; -#[frozen_abi(digest = "3JVSVs9JHV2ZZNVTz3R6qKiFsaBYqzgTuxYjFJ1NwPSY")] +#[frozen_abi(digest = "BQcJmh4VRCiNNtqjKPyphs9ULFbSUKGGfx6hz9SWBtqU")] pub type BankSlotDelta = SlotDelta>; // Eager rent collection repeats in cyclic manner. diff --git a/sdk/program/src/instruction.rs b/sdk/program/src/instruction.rs index 5a8559231ce447..0de8f9337fcf2e 100644 --- a/sdk/program/src/instruction.rs +++ b/sdk/program/src/instruction.rs @@ -256,10 +256,6 @@ pub enum InstructionError { /// Active vote account close #[error("Cannot close vote account unless it stopped voting at least one full epoch ago")] ActiveVoteAccountClose, - - // Insufficient stake delegation - #[error("Stake amount is below the minimum delegation requirements")] - InsufficientStakeDelegation, // Note: For any new error added here an equivalent ProgramError and its // conversions must also be added } diff --git a/sdk/program/src/program_error.rs b/sdk/program/src/program_error.rs index 32069ad93093f2..d0e7e7643b4c07 100644 --- a/sdk/program/src/program_error.rs +++ b/sdk/program/src/program_error.rs @@ -55,8 +55,6 @@ pub enum ProgramError { MaxAccountsDataSizeExceeded, #[error("Cannot close vote account unless it stopped voting at least one full epoch ago")] ActiveVoteAccountClose, - #[error("Stake amount is below the minimum delegation requirements")] - InsufficientStakeDelegation, } pub trait PrintProgramError { @@ -97,7 +95,6 @@ impl PrintProgramError for ProgramError { Self::IllegalOwner => msg!("Error: IllegalOwner"), Self::MaxAccountsDataSizeExceeded => msg!("Error: MaxAccountsDataSizeExceeded"), Self::ActiveVoteAccountClose => msg!("Error: ActiveVoteAccountClose"), - Self::InsufficientStakeDelegation => msg!("Error: InsufficientStakeDelegation"), } } } @@ -130,7 +127,6 @@ pub const UNSUPPORTED_SYSVAR: u64 = to_builtin!(17); pub const ILLEGAL_OWNER: u64 = to_builtin!(18); pub const MAX_ACCOUNTS_DATA_SIZE_EXCEEDED: u64 = to_builtin!(19); pub const ACTIVE_VOTE_ACCOUNT_CLOSE: u64 = to_builtin!(20); -pub const INSUFFICIENT_STAKE_DELEGATION: u64 = to_builtin!(21); // Warning: Any new program errors added here must also be: // - Added to the below conversions // - Added as an equivilent to InstructionError @@ -159,7 +155,6 @@ impl From for u64 { ProgramError::IllegalOwner => ILLEGAL_OWNER, ProgramError::MaxAccountsDataSizeExceeded => MAX_ACCOUNTS_DATA_SIZE_EXCEEDED, ProgramError::ActiveVoteAccountClose => ACTIVE_VOTE_ACCOUNT_CLOSE, - ProgramError::InsufficientStakeDelegation => INSUFFICIENT_STAKE_DELEGATION, ProgramError::Custom(error) => { if error == 0 { CUSTOM_ZERO @@ -194,7 +189,6 @@ impl From for ProgramError { ILLEGAL_OWNER => Self::IllegalOwner, MAX_ACCOUNTS_DATA_SIZE_EXCEEDED => Self::MaxAccountsDataSizeExceeded, ACTIVE_VOTE_ACCOUNT_CLOSE => Self::ActiveVoteAccountClose, - INSUFFICIENT_STAKE_DELEGATION => Self::InsufficientStakeDelegation, _ => Self::Custom(error as u32), } } @@ -225,7 +219,6 @@ impl TryFrom for ProgramError { Self::Error::IllegalOwner => Ok(Self::IllegalOwner), Self::Error::MaxAccountsDataSizeExceeded => Ok(Self::MaxAccountsDataSizeExceeded), Self::Error::ActiveVoteAccountClose => Ok(Self::ActiveVoteAccountClose), - Self::Error::InsufficientStakeDelegation => Ok(Self::InsufficientStakeDelegation), _ => Err(error), } } @@ -258,7 +251,6 @@ where ILLEGAL_OWNER => Self::IllegalOwner, MAX_ACCOUNTS_DATA_SIZE_EXCEEDED => Self::MaxAccountsDataSizeExceeded, ACTIVE_VOTE_ACCOUNT_CLOSE => Self::ActiveVoteAccountClose, - INSUFFICIENT_STAKE_DELEGATION => Self::InsufficientStakeDelegation, _ => { // A valid custom error has no bits set in the upper 32 if error >> BUILTIN_BIT_SHIFT == 0 { diff --git a/storage-proto/proto/transaction_by_addr.proto b/storage-proto/proto/transaction_by_addr.proto index 0211042b1bf7a7..f4896906864efe 100644 --- a/storage-proto/proto/transaction_by_addr.proto +++ b/storage-proto/proto/transaction_by_addr.proto @@ -115,7 +115,6 @@ enum InstructionErrorType { ILLEGAL_OWNER = 49; MAX_ACCOUNTS_DATA_SIZE_EXCEEDED = 50; ACTIVE_VOTE_ACCOUNT_CLOSE = 51; - INSUFFICIENT_STAKE_DELEGATION = 52; } message UnixTimestamp { diff --git a/storage-proto/src/convert.rs b/storage-proto/src/convert.rs index 8b6fcfa7ab9bad..997898ea6062f7 100644 --- a/storage-proto/src/convert.rs +++ b/storage-proto/src/convert.rs @@ -706,7 +706,6 @@ impl TryFrom for TransactionError { 49 => InstructionError::IllegalOwner, 50 => InstructionError::MaxAccountsDataSizeExceeded, 51 => InstructionError::ActiveVoteAccountClose, - 52 => InstructionError::InsufficientStakeDelegation, _ => return Err("Invalid InstructionError"), }; @@ -1004,9 +1003,6 @@ impl From for tx_by_addr::TransactionError { InstructionError::ActiveVoteAccountClose => { tx_by_addr::InstructionErrorType::ActiveVoteAccountClose } - InstructionError::InsufficientStakeDelegation => { - tx_by_addr::InstructionErrorType::InsufficientStakeDelegation - } } as i32, custom: match instruction_error { InstructionError::Custom(custom) => {