From 3bfcdeb2502141a5b9016240eb0e5fa22826df66 Mon Sep 17 00:00:00 2001 From: thiolliere <gui.thiolliere@gmail.com> Date: Wed, 2 Oct 2019 12:36:50 +0200 Subject: [PATCH] Fix quantization from OnDilution in treasury (#3736) * fix * bump version * remove println --- substrate/node/runtime/src/lib.rs | 2 +- substrate/srml/treasury/src/lib.rs | 74 +++++++++++++++--------------- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 7163d2c7365..f4f71e37f36 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -84,7 +84,7 @@ 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: 168, + spec_version: 169, impl_version: 169, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/srml/treasury/src/lib.rs b/substrate/srml/treasury/src/lib.rs index 0fd561fca00..db8b0f34c90 100644 --- a/substrate/srml/treasury/src/lib.rs +++ b/substrate/srml/treasury/src/lib.rs @@ -75,9 +75,9 @@ use support::traits::{ Currency, ExistenceRequirement, Get, Imbalance, OnDilution, OnUnbalanced, ReservableCurrency, WithdrawReason }; -use sr_primitives::{Permill, ModuleId}; +use sr_primitives::{Permill, Perbill, ModuleId}; use sr_primitives::traits::{ - Zero, EnsureOrigin, StaticLookup, CheckedSub, CheckedMul, AccountIdConversion + Zero, EnsureOrigin, StaticLookup, AccountIdConversion, CheckedSub }; use sr_primitives::weights::SimpleDispatchInfo; use codec::{Encode, Decode}; @@ -343,10 +343,9 @@ impl<T: Trait> OnDilution<BalanceOf<T>> for Module<T> { if !minted.is_zero() && !portion.is_zero() { let total_issuance = T::Currency::total_issuance(); if let Some(funding) = total_issuance.checked_sub(&portion) { - let funding = funding / portion; - if let Some(funding) = funding.checked_mul(&minted) { - Self::on_unbalanced(T::Currency::issue(funding)); - } + let increase_ratio = Perbill::from_rational_approximation(minted, portion); + let funding = increase_ratio * funding; + Self::on_unbalanced(T::Currency::issue(funding)); } } } @@ -359,7 +358,11 @@ mod tests { use runtime_io::with_externalities; use support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; use primitives::{H256, Blake2Hasher}; - use sr_primitives::{Perbill, traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header}; + use sr_primitives::{ + traits::{BlakeTwo256, OnFinalize, IdentityLookup}, + testing::Header, + assert_eq_error_rate, + }; impl_outer_origin! { pub enum Origin for Test {} @@ -460,6 +463,32 @@ mod tests { }); } + #[test] + fn minting_works_2() { + let tests = [(1, 10), (1, 20), (40, 130), (2, 66), (2, 67), (2, 100), (2, 101), (2, 134)]; + for &(minted, portion) in &tests { + with_externalities(&mut new_test_ext(), || { + let init_total_issuance = Balances::total_issuance(); + Treasury::on_dilution(minted, portion); + + assert_eq!( + Treasury::pot(), + (((init_total_issuance - portion) * minted) as f32 / portion as f32) + .round() as u64 + ); + + // Assert: + // portion / init_total_issuance + // == (portion + minted) / (init_total_issuance + Treasury::pot() + minted), + assert_eq_error_rate!( + portion * 1_000 / init_total_issuance, + (portion + minted) * 1_000 / (init_total_issuance + Treasury::pot() + minted), + 2, + ); + }); + } + } + #[test] fn spend_proposal_takes_min_deposit() { with_externalities(&mut new_test_ext(), || { @@ -577,37 +606,6 @@ mod tests { }); } - #[test] - // Note: This test demonstrates that `on_dilution` does not increase the pot with good resolution - // with large amounts of the network staked. https://github.com/paritytech/substrate/issues/2579 - // A fix to 2579 should include a change of this test. - fn on_dilution_quantization_effects() { - with_externalities(&mut new_test_ext(), || { - // minted = 1% of total issuance for all cases - assert_eq!(Balances::total_issuance(), 200); - - Treasury::on_dilution(2, 66); // portion = 33% of total issuance - 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 - 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 - 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) - // then the pot will not increase. - Treasury::on_dilution(2, 101); // portion = 50+eps% of total issuance - assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 101) / 101 * 2 - - Treasury::on_dilution(2, 134); // portion = 67% of total issuance - assert_eq!(Treasury::pot(), 0); // should increase by 0 (200 - 134) / 134 * 2 - }); - } - #[test] fn pot_underflow_should_not_diminish() { with_externalities(&mut new_test_ext(), || { -- GitLab