Skip to content

Commit

Permalink
First validator rewards (#138)
Browse files Browse the repository at this point in the history
* change getReawrd trait to compute Era trait

* fix bin

* add first validator reards logic

* add first rewards compute_era logic in validator module

* add runtime

* fix type name

* up version
  • Loading branch information
satellitex authored Apr 22, 2020
1 parent 133439e commit c109001
Show file tree
Hide file tree
Showing 16 changed files with 217 additions and 49 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion bin/node/cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "plasm-cli"
version = "0.8.0"
version = "0.8.1"
authors = [
"Takumi Yamashita <[email protected]>",
"Aleksandr Krupenkin <[email protected]>",
Expand Down
2 changes: 1 addition & 1 deletion bin/node/primitives/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "plasm-primitives"
version = "0.8.0"
version = "0.8.1"
authors = [
"Takumi Yamashita <[email protected]>",
"Aleksandr Krupenkin <[email protected]>"
Expand Down
2 changes: 1 addition & 1 deletion bin/node/rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "plasm-rpc"
version = "0.8.0"
version = "0.8.1"
authors = [
"Takumi Yamashita <[email protected]>",
"Aleksandr Krupenkin <[email protected]>"
Expand Down
2 changes: 1 addition & 1 deletion bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "plasm-runtime"
version = "0.8.0"
version = "0.8.1"
authors = [
"Takumi Yamashita <[email protected]>",
"Aleksandr Krupenkin <[email protected]>"
Expand Down
12 changes: 7 additions & 5 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to equal spec_version. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 40,
impl_version: 40,
spec_version: 41,
impl_version: 41,
apis: RUNTIME_API_VERSIONS,
};

Expand Down Expand Up @@ -191,9 +191,9 @@ impl pallet_plasm_rewards::Trait for Runtime {
type Time = Timestamp;
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
type GetForDappsStaking = DappsStaking;
type GetForSecurityStaking = PlasmValidator;
type ComputeTotalPayout = pallet_plasm_rewards::inflation::SimpleComputeTotalPayout;
type ComputeEraForDapps = DappsStaking;
type ComputeEraForSecurity = PlasmValidator;
type ComputeTotalPayout = pallet_plasm_rewards::inflation::FirstPlasmIncentive<u32>;
type MaybeValidators = PlasmValidator;
type Event = Event;
}
Expand All @@ -205,6 +205,8 @@ impl pallet_plasm_validator::Trait for Runtime {
type Reward = (); // Reward is minted.
type EraFinder = PlasmRewards;
type ForSecurityEraReward = PlasmRewards;
type ComputeEraParam = u32;
type ComputeEra = PlasmValidator;
type Event = Event;
}

Expand Down
5 changes: 3 additions & 2 deletions frame/dapps-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use frame_support::{
use frame_system::{self as system, ensure_signed};
use pallet_contract_operator::ContractFinder;
use pallet_plasm_rewards::{
traits::{EraFinder, ForDappsEraRewardFinder, GetEraStakingAmount},
traits::{ComputeEraWithParam, EraFinder, ForDappsEraRewardFinder},
EraIndex, Releases,
};
pub use pallet_staking::{Forcing, RewardDestination};
Expand Down Expand Up @@ -799,7 +799,8 @@ impl<T: Trait> Module<T> {
}

/// Get the amount of staking per Era in a module in the Plasm Network.
impl<T: Trait> GetEraStakingAmount<EraIndex, BalanceOf<T>> for Module<T> {
impl<T: Trait> ComputeEraWithParam<EraIndex> for Module<T> {
type Param = BalanceOf<T>;
fn compute(era: &EraIndex) -> BalanceOf<T> {
Self::elected_operators(era)
}
Expand Down
4 changes: 2 additions & 2 deletions frame/dapps-staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ impl pallet_plasm_rewards::Trait for Test {
type Time = Timestamp;
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
type GetForDappsStaking = DappsStaking;
type GetForSecurityStaking = DappsStaking;
type ComputeEraForDapps = DappsStaking;
type ComputeEraForSecurity = DappsStaking;
type ComputeTotalPayout = SimpleComputeTotalPayout;
type MaybeValidators = DummyMaybeValidators;
type Event = ();
Expand Down
116 changes: 106 additions & 10 deletions frame/plasm-rewards/src/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,61 @@
use super::*;
use sp_arithmetic::traits::BaseArithmetic;
use sp_std::marker::PhantomData;
use traits::ComputeTotalPayout;

pub struct FirstPlasmIncentive<N: BaseArithmetic + Clone + From<u32>> {
_phantom: PhantomData<N>,
}

impl<L, D> ComputeTotalPayout<L, D> for FirstPlasmIncentive<L>
where
L: BaseArithmetic + Clone + From<u32>,
{
fn compute<N, M>(
total_tokens: N,
era_duration: M,
number_of_validator: L,
_dapps_staking: D,
) -> (N, N)
where
N: BaseArithmetic + Clone + From<u32>,
M: BaseArithmetic + Clone + From<u32>,
{
const TARGETS_NUMBER: u128 = 100;
const MILLISECONDS_PER_YEAR: u128 = 1000 * 3600 * 24 * 36525 / 100;
// I_0 = 2.5%.
const I_0_DENOMINATOR: u128 = 25;
const I_0_NUMERATOR: u128 = 1000;
let number_of_validator_clone: u128 = number_of_validator.clone().unique_saturated_into();
let era_duration_clone: u128 = era_duration.clone().unique_saturated_into();
let number_of_validator: u128 = number_of_validator.unique_saturated_into();
let portion = if TARGETS_NUMBER < number_of_validator_clone {
// TotalForSecurityRewards
// = TotalAmountOfIssue * I_0% * (EraDuration / 1year)

// denominator: I_0_DENOMINATOR * EraDuration
// numerator: 1year * I_0_NUMERATOR
Perbill::from_rational_approximation(
I_0_DENOMINATOR * era_duration_clone,
MILLISECONDS_PER_YEAR * I_0_NUMERATOR,
)
} else {
// TotalForSecurityRewards
// = TotalAmountOfIssue * I_0% * (NumberOfValidators/TargetsNumber) * (EraDuration/1year)

// denominator: I_0_DENOMINATOR * NumberOfValidators * EraDuration
// numerator: 1year * I_0_NUMERATOR * TargetsNumber
Perbill::from_rational_approximation(
I_0_DENOMINATOR * number_of_validator * era_duration_clone,
MILLISECONDS_PER_YEAR * I_0_NUMERATOR * TARGETS_NUMBER,
)
};
let payout = portion * total_tokens;
(payout, N::zero())
}
}

pub struct SimpleComputeTotalPayout;

/// The total payout to all operators and validators and their nominators per era.
Expand All @@ -18,12 +71,12 @@ pub struct SimpleComputeTotalPayout;
/// 20% of total issue tokens per a year.
///
/// `era_duration` is expressed in millisecond.
impl ComputeTotalPayout for SimpleComputeTotalPayout {
impl<V, D> ComputeTotalPayout<V, D> for SimpleComputeTotalPayout {
fn compute<N, M>(
total_tokens: N,
era_duration: M,
_validator_staking: N,
_dapps_staking: N,
_validator_staking: V,
_dapps_staking: D,
) -> (N, N)
where
N: BaseArithmetic + Clone + From<u32>,
Expand All @@ -40,7 +93,12 @@ impl ComputeTotalPayout for SimpleComputeTotalPayout {
}
}

pub struct MaintainRatioComputeTotalPayout;
pub struct MaintainRatioComputeTotalPayout<Balance>
where
Balance: BaseArithmetic + Clone + From<u32>,
{
_phantom: PhantomData<Balance>,
}

/// The total payout to all operators and validators and their nominators per era.
///
Expand All @@ -49,12 +107,15 @@ pub struct MaintainRatioComputeTotalPayout;
/// Maintainn is Distribute rewards while maintaining a ratio of validator and dapps-compatible staking amounts.
///
/// `era_duration` is expressed in millisecond.
impl ComputeTotalPayout for MaintainRatioComputeTotalPayout {
impl<Balance> ComputeTotalPayout<Balance, Balance> for MaintainRatioComputeTotalPayout<Balance>
where
Balance: BaseArithmetic + Clone + From<u32>,
{
fn compute<N, M>(
total_tokens: N,
era_duration: M,
validator_staking: N,
dapps_staking: N,
validator_staking: Balance,
dapps_staking: Balance,
) -> (N, N)
where
N: BaseArithmetic + Clone + From<u32>,
Expand All @@ -67,8 +128,8 @@ impl ComputeTotalPayout for MaintainRatioComputeTotalPayout {
MILLISECONDS_PER_YEAR * 5,
);
let payout = portion * total_tokens;
if validator_staking == N::zero() {
if dapps_staking == N::zero() {
if validator_staking == Balance::zero() {
if dapps_staking == Balance::zero() {
return (N::zero(), N::zero());
}
return (N::zero(), payout);
Expand Down Expand Up @@ -112,14 +173,25 @@ mod test {
where
N: BaseArithmetic + Clone + From<u32>,
{
MaintainRatioComputeTotalPayout::compute(
MaintainRatioComputeTotalPayout::<N>::compute(
total_tokens,
era_duration,
validator_staking,
dapps_staking,
)
}

fn compute_first_rewards_test<N>(
total_tokens: N,
era_duration: u64,
number_of_validator: u32,
) -> (N, N)
where
N: BaseArithmetic + Clone + From<u32>,
{
FirstPlasmIncentive::<u32>::compute(total_tokens, era_duration, number_of_validator, 0)
}

#[test]
fn test_compute_test() {
const YEAR: u64 = 365 * 24 * 60 * 60 * 1000;
Expand Down Expand Up @@ -177,4 +249,28 @@ mod test {
(0, 0)
);
}

#[test]
fn test_first_rewards_compute() {
const YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
assert_eq!(
compute_first_rewards_test(100_000_000u64, YEAR, 100),
(2_500_000, 0)
);

assert_eq!(
compute_first_rewards_test(100_000_000u64, YEAR, 150),
(2_500_000, 0)
);

assert_eq!(
compute_first_rewards_test(100_000_000u64, YEAR, 50),
(1_250_000, 0)
);

assert_eq!(
compute_first_rewards_test(100_000_000u64, YEAR / 365, 100),
(2_500_000 / 365, 0)
);
}
}
13 changes: 8 additions & 5 deletions frame/plasm-rewards/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,16 @@ pub trait Trait: pallet_session::Trait {
type BondingDuration: Get<EraIndex>;

/// Get the amount of staking for dapps per era.
type GetForDappsStaking: traits::GetEraStakingAmount<EraIndex, BalanceOf<Self>>;
type ComputeEraForDapps: ComputeEraWithParam<EraIndex>;

/// Get the amount of staking for security per era.
type GetForSecurityStaking: traits::GetEraStakingAmount<EraIndex, BalanceOf<Self>>;
type ComputeEraForSecurity: ComputeEraWithParam<EraIndex>;

/// How to compute total issue PLM for rewards.
type ComputeTotalPayout: traits::ComputeTotalPayout;
type ComputeTotalPayout: ComputeTotalPayout<
<Self::ComputeEraForSecurity as ComputeEraWithParam<EraIndex>>::Param,
<Self::ComputeEraForDapps as ComputeEraWithParam<EraIndex>>::Param,
>;

/// Maybe next validators.
type MaybeValidators: traits::MaybeValidators<EraIndex, Self::AccountId>;
Expand Down Expand Up @@ -375,8 +378,8 @@ impl<T: Trait> Module<T> {

if !era_duration.is_zero() {
let total_payout = T::Currency::total_issuance();
let for_dapps = T::GetForDappsStaking::compute(&active_era.index);
let for_security = T::GetForSecurityStaking::compute(&active_era.index);
let for_dapps = T::ComputeEraForDapps::compute(&active_era.index);
let for_security = T::ComputeEraForSecurity::compute(&active_era.index);

let (for_security_reward, for_dapps_rewards) = T::ComputeTotalPayout::compute(
total_payout,
Expand Down
14 changes: 8 additions & 6 deletions frame/plasm-rewards/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use sp_core::{crypto::key_types, H256};
use sp_runtime::testing::{Header, UintAuthorityId};
use sp_runtime::traits::{BlakeTwo256, ConvertInto, IdentityLookup, OpaqueKeys};
use sp_runtime::{KeyTypeId, Perbill};
use traits::{GetEraStakingAmount, MaybeValidators};
use traits::{ComputeEraWithParam, MaybeValidators};

pub type BlockNumber = u64;
pub type AccountId = u64;
Expand Down Expand Up @@ -142,14 +142,16 @@ impl pallet_balances::Trait for Test {
}

pub struct DummyForSecurityStaking;
impl GetEraStakingAmount<EraIndex, Balance> for DummyForSecurityStaking {
impl ComputeEraWithParam<EraIndex> for DummyForSecurityStaking {
type Param = Balance;
fn compute(era: &EraIndex) -> Balance {
(era * 1_000_000).into()
}
}

pub struct DummyForDappsStaking;
impl GetEraStakingAmount<EraIndex, Balance> for DummyForDappsStaking {
impl ComputeEraWithParam<EraIndex> for DummyForDappsStaking {
type Param = Balance;
fn compute(era: &EraIndex) -> Balance {
(era * 200_000).into()
}
Expand All @@ -172,9 +174,9 @@ impl Trait for Test {
type Time = Timestamp;
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
type GetForDappsStaking = DummyForDappsStaking;
type GetForSecurityStaking = DummyForSecurityStaking;
type ComputeTotalPayout = inflation::MaintainRatioComputeTotalPayout;
type ComputeEraForDapps = DummyForDappsStaking;
type ComputeEraForSecurity = DummyForSecurityStaking;
type ComputeTotalPayout = inflation::MaintainRatioComputeTotalPayout<Balance>;
type MaybeValidators = DummyMaybeValidators;
type Event = ();
}
Expand Down
Loading

0 comments on commit c109001

Please sign in to comment.