Skip to content

Commit ac65294

Browse files
authored
enable 1 sol minimum delegation (#240)
1 parent 06e46f8 commit ac65294

3 files changed

Lines changed: 36 additions & 52 deletions

File tree

program/src/lib.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,6 @@ pub mod entrypoint;
77

88
solana_pubkey::declare_id!("Stake11111111111111111111111111111111111111");
99

10-
// placeholders for features
11-
// we have ONE feature in the current stake program we care about:
12-
// * stake_raise_minimum_delegation_to_1_sol /
13-
// 9onWzzvCzNC2jfhxxeqRgs5q7nFAAKpCUvkj6T6GJK9i this may or may not be
14-
// activated by time we are done, but it should be confined to the program so
15-
// we use a placeholder for now to call it out. but we can just change the
16-
// program. it is unclear if or when it will ever be activated, because it
17-
// requires a validator vote
18-
const FEATURE_STAKE_RAISE_MINIMUM_DELEGATION_TO_1_SOL: bool = false;
19-
2010
// feature_set::reduce_stake_warmup_cooldown changed the warmup/cooldown from
2111
// 25% to 9%. a function is provided by the sdk,
2212
// new_warmup_cooldown_rate_epoch(), which returns the epoch this change
@@ -34,10 +24,6 @@ const PERPETUAL_NEW_WARMUP_COOLDOWN_RATE_EPOCH: Option<u64> = Some(0);
3424
/// delegation.
3525
#[inline(always)]
3626
pub fn get_minimum_delegation() -> u64 {
37-
if FEATURE_STAKE_RAISE_MINIMUM_DELEGATION_TO_1_SOL {
38-
const MINIMUM_DELEGATION_SOL: u64 = 1;
39-
MINIMUM_DELEGATION_SOL * LAMPORTS_PER_SOL
40-
} else {
41-
1
42-
}
27+
const MINIMUM_DELEGATION_SOL: u64 = 1;
28+
MINIMUM_DELEGATION_SOL * LAMPORTS_PER_SOL
4329
}

program/tests/program_test.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,8 +1048,8 @@ async fn program_test_split(split_source_type: StakeLifecycle) {
10481048
}
10491049
);
10501050

