Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC-201/205] Staking and validator storage rework #1442

Merged
merged 27 commits into from
May 3, 2023

Conversation

goran-ethernal
Copy link
Collaborator

@goran-ethernal goran-ethernal commented Apr 27, 2023

Description

This PR refactors the workflow of validators staking and validator set storage in accordance to RFCs 201 and 205.

Edge is now used as L2, meaning it can operate only in bridge mode, and from now on called a Supernet. Its validators are registered on, and stake on the rootchain. A stake is transferred to childchain through the bridge mechanism, and the validator set is updated on the client itself. It is worth noting that staking is done in the native root token on the rootchain.

Two new contracts are deployed to rootchain:

  1. StakeManager - a single instance contract on rootchain that has references to each supernet and handles staking for each of them on rootchain.
  2. CustomSupernetManager - a contract that will be deployed for each supernet, which stores the validator info for a given supernet, whitelists, registers, and bridges stake to its supernet (childchain).

After StakeManager is deployed, and SupernetManager is deployed for the given supernet, deployer needs to register the SupernetManager to StakeManager by calling the registerChildChain function. This function will emit an event that contains an id of the SupernetManager (or given supernet). That id will be our new chainID of the childChain and needs to be added to genesis file generated by the genesis command (this can be done manually, but the deploy command provided by Edge, does this automatically).

After the contracts are deployed on the rootchain, SupernetManager deployer can whitelist validators in the genesis file to it, by calling the whitelist function (note, only the deployer can do this).

After the validators are whitelisted on the rootchain, each of them can proceed to register itself on the SupernetManager, by calling the register function. They need to provide their public bls key and signature when registering.

After validators register themselves on the SupernetManager, they can do the initial staking on the rootchain, by calling the stakeFor function on StakeManager, and providing the chainID the StakeManager emitted when registering SupernetManager, and the amount of tokens they want to stake. By using the chainID, StakeManager knows on which supernet the given validator wants to stake. It is worth noting that validators can change stakes as they wish before starting the child chain. Once the genesis staking is finalized by the SupernetManager deployer, validators stake at that moment will be considered final, and childchain can be started.

Genesis staking is finalized by the SupernetManager deployer by calling the finalizeGenesis function on the contract.

After genesis staking is finalized on the rootchain, supernet (childchain) can be started.

Once the supernet is started, each stake change on the rootchain is bridged to the ValidatorSet contract on the child chain which acts as an ERC20 implementation, where balances of accounts are their stake on the rootchain.

Unstaking is done on the supernet first, by calling the unstake function on the ValidatorSet contract. The user needs to wait for one epoch so that he can withdraw his stake from the supernet to the rootchain. Withdraw on the ValidatorSet contract, bridges the unstaked amount to the rootchain StakeManager contract. This releases the given stake on the rootchain and the user can withdraw it from the StakeManager by calling the withdrawStake function.

