Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Implements a variable deposit base calculation for EPM signed submissions #13983

Open
wants to merge 63 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
cda7c0e
Implements a variable deposit base calculation in EPM
gpestana Apr 23, 2023
cf5cd81
Implements geometric increase of base deposit based on the number of …
gpestana Apr 26, 2023
8b7e455
Finishes implementation and test
gpestana Apr 27, 2023
b9d90aa
More docs
gpestana Apr 27, 2023
95217b7
fixes docs
gpestana Apr 27, 2023
66a0bfb
Update frame/election-provider-multi-phase/src/signed.rs
gpestana May 4, 2023
a1636ca
Update bin/node/runtime/src/lib.rs
gpestana May 4, 2023
cb33150
Adds force_origin support (#13845)
gupnik Apr 24, 2023
0591d11
Vote locks for all reasons except RESERVE (#13914)
muharem Apr 24, 2023
1a14c52
[ci] Update buildah command and version (#13989)
alvicsam Apr 24, 2023
1c781d6
Bump enumflags2 from 0.7.5 to 0.7.7 (#13995)
dependabot[bot] Apr 24, 2023
e5a9709
frame-support-procedural: Fix detection of the tuples feature (#13996)
bkchr Apr 24, 2023
2d277ad
pallet-democracy: Do not request the proposal when scheduling (#13827)
bkchr Apr 25, 2023
db79585
[ci] Add message to cargo-deny (#14001)
alvicsam Apr 25, 2023
e34ab81
refactor(cli): Make some run params reusable (#13870)
yjhmelody Apr 25, 2023
c463fb0
contracts Add LOG_TARGET constant (#14002)
pgherveou Apr 25, 2023
316bced
frame-support: migrate some tests from `decl_*` macros to the new `pa…
koushiro Apr 25, 2023
4286a74
Removes ReportsByKindIndex (#13936)
gupnik Apr 25, 2023
f05447f
Allow missing docs for autogen weights. (#14011)
gilescope Apr 25, 2023
5ca19ef
[contracts] Port host functions to Weight V2 and storage deposit limi…
agryaznov Apr 26, 2023
7ddac2d
sp-core: remove useless bounded module (#13865)
koushiro Apr 26, 2023
4df1a87
fix a test (#14021)
agryaznov Apr 26, 2023
df3a709
Various minor fixes (#13945)
gavofyork Apr 26, 2023
941de8e
contracts Add storage_deposit test (#14003)
pgherveou Apr 27, 2023
76c802e
remote-externalities: batch insert key/values (#14004)
liamaharon Apr 27, 2023
9b487cd
collective pallet: sort genesis members and enforce max len constrain…
liamaharon Apr 27, 2023
db806ea
sc-network-sync: Improve error reporting (#14025)
bkchr Apr 27, 2023
5c320d3
contracts Fix store-call test path (#14028)
pgherveou Apr 27, 2023
49f69e4
chore(cli): make cli display docs correctly (#14017)
yjhmelody Apr 27, 2023
3b05747
improve staking interface methods (#14023)
kianenigma Apr 27, 2023
a5c6264
try-runtime-cli: improve ci stability (#14030)
liamaharon Apr 27, 2023
a6aa272
FRAME: inherited call weight syntax (#13932)
ggwpez Apr 27, 2023
07b1541
Implements `try_state` hook in elections and EPM pallets (#13979)
gpestana Apr 27, 2023
be73ca3
Bump wasmtime from 6.0.1 to 6.0.2 (#14037)
dependabot[bot] Apr 27, 2023
d20deb0
Improve contribution guidelines (#13902)
bkchr Apr 28, 2023
063b3b0
CI: Remove crate publish check (#14044)
ggwpez Apr 28, 2023
9ad2b40
fix(in_mem): fix the clone logic (#14038)
yjhmelody Apr 29, 2023
476ebd4
Contracts: runtime_call and storage_deposit (#13990)
pgherveou Apr 29, 2023
0e3c6b5
Fix bags-list tests execution (#14047)
bkchr May 1, 2023
513463b
CI: migrate to Google Cloud (#13994)
rcny May 2, 2023
f541d16
rpc: Use the blocks pinning API for chainHead methods (#13233)
lexnv May 2, 2023
2b3e750
contracts: Make Origin information available (#13708)
juangirini May 2, 2023
6ebcadd
Bump clap to 4.2.5 (#14061)
May 2, 2023
e296263
Manual seal delayed finalize (#13999)
shunsukew May 2, 2023
7eeb77d
Don't run `check-crates-publishing` job on prs (#14064)
May 3, 2023
dcaebbe
Only calculate tree route during finalization when there are multiple…
skunert May 3, 2023
4b7f99b
test-staking-e2e: Add to main `Cargo.toml`. (#14062)
bkchr May 3, 2023
89acf47
contracts: add events to ContractResult (#13807)
juangirini May 3, 2023
5f8f249
rpc server: break legacy CLI options and remove "backward compatible …
niklasad1 May 3, 2023
2668e9a
Makes DepositCalculator trait more generic
gpestana May 4, 2023
792ecc4
Merge branch 'master' into gpestana/epm_variable_deposit_base
gpestana May 4, 2023
1960329
Fixed runtime configs
gpestana May 4, 2023
afb016d
Merge remote-tracking branch 'origin/master' into gpestana/epm_variab…
May 4, 2023
1558456
Updates e2e integration tests mock
gpestana May 4, 2023
310a116
Merge remote-tracking branch 'origin/master' into gpestana/epm_variab…
May 17, 2023
0098612
Refactors the traits
gpestana May 17, 2023
99622a5
Update frame/election-provider-multi-phase/src/signed.rs
gpestana May 21, 2023
49e053b
Merge branch 'master' into gpestana/epm_variable_deposit_base
gpestana Jun 9, 2023
f053577
Nits and addresses review comments
gpestana Jun 9, 2023
f11d312
Merge branch 'master' into gpestana/epm_variable_deposit_base
gpestana Jun 9, 2023
856828e
".git/.scripts/commands/fmt/fmt.sh"
Jun 9, 2023
fe49a49
Parameterize GeometricProgression instead of using dedicated associat…
gpestana Jun 12, 2023
a51a3eb
Merge branch 'master' into gpestana/epm_variable_deposit_base
gpestana Aug 10, 2023
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
9 changes: 6 additions & 3 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use frame_system::{
};
pub use node_primitives::{AccountId, Signature};
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
use pallet_election_provider_multi_phase::SolutionAccuracyOf;
use pallet_election_provider_multi_phase::{GeometricDepositBase, SolutionAccuracyOf};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use pallet_nfts::PalletFeatures;
use pallet_nis::WithMaximumOf;
Expand Down Expand Up @@ -621,7 +621,8 @@ parameter_types! {

// signed config
pub const SignedRewardBase: Balance = 1 * DOLLARS;
pub const SignedDepositBase: Balance = 1 * DOLLARS;
pub const SignedFixedDepositBase: Balance = 1 * DOLLARS;
pub const SignedDepositBaseIncreaseFactor: Percent = Percent::from_percent(10);
pub const SignedDepositByte: Balance = 1 * CENTS;

pub BetterUnsignedThreshold: Perbill = Perbill::from_rational(1u32, 10_000);
Expand Down Expand Up @@ -747,7 +748,9 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
type MinerConfig = Self;
type SignedMaxSubmissions = ConstU32<10>;
type SignedRewardBase = SignedRewardBase;
type SignedDepositBase = SignedDepositBase;
type SignedDepositBase = GeometricDepositBase<Runtime>;
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
type SignedFixedDepositBase = SignedFixedDepositBase;
type SignedDepositBaseIncreaseFactor = SignedDepositBaseIncreaseFactor;
type SignedDepositByte = SignedDepositByte;
type SignedMaxRefunds = ConstU32<3>;
type SignedDepositWeight = ();
Expand Down
22 changes: 17 additions & 5 deletions frame/election-provider-multi-phase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ use sp_runtime::{
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
TransactionValidityError, ValidTransaction,
},
DispatchError, ModuleError, PerThing, Perbill, RuntimeDebug, SaturatedConversion,
DispatchError, ModuleError, PerThing, Perbill, Percent, RuntimeDebug, SaturatedConversion,
};
use sp_std::prelude::*;

Expand All @@ -274,8 +274,8 @@ use unsigned::VoterOf;
pub use weights::WeightInfo;

pub use signed::{
BalanceOf, NegativeImbalanceOf, PositiveImbalanceOf, SignedSubmission, SignedSubmissionOf,
SignedSubmissions, SubmissionIndicesOf,
BalanceOf, GeometricDepositBase, NegativeImbalanceOf, PositiveImbalanceOf, SignedSubmission,
SignedSubmissionOf, SignedSubmissions, SubmissionIndicesOf,
};
pub use unsigned::{Miner, MinerConfig};

Expand Down Expand Up @@ -567,6 +567,7 @@ pub mod pallet {
use frame_election_provider_support::{InstantElectionProvider, NposSolver};
use frame_support::{pallet_prelude::*, traits::EstimateCallFee};
use frame_system::pallet_prelude::*;
use sp_runtime::traits::Convert;

#[pallet::config]
pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
Expand Down Expand Up @@ -644,9 +645,16 @@ pub mod pallet {
#[pallet::constant]
type SignedRewardBase: Get<BalanceOf<Self>>;

/// Base deposit for a signed solution.
/// Fixed base deposit for a signed solution.
#[pallet::constant]
type SignedDepositBase: Get<BalanceOf<Self>>;
type SignedFixedDepositBase: Get<BalanceOf<Self>>;

/// Increase factor of the geometric series for the base deposit computation.
///
/// If 0, then signed base deposit remains constant regardless of the submissions queue size
/// (and equal to `SignedFixedDepositBase`).
#[pallet::constant]
type SignedDepositBaseIncreaseFactor: Get<Percent>;

/// Per-byte deposit for a signed solution.
#[pallet::constant]
Expand All @@ -673,6 +681,10 @@ pub mod pallet {
#[pallet::constant]
type MaxWinners: Get<u32>;

/// Something that calculates the signed deposit base based on the signed submissions queue
/// size.
type SignedDepositBase: Convert<usize, BalanceOf<Self>>;

/// Handler for the slashed deposits.
type SlashHandler: OnUnbalanced<NegativeImbalanceOf<Self>>;

Expand Down
34 changes: 29 additions & 5 deletions frame/election-provider-multi-phase/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// limitations under the License.

use super::*;
use crate::{self as multi_phase, unsigned::MinerConfig};
use crate::{self as multi_phase, signed::GeometricDepositBase, unsigned::MinerConfig};
use frame_election_provider_support::{
data_provider,
onchain::{self},
Expand Down Expand Up @@ -44,7 +44,7 @@ use sp_npos_elections::{
};
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
traits::{BlakeTwo256, Convert, IdentityLookup},
PerU16,
};
use std::sync::Arc;
Expand Down Expand Up @@ -287,7 +287,11 @@ parameter_types! {
pub static UnsignedPhase: BlockNumber = 5;
pub static SignedMaxSubmissions: u32 = 5;
pub static SignedMaxRefunds: u32 = 1;
pub static SignedDepositBase: Balance = 5;
// for tests only. if `EnableVariableDepositBase` is true, the deposit base will be calculated
// by `Multiphase::DepositBase`. Otherwise the deposit base is `SignedFixedDepositBase`.
pub static EnableVariableDepositBase: bool = false;
pub static SignedFixedDepositBase: Balance = 5;
pub static SignedDepositBaseIncreaseFactor: Percent = Percent::from_percent(10);
pub static SignedDepositByte: Balance = 0;
pub static SignedDepositWeight: Balance = 0;
pub static SignedRewardBase: Balance = 7;
Expand Down Expand Up @@ -393,7 +397,9 @@ impl crate::Config for Runtime {
type OffchainRepeat = OffchainRepeat;
type MinerTxPriority = MinerTxPriority;
type SignedRewardBase = SignedRewardBase;
type SignedDepositBase = SignedDepositBase;
type SignedDepositBase = Self;
type SignedFixedDepositBase = SignedFixedDepositBase;
type SignedDepositBaseIncreaseFactor = SignedDepositBaseIncreaseFactor;
type SignedDepositByte = ();
type SignedDepositWeight = ();
type SignedMaxWeight = SignedMaxWeight;
Expand All @@ -415,6 +421,18 @@ impl crate::Config for Runtime {
type Solver = SequentialPhragmen<AccountId, SolutionAccuracyOf<Runtime>, Balancing>;
}

impl Convert<usize, BalanceOf<Runtime>> for Runtime {
/// returns the geometric increase deposit fee if `EnableVariableDepositBase` is set, otherwise
/// the fee is `SignedFixedDepositBase`.
fn convert(queue_len: usize) -> Balance {
if !EnableVariableDepositBase::get() {
SignedFixedDepositBase::get()
} else {
GeometricDepositBase::<Runtime>::convert(queue_len)
}
}
}

impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runtime
where
RuntimeCall: From<LocalCall>,
Expand Down Expand Up @@ -561,8 +579,14 @@ impl ExtBuilder {
<SignedMaxSubmissions>::set(count);
self
}
pub fn signed_base_deposit(self, base: u64, variable: bool, increase: Percent) -> Self {
<EnableVariableDepositBase>::set(variable);
<SignedFixedDepositBase>::set(base);
<SignedDepositBaseIncreaseFactor>::set(increase);
self
}
pub fn signed_deposit(self, base: u64, byte: u64, weight: u64) -> Self {
<SignedDepositBase>::set(base);
<SignedFixedDepositBase>::set(base);
<SignedDepositByte>::set(byte);
<SignedDepositWeight>::set(weight);
self
Expand Down
88 changes: 83 additions & 5 deletions frame/election-provider-multi-phase/src/signed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

//! The signed phase implementation.

use core::marker::PhantomData;

use crate::{
unsigned::MinerConfig, Config, ElectionCompute, Pallet, QueuedSolution, RawSolution,
ReadySolution, SignedSubmissionIndices, SignedSubmissionNextIndex, SignedSubmissionsMap,
Expand All @@ -31,8 +33,8 @@ use sp_arithmetic::traits::SaturatedConversion;
use sp_core::bounded::BoundedVec;
use sp_npos_elections::ElectionScore;
use sp_runtime::{
traits::{Saturating, Zero},
RuntimeDebug,
traits::{Convert, Saturating, Zero},
FixedPointNumber, FixedU128, Percent, RuntimeDebug,
};
use sp_std::{
cmp::Ordering,
Expand Down Expand Up @@ -349,6 +351,31 @@ impl<T: Config> SignedSubmissions<T> {
}
}

/// Type that can be used to calculate the deposit base for signed submissions.
///
/// The deposit base is calculated as a geometric progression based on the number of signed
/// submissions in the queue. The size of the queue represents the progression term.
pub struct GeometricDepositBase<T> {
_marker: PhantomData<T>,
}

impl<T: Config> Convert<usize, BalanceOf<T>> for GeometricDepositBase<T> {
// Calculates the base deposit as a geometric progression based on the number of signed
// su Calculates.
gpestana marked this conversation as resolved.
Show resolved Hide resolved
//
// The nth term is obtained by calculating `base * (1 + increase_factor)^nth`. Example: factor
// 5, with initial deposit of 1000 and 10% of increase factor is 1000 * (1 + 0.1)^5.
fn convert(queue_len: usize) -> BalanceOf<T> {
let increase_factor: FixedU128 =
<Percent as Into<FixedU128>>::into(T::SignedDepositBaseIncreaseFactor::get()) +
sp_runtime::traits::One::one();
gpestana marked this conversation as resolved.
Show resolved Hide resolved

increase_factor
.saturating_pow(queue_len)
.saturating_mul_int(T::SignedFixedDepositBase::get())
}
}

impl<T: Config> Pallet<T> {
/// `Self` accessor for `SignedSubmission<T>`.
pub fn signed_submissions() -> SignedSubmissions<T> {
Expand Down Expand Up @@ -521,14 +548,14 @@ impl<T: Config> Pallet<T> {
size: SolutionOrSnapshotSize,
) -> BalanceOf<T> {
let encoded_len: u32 = raw_solution.encoded_size().saturated_into();
let encoded_len: BalanceOf<T> = encoded_len.into();
let encoded_len_balance: BalanceOf<T> = encoded_len.into();
let feasibility_weight = Self::solution_weight_of(raw_solution, size);

let len_deposit = T::SignedDepositByte::get().saturating_mul(encoded_len);
let len_deposit = T::SignedDepositByte::get().saturating_mul(encoded_len_balance);
let weight_deposit = T::SignedDepositWeight::get()
.saturating_mul(feasibility_weight.ref_time().saturated_into());

T::SignedDepositBase::get()
T::SignedDepositBase::convert(Self::signed_submissions().len())
.saturating_add(len_deposit)
.saturating_add(weight_deposit)
}
Expand All @@ -539,6 +566,7 @@ mod tests {
use super::*;
use crate::{mock::*, ElectionCompute, ElectionError, Error, Event, Perbill, Phase};
use frame_support::{assert_noop, assert_ok, assert_storage_noop};
use sp_runtime::Percent;

#[test]
fn cannot_submit_too_early() {
Expand Down Expand Up @@ -775,6 +803,56 @@ mod tests {
})
}

#[test]
fn geometric_deposit_queue_size_works() {
let constant = vec![1000; 10];
// geometric progression with 10% increase in each iteration for 10 terms.
let progression_10 = vec![1000, 1100, 1210, 1331, 1464, 1610, 1771, 1948, 2143, 2357];
let progression_40 = vec![1000, 1400, 1960, 2744, 3841, 5378, 7529, 10541, 14757, 20661];

let check_progressive_base_fee = |expected: &Vec<u64>| {
for s in 0..SignedMaxSubmissions::get() {
let account = 99 + s as u64;
Balances::make_free_balance_be(&account, 10000000);
let mut solution = raw_solution();
solution.score.minimal_stake -= s as u128;

assert_ok!(MultiPhase::submit(RuntimeOrigin::signed(account), Box::new(solution)));
assert_eq!(balances(&account).1, expected[s as usize])
}
};

ExtBuilder::default()
.signed_max_submission(10)
.signed_base_deposit(1000, true, Percent::from_percent(0))
.build_and_execute(|| {
roll_to_signed();
assert!(MultiPhase::current_phase().is_signed());

check_progressive_base_fee(&constant);
});

ExtBuilder::default()
.signed_max_submission(10)
.signed_base_deposit(1000, true, Percent::from_percent(10))
.build_and_execute(|| {
roll_to_signed();
assert!(MultiPhase::current_phase().is_signed());

check_progressive_base_fee(&progression_10);
});

ExtBuilder::default()
.signed_max_submission(10)
.signed_base_deposit(1000, true, Percent::from_percent(40))
.build_and_execute(|| {
roll_to_signed();
assert!(MultiPhase::current_phase().is_signed());

check_progressive_base_fee(&progression_40);
});
}

#[test]
fn call_fee_refund_is_limited_by_signed_max_refunds() {
ExtBuilder::default().build_and_execute(|| {
Expand Down
13 changes: 9 additions & 4 deletions frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use sp_npos_elections::{ElectionScore, VoteWeight};
use sp_runtime::{
testing,
traits::{IdentityLookup, Zero},
transaction_validity, PerU16, Perbill,
transaction_validity, PerU16, Perbill, Percent,
};
use sp_staking::{
offence::{DisableStrategy, OffenceDetails, OnOffenceHandler},
Expand All @@ -40,7 +40,8 @@ use std::collections::BTreeMap;

use frame_election_provider_support::{onchain, ElectionDataProvider, SequentialPhragmen, Weight};
use pallet_election_provider_multi_phase::{
unsigned::MinerConfig, ElectionCompute, QueuedSolution, SolutionAccuracyOf,
unsigned::MinerConfig, ElectionCompute, GeometricDepositBase, QueuedSolution,
SolutionAccuracyOf,
};
use pallet_staking::StakerStatus;

Expand Down Expand Up @@ -190,7 +191,9 @@ parameter_types! {
pub static TransactionPriority: transaction_validity::TransactionPriority = 1;
pub static MaxWinners: u32 = 100;
pub static MaxVotesPerVoter: u32 = 16;
pub static MaxNominations: u32 = 16;
pub static MaxNominations: u32 = 16;
pub static SignedFixedDepositBase: Balance = 1;
pub static SignedDepositBaseIncreaseFactor: Percent = Percent::from_percent(10);
}

impl pallet_election_provider_multi_phase::Config for Runtime {
Expand All @@ -206,7 +209,9 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
type MinerConfig = Self;
type SignedMaxSubmissions = ConstU32<10>;
type SignedRewardBase = ();
type SignedDepositBase = ();
type SignedDepositBase = GeometricDepositBase<Runtime>;
type SignedFixedDepositBase = SignedFixedDepositBase;
type SignedDepositBaseIncreaseFactor = SignedDepositBaseIncreaseFactor;
type SignedDepositByte = ();
type SignedMaxRefunds = ConstU32<3>;
type SignedDepositWeight = ();
Expand Down
2 changes: 1 addition & 1 deletion frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@
//! ```
//! use pallet_staking::{self as staking};
//!
//! #[frame_support::pallet]
//! #[frame_support::pallet(dev_mode)]
gpestana marked this conversation as resolved.
Show resolved Hide resolved
//! pub mod pallet {
//! use super::*;
//! use frame_support::pallet_prelude::*;
Expand Down