Skip to content

Commit

Permalink
Update predeployed staking SC (#397)
Browse files Browse the repository at this point in the history
* Update predeployed staking SC

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add CLI flag for providing maximum validator count to PoS

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Fix lint

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add sanity check for max validator count value

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Update check behaviour for max validator count

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add support for configurable minimum validator count

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add missing value in default configuration

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Fix lint error

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add new type for staking contract params

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Update error handling in predeploy process

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Update staking contract bytecode

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add generic error for PoS validator number

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Update SC bytecode

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Update storage write process for min and max validator counts

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add sanity check in predeploy process

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add validator limit test for PoS

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Add test for default max validator limit in PoS

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Fix merge conflicts

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Fix lint errors

Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>

* Fix git merge

* Remove unnecessary log

* change bytecode to match staking-contract repo

* fix linter errors

* Fix PR comments

* Refactor validator setter in genesis

* Add missing spacing

* Change min and max validator number to uint256

* Change min and max validator count to pointer in switch

* Fix linter errors

* Add additional check for validator set by prefix

* add additional check for pos switch

* Fix typo

Co-authored-by: AleksaOpacic <aleksaopacic988@gmail.com>
  • Loading branch information
0xpanoramix and 0xAleksaOpacic authored Mar 30, 2022
1 parent cc56e29 commit 3543e50
Show file tree
Hide file tree
Showing 19 changed files with 427 additions and 69 deletions.
29 changes: 29 additions & 0 deletions command/common.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
package command

import (
"errors"
"github.com/0xPolygon/polygon-edge/helper/common"
)

const (
ConsensusFlag = "consensus"
NoDiscoverFlag = "no-discover"
BootnodeFlag = "bootnode"
LogLevelFlag = "log-level"
)

var (
errInvalidValidatorRange = errors.New("minimum number of validators can not be greater than the " +
"maximum number of validators")
errInvalidMinNumValidators = errors.New("minimum number of validators must be greater than 0")
errInvalidMaxNumValidators = errors.New("maximum number of validators must be lower or equal " +
"than MaxSafeJSInt (2^53 - 2)")
)

func ValidateMinMaxValidatorsNumber(minValidatorCount uint64, maxValidatorCount uint64) error {
if minValidatorCount < 1 {
return errInvalidMinNumValidators
}

if minValidatorCount > maxValidatorCount {
return errInvalidValidatorRange
}

if maxValidatorCount > common.MaxSafeJSInt {
return errInvalidMaxNumValidators
}

return nil
}
13 changes: 13 additions & 0 deletions command/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/consensus/ibft"
"github.com/0xPolygon/polygon-edge/helper/common"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -126,6 +127,18 @@ func setFlags(cmd *cobra.Command) {
command.DefaultGenesisGasLimit,
),
)
cmd.Flags().Uint64Var(
&params.minNumValidators,
minValidatorCount,
1,
"the minimum number of validators in the validator set for PoS",
)
cmd.Flags().Uint64Var(
&params.maxNumValidators,
maxValidatorCount,
common.MaxSafeJSInt,
"the maximum number of validators in the validator set for PoS",
)
}