1051-
// an active or transitioning stake account cannot have less than the minimum
1052-
// delegation note this is NOT dependent on the minimum delegation feature.
1051+
// an active or transitioning stake account cannot have less than the minimum delegation
1052+
// this is NOT dependent on the one sol minimum delegation feature
10531053
// there was ALWAYS a minimum. it was one lamport!
10541054
if split_source_type.minimum_delegation_enforced() {
10551055
// underfunded destination fails
@@ -1063,7 +1063,7 @@ async fn program_test_split(split_source_type: StakeLifecycle) {
10631063
let e = process_instruction(&mut context, instruction, &signers)
10641064
.await
10651065
.unwrap_err();
1066-
assert_eq!(e, ProgramError::InsufficientFunds);
1066+
assert_eq!(e, StakeError::InsufficientDelegation.into());
10671067

10681068
// underfunded source fails
10691069
let instruction = &ixn::split(
@@ -1398,10 +1398,6 @@ async fn program_test_deactivate(activate: bool) {
13981398
assert_eq!(e, StakeError::AlreadyDeactivated.into());
13991399
}
14001400

1401-
// XXX the original test_merge is a stupid test
1402-
// the real thing is test_merge_active_stake which actively controls clock and
1403-
// stake_history but im just trying to smoke test rn so lets do something
1404-
// simpler
14051401
#[test_matrix(
14061402
[StakeLifecycle::Uninitialized, StakeLifecycle::Initialized, StakeLifecycle::Activating,
14071403
StakeLifecycle::Active, StakeLifecycle::Deactivating, StakeLifecycle::Deactive],

program/tests/stake_instruction.rs

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,24 +3602,30 @@ fn test_split_minimum_stake_delegation() {
36023602
is_writable: true,
36033603
},
36043604
];
3605-
// NOTE with a 1lamp minimum delegation, cases 2 and 4 merely hit the zero split error
3606-
// these would be InsufficientDelegation if the minimum were 1sol
36073605
for (source_delegation, split_amount, expected_result) in [
3606+
// 0: source is twice minimum, we split minimum
3607+
// success
36083608
(minimum_delegation * 2, minimum_delegation, Ok(())),
3609+
// 1: source is twice minimum, we split one less than minimum
3610+
// dest stake becomes underfunded
36093611
(
36103612
minimum_delegation * 2,
36113613
minimum_delegation - 1,
3612-
Err(ProgramError::InsufficientFunds),
3614+
Err(StakeError::InsufficientDelegation.into()),
36133615
),
3616+
// 2: source is one less than twice minimum, we split minimum
3617+
// source stake becomes underfunded
36143618
(
36153619
(minimum_delegation * 2) - 1,
36163620
minimum_delegation,
36173621
Err(StakeError::InsufficientDelegation.into()),
36183622
),
3623+
// 3: source is two less than twice minimum, we split one less than minimum
3624+
// both stakes become underfunded
36193625
(
36203626
(minimum_delegation - 1) * 2,
36213627
minimum_delegation - 1,
3622-
Err(ProgramError::InsufficientFunds),
3628+
Err(StakeError::InsufficientDelegation.into()),
36233629
),
36243630
] {
36253631
let source_account = AccountSharedData::new_data_with_space(
@@ -3854,12 +3860,9 @@ fn test_initialized_split_destination_minimum_balance() {
38543860
/// Ensure that `split()` correctly handles prefunded destination accounts from staked stakes.
38553861
/// When a destination account already has funds, ensure the minimum split amount reduces
38563862
/// accordingly.
3857-
// NOTE it is not presently possible to test 1sol minimum delegation
3858-
// #[test_case(feature_set_all_enabled(), &[Err(StakeError::InsufficientDelegation.into()), Err(StakeError::InsufficientDelegation.into())]; "all_enabled")]
38593863
#[test]
38603864
fn test_staked_split_destination_minimum_balance() {
38613865
let mollusk = mollusk_bpf();
3862-
let expected_results = &[Ok(()), Ok(())];
38633866

38643867
let minimum_delegation = crate::get_minimum_delegation();
38653868
let rent = Rent::default();
@@ -3884,77 +3887,76 @@ fn test_staked_split_destination_minimum_balance() {
38843887
},
38853888
];
38863889
for (destination_starting_balance, split_amount, expected_result) in [
3887-
// split amount must be non zero
3890+
// 0: split amount must be non zero
38883891
(
38893892
rent_exempt_reserve + minimum_delegation,
38903893
0,
38913894
Err(ProgramError::InsufficientFunds),
38923895
),
3893-
// destination is fully funded:
3894-
// - old behavior: any split amount is OK
3895-
// - new behavior: split amount must be at least the minimum delegation
3896+
// 1: destination is fully funded
3897+
// split amount must still be at least the minimum delegation
38963898
(
38973899
rent_exempt_reserve + minimum_delegation,
3898-
1,
3899-
expected_results[0].clone(),
3900+
minimum_delegation - 1,
3901+
Err(StakeError::InsufficientDelegation.into()),
39003902
),
3901-
// if destination is only short by 1 lamport, then...
3902-
// - old behavior: split amount can be 1 lamport
3903-
// - new behavior: split amount must be at least the minimum delegation
3903+
// 2: destination is short by 1 lamport
3904+
// split amount must still be at least the minimum delegation
39043905
(
39053906
rent_exempt_reserve + minimum_delegation - 1,
39063907
1,
3907-
expected_results[1].clone(),
3908+
Err(StakeError::InsufficientDelegation.into()),
39083909
),
3909-
// destination short by 2 lamports, so 1 isn't enough (non-zero split amount)
3910+
// 3: destination short by 2 lamports
3911+
// split amount must still be at least the minimum delegation
39103912
(
39113913
rent_exempt_reserve + minimum_delegation - 2,
39123914
1,
3913-
Err(ProgramError::InsufficientFunds),
3915+
Err(StakeError::InsufficientDelegation.into()),
39143916
),
3915-
// destination is rent exempt, so split enough for minimum delegation
3917+
// 4: destination is rent exempt, so split enough for minimum delegation
39163918
(rent_exempt_reserve, minimum_delegation, Ok(())),
3917-
// destination is rent exempt, but split amount less than minimum delegation
3919+
// 5: destination is rent exempt, but split amount less than minimum delegation
39183920
(
39193921
rent_exempt_reserve,
3920-
minimum_delegation.saturating_sub(1), // when minimum is 0, this blows up!
3921-
Err(ProgramError::InsufficientFunds),
3922+
minimum_delegation - 1,
3923+
Err(StakeError::InsufficientDelegation.into()),
39223924
),
3923-
// destination is not rent exempt, so any split amount fails, including enough for rent
3925+
// 6: destination is not rent exempt, so any split amount fails, including enough for rent
39243926
// and minimum delegation
39253927
(
39263928
rent_exempt_reserve - 1,
39273929
minimum_delegation + 1,
39283930
Err(ProgramError::InsufficientFunds),
39293931
),
3930-
// destination is not rent exempt, but split amount only for minimum delegation
3932+
// 7: destination is not rent exempt, but split amount only for minimum delegation
39313933
(
39323934
rent_exempt_reserve - 1,
39333935
minimum_delegation,
39343936
Err(ProgramError::InsufficientFunds),
39353937
),
3936-
// destination is not rent exempt, so any split amount fails, including case where
3938+
// 8: destination is not rent exempt, so any split amount fails, including case where
39373939
// destination has smallest non-zero balance
39383940
(
39393941
1,
39403942
rent_exempt_reserve + minimum_delegation - 1,
39413943
Err(ProgramError::InsufficientFunds),
39423944
),
3943-
// destination has smallest non-zero balance, but cannot split less than the minimum
3945+
// 9: destination has smallest non-zero balance, but cannot split less than the minimum
39443946
// balance requirements minus what destination already has
39453947
(
39463948
1,
39473949
rent_exempt_reserve + minimum_delegation - 2,
39483950
Err(ProgramError::InsufficientFunds),
39493951
),
3950-
// destination has zero lamports, so any split amount fails, including at least rent
3952+
// 10: destination has zero lamports, so any split amount fails, including at least rent
39513953
// exempt reserve plus minimum delegation
39523954
(
39533955
0,
39543956
rent_exempt_reserve + minimum_delegation,
39553957
Err(ProgramError::InsufficientFunds),
39563958
),
3957-
// destination has zero lamports, but split amount is less than rent exempt reserve
3959+
// 11: destination has zero lamports, but split amount is less than rent exempt reserve
39583960
// plus minimum delegation
39593961
(
39603962
0,

0 commit comments

Comments
 (0)