Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Fix minting to do what it's meant to.
  • Loading branch information
gavofyork committed Sep 10, 2018
commit 2cccb16c87af49bbf838c286292cbafb6c8c8680
2 changes: 1 addition & 1 deletion demo/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ mod tests {
validator_count: 3,
minimum_validator_count: 0,
bonding_duration: 0,
early_era_slash: 0,
offline_slash: 0,
session_reward: 0,
offline_slash_grace: 0,
}),
Expand Down
4 changes: 2 additions & 2 deletions demo/service/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
staking: Some(StakingConfig {
current_era: 0,
intentions: initial_authorities.iter().cloned().map(Into::into).collect(),
early_era_slash: 10000,
offline_slash: 10000,
session_reward: 100,
validator_count: 12,
sessions_per_era: 12, // 1 hour per era
Expand Down Expand Up @@ -148,7 +148,7 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
validator_count: 2,
sessions_per_era: 5,
bonding_duration: 2 * 60 * 12,
early_era_slash: 0,
offline_slash: 0,
session_reward: 0,
offline_slash_grace: 0,
}),
Expand Down
4 changes: 2 additions & 2 deletions substrate/runtime/balances/src/genesis_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl<T: Trait> Default for GenesisConfig<T> {

impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
let total_stake: T::Balance = self.balances.iter().fold(Zero::zero(), |acc, &(_, n)| acc + n);
let total_issuance: T::Balance = self.balances.iter().fold(Zero::zero(), |acc, &(_, n)| acc + n);

let mut r: runtime_io::TestExternalities<KeccakHasher> = map![
Self::hash(<NextEnumSet<T>>::key()).to_vec() => T::AccountIndex::sa(self.balances.len() / ENUM_SET_SIZE).encode(),
Expand All @@ -68,7 +68,7 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
Self::hash(<CreationFee<T>>::key()).to_vec() => self.creation_fee.encode(),
Self::hash(<ExistentialDeposit<T>>::key()).to_vec() => self.existential_deposit.encode(),
Self::hash(<ReclaimRebate<T>>::key()).to_vec() => self.reclaim_rebate.encode(),
Self::hash(<TotalIssuance<T>>::key()).to_vec() => total_stake.encode()
Self::hash(<TotalIssuance<T>>::key()).to_vec() => total_issuance.encode()
];

let ids: Vec<_> = self.balances.iter().map(|x| x.0.clone()).collect();
Expand Down
18 changes: 9 additions & 9 deletions substrate/runtime/balances/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ impl<
}
}