// setLegacyFlags sets the legacy flags to preserve backwards compatibility
Expand Down
50 changes: 47 additions & 3 deletions command/genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package genesis
import (
"errors"
"fmt"

"github.com/0xPolygon/polygon-edge/chain"
"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
Expand All @@ -23,6 +24,8 @@ const (
epochSizeFlag = "epoch-size"
blockGasLimitFlag = "block-gas-limit"
posFlag = "pos"
minValidatorCount = "min-validator-count"
maxValidatorCount = "max-validator-count"
)

// Legacy flags that need to be preserved for running clients
Expand All @@ -37,6 +40,7 @@ var (
var (
errValidatorsNotSpecified = errors.New("validator information not specified")
errValidatorsSpecifiedIncorrectly = errors.New("validator information specified through mutually exclusive flags")
errValidatorNumberExceedsMax = errors.New("validator number exceeds max validator number")
errUnsupportedConsensus = errors.New("specified consensusRaw not supported")
errMissingBootnode = errors.New("at least 1 bootnode is required")
errInvalidEpochSize = errors.New("epoch size must be greater than 1")
Expand All @@ -58,6 +62,9 @@ type genesisParams struct {
blockGasLimit uint64
isPos bool

minNumValidators uint64
maxNumValidators uint64

extraData []byte
consensus server.ConsensusType

Expand Down Expand Up @@ -104,6 +111,11 @@ func (p *genesisParams) validateFlags() error {
return errInvalidEpochSize
}

// Validate min and max validators number
if err := command.ValidateMinMaxValidatorsNumber(p.minNumValidators, p.maxNumValidators); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -138,19 +150,26 @@ func (p *genesisParams) initRawParams() error {
return nil
}

func (p *genesisParams) initValidatorSet() error {
// setValidatorSetFromCli sets validator set from cli command
func (p *genesisParams) setValidatorSetFromCli() {
if len(p.ibftValidatorsRaw) != 0 {
for _, val := range p.ibftValidatorsRaw {
p.ibftValidators = append(
p.ibftValidators,
types.StringToAddress(val),
)
}
}
}

// setValidatorSetFromPrefixPath sets validator set from prefix path
func (p *genesisParams) setValidatorSetFromPrefixPath() error {
var readErr error

if !p.areValidatorsSetByPrefix() {
return nil
}

var readErr error
if p.ibftValidators, readErr = getValidatorsFromPrefixPath(
p.validatorPrefixPath,
); readErr != nil {
Expand All @@ -160,6 +179,27 @@ func (p *genesisParams) initValidatorSet() error {
return nil
}

func (p *genesisParams) initValidatorSet() error {
// Set validator set
// Priority goes to cli command over prefix path
if err := p.setValidatorSetFromPrefixPath(); err != nil {
return err
}

p.setValidatorSetFromCli()

// Validate if validator number exceeds max number
if ok := p.isValidatorNumberValid(); !ok {
return errValidatorNumberExceedsMax
}

return nil
}

func (p *genesisParams) isValidatorNumberValid() bool {
return uint64(len(p.ibftValidators)) <= p.maxNumValidators
}

func (p *genesisParams) initIBFTExtraData() {
if p.consensus != server.IBFTConsensus {
return
Expand Down Expand Up @@ -262,7 +302,11 @@ func (p *genesisParams) shouldPredeployStakingSC() bool {
}

func (p *genesisParams) predeployStakingSC() (*chain.GenesisAccount, error) {
stakingAccount, predeployErr := stakingHelper.PredeployStakingSC(p.ibftValidators)
stakingAccount, predeployErr := stakingHelper.PredeployStakingSC(p.ibftValidators,
stakingHelper.PredeployParams{
MinValidatorCount: p.minNumValidators,
MaxValidatorCount: p.maxNumValidators,
})
if predeployErr != nil {
return nil, predeployErr
}
Expand Down
12 changes: 12 additions & 0 deletions command/ibft/switch/ibft_switch.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ func setFlags(cmd *cobra.Command) {
"",
"the height to switch the new type",
)
cmd.Flags().StringVar(
&params.minValidatorCountRaw,
minValidatorCount,
"",
"the minimum number of validators in the validator set for PoS",
)
cmd.Flags().StringVar(
&params.maxValidatorCountRaw,
maxValidatorCount,
"",
"the maximum number of validators in the validator set for PoS",
)
}

func setRequiredFlags(cmd *cobra.Command) {
Expand Down
138 changes: 118 additions & 20 deletions command/ibft/switch/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import (
)

const (
chainFlag = "chain"
typeFlag = "type"
deploymentFlag = "deployment"
fromFlag = "from"
chainFlag = "chain"
typeFlag = "type"
deploymentFlag = "deployment"
fromFlag = "from"
minValidatorCount = "min-validator-count"
maxValidatorCount = "max-validator-count"
)

var (
Expand All @@ -28,15 +30,20 @@ var (
)

type switchParams struct {
typeRaw string
fromRaw string
deploymentRaw string
genesisPath string
typeRaw string
fromRaw string
deploymentRaw string
maxValidatorCountRaw string
minValidatorCountRaw string
genesisPath string

mechanismType ibft.MechanismType
deployment *uint64
from uint64
genesisConfig *chain.Chain

maxValidatorCount *uint64
minValidatorCount *uint64
}

func (p *switchParams) getRequiredFlags() []string {
Expand Down Expand Up @@ -79,22 +86,86 @@ func (p *switchParams) initMechanismType() error {

func (p *switchParams) initDeployment() error {
if p.deploymentRaw != "" {
if p.mechanismType == ibft.PoS {
d, err := types.ParseUint64orHex(&p.deploymentRaw)
if err != nil {
return fmt.Errorf(
"unable to parse deployment value, %w",
err,
)
}

p.deployment = &d
} else {
if p.mechanismType != ibft.PoS {
return fmt.Errorf(
"doesn't support contract deployment in %s",
string(p.mechanismType),
)
}

d, err := types.ParseUint64orHex(&p.deploymentRaw)
if err != nil {
return fmt.Errorf(
"unable to parse deployment value, %w",
err,
)
}

p.deployment = &d
}

if p.minValidatorCountRaw != "" {
if p.mechanismType != ibft.PoS {
return fmt.Errorf(
"doesn't support min validator count in %s",
string(p.mechanismType),
)
}

value, err := types.ParseUint64orHex(&p.minValidatorCountRaw)
if err != nil {
return fmt.Errorf(
"unable to parse min validator count value, %w",
err,
)
}

p.minValidatorCount = &value
}

if p.maxValidatorCountRaw != "" {
if p.mechanismType != ibft.PoS {
return fmt.Errorf(
"doesn't support max validator count in %s",
string(p.mechanismType),
)
}

value, err := types.ParseUint64orHex(&p.maxValidatorCountRaw)
if err != nil {
return fmt.Errorf(
"unable to parse max validator count value, %w",
err,
)
}

p.maxValidatorCount = &value
}

if err := p.validateMinMaxValidatorNumber(); err != nil {
return err
}

return nil
}

func (p *switchParams) validateMinMaxValidatorNumber() error {
// Validate min and max validators number if not nil
// If they are not defined they will get default values
// in PoSMechanism
minValidatorCount := uint64(1)
maxValidatorCount := common.MaxSafeJSInt

if p.minValidatorCount != nil {
minValidatorCount = *p.minValidatorCount
}

if p.maxValidatorCount != nil {
maxValidatorCount = *p.maxValidatorCount
}

if err := command.ValidateMinMaxValidatorsNumber(minValidatorCount, maxValidatorCount); err != nil {
return err
}

return nil
Expand Down Expand Up @@ -136,6 +207,8 @@ func (p *switchParams) updateGenesisConfig() error {
p.mechanismType,
p.from,
p.deployment,
p.maxValidatorCount,
p.minValidatorCount,
)
}

Expand Down Expand Up @@ -167,6 +240,18 @@ func (p *switchParams) getResult() command.CommandResult {
result.Deployment = &common.JSONNumber{Value: *p.deployment}
}

if p.minValidatorCount != nil {
result.MinValidatorCount = common.JSONNumber{Value: *p.minValidatorCount}
} else {
result.MinValidatorCount = common.JSONNumber{Value: 1}
}

if p.maxValidatorCount != nil {
result.MaxValidatorCount = common.JSONNumber{Value: *p.maxValidatorCount}
} else {
result.MaxValidatorCount = common.JSONNumber{Value: common.MaxSafeJSInt}
}

return result
}

Expand All @@ -175,6 +260,8 @@ func appendIBFTForks(
mechanismType ibft.MechanismType,
from uint64,
deployment *uint64,
maxValidatorCount *uint64,
minValidatorCount *uint64,
) error {
ibftConfig, ok := cc.Params.Engine["ibft"].(map[string]interface{})
if !ok {
Expand All @@ -201,8 +288,19 @@ func appendIBFTForks(
Type: mechanismType,
From: common.JSONNumber{Value: from},
}

if mechanismType == ibft.PoS {
newFork.Deployment = &common.JSONNumber{Value: *deployment}
if deployment != nil {
newFork.Deployment = &common.JSONNumber{Value: *deployment}
}

if maxValidatorCount != nil {
newFork.MaxValidatorCount = &common.JSONNumber{Value: *maxValidatorCount}
}

if minValidatorCount != nil {
newFork.MinValidatorCount = &common.JSONNumber{Value: *minValidatorCount}
}
}

ibftForks = append(ibftForks, newFork)
Expand Down
Loading

0 comments on commit 3543e50

Please sign in to comment.