mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 16:51:03 +00:00
Initial mechanics for 80:20 fee split (#2912)
* Initial mechanics for 80:20 fee split Also: - Introduce extra functions for Imbalance manipulation; - Store treasury pot in an account, letting total issuance account for it. * Fix some tests * Fix some tests * Minor cleanups * Update parity-codec version (#2855) * Update parity-codec version * Update grandpa, rhododendron and trie-bench * Use primitive-types from crates.io * Bump impl version * Fix trie-bench version * Fix lock files * Fix versions * Update codec to 4.1 * merge fix * Revert merge * More reversions * Remove accidental code * Update locks * Bump runtime * Update locks * Tweaks and label TODO * Update srml/treasury/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update issue number * Update core/sr-primitives/src/traits.rs Co-Authored-By: Robert Habermeier <rphmeier@gmail.com> * Fix wasm build * Fix subkey build
This commit is contained in:
Generated
+2
@@ -2268,6 +2268,7 @@ dependencies = [
|
|||||||
"sr-std 2.0.0",
|
"sr-std 2.0.0",
|
||||||
"sr-version 2.0.0",
|
"sr-version 2.0.0",
|
||||||
"srml-aura 2.0.0",
|
"srml-aura 2.0.0",
|
||||||
|
"srml-authorship 0.1.0",
|
||||||
"srml-balances 2.0.0",
|
"srml-balances 2.0.0",
|
||||||
"srml-contracts 2.0.0",
|
"srml-contracts 2.0.0",
|
||||||
"srml-council 2.0.0",
|
"srml-council 2.0.0",
|
||||||
@@ -3772,6 +3773,7 @@ dependencies = [
|
|||||||
"srml-support-procedural 2.0.0",
|
"srml-support-procedural 2.0.0",
|
||||||
"srml-system 2.0.0",
|
"srml-system 2.0.0",
|
||||||
"substrate-inherents 2.0.0",
|
"substrate-inherents 2.0.0",
|
||||||
|
"substrate-primitives 2.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -69,6 +69,14 @@ pub type Justification = Vec<u8>;
|
|||||||
|
|
||||||
use traits::{Verify, Lazy};
|
use traits::{Verify, Lazy};
|
||||||
|
|
||||||
|
/// A module identifier. These are per module and should be stored in a registry somewhere.
|
||||||
|
#[derive(Clone, Copy, Eq, PartialEq, Encode, Decode)]
|
||||||
|
pub struct ModuleId(pub [u8; 8]);
|
||||||
|
|
||||||
|
impl traits::TypeId for ModuleId {
|
||||||
|
const TYPE_ID: [u8; 4] = *b"modl";
|
||||||
|
}
|
||||||
|
|
||||||
/// A String that is a `&'static str` on `no_std` and a `Cow<'static, str>` on `std`.
|
/// A String that is a `&'static str` on `no_std` and a `Cow<'static, str>` on `std`.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub type RuntimeString = ::std::borrow::Cow<'static, str>;
|
pub type RuntimeString = ::std::borrow::Cow<'static, str>;
|
||||||
|
|||||||
@@ -830,6 +830,110 @@ pub trait OpaqueKeys: Clone {
|
|||||||
fn ownership_proof_is_valid(&self, _proof: &[u8]) -> bool { true }
|
fn ownership_proof_is_valid(&self, _proof: &[u8]) -> bool { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TrailingZeroInput<'a>(&'a [u8]);
|
||||||
|
impl<'a> codec::Input for TrailingZeroInput<'a> {
|
||||||
|
fn read(&mut self, into: &mut [u8]) -> usize {
|
||||||
|
let len = into.len().min(self.0.len());
|
||||||
|
into[..len].copy_from_slice(&self.0[..len]);
|
||||||
|
for i in &mut into[len..] {
|
||||||
|
*i = 0;
|
||||||
|
}
|
||||||
|
self.0 = &self.0[len..];
|
||||||
|
into.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This type can be converted into and possibly from an AccountId (which itself is generic).
|
||||||
|
pub trait AccountIdConversion<AccountId>: Sized {
|
||||||
|
/// Convert into an account ID. This is infallible.
|
||||||
|
fn into_account(&self) -> AccountId;
|
||||||
|
|
||||||
|
/// Try to convert an account ID into this type. Might not succeed.
|
||||||
|
fn try_from_account(a: &AccountId) -> Option<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide a simply 4 byte identifier for a type.
|
||||||
|
pub trait TypeId {
|
||||||
|
/// Simple 4 byte identifier.
|
||||||
|
const TYPE_ID: [u8; 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Format is TYPE_ID ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to fill AccountId.
|
||||||
|
impl<T: Encode + Decode + Default, Id: Encode + Decode + TypeId> AccountIdConversion<T> for Id {
|
||||||
|
fn into_account(&self) -> T {
|
||||||
|
(Id::TYPE_ID, self).using_encoded(|b|
|
||||||
|
T::decode(&mut TrailingZeroInput(b))
|
||||||
|
).unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_from_account(x: &T) -> Option<Self> {
|
||||||
|
x.using_encoded(|d| {
|
||||||
|
if &d[0..4] != Id::TYPE_ID { return None }
|
||||||
|
let mut cursor = &d[4..];
|
||||||
|
let result = Decode::decode(&mut cursor)?;
|
||||||
|
if cursor.iter().all(|x| *x == 0) {
|
||||||
|
Some(result)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::AccountIdConversion;
|
||||||
|
use crate::codec::{Encode, Decode};
|
||||||
|
|
||||||
|
#[derive(Encode, Decode, Default, PartialEq, Debug)]
|
||||||
|
struct U32Value(u32);
|
||||||
|
impl super::TypeId for U32Value {
|
||||||
|
const TYPE_ID: [u8; 4] = [0x0d, 0xf0, 0xfe, 0xca];
|
||||||
|
}
|
||||||
|
// cafef00d
|
||||||
|
|
||||||
|
#[derive(Encode, Decode, Default, PartialEq, Debug)]
|
||||||
|
struct U16Value(u16);
|
||||||
|
impl super::TypeId for U16Value {
|
||||||
|
const TYPE_ID: [u8; 4] = [0xfe, 0xca, 0x0d, 0xf0];
|
||||||
|
}
|
||||||
|
// f00dcafe
|
||||||
|
|
||||||
|
type AccountId = u64;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_account_should_work() {
|
||||||
|
let r: AccountId = U32Value::into_account(&U32Value(0xdeadbeef));
|
||||||
|
assert_eq!(r, 0x_deadbeef_cafef00d);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_from_account_should_work() {
|
||||||
|
let r = U32Value::try_from_account(&0x_deadbeef_cafef00d_u64);
|
||||||
|
assert_eq!(r.unwrap(), U32Value(0xdeadbeef));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_account_with_fill_should_work() {
|
||||||
|
let r: AccountId = U16Value::into_account(&U16Value(0xc0da));
|
||||||
|
assert_eq!(r, 0x_0000_c0da_f00dcafe);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_from_account_with_fill_should_work() {
|
||||||
|
let r = U16Value::try_from_account(&0x0000_c0da_f00dcafe_u64);
|
||||||
|
assert_eq!(r.unwrap(), U16Value(0xc0da));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bad_try_from_account_should_fail() {
|
||||||
|
let r = U16Value::try_from_account(&0x0000_c0de_baadcafe_u64);
|
||||||
|
assert!(r.is_none());
|
||||||
|
let r = U16Value::try_from_account(&0x0100_c0da_f00dcafe_u64);
|
||||||
|
assert!(r.is_none());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Calls a given macro a number of times with a set of fixed params and an incrementing numeral.
|
/// Calls a given macro a number of times with a set of fixed params and an incrementing numeral.
|
||||||
/// e.g.
|
/// e.g.
|
||||||
/// ```nocompile
|
/// ```nocompile
|
||||||
|
|||||||
+1
@@ -2397,6 +2397,7 @@ dependencies = [
|
|||||||
"srml-metadata 2.0.0",
|
"srml-metadata 2.0.0",
|
||||||
"srml-support-procedural 2.0.0",
|
"srml-support-procedural 2.0.0",
|
||||||
"substrate-inherents 2.0.0",
|
"substrate-inherents 2.0.0",
|
||||||
|
"substrate-primitives 2.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+1
@@ -2521,6 +2521,7 @@ dependencies = [
|
|||||||
"srml-metadata 2.0.0",
|
"srml-metadata 2.0.0",
|
||||||
"srml-support-procedural 2.0.0",
|
"srml-support-procedural 2.0.0",
|
||||||
"substrate-inherents 2.0.0",
|
"substrate-inherents 2.0.0",
|
||||||
|
"substrate-primitives 2.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ mod tests {
|
|||||||
use system::{EventRecord, Phase};
|
use system::{EventRecord, Phase};
|
||||||
use node_runtime::{Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances,
|
use node_runtime::{Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances,
|
||||||
BuildStorage, GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System,
|
BuildStorage, GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System,
|
||||||
SystemConfig, GrandpaConfig, IndicesConfig, Event, SessionKeys};
|
SystemConfig, GrandpaConfig, IndicesConfig, Event, SessionKeys, Treasury};
|
||||||
use wabt;
|
use wabt;
|
||||||
use primitives::map;
|
use primitives::map;
|
||||||
|
|
||||||
@@ -566,6 +566,34 @@ mod tests {
|
|||||||
event: Event::system(system::Event::ExtrinsicSuccess),
|
event: Event::system(system::Event::ExtrinsicSuccess),
|
||||||
topics: vec![],
|
topics: vec![],
|
||||||
},
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::ApplyExtrinsic(1),
|
||||||
|
event: Event::indices(
|
||||||
|
indices::RawEvent::NewAccountIndex(Treasury::account_id(), 6)
|
||||||
|
),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::ApplyExtrinsic(1),
|
||||||
|
event: Event::balances(
|
||||||
|
balances::RawEvent::NewAccount(Treasury::account_id(), 0)
|
||||||
|
),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::ApplyExtrinsic(1),
|
||||||
|
event: Event::indices(
|
||||||
|
indices::RawEvent::NewAccountIndex(Default::default(), 7)
|
||||||
|
),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
|
EventRecord {
|
||||||
|
phase: Phase::ApplyExtrinsic(1),
|
||||||
|
event: Event::balances(
|
||||||
|
balances::RawEvent::NewAccount(Default::default(), 1)
|
||||||
|
),
|
||||||
|
topics: vec![],
|
||||||
|
},
|
||||||
EventRecord {
|
EventRecord {
|
||||||
phase: Phase::ApplyExtrinsic(1),
|
phase: Phase::ApplyExtrinsic(1),
|
||||||
event: Event::balances(balances::RawEvent::Transfer(
|
event: Event::balances(balances::RawEvent::Transfer(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ offchain-primitives = { package = "substrate-offchain-primitives", path = "../..
|
|||||||
version = { package = "sr-version", path = "../../core/sr-version", default-features = false }
|
version = { package = "sr-version", path = "../../core/sr-version", default-features = false }
|
||||||
support = { package = "srml-support", path = "../../srml/support", default-features = false }
|
support = { package = "srml-support", path = "../../srml/support", default-features = false }
|
||||||
aura = { package = "srml-aura", path = "../../srml/aura", default-features = false }
|
aura = { package = "srml-aura", path = "../../srml/aura", default-features = false }
|
||||||
|
authorship = { package = "srml-authorship", path = "../../srml/authorship", default-features = false }
|
||||||
balances = { package = "srml-balances", path = "../../srml/balances", default-features = false }
|
balances = { package = "srml-balances", path = "../../srml/balances", default-features = false }
|
||||||
contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false }
|
contracts = { package = "srml-contracts", path = "../../srml/contracts", default-features = false }
|
||||||
council = { package = "srml-council", path = "../../srml/council", default-features = false }
|
council = { package = "srml-council", path = "../../srml/council", default-features = false }
|
||||||
@@ -48,6 +49,7 @@ std = [
|
|||||||
"runtime_primitives/std",
|
"runtime_primitives/std",
|
||||||
"support/std",
|
"support/std",
|
||||||
"aura/std",
|
"aura/std",
|
||||||
|
"authorship/std",
|
||||||
"balances/std",
|
"balances/std",
|
||||||
"contracts/std",
|
"contracts/std",
|
||||||
"council/std",
|
"council/std",
|
||||||
|
|||||||
@@ -21,7 +21,9 @@
|
|||||||
#![recursion_limit="256"]
|
#![recursion_limit="256"]
|
||||||
|
|
||||||
use rstd::prelude::*;
|
use rstd::prelude::*;
|
||||||
use support::{construct_runtime, parameter_types};
|
use support::{
|
||||||
|
construct_runtime, parameter_types, traits::{SplitTwoWays, Currency, OnUnbalanced}
|
||||||
|
};
|
||||||
use substrate_primitives::u32_trait::{_1, _2, _3, _4};
|
use substrate_primitives::u32_trait::{_1, _2, _3, _4};
|
||||||
use node_primitives::{
|
use node_primitives::{
|
||||||
AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Signature, AuraId
|
AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Signature, AuraId
|
||||||
@@ -58,8 +60,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|||||||
spec_name: create_runtime_str!("node"),
|
spec_name: create_runtime_str!("node"),
|
||||||
impl_name: create_runtime_str!("substrate-node"),
|
impl_name: create_runtime_str!("substrate-node"),
|
||||||
authoring_version: 10,
|
authoring_version: 10,
|
||||||
spec_version: 99,
|
spec_version: 100,
|
||||||
impl_version: 106,
|
impl_version: 100,
|
||||||
apis: RUNTIME_API_VERSIONS,
|
apis: RUNTIME_API_VERSIONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,6 +74,23 @@ pub fn native_version() -> NativeVersion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
|
||||||
|
|
||||||
|
pub struct Author;
|
||||||
|
|
||||||
|
impl OnUnbalanced<NegativeImbalance> for Author {
|
||||||
|
fn on_unbalanced(amount: NegativeImbalance) {
|
||||||
|
Balances::resolve_creating(&Authorship::author(), amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DealWithFees = SplitTwoWays<
|
||||||
|
Balance,
|
||||||
|
NegativeImbalance,
|
||||||
|
_4, Treasury, // 4 parts (80%) goes to the treasury.
|
||||||
|
_1, Author, // 1 part (20%) goes to the block author.
|
||||||
|
>;
|
||||||
|
|
||||||
pub struct CurrencyToVoteHandler;
|
pub struct CurrencyToVoteHandler;
|
||||||
|
|
||||||
impl CurrencyToVoteHandler {
|
impl CurrencyToVoteHandler {
|
||||||
@@ -115,7 +134,7 @@ impl balances::Trait for Runtime {
|
|||||||
type OnFreeBalanceZero = ((Staking, Contracts), Session);
|
type OnFreeBalanceZero = ((Staking, Contracts), Session);
|
||||||
type OnNewAccount = Indices;
|
type OnNewAccount = Indices;
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
type TransactionPayment = ();
|
type TransactionPayment = DealWithFees;
|
||||||
type DustRemoval = ();
|
type DustRemoval = ();
|
||||||
type TransferPayment = ();
|
type TransferPayment = ();
|
||||||
}
|
}
|
||||||
@@ -125,6 +144,18 @@ impl timestamp::Trait for Runtime {
|
|||||||
type OnTimestampSet = Aura;
|
type OnTimestampSet = Aura;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const UncleGenerations: u64 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: #2986 implement this properly
|
||||||
|
impl authorship::Trait for Runtime {
|
||||||
|
type FindAuthor = ();
|
||||||
|
type UncleGenerations = UncleGenerations;
|
||||||
|
type FilterUncle = ();
|
||||||
|
type EventHandler = ();
|
||||||
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const Period: BlockNumber = 10 * MINUTES;
|
pub const Period: BlockNumber = 10 * MINUTES;
|
||||||
pub const Offset: BlockNumber = 0;
|
pub const Offset: BlockNumber = 0;
|
||||||
@@ -250,6 +281,7 @@ construct_runtime!(
|
|||||||
System: system::{Module, Call, Storage, Config, Event},
|
System: system::{Module, Call, Storage, Config, Event},
|
||||||
Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
|
Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
|
||||||
Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
|
Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
|
||||||
|
Authorship: authorship::{Module, Call, Storage},
|
||||||
Indices: indices,
|
Indices: indices,
|
||||||
Balances: balances,
|
Balances: balances,
|
||||||
Session: session::{Module, Call, Storage, Event, Config<T>},
|
Session: session::{Module, Call, Storage, Event, Config<T>},
|
||||||
|
|||||||
Generated
+15
@@ -1499,6 +1499,7 @@ dependencies = [
|
|||||||
"sr-std 2.0.0",
|
"sr-std 2.0.0",
|
||||||
"sr-version 2.0.0",
|
"sr-version 2.0.0",
|
||||||
"srml-aura 2.0.0",
|
"srml-aura 2.0.0",
|
||||||
|
"srml-authorship 0.1.0",
|
||||||
"srml-balances 2.0.0",
|
"srml-balances 2.0.0",
|
||||||
"srml-contracts 2.0.0",
|
"srml-contracts 2.0.0",
|
||||||
"srml-council 2.0.0",
|
"srml-council 2.0.0",
|
||||||
@@ -2452,6 +2453,19 @@ dependencies = [
|
|||||||
"substrate-primitives 2.0.0",
|
"substrate-primitives 2.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "srml-authorship"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"parity-codec 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"sr-io 2.0.0",
|
||||||
|
"sr-primitives 2.0.0",
|
||||||
|
"sr-std 2.0.0",
|
||||||
|
"srml-support 2.0.0",
|
||||||
|
"srml-system 2.0.0",
|
||||||
|
"substrate-primitives 2.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "srml-balances"
|
name = "srml-balances"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@@ -2642,6 +2656,7 @@ dependencies = [
|
|||||||
"srml-metadata 2.0.0",
|
"srml-metadata 2.0.0",
|
||||||
"srml-support-procedural 2.0.0",
|
"srml-support-procedural 2.0.0",
|
||||||
"substrate-inherents 2.0.0",
|
"substrate-inherents 2.0.0",
|
||||||
|
"substrate-primitives 2.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
//!
|
//!
|
||||||
//! This tracks the current author of the block and recent uncles.
|
//! This tracks the current author of the block and recent uncles.
|
||||||
|
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use rstd::prelude::*;
|
use rstd::prelude::*;
|
||||||
use rstd::collections::btree_set::BTreeSet;
|
use rstd::collections::btree_set::BTreeSet;
|
||||||
use srml_support::{decl_module, decl_storage, for_each_tuple, StorageValue};
|
use srml_support::{decl_module, decl_storage, for_each_tuple, StorageValue};
|
||||||
@@ -102,6 +104,15 @@ pub trait FilterUncle<Header, Author> {
|
|||||||
-> Result<(Option<Author>, Self::Accumulator), &'static str>;
|
-> Result<(Option<Author>, Self::Accumulator), &'static str>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<H, A> FilterUncle<H, A> for () {
|
||||||
|
type Accumulator = ();
|
||||||
|
fn filter_uncle(_: &H, acc: Self::Accumulator)
|
||||||
|
-> Result<(Option<A>, Self::Accumulator), &'static str>
|
||||||
|
{
|
||||||
|
Ok((None, acc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A filter on uncles which verifies seals and does no additional checks.
|
/// A filter on uncles which verifies seals and does no additional checks.
|
||||||
/// This is well-suited to consensus modes such as PoW where the cost of
|
/// This is well-suited to consensus modes such as PoW where the cost of
|
||||||
/// equivocating is high.
|
/// equivocating is high.
|
||||||
@@ -201,8 +212,8 @@ decl_module! {
|
|||||||
|
|
||||||
fn on_finalize() {
|
fn on_finalize() {
|
||||||
// ensure we never go to trie with these values.
|
// ensure we never go to trie with these values.
|
||||||
let _ = <Self as Store>::Author::take();
|
<Self as Store>::Author::kill();
|
||||||
let _ = <Self as Store>::DidSetUncles::take();
|
<Self as Store>::DidSetUncles::kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provide a set of uncles.
|
/// Provide a set of uncles.
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ use srml_support::traits::{
|
|||||||
use srml_support::dispatch::Result;
|
use srml_support::dispatch::Result;
|
||||||
use primitives::traits::{
|
use primitives::traits::{
|
||||||
Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub,
|
Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub,
|
||||||
MaybeSerializeDebug, Saturating
|
MaybeSerializeDebug, Saturating, Bounded
|
||||||
};
|
};
|
||||||
use system::{IsDeadAccount, OnNewAccount, ensure_signed};
|
use system::{IsDeadAccount, OnNewAccount, ensure_signed};
|
||||||
|
|
||||||
@@ -313,7 +313,9 @@ decl_storage! {
|
|||||||
///
|
///
|
||||||
/// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets
|
/// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets
|
||||||
/// collapsed to zero if it ever becomes less than `ExistentialDeposit`.
|
/// collapsed to zero if it ever becomes less than `ExistentialDeposit`.
|
||||||
pub FreeBalance get(free_balance) build(|config: &GenesisConfig<T, I>| config.balances.clone()): map T::AccountId => T::Balance;
|
pub FreeBalance get(free_balance)
|
||||||
|
build(|config: &GenesisConfig<T, I>| config.balances.clone()):
|
||||||
|
map T::AccountId => T::Balance;
|
||||||
|
|
||||||
/// The amount of the balance of a given account that is externally reserved; this can still get
|
/// The amount of the balance of a given account that is externally reserved; this can still get
|
||||||
/// slashed, but gets slashed last of all.
|
/// slashed, but gets slashed last of all.
|
||||||
@@ -735,6 +737,26 @@ where
|
|||||||
<FreeBalance<T, I>>::get(who)
|
<FreeBalance<T, I>>::get(who)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance {
|
||||||
|
<TotalIssuance<T, I>>::mutate(|issued|
|
||||||
|
issued.checked_sub(&amount).unwrap_or_else(|| {
|
||||||
|
amount = *issued;
|
||||||
|
Zero::zero()
|
||||||
|
})
|
||||||
|
);
|
||||||
|
PositiveImbalance::new(amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance {
|
||||||
|
<TotalIssuance<T, I>>::mutate(|issued|
|
||||||
|
*issued = issued.checked_add(&amount).unwrap_or_else(|| {
|
||||||
|
amount = Self::Balance::max_value() - *issued;
|
||||||
|
Self::Balance::max_value()
|
||||||
|
})
|
||||||
|
);
|
||||||
|
NegativeImbalance::new(amount)
|
||||||
|
}
|
||||||
|
|
||||||
// # <weight>
|
// # <weight>
|
||||||
// Despite iterating over a list of locks, they are limited by the number of
|
// Despite iterating over a list of locks, they are limited by the number of
|
||||||
// lock IDs, which means the number of runtime modules that intend to use and create locks.
|
// lock IDs, which means the number of runtime modules that intend to use and create locks.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ srml-metadata = { path = "../metadata", default-features = false }
|
|||||||
sr-std = { path = "../../core/sr-std", default-features = false }
|
sr-std = { path = "../../core/sr-std", default-features = false }
|
||||||
runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false }
|
runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false }
|
||||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||||
|
substrate-primitives = { path = "../../core/primitives", default-features = false }
|
||||||
inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false }
|
inherents = { package = "substrate-inherents", path = "../../core/inherents", default-features = false }
|
||||||
srml-support-procedural = { path = "./procedural" }
|
srml-support-procedural = { path = "./procedural" }
|
||||||
paste = "0.1"
|
paste = "0.1"
|
||||||
|
|||||||
@@ -18,10 +18,11 @@
|
|||||||
//!
|
//!
|
||||||
//! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module.
|
//! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module.
|
||||||
|
|
||||||
use crate::rstd::result;
|
use crate::rstd::{result, marker::PhantomData, ops::Div};
|
||||||
use crate::codec::{Codec, Encode, Decode};
|
use crate::codec::{Codec, Encode, Decode};
|
||||||
|
use substrate_primitives::u32_trait::Value as U32;
|
||||||
use crate::runtime_primitives::traits::{
|
use crate::runtime_primitives::traits::{
|
||||||
MaybeSerializeDebug, SimpleArithmetic
|
MaybeSerializeDebug, SimpleArithmetic, Saturating
|
||||||
};
|
};
|
||||||
use crate::runtime_primitives::ConsensusEngineId;
|
use crate::runtime_primitives::ConsensusEngineId;
|
||||||
|
|
||||||
@@ -111,6 +112,14 @@ pub trait FindAuthor<Author> {
|
|||||||
where I: 'a + IntoIterator<Item=(ConsensusEngineId, &'a [u8])>;
|
where I: 'a + IntoIterator<Item=(ConsensusEngineId, &'a [u8])>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A> FindAuthor<A> for () {
|
||||||
|
fn find_author<'a, I>(_: I) -> Option<A>
|
||||||
|
where I: 'a + IntoIterator<Item=(ConsensusEngineId, &'a [u8])>
|
||||||
|
{
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A trait for verifying the seal of a header and returning the author.
|
/// A trait for verifying the seal of a header and returning the author.
|
||||||
pub trait VerifySeal<Header, Author> {
|
pub trait VerifySeal<Header, Author> {
|
||||||
/// Verify a header and return the author, if any.
|
/// Verify a header and return the author, if any.
|
||||||
@@ -270,6 +279,34 @@ impl<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Split an unbalanced amount two ways between a common divisor.
|
||||||
|
pub struct SplitTwoWays<
|
||||||
|
Balance,
|
||||||
|
Imbalance,
|
||||||
|
Part1,
|
||||||
|
Target1,
|
||||||
|
Part2,
|
||||||
|
Target2,
|
||||||
|
>(PhantomData<(Balance, Imbalance, Part1, Target1, Part2, Target2)>);
|
||||||
|
|
||||||
|
impl<
|
||||||
|
Balance: From<u32> + Saturating + Div<Output=Balance>,
|
||||||
|
I: Imbalance<Balance>,
|
||||||
|
Part1: U32,
|
||||||
|
Target1: OnUnbalanced<I>,
|
||||||
|
Part2: U32,
|
||||||
|
Target2: OnUnbalanced<I>,
|
||||||
|
> OnUnbalanced<I> for SplitTwoWays<Balance, I, Part1, Target1, Part2, Target2>
|
||||||
|
{
|
||||||
|
fn on_unbalanced(amount: I) {
|
||||||
|
let total: u32 = Part1::VALUE + Part2::VALUE;
|
||||||
|
let amount1 = amount.peek().saturating_mul(Part1::VALUE.into()) / total.into();
|
||||||
|
let (imb1, imb2) = amount.split(amount1);
|
||||||
|
Target1::on_unbalanced(imb1);
|
||||||
|
Target2::on_unbalanced(imb2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Abstraction over a fungible assets system.
|
/// Abstraction over a fungible assets system.
|
||||||
pub trait Currency<AccountId> {
|
pub trait Currency<AccountId> {
|
||||||
/// The balance of an account.
|
/// The balance of an account.
|
||||||
@@ -299,6 +336,21 @@ pub trait Currency<AccountId> {
|
|||||||
/// `ExistentialDeposit`.
|
/// `ExistentialDeposit`.
|
||||||
fn minimum_balance() -> Self::Balance;
|
fn minimum_balance() -> Self::Balance;
|
||||||
|
|
||||||
|
/// Reduce the total issuance by `amount` and return the according imbalance. The imbalance will
|
||||||
|
/// typically be used to reduce an account by the same amount with e.g. `settle`.
|
||||||
|
///
|
||||||
|
/// This is infallible, but doesn't guarantee that the entire `amount` is burnt, for example
|
||||||
|
/// in the case of underflow.
|
||||||
|
fn burn(amount: Self::Balance) -> Self::PositiveImbalance;
|
||||||
|
|
||||||
|
/// Increase the total issuance by `amount` and return the according imbalance. The imbalance
|
||||||
|
/// will typically be used to increase an account by the same amount with e.g.
|
||||||
|
/// `resolve_into_existing` or `resolve_creating`.
|
||||||
|
///
|
||||||
|
/// This is infallible, but doesn't guarantee that the entire `amount` is issued, for example
|
||||||
|
/// in the case of overflow.
|
||||||
|
fn issue(amount: Self::Balance) -> Self::NegativeImbalance;
|
||||||
|
|
||||||
/// The 'free' balance of a given account.
|
/// The 'free' balance of a given account.
|
||||||
///
|
///
|
||||||
/// This is the only balance that matters in terms of most operations on tokens. It alone
|
/// This is the only balance that matters in terms of most operations on tokens. It alone
|
||||||
@@ -355,17 +407,18 @@ pub trait Currency<AccountId> {
|
|||||||
value: Self::Balance
|
value: Self::Balance
|
||||||
) -> result::Result<Self::PositiveImbalance, &'static str>;
|
) -> result::Result<Self::PositiveImbalance, &'static str>;
|
||||||
|
|
||||||
/// Removes some free balance from `who` account for `reason` if possible. If `liveness` is `KeepAlive`,
|
/// Similar to deposit_creating, only accepts a `NegativeImbalance` and returns nothing on
|
||||||
/// then no less than `ExistentialDeposit` must be left remaining.
|
/// success.
|
||||||
///
|
fn resolve_into_existing(
|
||||||
/// This checks any locks, vesting, and liquidity requirements. If the removal is not possible, then it
|
|
||||||
/// returns `Err`.
|
|
||||||
fn withdraw(
|
|
||||||
who: &AccountId,
|
who: &AccountId,
|
||||||
value: Self::Balance,
|
value: Self::NegativeImbalance,
|
||||||
reason: WithdrawReason,
|
) -> result::Result<(), Self::NegativeImbalance> {
|
||||||
liveness: ExistenceRequirement,
|
let v = value.peek();
|
||||||
) -> result::Result<Self::NegativeImbalance, &'static str>;
|
match Self::deposit_into_existing(who, v) {
|
||||||
|
Ok(opposite) => Ok(drop(value.offset(opposite))),
|
||||||
|
_ => Err(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds up to `value` to the free balance of `who`. If `who` doesn't exist, it is created.
|
/// Adds up to `value` to the free balance of `who`. If `who` doesn't exist, it is created.
|
||||||
///
|
///
|
||||||
@@ -375,6 +428,45 @@ pub trait Currency<AccountId> {
|
|||||||
value: Self::Balance,
|
value: Self::Balance,
|
||||||
) -> Self::PositiveImbalance;
|
) -> Self::PositiveImbalance;
|
||||||
|
|
||||||
|
/// Similar to deposit_creating, only accepts a `NegativeImbalance` and returns nothing on
|
||||||
|
/// success.
|
||||||
|
fn resolve_creating(
|
||||||
|
who: &AccountId,
|
||||||
|
value: Self::NegativeImbalance,
|
||||||
|
) {
|
||||||
|
let v = value.peek();
|
||||||
|
drop(value.offset(Self::deposit_creating(who, v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes some free balance from `who` account for `reason` if possible. If `liveness` is
|
||||||
|
/// `KeepAlive`, then no less than `ExistentialDeposit` must be left remaining.
|
||||||
|
///
|
||||||
|
/// This checks any locks, vesting, and liquidity requirements. If the removal is not possible,
|
||||||
|
/// then it returns `Err`.
|
||||||
|
///
|
||||||
|
/// If the operation is successful, this will return `Ok` with a `NegativeImbalance` whose value
|
||||||
|
/// is `value`.
|
||||||
|
fn withdraw(
|
||||||
|
who: &AccountId,
|
||||||
|
value: Self::Balance,
|
||||||
|
reason: WithdrawReason,
|
||||||
|
liveness: ExistenceRequirement,
|
||||||
|
) -> result::Result<Self::NegativeImbalance, &'static str>;
|
||||||
|
|
||||||
|
/// Similar to withdraw, only accepts a `PositiveImbalance` and returns nothing on success.
|
||||||
|
fn settle(
|
||||||
|
who: &AccountId,
|
||||||
|
value: Self::PositiveImbalance,
|
||||||
|
reason: WithdrawReason,
|
||||||
|
liveness: ExistenceRequirement,
|
||||||
|
) -> result::Result<(), Self::PositiveImbalance> {
|
||||||
|
let v = value.peek();
|
||||||
|
match Self::withdraw(who, v, reason, liveness) {
|
||||||
|
Ok(opposite) => Ok(drop(value.offset(opposite))),
|
||||||
|
_ => Err(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Ensure an account's free balance equals some value; this will create the account
|
/// Ensure an account's free balance equals some value; this will create the account
|
||||||
/// if needed.
|
/// if needed.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -70,11 +70,14 @@
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use rstd::prelude::*;
|
use rstd::prelude::*;
|
||||||
use srml_support::{StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure};
|
use srml_support::{StorageValue, StorageMap, decl_module, decl_storage, decl_event, ensure, print};
|
||||||
use srml_support::traits::{Currency, ReservableCurrency, OnDilution, OnUnbalanced, Imbalance};
|
use srml_support::traits::{
|
||||||
use runtime_primitives::{Permill,
|
Currency, ReservableCurrency, OnDilution, OnUnbalanced, Imbalance, WithdrawReason,
|
||||||
traits::{Zero, EnsureOrigin, StaticLookup, Saturating, CheckedSub, CheckedMul}
|
ExistenceRequirement
|
||||||
};
|
};
|
||||||
|
use runtime_primitives::{Permill, ModuleId, traits::{
|
||||||
|
Zero, EnsureOrigin, StaticLookup, CheckedSub, CheckedMul, AccountIdConversion
|
||||||
|
}};
|
||||||
use parity_codec::{Encode, Decode};
|
use parity_codec::{Encode, Decode};
|
||||||
use system::ensure_signed;
|
use system::ensure_signed;
|
||||||
|
|
||||||
@@ -82,6 +85,8 @@ type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::Ac
|
|||||||
type PositiveImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::PositiveImbalance;
|
type PositiveImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::PositiveImbalance;
|
||||||
type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
|
type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
|
||||||
|
|
||||||
|
const MODULE_ID: ModuleId = ModuleId(*b"py/trsry");
|
||||||
|
|
||||||
pub trait Trait: system::Trait {
|
pub trait Trait: system::Trait {
|
||||||
/// The staking balance.
|
/// The staking balance.
|
||||||
type Currency: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
|
type Currency: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
|
||||||
@@ -135,12 +140,6 @@ decl_module! {
|
|||||||
Self::deposit_event(RawEvent::Proposed(c));
|
Self::deposit_event(RawEvent::Proposed(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the balance of funds available to spend.
|
|
||||||
fn set_pot(#[compact] new_pot: BalanceOf<T>) {
|
|
||||||
// Put the new value into storage.
|
|
||||||
<Pot<T>>::put(new_pot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// (Re-)configure this module.
|
/// (Re-)configure this module.
|
||||||
fn configure(
|
fn configure(
|
||||||
#[compact] proposal_bond: Permill,
|
#[compact] proposal_bond: Permill,
|
||||||
@@ -224,9 +223,6 @@ decl_storage! {
|
|||||||
|
|
||||||
// State...
|
// State...
|
||||||
|
|
||||||
/// Total funds available to this module for spending.
|
|
||||||
Pot get(pot): BalanceOf<T>;
|
|
||||||
|
|
||||||
/// Number of proposals that have been made.
|
/// Number of proposals that have been made.
|
||||||
ProposalCount get(proposal_count): ProposalIndex;
|
ProposalCount get(proposal_count): ProposalIndex;
|
||||||
|
|
||||||
@@ -260,6 +256,14 @@ decl_event!(
|
|||||||
impl<T: Trait> Module<T> {
|
impl<T: Trait> Module<T> {
|
||||||
// Add public immutables and private mutables.
|
// Add public immutables and private mutables.
|
||||||
|
|
||||||
|
/// The account ID of the treasury pot.
|
||||||
|
///
|
||||||
|
/// This actually does computation. If you need to keep using it, then make sure you cache the
|
||||||
|
/// value and only call this once.
|
||||||
|
pub fn account_id() -> T::AccountId {
|
||||||
|
MODULE_ID.into_account()
|
||||||
|
}
|
||||||
|
|
||||||
/// The needed bond for a proposal whose spend is `value`.
|
/// The needed bond for a proposal whose spend is `value`.
|
||||||
fn calculate_bond(value: BalanceOf<T>) -> BalanceOf<T> {
|
fn calculate_bond(value: BalanceOf<T>) -> BalanceOf<T> {
|
||||||
Self::proposal_bond_minimum().max(Self::proposal_bond() * value)
|
Self::proposal_bond_minimum().max(Self::proposal_bond() * value)
|
||||||
@@ -298,18 +302,36 @@ impl<T: Trait> Module<T> {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
T::MintedForSpending::on_unbalanced(imbalance);
|
|
||||||
|
|
||||||
if !missed_any {
|
if !missed_any {
|
||||||
// burn some proportion of the remaining budget if we run a surplus.
|
// burn some proportion of the remaining budget if we run a surplus.
|
||||||
let burn = (Self::burn() * budget_remaining).min(budget_remaining);
|
let burn = (Self::burn() * budget_remaining).min(budget_remaining);
|
||||||
budget_remaining -= burn;
|
budget_remaining -= burn;
|
||||||
|
imbalance.subsume(T::Currency::burn(burn));
|
||||||
Self::deposit_event(RawEvent::Burnt(burn))
|
Self::deposit_event(RawEvent::Burnt(burn))
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::deposit_event(RawEvent::Rollover(budget_remaining));
|
if let Err(problem) = T::Currency::settle(
|
||||||
|
&Self::account_id(),
|
||||||
|
imbalance,
|
||||||
|
WithdrawReason::Transfer,
|
||||||
|
ExistenceRequirement::KeepAlive
|
||||||
|
) {
|
||||||
|
print("Inconsistent state - couldn't settle imbalance for funds spent by treasury");
|
||||||
|
// Nothing else to do here.
|
||||||
|
drop(problem);
|
||||||
|
}
|
||||||
|
|
||||||
<Pot<T>>::put(budget_remaining);
|
Self::deposit_event(RawEvent::Rollover(budget_remaining));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pot() -> BalanceOf<T> {
|
||||||
|
T::Currency::free_balance(&Self::account_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Trait> OnUnbalanced<NegativeImbalanceOf<T>> for Module<T> {
|
||||||
|
fn on_unbalanced(amount: NegativeImbalanceOf<T>) {
|
||||||
|
T::Currency::resolve_creating(&Self::account_id(), amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +344,7 @@ impl<T: Trait> OnDilution<BalanceOf<T>> for Module<T> {
|
|||||||
if let Some(funding) = total_issuance.checked_sub(&portion) {
|
if let Some(funding) = total_issuance.checked_sub(&portion) {
|
||||||
let funding = funding / portion;
|
let funding = funding / portion;
|
||||||
if let Some(funding) = funding.checked_mul(&minted) {
|
if let Some(funding) = funding.checked_mul(&minted) {
|
||||||
<Pot<T>>::mutate(|x| *x = x.saturating_add(funding));
|
Self::on_unbalanced(T::Currency::issue(funding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,6 +541,7 @@ mod tests {
|
|||||||
fn accepted_spend_proposal_enacted_on_spend_period() {
|
fn accepted_spend_proposal_enacted_on_spend_period() {
|
||||||
with_externalities(&mut new_test_ext(), || {
|
with_externalities(&mut new_test_ext(), || {
|
||||||
Treasury::on_dilution(100, 100);
|
Treasury::on_dilution(100, 100);
|
||||||
|
assert_eq!(Treasury::pot(), 100);
|
||||||
|
|
||||||
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
|
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
|
||||||
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0));
|
assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0));
|
||||||
@@ -536,25 +559,27 @@ mod tests {
|
|||||||
fn on_dilution_quantization_effects() {
|
fn on_dilution_quantization_effects() {
|
||||||
with_externalities(&mut new_test_ext(), || {
|
with_externalities(&mut new_test_ext(), || {
|
||||||
// minted = 1% of total issuance for all cases
|
// minted = 1% of total issuance for all cases
|
||||||
let _ = Treasury::set_pot(0);
|
|
||||||
assert_eq!(Balances::total_issuance(), 200);
|
assert_eq!(Balances::total_issuance(), 200);
|
||||||
|
|
||||||
Treasury::on_dilution(2, 66); // portion = 33% of total issuance
|
Treasury::on_dilution(2, 66); // portion = 33% of total issuance
|
||||||
assert_eq!(Treasury::pot(), 4); // should increase by 4 (200 - 66) / 66 * 2
|
assert_eq!(Treasury::pot(), 4); // should increase by 4 (200 - 66) / 66 * 2
|
||||||
|
Balances::make_free_balance_be(&Treasury::account_id(), 0);
|
||||||
|
|
||||||
Treasury::on_dilution(2, 67); // portion = 33+eps% of total issuance
|
Treasury::on_dilution(2, 67); // portion = 33+eps% of total issuance
|
||||||
assert_eq!(Treasury::pot(), 6); // should increase by 2 (200 - 67) / 67 * 2
|
assert_eq!(Treasury::pot(), 2); // should increase by 2 (200 - 67) / 67 * 2
|
||||||
|
Balances::make_free_balance_be(&Treasury::account_id(), 0);
|
||||||
|
|
||||||
Treasury::on_dilution(2, 100); // portion = 50% of total issuance
|
Treasury::on_dilution(2, 100); // portion = 50% of total issuance
|
||||||
assert_eq!(Treasury::pot(), 8); // should increase by 2 (200 - 100) / 100 * 2
|
assert_eq!(Treasury::pot(), 2); // should increase by 2 (200 - 100) / 100 * 2
|
||||||
|
Balances::make_free_balance_be(&Treasury::account_id(), 0);
|
||||||
|
|
||||||
// If any more than 50% of the network is staked (i.e. (2 * portion) > total_issuance)
|
// If any more than 50% of the network is staked (i.e. (2 * portion) > total_issuance)
|
||||||
// then the pot will not increase.
|
// then the pot will not increase.
|
||||||
Treasury::on_dilution(2, 101); // portion = 50+eps% of total issuance
|
Treasury::on_dilution(2, 101); // portion = 50+eps% of total issuance
|
||||||
assert_eq!(Treasury::pot(), 8); // should increase by 0 (200 - 101) / 101 * 2
|
assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 101) / 101 * 2
|
||||||
|
|
||||||
Treasury::on_dilution(2, 134); // portion = 67% of total issuance
|
Treasury::on_dilution(2, 134); // portion = 67% of total issuance
|
||||||
assert_eq!(Treasury::pot(), 8); // should increase by 0 (200 - 134) / 134 * 2
|
assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 134) / 134 * 2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,7 +597,7 @@ mod tests {
|
|||||||
Treasury::on_dilution(100, 100);
|
Treasury::on_dilution(100, 100);
|
||||||
<Treasury as OnFinalize<u64>>::on_finalize(4);
|
<Treasury as OnFinalize<u64>>::on_finalize(4);
|
||||||
assert_eq!(Balances::free_balance(&3), 150);
|
assert_eq!(Balances::free_balance(&3), 150);
|
||||||
assert_eq!(Treasury::pot(), 25);
|
assert_eq!(Treasury::pot(), 75);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user