On the supernet (childchain) we have two new contracts:

  1. ValidatorSet - as mentioned earlier is just a ERC20 implementation that wraps the stake change on rootchain to the childchain, where balance of an account on ValidatorSet is the stake of the given account on the rootchain. It also has bridge functionality to bridge the stake/unstake changes from one chain to the other. ValidatorSet has the old commitFunction to commit the ending of an epoch, but does not handle rewards distribution.
  2. RewardPool - is a new contract that handles the reward distribution. It is called by the edge client in a state transaction to distribute rewards to block signers at the epoch-ending block. It uses a reward token (an ERC20 implementation, which can be either a native ERC20 token on childchain or a custom ERC20 token provided by the client.

A graphical look of the new flow can be seen on the picture below:

stake_manager_flow

Deployment steps are now changed to support this:

  1. Initialize secrets for initial validators.
  2. Do genesis command. It is important to note that we added two new flags in genesis command:
  • --reward-token - hex encoded byte code of a custom reward ERC20 token if clients want to use a custom ERC20 token for rewards. If not provided, native ERC20 token on child chain will be used for rewards.
  • --reward-wallet - a mandatory flag where users define a reward wallet address and the amount of tokens that need to be premined to it on genesis (address:amount).
  1. Either manually deploy the StakeManager and CustomSupernetManager contracts, initialize them and register supernet to StakeManager, or use the provided deploy command by Edge that simplifies this workflow. Keep in mind that if you opt to do the manual deployment of rootchain contracts, you will need to extract the chainID of you supernet that is emitted by StakeManager when registering the supernet to it, by reading the transaction logs, and updating the genesis file manually. That is why we recommend using the deploy command, which does all this automatically.
  2. Whitelist genesis validators to CustomSupernetManager. You can use the whitelist-validators command provided by Edge.
  3. Each validator needs to register itself to CustomSupernetManager.
  4. Each validator needs to stake some tokens on the StakeManager. Keep in mind they need to provide the chainID from genesis.
  5. SupernetManager deployer needs to finalize genesis staking on it as a final step before starting the supernet. We recommend using the supernet command provided by Edge.

Changes include

  • Bugfix (non-breaking change that solves an issue)
  • Hotfix (change that solves an urgent issue, and requires immediate attention)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (change that is not backwards-compatible and/or changes current functionality)

Breaking changes

  • Edge can only be run as L2 (operating only in bridge mode, therefore it is not possible to run it as L1, sovereign chain anymore).
  • More steps in deployment.
  • Staking is done on rootchain.
  • Validator set storage and update are done on edge client based on changed stake in rootchain.
  • Existing commands are changed.
  • Reward distribution needs a wallet address.

Checklist

  • I have assigned this PR to myself
  • I have added at least 1 reviewer
  • I have added the relevant labels
  • I have updated the official documentation
  • I have added sufficient documentation in code

Testing

  • I have tested this code with the official test suite
  • I have tested this code manually

goran-ethernal and others added 19 commits April 20, 2023 09:01
* Deploy root contracts

* New child contracts deployment

* Lint fix

* nil reference exception fix

* Comments fix
* Change whitelist and register commands

* Build fix

* Lint fix

* Include submodule fix

* Remove leftover const

* Minor change

* Minor updates

* Check error before checking doesMatch flag

* Add private key flag to whitelist command

* two new GetXYZFromSecret methods

* Change whitelist command for secrets

* Lint fix

---------

Co-authored-by: Stefan Negovanović <[email protected]>
Co-authored-by: Igor Crevar <[email protected]>
* Register child chain to StakeManager

* Lint fix

* Small fix

* Comments fix
* Change stake command

* Build fix

* Bring commands back to polybft command

* Validate jsonRPC address

* Comments fix

* Build fix

* Lint fix
* Supernet command

* Use GetECDSAKey in whitelist command

* Validate jsonRPC address

* Comments fix

* Comments fix

* Rebase fix
* Change validator info command

* Lint fix
* Validate validator set delta

* Lint fix

* Remove comment

* Add test
* Initial changes

* Lint fix

* Comments fix

* Comments fix

* Remove comment

* Comments fix

* Improve sorted map

* Comments fix

* Lint fix

* Add comments in code

* Comments fix

* New UT

* Lint fix

* Call stakeManager in consensus runtime

* Testing deterministic behavior of sort by stake

* simple changes

* even simplier things

* different stakeMap and some refactoring

* lower number of execution times for test

* fix

---------

Co-authored-by: Igor Crevar <[email protected]>
* Initial changes

* Change withdraw command

* Unstake command change

* Remove ChildValidatorSet

* Deploy MockRewardContract

* Deploy contract fix

* Lint fix

* Fix sc_integration_test

* Separate unstake and withdraw

* Comments fix
* Save full validator set in db

* Lint fix

* Fix

* Test fix

* validatorStakeMap refactor

* lint fix

---------

Co-authored-by: Igor Crevar <[email protected]>
* Add whitelist and register validator steps to e2e tests

* Initial staking on genesis

* Finalize genesis set on supernet manager

* Parallelize register and stake commands

* Lint fix

* Small optimization

* Comments fix

* Return negative case MakeKOSKSignature test

* Lint fix
* New init of contracts

* Reward token configuration

* Rebase fix

* Lint fix

* Validate wallet amount in genesis

* Comments fix

* Comments fix

* Comments fix
* WithoutBridge

* fix fund command test

* Remove WithBridge invocation

* Rename error message

* Rename to initializeNew (unblock whitelist)

* kosk refactor

* Kosk key fix

* Lint fix

* Kosk signature print

* Remove chainID from register command

* Remove leftovers and lint fixes

* Remove chain-id flag from register validator command

* Remove feat-polybft-release for core-contracts submodule

* Remove delegation e2e test

* GetValidatorInfo refactor

* Remove comments

* Latest SC spec

* Leftover and comment

* Fix Test_MakeKOSKSignature

* Fix GetValidatorInfo, partially fix stake function

* RewardPool updates

* Withdraw child and withdraw root functions, obsolete e2e test with delegate

* Increase timeout to 1.5h

* Lint fix

* Register and white list validators

* Fix typo

* ChangeVotingPower test fix

* Lint fix

* Fund per validator

* Unstake test fix

* amount should be big.Int

* Update SCs and lint fix

* Fix TestE2E_Consensus_MintableERC20NativeToken

* Fix TestE2E_Consensus_Validator_Unstake

* Unstake test fix

* Fix RegisterValidator test

* Lint fix

* ChangeVotingPower test modification

* TestIntegration_CommitEpoch fix

* Fix TestE2E_Bridge_ChangeVotingPower

* Minor fixes

* Fix TestE2E_Bridge_ChangeVotingPower (part 2)

* Update smart contracts

* Remove commented code

* RFC-201-205 Stake manager db fix (#1457)

* stake manager db fix

* bls key

* Fix with Data field error on logs

* Fix timeout

* Fix test timeout

* Copy data array

* Remove log copying from bindings generator

* Wait for epoch ending block in ChangeVotingPower e2e test

* Persist initial validator set as epoch id 0

---------

Co-authored-by: Goran Rojovic <[email protected]>
Co-authored-by: Stefan Negovanović <[email protected]>

* Update README

---------

Co-authored-by: Stefan Negovanović <[email protected]>
Co-authored-by: Goran Rojovic <[email protected]>
@goran-ethernal goran-ethernal marked this pull request as ready for review May 2, 2023 12:34
@goran-ethernal goran-ethernal requested a review from a team May 2, 2023 12:36
@goran-ethernal goran-ethernal self-assigned this May 2, 2023
@goran-ethernal goran-ethernal added the breaking change Functionality that contains breaking changes label May 2, 2023
@Stefan-Ethernal Stefan-Ethernal added the feature New update to Polygon Edge label May 2, 2023
@goran-ethernal goran-ethernal merged commit fe843f6 into develop May 3, 2023
@github-actions github-actions bot locked and limited conversation to collaborators May 3, 2023
@goran-ethernal goran-ethernal deleted the feat/validator-storage-rework branch May 3, 2023 14:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
breaking change Functionality that contains breaking changes feature New update to Polygon Edge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants