Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increases staking delays #1030

Merged
merged 8 commits into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions node/service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ moonbeam-rpc-primitives-debug = { path = "../../primitives/rpc/debug" }
moonbeam-rpc-primitives-txpool = { path = "../../primitives/rpc/txpool" }
moonbeam-rpc-trace = { path = "../../client/rpc/trace" }
moonbeam-rpc-txpool = { path = "../../client/rpc/txpool" }
parachain-staking = { path = "../../pallets/parachain-staking" }

# Moonbeam runtimes
moonbase-runtime = { path = "../../runtime/moonbase", optional = true }
Expand Down
28 changes: 17 additions & 11 deletions node/service/src/chain_spec/moonbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,29 @@ pub fn get_chain_spec(para_id: ParaId) -> ChainSpec {
}

pub fn moonbeam_inflation_config() -> InflationInfo<Balance> {
fn to_round_inflation(annual: Range<Perbill>) -> Range<Perbill> {
use parachain_staking::inflation::{perbill_annual_to_perbill_round, BLOCKS_PER_YEAR};
perbill_annual_to_perbill_round(
annual,
// rounds per year
BLOCKS_PER_YEAR / moonbase_runtime::DefaultBlocksPerRound::get(),
)
}
let annual = Range {
min: Perbill::from_percent(4),
ideal: Perbill::from_percent(5),
max: Perbill::from_percent(5),
};
InflationInfo {
// staking expectations
expect: Range {
min: 100_000 * UNIT,
ideal: 200_000 * UNIT,
max: 500_000 * UNIT,
},
annual: Range {
min: Perbill::from_percent(4),
ideal: Perbill::from_percent(5),
max: Perbill::from_percent(5),
},
// 8766 rounds (hours) in a year
round: Range {
min: Perbill::from_parts(Perbill::from_percent(4).deconstruct() / 8766),
ideal: Perbill::from_parts(Perbill::from_percent(5).deconstruct() / 8766),
max: Perbill::from_parts(Perbill::from_percent(5).deconstruct() / 8766),
},
// annual inflation
annual,
round: to_round_inflation(annual),
}
}

Expand Down
28 changes: 17 additions & 11 deletions node/service/src/chain_spec/moonbeam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,29 @@ pub fn get_chain_spec(para_id: ParaId) -> ChainSpec {
}

pub fn moonbeam_inflation_config() -> InflationInfo<Balance> {
fn to_round_inflation(annual: Range<Perbill>) -> Range<Perbill> {
use parachain_staking::inflation::{perbill_annual_to_perbill_round, BLOCKS_PER_YEAR};
perbill_annual_to_perbill_round(
annual,
// rounds per year
BLOCKS_PER_YEAR / moonbeam_runtime::DefaultBlocksPerRound::get(),
)
}
let annual = Range {
min: Perbill::from_percent(4),
ideal: Perbill::from_percent(5),
max: Perbill::from_percent(5),
};
InflationInfo {
// staking expectations
expect: Range {
min: 100_000 * GLMR,
ideal: 200_000 * GLMR,
max: 500_000 * GLMR,
},
annual: Range {
min: Perbill::from_percent(4),
ideal: Perbill::from_percent(5),
max: Perbill::from_percent(5),
},
// 8766 rounds (hours) in a year
round: Range {
min: Perbill::from_parts(Perbill::from_percent(4).deconstruct() / 8766),
ideal: Perbill::from_parts(Perbill::from_percent(5).deconstruct() / 8766),
max: Perbill::from_parts(Perbill::from_percent(5).deconstruct() / 8766),
},
// annual inflation
annual,
round: to_round_inflation(annual),
}
}

Expand Down
28 changes: 17 additions & 11 deletions node/service/src/chain_spec/moonriver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,23 +140,29 @@ pub fn get_chain_spec(para_id: ParaId) -> ChainSpec {
}

pub fn moonbeam_inflation_config() -> InflationInfo<Balance> {
fn to_round_inflation(annual: Range<Perbill>) -> Range<Perbill> {
use parachain_staking::inflation::{perbill_annual_to_perbill_round, BLOCKS_PER_YEAR};
perbill_annual_to_perbill_round(
annual,
// rounds per year
BLOCKS_PER_YEAR / moonriver_runtime::DefaultBlocksPerRound::get(),
)
}
let annual = Range {
min: Perbill::from_percent(4),
ideal: Perbill::from_percent(5),
max: Perbill::from_percent(5),
};
InflationInfo {
// staking expectations
expect: Range {
min: 100_000 * MOVR,
ideal: 200_000 * MOVR,
max: 500_000 * MOVR,
},
annual: Range {
min: Perbill::from_percent(4),
ideal: Perbill::from_percent(5),
max: Perbill::from_percent(5),
},
// 8766 rounds (hours) in a year
round: Range {
min: Perbill::from_parts(Perbill::from_percent(4).deconstruct() / 8766),
ideal: Perbill::from_parts(Perbill::from_percent(5).deconstruct() / 8766),
max: Perbill::from_parts(Perbill::from_percent(5).deconstruct() / 8766),
},
// annual inflation
annual,
round: to_round_inflation(annual),
}
}

Expand Down
7 changes: 5 additions & 2 deletions pallets/parachain-staking/src/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use substrate_fixed::types::{I32F32, I64F64};

const SECONDS_PER_YEAR: u32 = 31557600;
const SECONDS_PER_BLOCK: u32 = 12;
const BLOCKS_PER_YEAR: u32 = SECONDS_PER_YEAR / SECONDS_PER_BLOCK;
pub const BLOCKS_PER_YEAR: u32 = SECONDS_PER_YEAR / SECONDS_PER_BLOCK;

fn rounds_per_year<T: Config>() -> u32 {
let blocks_per_round = <Pallet<T>>::round().length;
Expand Down Expand Up @@ -60,7 +60,10 @@ impl<T: Ord + Copy> From<T> for Range<T> {
}
/// Convert an annual inflation to a round inflation
/// round = 1 - (1+annual)^(1/rounds_per_year)
fn perbill_annual_to_perbill_round(annual: Range<Perbill>, rounds_per_year: u32) -> Range<Perbill> {
pub fn perbill_annual_to_perbill_round(
annual: Range<Perbill>,
rounds_per_year: u32,
) -> Range<Perbill> {
let exponent = I32F32::from_num(1) / I32F32::from_num(rounds_per_year);
let annual_to_round = |annual: Perbill| -> Perbill {
let x = I32F32::from_num(annual.deconstruct()) / I32F32::from_num(Perbill::ACCURACY);
Expand Down
2 changes: 1 addition & 1 deletion pallets/parachain-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

#[cfg(any(test, feature = "runtime-benchmarks"))]
mod benchmarks;
mod inflation;
pub mod inflation;
pub mod migrations;
#[cfg(test)]
mod mock;
Expand Down
22 changes: 11 additions & 11 deletions runtime/moonbase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,19 +705,19 @@ impl parachain_info::Config for Runtime {}
parameter_types! {
/// Minimum round length is 2 minutes (10 * 12 second block times)
pub const MinBlocksPerRound: u32 = 10;
/// Default BlocksPerRound is every hour (300 * 12 second block times)
pub const DefaultBlocksPerRound: u32 = 300;
/// Collator candidate exits are delayed by 2 hours (2 * 300 * block_time)
/// Blocks per round
pub const DefaultBlocksPerRound: u32 = 2 * HOURS;
/// Rounds before the collator leaving the candidates request can be executed
pub const LeaveCandidatesDelay: u32 = 2;
/// Collator candidate bond increases/decreases are delayed by 2 hours (2 * 300 block_time)
/// Rounds before the candidate bond increase/decrease can be executed
pub const CandidateBondLessDelay: u32 = 2;
/// Delegator exits are delayed by 2 hours (2 * 300 * block_time)
/// Rounds before the delegator exit can be executed
pub const LeaveDelegatorsDelay: u32 = 2;
/// Delegation revocations are delayed by 2 hours (2 * 300 * block_time)
/// Rounds before the delegator revocation can be executed
pub const RevokeDelegationDelay: u32 = 2;
/// Delegation bond decreases are delayed by 2 hours (2 * 300 * block_time)
/// Rounds before the delegator bond increase/decrease can be executed
pub const DelegationBondLessDelay: u32 = 2;
/// Reward payments are delayed by 2 hours (2 * 300 * block_time)
/// Rounds before the reward is paid
pub const RewardPaymentDelay: u32 = 2;
/// Minimum collators selected per round, default at genesis and minimum forever after
pub const MinSelectedCandidates: u32 = 8;
Expand All @@ -730,9 +730,9 @@ parameter_types! {
/// Default percent of inflation set aside for parachain bond every round
pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30);
/// Minimum stake required to become a collator
pub const MinCollatorStk: u128 = 1 * currency::KILOUNIT * currency::SUPPLY_FACTOR;
pub const MinCollatorStk: u128 = 1000 * currency::UNIT * currency::SUPPLY_FACTOR;
/// Minimum stake required to be reserved to be a candidate
pub const MinCandidateStk: u128 = 1 * currency::KILOUNIT * currency::SUPPLY_FACTOR;
pub const MinCandidateStk: u128 = 500 * currency::UNIT * currency::SUPPLY_FACTOR;
/// Minimum stake required to be reserved to be a delegator
pub const MinDelegatorStk: u128 = 5 * currency::UNIT * currency::SUPPLY_FACTOR;
}
Expand Down Expand Up @@ -1788,7 +1788,7 @@ mod tests {

// staking minimums
assert_eq!(MinCollatorStk::get(), Balance::from(1 * KILOUNIT));
assert_eq!(MinCandidateStk::get(), Balance::from(1 * KILOUNIT));
assert_eq!(MinCandidateStk::get(), Balance::from(500 * UNIT));
assert_eq!(MinDelegatorStk::get(), Balance::from(5 * UNIT));

// crowdloan min reward
Expand Down
8 changes: 4 additions & 4 deletions runtime/moonbase/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,15 +417,15 @@ fn reward_block_authors() {
.build()
.execute_with(|| {
set_parachain_inherent_data();
for x in 2..599 {
for x in 2..1199 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to express these in terms of the configuration values like 5 * LeaveDelegatorsDelay or whatever value this is. But that can be for a followup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my deferred staking PR (#1035 ) I added a roll_to_round_begin which takes a round number rather than a block number. That's only loosely related to this...

set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(x);
}
// no rewards doled out yet
assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 1_000 * UNIT,);
assert_eq!(Balances::free_balance(AccountId::from(BOB)), 500 * UNIT,);
set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(600);
run_to_block(1200);
// rewards minted and distributed
assert_eq!(
Balances::free_balance(AccountId::from(ALICE)),
Expand Down Expand Up @@ -464,7 +464,7 @@ fn reward_block_authors_with_parachain_bond_reserved() {
root_origin(),
AccountId::from(CHARLIE),
),);
for x in 2..599 {
for x in 2..1199 {
set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(x);
}
Expand All @@ -473,7 +473,7 @@ fn reward_block_authors_with_parachain_bond_reserved() {
assert_eq!(Balances::free_balance(AccountId::from(BOB)), 500 * UNIT,);
assert_eq!(Balances::free_balance(AccountId::from(CHARLIE)), UNIT,);
set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(600);
run_to_block(1200);
// rewards minted and distributed
assert_eq!(
Balances::free_balance(AccountId::from(ALICE)),
Expand Down
30 changes: 15 additions & 15 deletions runtime/moonbeam/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,19 +665,19 @@ impl parachain_info::Config for Runtime {}
parameter_types! {
/// Minimum round length is 2 minutes (10 * 12 second block times)
pub const MinBlocksPerRound: u32 = 10;
/// Default BlocksPerRound is every 4 hours (1200 * 12 second block times)
pub const DefaultBlocksPerRound: u32 = 4 * HOURS;
/// Collator candidate exit delay (number of rounds)
pub const LeaveCandidatesDelay: u32 = 2;
/// Collator candidate bond increases/decreases delay (number of rounds)
pub const CandidateBondLessDelay: u32 = 2;
/// Delegator exit delay (number of rounds)
pub const LeaveDelegatorsDelay: u32 = 2;
/// Delegation revocations delay (number of rounds)
pub const RevokeDelegationDelay: u32 = 2;
/// Delegation bond decreases delay (number of rounds)
pub const DelegationBondLessDelay: u32 = 2;
/// Reward payments delay (number of rounds)
/// Blocks per round
pub const DefaultBlocksPerRound: u32 = 6 * HOURS;
/// Rounds before the collator leaving the candidates request can be executed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Rounds before the collator leaving the candidates request can be executed
/// Rounds before the candidate's request to leave can be executed

My rewording makes it clear that this applies to all candidates, not just the selected collators. But after writing it, I wasn't sure that was actually true.

pub const LeaveCandidatesDelay: u32 = 4 * 7;
/// Rounds before the candidate bond increase/decrease can be executed
pub const CandidateBondLessDelay: u32 = 4 * 7;
/// Rounds before the delegator exit can be executed
pub const LeaveDelegatorsDelay: u32 = 4 * 7;
/// Rounds before the delegator revocation can be executed
pub const RevokeDelegationDelay: u32 = 4 * 7;
/// Rounds before the delegator bond increase/decrease can be executed
pub const DelegationBondLessDelay: u32 = 4 * 7;
/// Rounds before the reward is paid
pub const RewardPaymentDelay: u32 = 2;
/// Minimum collators selected per round, default at genesis and minimum forever after
pub const MinSelectedCandidates: u32 = 8;
Expand All @@ -690,10 +690,10 @@ parameter_types! {
/// Default percent of inflation set aside for parachain bond every round
pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30);
/// Minimum stake required to become a collator
pub const MinCollatorStk: u128 = 1 * currency::KILOGLMR * currency::SUPPLY_FACTOR;
pub const MinCollatorStk: u128 = 1000 * currency::GLMR * currency::SUPPLY_FACTOR;
// TODO: Restore to 100_000 for Phase 2 (remove the division by 10)
/// Minimum stake required to be reserved to be a candidate
pub const MinCandidateStk: u128 = currency::KILOGLMR * currency::SUPPLY_FACTOR / 10;
pub const MinCandidateStk: u128 = 1000 * currency::GLMR * currency::SUPPLY_FACTOR / 10;
4meta5 marked this conversation as resolved.
Show resolved Hide resolved
/// Minimum stake required to be reserved to be a delegator
pub const MinDelegatorStk: u128 = 5 * currency::GLMR * currency::SUPPLY_FACTOR;
}
Expand Down
8 changes: 4 additions & 4 deletions runtime/moonbeam/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ fn reward_block_authors() {
.build()
.execute_with(|| {
set_parachain_inherent_data();
for x in 2..2399 {
for x in 2..3599 {
set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(x);
}
Expand All @@ -435,7 +435,7 @@ fn reward_block_authors() {
);
assert_eq!(Balances::free_balance(AccountId::from(BOB)), 50_000 * GLMR,);
set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(2400);
run_to_block(3600);
// rewards minted and distributed
assert_eq!(
Balances::free_balance(AccountId::from(ALICE)),
Expand Down Expand Up @@ -474,7 +474,7 @@ fn reward_block_authors_with_parachain_bond_reserved() {
root_origin(),
AccountId::from(CHARLIE),
),);
for x in 2..2399 {
for x in 2..3599 {
set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(x);
}
Expand All @@ -486,7 +486,7 @@ fn reward_block_authors_with_parachain_bond_reserved() {
assert_eq!(Balances::free_balance(AccountId::from(BOB)), 50_000 * GLMR,);
assert_eq!(Balances::free_balance(AccountId::from(CHARLIE)), 100 * GLMR,);
set_author(NimbusId::from_slice(&ALICE_NIMBUS));
run_to_block(2400);
run_to_block(3600);
// rewards minted and distributed
assert_eq!(
Balances::free_balance(AccountId::from(ALICE)),
Expand Down
32 changes: 16 additions & 16 deletions runtime/moonriver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,19 +646,19 @@ impl parachain_info::Config for Runtime {}
parameter_types! {
/// Minimum round length is 2 minutes (10 * 12 second block times)
pub const MinBlocksPerRound: u32 = 10;
/// Default BlocksPerRound is every hour (300 * 12 second block times)
pub const DefaultBlocksPerRound: u32 = 300;
/// Collator candidate exits are delayed by 2 hours (2 * 300 * block_time)
pub const LeaveCandidatesDelay: u32 = 2;
/// Collator candidate bond increases/decreases are delayed by 2 hours (2 * 300 block_time)
pub const CandidateBondLessDelay: u32 = 2;
/// Delegator exits are delayed by 2 hours (2 * 300 * block_time)
pub const LeaveDelegatorsDelay: u32 = 2;
/// Delegation revocations are delayed by 2 hours (2 * 300 * block_time)
pub const RevokeDelegationDelay: u32 = 2;
/// Delegation bond decreases are delayed by 2 hours (2 * 300 * block_time)
pub const DelegationBondLessDelay: u32 = 2;
/// Reward payments are delayed by 2 hours (2 * 300 * block_time)
/// Blocks per round
pub const DefaultBlocksPerRound: u32 = 2 * HOURS;
/// Rounds before the collator leaving the candidates request can be executed
pub const LeaveCandidatesDelay: u32 = 24;
/// Rounds before the candidate bond increase/decrease can be executed
pub const CandidateBondLessDelay: u32 = 24;
/// Rounds before the delegator exit can be executed
pub const LeaveDelegatorsDelay: u32 = 24;
/// Rounds before the delegator revocation can be executed
pub const RevokeDelegationDelay: u32 = 24;
/// Rounds before the delegator bond increase/decrease can be executed
pub const DelegationBondLessDelay: u32 = 24;
/// Rounds before the reward is paid
pub const RewardPaymentDelay: u32 = 2;
/// Minimum collators selected per round, default at genesis and minimum forever after
pub const MinSelectedCandidates: u32 = 8;
Expand All @@ -671,9 +671,9 @@ parameter_types! {
/// Default percent of inflation set aside for parachain bond every round
pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30);
/// Minimum stake required to become a collator
pub const MinCollatorStk: u128 = 1 * currency::KILOMOVR * currency::SUPPLY_FACTOR;
pub const MinCollatorStk: u128 = 1000 * currency::MOVR * currency::SUPPLY_FACTOR;
/// Minimum stake required to be reserved to be a candidate
pub const MinCandidateStk: u128 = 1 * currency::KILOMOVR * currency::SUPPLY_FACTOR;
pub const MinCandidateStk: u128 = 500 * currency::MOVR * currency::SUPPLY_FACTOR;
/// Minimum stake required to be reserved to be a delegator
pub const MinDelegatorStk: u128 = 5 * currency::MOVR * currency::SUPPLY_FACTOR;
}
Expand Down Expand Up @@ -1151,7 +1151,7 @@ mod tests {

// staking minimums
assert_eq!(MinCollatorStk::get(), Balance::from(1 * KILOMOVR));
assert_eq!(MinCandidateStk::get(), Balance::from(1 * KILOMOVR));
assert_eq!(MinCandidateStk::get(), Balance::from(500 * MOVR));
assert_eq!(MinDelegatorStk::get(), Balance::from(5 * MOVR));

// crowdloan min reward
Expand Down
Loading