Joystream / joystream

Joystream Monorepo
http://www.joystream.org
GNU General Public License v3.0
1.42k stars 115 forks source link

Launching with restricted NPoS #4286

Closed mnaamani closed 2 years ago

mnaamani commented 2 years ago

Background

As an alternative option to starting chain with PoA configuration which would require a lot of code changes, we can start the chain with NPoS but with a very constrained configuration.

Objectives

  1. Start chain with an initial set of validators, without ability for any participants to join this set.
  2. The initial set of validators must receive zero rewards. (nominators too)

Proposal

Validators and nominators config.

Can be achieved in two ways:

A. By ensuring the runtime configuration has the BaseCallFilter filter enabled on the system pallet that prevents any dispatches on the staking pallet. This will prevent bond() and validate() and nominate() calls which is how validators join the "waiting list" of validators to be selected in future sessions, and how participants become nominators.

B. By setting the minimum validator and nominator bond to an impractically high value, Balance::max_value(), either after launch by making a sudo call to staking::set_staking_configs(), or by modifying the genesis_build step in the staking pallet to allow bonding first of the initial validators (with minimal stake), and as last step to increase the min bond to max value.

I would opt for A since it is simpler to implement (already implemented in-fact) and doesn't require making further changes to the staking pallet.

Zero Rewards config.

The EraPayout trait https://github.com/Joystream/substrate/blob/31f4f7654cf8e27e0d73ffeb1c11b2df2d4fbffe/frame/staking/src/lib.rs#L768

Risks

Adding more validators or removing to the set will force us to re-enable the staking pallet calls in the filter. If we need to do this before the right time, it can be problematic. We may also face this problem if validator keys are compromised and need to be changed.

Disadvantage

As pointed out in a recent call, launching this way prevents new participants from preparing ahead of time for the switch to NPoS.

┆Issue is synchronized with this Asana task by Unito

mnaamani commented 2 years ago

A. By ensuring the runtime configuration has the BaseCallFilter filter enabled on the system pallet that prevents any dispatches on the staking pallet. This will prevent bond() and validate() and nominate() calls which is how validators join the "waiting list" of validators to be selected in future sessions, and how participants become nominators.

Actually remembering back this PR https://github.com/Joystream/joystream/pull/4213 we need to make sure utils::batch is also disabled (only sudo will be able to make utils:batch calls because sudo bypasses filter - as we might need it during bootstrapping scripts)

bedeho commented 2 years ago

😅

ignazio-bovo commented 2 years ago

Modify the transaction payment pallet configuration to burn all fees and tips:

Transaction payment happens in 2 phases:

  1. Tx estimated_fee + tip are Currency::withdrawn(i.e. slashed from the tx sender usable balance, hence locks are considered) before the transaction is executed in order to secure the payment
  2. After the transaction was executed the transaction weight can be adjusted, depending on the used resources by the transaction. Two steps are now necessary a. Refund excess feeswith a deposit_into_existing(sender_account, refund_amount). b. The actual_fees + tip can be then deposited into the =(treasury, block_author)= accounts via on_unbalanceds([actual_fees, tip].iter()) according to the specified treasury/author ratio. Setting our implementation for on_unbalanceds to a no-op we should be set
mnaamani commented 2 years ago

Update: Additional configuration should be done to prevent validators gaining any points during an era in the "PoA" phase to prevent the the initial PoA validators from taking all the rewards of the first era once in the NPoS phase, by removing Staking as EventHandler for Authorship

impl pallet_authorship::Config for Runtime {
    type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
    type UncleGenerations = UncleGenerations;
    type FilterUncle = ();
    type EventHandler = ImOnline;  // <= PoA // NPoS => (Staking, ImOnline);
}