/// Trait for a hook to get called when some balance has been minted.
pub trait OnMinted<Balance> {
/// Some balance `b` was minted.
fn on_minted(b: Balance);
/// Trait for a hook to get called when some balance has been minted, causing dilution.
pub trait OnDilution<Balance> {
/// Some `portion` of the total balance "grew" by `minted`.
fn on_dilution(minted: Balance, portion: Balance);
Copy link
Contributor

Choose a reason for hiding this comment

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

is the portion before or after having balance minted to it?

Copy link
Contributor

Choose a reason for hiding this comment

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

(documentation should answer this question)

}

impl<Balance> OnMinted<Balance> for () {
fn on_minted(_b: Balance) {}
impl<Balance> OnDilution<Balance> for () {
fn on_dilution(_minted: Balance, _portion: Balance) {}
}

/// Determinator for whether a given account is able to transfer balance.
Expand Down Expand Up @@ -159,7 +159,7 @@ impl<A, I, B> From<RawEvent<A, I, B>> for () {
decl_storage! {
trait Store for Module<T: Trait> as Balances {
/// The total amount of stake on the system.
pub TotalIssuance get(total_stake): required T::Balance;
pub TotalIssuance get(total_issuance): required T::Balance;
/// The minimum amount allowed to keep an account open.
pub ExistentialDeposit get(existential_deposit): required T::Balance;
/// The amount credited to a destination's account whose index was reclaimed.
Expand Down Expand Up @@ -627,13 +627,13 @@ impl<T: Trait> Module<T> {

/// Increase TotalIssuance by Value.
pub fn increase_total_stake_by(value: T::Balance) {
if let Some(v) = <Module<T>>::total_stake().checked_add(&value) {
if let Some(v) = <Module<T>>::total_issuance().checked_add(&value) {
<TotalIssuance<T>>::put(v);
}
}
/// Decrease TotalIssuance by Value.
pub fn decrease_total_stake_by(value: T::Balance) {
if let Some(v) = <Module<T>>::total_stake().checked_sub(&value) {
if let Some(v) = <Module<T>>::total_issuance().checked_sub(&value) {
<TotalIssuance<T>>::put(v);
}
}
Expand Down
8 changes: 4 additions & 4 deletions substrate/runtime/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ impl<T: Trait> Module<T> {
// tally up votes for any expiring referenda.
for (index, _, proposal, vote_threshold) in Self::maturing_referendums_at(now) {
let (approve, against) = Self::tally(index);
let total_stake = <balances::Module<T>>::total_stake();
let total_issuance = <balances::Module<T>>::total_issuance();
Self::clear_referendum(index);
if vote_threshold.approved(approve, against, total_stake) {
if vote_threshold.approved(approve, against, total_issuance) {
Self::deposit_event(RawEvent::Passed(index));
let ok = proposal.dispatch(system::RawOrigin::Root.into()).is_ok();
Self::deposit_event(RawEvent::Executed(index, ok));
Expand Down Expand Up @@ -454,7 +454,7 @@ mod tests {
assert_eq!(Democracy::minimum_deposit(), 1);
assert_eq!(Democracy::referendum_count(), 0);
assert_eq!(Balances::free_balance(&42), 0);
assert_eq!(Balances::total_stake(), 210);
assert_eq!(Balances::total_issuance(), 210);
});
}

Expand Down Expand Up @@ -670,7 +670,7 @@ mod tests {
fn passing_low_turnout_voting_should_work() {
with_externalities(&mut new_test_ext(), || {
assert_eq!(Balances::free_balance(&42), 0);
assert_eq!(Balances::total_stake(), 210);
assert_eq!(Balances::total_issuance(), 210);

System::set_block_number(1);
let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove).unwrap();
Expand Down
8 changes: 4 additions & 4 deletions substrate/runtime/staking/src/genesis_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use primitives::traits::As;
use substrate_primitives::KeccakHasher;
use {runtime_io, primitives};
use super::{Trait, Intentions, CurrentEra, OfflineSlashGrace, MinimumValidatorCount,
BondingDuration, SessionsPerEra, ValidatorCount, SessionReward, EarlyEraSlash};
BondingDuration, SessionsPerEra, ValidatorCount, SessionReward, OfflineSlash};

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand All @@ -39,7 +39,7 @@ pub struct GenesisConfig<T: Trait> {
pub minimum_validator_count: u32,
pub bonding_duration: T::BlockNumber,
pub session_reward: T::Balance,
pub early_era_slash: T::Balance,
pub offline_slash: T::Balance,
pub offline_slash_grace: u32,
}

Expand All @@ -53,7 +53,7 @@ impl<T: Trait> Default for GenesisConfig<T> {
minimum_validator_count: 0,
bonding_duration: T::BlockNumber::sa(1000),
session_reward: T::Balance::sa(0),
early_era_slash: T::Balance::sa(0),
offline_slash: T::Balance::sa(0),
offline_slash_grace: 0,
}
}
Expand All @@ -69,7 +69,7 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
Self::hash(<BondingDuration<T>>::key()).to_vec() => self.bonding_duration.encode(),
Self::hash(<CurrentEra<T>>::key()).to_vec() => self.current_era.encode(),
Self::hash(<SessionReward<T>>::key()).to_vec() => self.session_reward.encode(),
Self::hash(<EarlyEraSlash<T>>::key()).to_vec() => self.early_era_slash.encode(),
Self::hash(<OfflineSlash<T>>::key()).to_vec() => self.offline_slash.encode(),
Self::hash(<OfflineSlashGrace<T>>::key()).to_vec() => self.offline_slash_grace.encode()
];
Ok(r.into())
Expand Down
28 changes: 16 additions & 12 deletions substrate/runtime/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use runtime_support::dispatch::Result;
use session::OnSessionChange;
use primitives::traits::{Zero, One, Bounded, OnFinalise,
As, Lookup};
use balances::{address::Address, OnMinted};
use balances::{address::Address, OnDilution};
use system::{ensure_root, ensure_signed};

mod mock;
Expand Down Expand Up @@ -98,7 +98,7 @@ impl<B: Default> Default for ValidatorPrefs<B> {

pub trait Trait: balances::Trait + session::Trait {
/// Some tokens minted.
type OnRewardMinted: OnMinted<<Self as balances::Trait>::Balance>;
type OnRewardMinted: OnDilution<<Self as balances::Trait>::Balance>;

/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
Expand Down Expand Up @@ -148,8 +148,8 @@ decl_storage! {
pub SessionsPerEra get(sessions_per_era): required T::BlockNumber;
/// Maximum reward, per validator, that is provided per acceptable session.
pub SessionReward get(session_reward): required T::Balance;
/// Slash, per validator that is taken per abnormal era end.
pub EarlyEraSlash get(early_era_slash): required T::Balance;
/// Slash, per validator that is taken for the first time they are found to be offline.
pub OfflineSlash get(offline_slash): required T::Balance;
/// Number of instances of offline reports before slashing begins for validators.
pub OfflineSlashGrace get(offline_slash_grace): default u32;
/// The length of the bonding duration in blocks.
Expand All @@ -172,8 +172,8 @@ decl_storage! {
/// The session index at which the era length last changed.
pub LastEraLengthChange get(last_era_length_change): default T::BlockNumber;

/// The current era stake threshold - unused at present. Consider for removal.
pub StakeThreshold get(stake_threshold): required T::Balance;
/// The highest and lowest staked validator slashable balances.
pub StakeRange get(stake_range): default (T::Balance, T::Balance);

/// The block at which the `who`'s funds become entirely liquid.
pub Bondage get(bondage): default map [ T::AccountId => T::BlockNumber ];
Expand Down Expand Up @@ -446,7 +446,9 @@ impl<T: Trait> Module<T> {
Self::reward_validator(v, reward);
}
Self::deposit_event(RawEvent::Reward(reward));
T::OnRewardMinted::on_minted(reward * <T::Balance as As<usize>>::sa(validators.len()));
let total_minted = reward * <T::Balance as As<usize>>::sa(validators.len());
let total_rewarded_stake = Self::stake_range().0 * <T::Balance as As<usize>>::sa(validators.len());
T::OnRewardMinted::on_dilution(total_minted, total_rewarded_stake);
}

let session_index = <session::Module<T>>::current_index();
Expand Down Expand Up @@ -491,11 +493,13 @@ impl<T: Trait> Module<T> {

intentions.sort_unstable_by(|&(ref b1, _), &(ref b2, _)| b2.cmp(&b1));

<StakeThreshold<T>>::put(
<StakeRange<T>>::put(
if !intentions.is_empty() {
let i = (<ValidatorCount<T>>::get() as usize).min(intentions.len() - 1);
intentions[i].0.clone()
} else { Zero::zero() }
let n = <ValidatorCount<T>>::get() as usize;
(intentions[0].0, intentions[n - 1].0)
} else {
(Zero::zero(), Zero::zero())
}
);
let vals = &intentions.into_iter()
.map(|(_, v)| v)
Expand Down Expand Up @@ -551,7 +555,7 @@ impl<T: Trait> consensus::OnOfflineValidator for Module<T> {

let event = if slash_count >= grace {
let instances = slash_count - grace;
let slash = Self::early_era_slash() << instances;
let slash = Self::offline_slash() << instances;
let next_slash = slash << 1u32;
let _ = Self::slash_validator(&v, slash);
if instances >= Self::validator_preferences(&v).unstake_threshold
Expand Down
2 changes: 1 addition & 1 deletion substrate/runtime/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub fn new_test_ext(ext_deposit: u64, session_length: u64, sessions_per_era: u64
minimum_validator_count: 0,
bonding_duration: sessions_per_era * session_length * 3,
session_reward: reward,
early_era_slash: if monied { 20 } else { 0 },
offline_slash: if monied { 20 } else { 0 },
offline_slash_grace: 0,
}.build_storage().unwrap());
t.extend(timestamp::GenesisConfig::<Test>{
Expand Down
30 changes: 16 additions & 14 deletions substrate/runtime/treasury/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use rstd::prelude::*;
use runtime_support::{StorageValue, StorageMap};
use runtime_support::dispatch::Result;
use runtime_primitives::{Permill, traits::{OnFinalise, Zero, EnsureOrigin}};
use balances::OnMinted;
use balances::OnDilution;
use system::{ensure_signed, ensure_root};

/// Our module's configuration trait. All our types and consts go in here. If the
Expand Down Expand Up @@ -278,9 +278,11 @@ impl<T: Trait> Module<T> {
}
}

impl<T: Trait> OnMinted<T::Balance> for Module<T> {
fn on_minted(b: T::Balance) {
<Pot<T>>::put(Self::pot() + b);
impl<T: Trait> OnDilution<T::Balance> for Module<T> {
fn on_dilution(minted: T::Balance, portion: T::Balance) {
let total_issuance = <balances::Module<T>>::total_issuance();
let funding = (total_issuance - portion) / portion * minted;
<Pot<T>>::mutate(|x| *x += funding);
}
}

Expand Down Expand Up @@ -377,7 +379,7 @@ mod tests {
fn new_test_ext() -> runtime_io::TestExternalities<KeccakHasher> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(balances::GenesisConfig::<Test>{
balances: vec![(0, 100), (1, 10), (2, 1)],
balances: vec![(0, 100), (1, 99), (2, 1)],
transaction_base_fee: 0,
transaction_byte_fee: 0,
transfer_fee: 0,
Expand Down Expand Up @@ -410,7 +412,7 @@ mod tests {
fn minting_works() {
with_externalities(&mut new_test_ext(), || {
// Check that accumulate works when we have Some value in Dummy already.
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);
assert_eq!(Treasury::pot(), 100);
});
}
Expand Down Expand Up @@ -443,7 +445,7 @@ mod tests {
#[test]
fn accepted_spend_proposal_ignored_outside_spend_period() {
with_externalities(&mut new_test_ext(), || {
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);

assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0));
Expand All @@ -457,7 +459,7 @@ mod tests {
#[test]
fn unused_pot_should_diminish() {
with_externalities(&mut new_test_ext(), || {
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);

<Treasury as OnFinalise<u64>>::on_finalise(2);
assert_eq!(Treasury::pot(), 50);
Expand All @@ -467,7 +469,7 @@ mod tests {
#[test]
fn rejected_spend_proposal_ignored_on_spend_period() {
with_externalities(&mut new_test_ext(), || {
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);

assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0));
Expand All @@ -481,7 +483,7 @@ mod tests {
#[test]
fn reject_already_rejected_spend_proposal_fails() {
with_externalities(&mut new_test_ext(), || {
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);

assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0));
Expand All @@ -506,7 +508,7 @@ mod tests {
#[test]
fn accept_already_rejected_spend_proposal_fails() {
with_externalities(&mut new_test_ext(), || {
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);

assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0));
Expand All @@ -517,7 +519,7 @@ mod tests {
#[test]
fn accepted_spend_proposal_enacted_on_spend_period() {
with_externalities(&mut new_test_ext(), || {
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);

assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0));
Expand All @@ -531,15 +533,15 @@ mod tests {
#[test]
fn pot_underflow_should_not_diminish() {
with_externalities(&mut new_test_ext(), || {
Treasury::on_minted(100);
Treasury::on_dilution(100, 100);

assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3));
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0));

<Treasury as OnFinalise<u64>>::on_finalise(2);
assert_eq!(Treasury::pot(), 100);

Treasury::on_minted(100);
Treasury::on_dilution(100, 100);
<Treasury as OnFinalise<u64>>::on_finalise(4);
assert_eq!(Balances::free_balance(&3), 150);
assert_eq!(Treasury::pot(), 25);
Expand Down