diff --git a/command/common.go b/command/common.go index 9422f3d187..4dfea3c4c7 100644 --- a/command/common.go +++ b/command/common.go @@ -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 +} diff --git a/command/genesis/genesis.go b/command/genesis/genesis.go index 8e11c7cc1f..74f4effbbf 100644 --- a/command/genesis/genesis.go +++ b/command/genesis/genesis.go @@ -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" ) @@ -126,6 +127,18 @@ func setFlags(cmd *cobra.Command) { command.DefaultGenesisGasLimit, ), ) + cmd.Flags().Uint64Var( + ¶ms.minNumValidators, + minValidatorCount, + 1, + "the minimum number of validators in the validator set for PoS", + ) + cmd.Flags().Uint64Var( + ¶ms.maxNumValidators, + maxValidatorCount, + common.MaxSafeJSInt, + "the maximum number of validators in the validator set for PoS", + ) } // setLegacyFlags sets the legacy flags to preserve backwards compatibility diff --git a/command/genesis/params.go b/command/genesis/params.go index 777008658e..72a41c9968 100644 --- a/command/genesis/params.go +++ b/command/genesis/params.go @@ -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" @@ -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 @@ -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") @@ -58,6 +62,9 @@ type genesisParams struct { blockGasLimit uint64 isPos bool + minNumValidators uint64 + maxNumValidators uint64 + extraData []byte consensus server.ConsensusType @@ -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 } @@ -138,7 +150,8 @@ 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( @@ -146,11 +159,17 @@ func (p *genesisParams) initValidatorSet() error { 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 { @@ -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 @@ -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 } diff --git a/command/ibft/switch/ibft_switch.go b/command/ibft/switch/ibft_switch.go index 87a712fef8..180b476603 100644 --- a/command/ibft/switch/ibft_switch.go +++ b/command/ibft/switch/ibft_switch.go @@ -51,6 +51,18 @@ func setFlags(cmd *cobra.Command) { "", "the height to switch the new type", ) + cmd.Flags().StringVar( + ¶ms.minValidatorCountRaw, + minValidatorCount, + "", + "the minimum number of validators in the validator set for PoS", + ) + cmd.Flags().StringVar( + ¶ms.maxValidatorCountRaw, + maxValidatorCount, + "", + "the maximum number of validators in the validator set for PoS", + ) } func setRequiredFlags(cmd *cobra.Command) { diff --git a/command/ibft/switch/params.go b/command/ibft/switch/params.go index 58b078651c..6ec5f57b90 100644 --- a/command/ibft/switch/params.go +++ b/command/ibft/switch/params.go @@ -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 ( @@ -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 { @@ -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 @@ -136,6 +207,8 @@ func (p *switchParams) updateGenesisConfig() error { p.mechanismType, p.from, p.deployment, + p.maxValidatorCount, + p.minValidatorCount, ) } @@ -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 } @@ -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 { @@ -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) diff --git a/command/ibft/switch/result.go b/command/ibft/switch/result.go index e75caec0a3..731416a299 100644 --- a/command/ibft/switch/result.go +++ b/command/ibft/switch/result.go @@ -9,10 +9,12 @@ import ( ) type IBFTSwitchResult struct { - Chain string `json:"chain"` - Type ibft.MechanismType `json:"type"` - From common.JSONNumber `json:"from"` - Deployment *common.JSONNumber `json:"deployment,omitempty"` + Chain string `json:"chain"` + Type ibft.MechanismType `json:"type"` + From common.JSONNumber `json:"from"` + Deployment *common.JSONNumber `json:"deployment,omitempty"` + MaxValidatorCount common.JSONNumber `json:"maxValidatorCount"` + MinValidatorCount common.JSONNumber `json:"minValidatorCount"` } func (r *IBFTSwitchResult) GetOutput() string { @@ -29,6 +31,8 @@ func (r *IBFTSwitchResult) GetOutput() string { } outputs = append(outputs, fmt.Sprintf("From|%d", r.From.Value)) + outputs = append(outputs, fmt.Sprintf("MaxValidatorCount|%d", r.MaxValidatorCount.Value)) + outputs = append(outputs, fmt.Sprintf("MinValidatorCount|%d", r.MinValidatorCount.Value)) buffer.WriteString(helper.FormatKV(outputs)) buffer.WriteString("\n") diff --git a/consensus/ibft/hooks.go b/consensus/ibft/hooks.go index 9522bc7566..967785a7b5 100644 --- a/consensus/ibft/hooks.go +++ b/consensus/ibft/hooks.go @@ -167,10 +167,12 @@ func (base *BaseConsensusMechanism) IsInRange(blockNumber uint64) bool { // IBFT Fork represents setting in params.engine.ibft of genesis.json type IBFTFork struct { - Type MechanismType `json:"type"` - Deployment *common.JSONNumber `json:"deployment,omitempty"` - From common.JSONNumber `json:"from"` - To *common.JSONNumber `json:"to,omitempty"` + Type MechanismType `json:"type"` + Deployment *common.JSONNumber `json:"deployment,omitempty"` + From common.JSONNumber `json:"from"` + To *common.JSONNumber `json:"to,omitempty"` + MaxValidatorCount *common.JSONNumber `json:"maxValidatorCount,omitempty"` + MinValidatorCount *common.JSONNumber `json:"minValidatorCount,omitempty"` } // ConsensusMechanismFactory is the factory function to create a consensus mechanism diff --git a/consensus/ibft/ibft.go b/consensus/ibft/ibft.go index a9f5411853..94b92464e9 100644 --- a/consensus/ibft/ibft.go +++ b/consensus/ibft/ibft.go @@ -21,7 +21,7 @@ import ( "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" "google.golang.org/grpc" - "google.golang.org/protobuf/types/known/anypb" + anypb "google.golang.org/protobuf/types/known/anypb" ) const ( diff --git a/consensus/ibft/ibft_test.go b/consensus/ibft/ibft_test.go index d42105395c..e4fa4ac8ae 100644 --- a/consensus/ibft/ibft_test.go +++ b/consensus/ibft/ibft_test.go @@ -17,7 +17,7 @@ import ( "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" - "google.golang.org/protobuf/types/known/anypb" + anypb "google.golang.org/protobuf/types/known/anypb" ) func TestTransition_ValidateState_Prepare(t *testing.T) { diff --git a/consensus/ibft/pos.go b/consensus/ibft/pos.go index 4ecbce513a..5ae14ef6c9 100644 --- a/consensus/ibft/pos.go +++ b/consensus/ibft/pos.go @@ -3,7 +3,6 @@ package ibft import ( "errors" "fmt" - "github.com/0xPolygon/polygon-edge/contracts/staking" stakingHelper "github.com/0xPolygon/polygon-edge/helper/staking" "github.com/0xPolygon/polygon-edge/state" @@ -15,6 +14,8 @@ type PoSMechanism struct { BaseConsensusMechanism // Params ContractDeployment uint64 // The height when deploying staking contract + MaxValidatorCount uint64 + MinValidatorCount uint64 } // PoSFactory initializes the required data @@ -72,6 +73,18 @@ func (pos *PoSMechanism) initializeParams(params *IBFTFork) error { } pos.ContractDeployment = params.Deployment.Value + + if params.MaxValidatorCount == nil { + pos.MaxValidatorCount = stakingHelper.MaxValidatorCount + } else { + pos.MaxValidatorCount = params.MaxValidatorCount.Value + } + + if params.MinValidatorCount == nil { + pos.MinValidatorCount = stakingHelper.MinValidatorCount + } else { + pos.MinValidatorCount = params.MinValidatorCount.Value + } } return nil @@ -146,7 +159,10 @@ func (pos *PoSMechanism) preStateCommitHook(rawParams interface{}) error { } // Deploy Staking contract - contractState, err := stakingHelper.PredeployStakingSC(nil) + contractState, err := stakingHelper.PredeployStakingSC(nil, stakingHelper.PredeployParams{ + MinValidatorCount: pos.MinValidatorCount, + MaxValidatorCount: pos.MaxValidatorCount, + }) if err != nil { return err } diff --git a/e2e/framework/config.go b/e2e/framework/config.go index a979d4538a..09a838119d 100644 --- a/e2e/framework/config.go +++ b/e2e/framework/config.go @@ -34,7 +34,7 @@ type TestServerConfig struct { IBFTDirPrefix string // The prefix of data directory for IBFT IBFTDir string // The name of data directory for IBFT PremineAccts []*SrvAccount // Accounts with existing balances (genesis accounts) - GenesisValidatorBalance *big.Int // Genesis balance for the validators + GenesisValidatorBalance *big.Int // Genesis the balance for the validators DevStakers []types.Address // List of initial staking addresses for the staking SC with dev consensus Consensus ConsensusType // Consensus MechanismType Bootnodes []string // Bootnode Addresses @@ -46,6 +46,8 @@ type TestServerConfig struct { ShowsLog bool // Flag specifying if logs are shown IsPos bool // Specifies the mechanism used for IBFT (PoA / PoS) Signer *crypto.EIP155Signer // Signer used for transactions + MinValidatorCount uint64 // Min validator count + MaxValidatorCount uint64 // Max validator count } // DataDir returns path of data directory server uses @@ -154,3 +156,13 @@ func (t *TestServerConfig) SetShowsLog(f bool) { func (t *TestServerConfig) SetEpochSize(epochSize uint64) { t.EpochSize = epochSize } + +// SetMinValidatorCount sets the min validator count +func (t *TestServerConfig) SetMinValidatorCount(val uint64) { + t.MinValidatorCount = val +} + +// SetMaxValidatorCount sets the max validator count +func (t *TestServerConfig) SetMaxValidatorCount(val uint64) { + t.MaxValidatorCount = val +} diff --git a/e2e/framework/testserver.go b/e2e/framework/testserver.go index 4b1a668e8f..1b50293a7c 100644 --- a/e2e/framework/testserver.go +++ b/e2e/framework/testserver.go @@ -24,6 +24,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/ibft" ibftOp "github.com/0xPolygon/polygon-edge/consensus/ibft/proto" "github.com/0xPolygon/polygon-edge/crypto" + stakingHelper "github.com/0xPolygon/polygon-edge/helper/staking" "github.com/0xPolygon/polygon-edge/helper/tests" "github.com/0xPolygon/polygon-edge/network" "github.com/0xPolygon/polygon-edge/secrets" @@ -282,6 +283,17 @@ func (t *TestServer) GenerateGenesis() error { // Make sure the correct mechanism is selected if t.Config.IsPos { args = append(args, "--pos") + + if t.Config.MinValidatorCount == 0 { + t.Config.MinValidatorCount = stakingHelper.MinValidatorCount + } + + if t.Config.MaxValidatorCount == 0 { + t.Config.MaxValidatorCount = stakingHelper.MaxValidatorCount + } + + args = append(args, "--min-validator-count", strconv.FormatUint(t.Config.MinValidatorCount, 10)) + args = append(args, "--max-validator-count", strconv.FormatUint(t.Config.MaxValidatorCount, 10)) } // add block gas limit diff --git a/e2e/pos_test.go b/e2e/pos_test.go index 3d81dfa4dd..2aa46e2ad7 100644 --- a/e2e/pos_test.go +++ b/e2e/pos_test.go @@ -2,6 +2,7 @@ package e2e import ( "context" + "crypto/ecdsa" "fmt" ibftOp "github.com/0xPolygon/polygon-edge/consensus/ibft/proto" "math/big" @@ -82,6 +83,86 @@ func validateValidatorSet( } } +func TestPoS_ValidatorBoundaries(t *testing.T) { + accounts := []struct { + key *ecdsa.PrivateKey + address types.Address + }{} + stakeAmount := framework.EthToWei(1) + numGenesisValidators := IBFTMinNodes + minValidatorCount := uint64(1) + maxValidatorCount := uint64(numGenesisValidators + 1) + numNewStakers := 2 + + for i := 0; i < numNewStakers; i++ { + k, a := tests.GenerateKeyAndAddr(t) + + accounts = append(accounts, struct { + key *ecdsa.PrivateKey + address types.Address + }{ + key: k, + address: a, + }) + } + + defaultBalance := framework.EthToWei(100) + ibftManager := framework.NewIBFTServersManager( + t, + numGenesisValidators, + IBFTDirPrefix, + func(i int, config *framework.TestServerConfig) { + config.SetSeal(true) + config.SetEpochSize(2) + config.PremineValidatorBalance(defaultBalance) + for j := 0; j < numNewStakers; j++ { + config.Premine(accounts[j].address, defaultBalance) + } + config.SetIBFTPoS(true) + config.SetMinValidatorCount(minValidatorCount) + config.SetMaxValidatorCount(maxValidatorCount) + }) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + ibftManager.StartServers(ctx) + + srv := ibftManager.GetServer(0) + + client := srv.JSONRPC() + + testCases := []struct { + name string + address types.Address + key *ecdsa.PrivateKey + expectedExistence bool + expectedSize int + }{ + { + name: "Can add a 5th validator", + address: accounts[0].address, + key: accounts[0].key, + expectedExistence: true, + expectedSize: numGenesisValidators + 1, + }, + { + name: "Can not add a 6th validator", + address: accounts[1].address, + key: accounts[1].key, + expectedExistence: false, + expectedSize: numGenesisValidators + 1, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + err := framework.StakeAmount(tt.address, tt.key, stakeAmount, srv) + assert.NoError(t, err) + validateValidatorSet(t, tt.address, client, tt.expectedExistence, tt.expectedSize) + }) + } +} + func TestPoS_Stake(t *testing.T) { stakerKey, stakerAddr := tests.GenerateKeyAndAddr(t) defaultBalance := framework.EthToWei(100) @@ -209,7 +290,7 @@ func TestPoS_Unstake(t *testing.T) { assert.Equal(t, expectedBalance.String(), stakedAmount.String()) - // Check the account balance + // Check the address balance fee := new(big.Int).Mul( big.NewInt(int64(receipt.GasUsed)), big.NewInt(framework.DefaultGasPrice), @@ -320,7 +401,7 @@ func TestPoS_UnstakeExploit(t *testing.T) { t.Fatalf("Unable to fetch block") } - // Find how much the account paid for all the transactions in this block + // Find how much the address paid for all the transactions in this block paidFee := big.NewInt(0).Mul(bigGasPrice, big.NewInt(int64(block.GasUsed))) // Check the balances @@ -472,7 +553,7 @@ func TestPoS_StakeUnstakeExploit(t *testing.T) { t.Fatalf("Unable to fetch block") } - // Find how much the account paid for all the transactions in this block + // Find how much the address paid for all the transactions in this block paidFee := big.NewInt(0).Mul(bigGasPrice, big.NewInt(int64(block.GasUsed))) // Check the balances @@ -492,7 +573,7 @@ func TestPoS_StakeUnstakeExploit(t *testing.T) { "Staked address balance mismatch after stake / unstake exploit", ) - // Make sure the account balances match up + // Make sure the address balances match up // expBalance = previousAccountBalance + stakeRefund - 1 ETH - block fees expBalance := big.NewInt(0).Sub(big.NewInt(0).Add(defaultBalance, bigDefaultStakedBalance), oneEth) @@ -600,7 +681,7 @@ func TestPoS_StakeUnstakeWithinSameBlock(t *testing.T) { t.Fatalf("Unable to fetch block") } - // Find how much the account paid for all the transactions in this block + // Find how much the address paid for all the transactions in this block paidFee := big.NewInt(0).Mul(bigGasPrice, big.NewInt(int64(block.GasUsed))) // Check the balances @@ -617,7 +698,7 @@ func TestPoS_StakeUnstakeWithinSameBlock(t *testing.T) { "Staked address balance mismatch after stake / unstake events", ) - // Make sure the account balances match up + // Make sure the address balances match up // expBalance = previousAccountBalance - block fees expBalance := big.NewInt(0).Sub(defaultBalance, paidFee) diff --git a/helper/common/common.go b/helper/common/common.go index 0413b3c9b7..d60f620efc 100644 --- a/helper/common/common.go +++ b/helper/common/common.go @@ -14,6 +14,14 @@ import ( "github.com/0xPolygon/polygon-edge/types" ) +var ( + // MaxSafeJSInt represents max value which JS support + // It is used for smartContract fields + // Our staking repo is written in JS, as are many other clients + // If we use higher value JS will not be able to parse it + MaxSafeJSInt = uint64(math.Pow(2, 53) - 2) +) + // Min returns the strictly lower number func Min(a, b uint64) uint64 { if a < b { @@ -148,3 +156,21 @@ func GetTerminationSignalCh() <-chan os.Signal { return signalCh } + +// PadLeftOrTrim left-pads the passed in byte array to the specified size, +// or trims the array if it exceeds the passed in size +func PadLeftOrTrim(bb []byte, size int) []byte { + l := len(bb) + if l == size { + return bb + } + + if l > size { + return bb[l-size:] + } + + tmp := make([]byte, size) + copy(tmp[size-l:], bb) + + return tmp +} diff --git a/helper/staking/staking.go b/helper/staking/staking.go index f61aa8a744..164aa05f72 100644 --- a/helper/staking/staking.go +++ b/helper/staking/staking.go @@ -2,6 +2,7 @@ package staking import ( "fmt" + "github.com/0xPolygon/polygon-edge/helper/common" "math/big" "github.com/0xPolygon/polygon-edge/chain" @@ -10,23 +11,10 @@ import ( "github.com/0xPolygon/polygon-edge/types" ) -// PadLeftOrTrim left-pads the passed in byte array to the specified size, -// or trims the array if it exceeds the passed in size -func PadLeftOrTrim(bb []byte, size int) []byte { - l := len(bb) - if l == size { - return bb - } - - if l > size { - return bb[l-size:] - } - - tmp := make([]byte, size) - copy(tmp[size-l:], bb) - - return tmp -} +var ( + MinValidatorCount = uint64(1) + MaxValidatorCount = common.MaxSafeJSInt +) // getAddressMapping returns the key for the SC storage mapping (address => something) // @@ -36,8 +24,8 @@ func getAddressMapping(address types.Address, slot int64) []byte { bigSlot := big.NewInt(slot) finalSlice := append( - PadLeftOrTrim(address.Bytes(), 32), - PadLeftOrTrim(bigSlot.Bytes(), 32)..., + common.PadLeftOrTrim(address.Bytes(), 32), + common.PadLeftOrTrim(bigSlot.Bytes(), 32)..., ) keccakValue := keccak.Keccak256(nil, finalSlice) @@ -77,7 +65,7 @@ func getStorageIndexes(address types.Address, index int64) *StorageIndexes { // Index for array types is calculated as keccak(slot) + index // The slot for the dynamic arrays that's put in the keccak needs to be in hex form (padded 64 chars) storageIndexes.ValidatorsIndex = getIndexWithOffset( - keccak.Keccak256(nil, PadLeftOrTrim(big.NewInt(validatorsSlot).Bytes(), 32)), + keccak.Keccak256(nil, common.PadLeftOrTrim(big.NewInt(validatorsSlot).Bytes(), 32)), index, ) @@ -88,6 +76,12 @@ func getStorageIndexes(address types.Address, index int64) *StorageIndexes { return &storageIndexes } +// PredeployParams contains the values used to predeploy the PoS staking contract +type PredeployParams struct { + MinValidatorCount uint64 + MaxValidatorCount uint64 +} + // StorageIndexes is a wrapper for different storage indexes that // need to be modified type StorageIndexes struct { @@ -106,18 +100,21 @@ var ( addressToStakedAmountSlot = int64(2) // Slot 2 addressToValidatorIndexSlot = int64(3) // Slot 3 stakedAmountSlot = int64(4) // Slot 4 + minNumValidatorSlot = int64(5) // Slot 5 + maxNumValidatorSlot = int64(6) // Slot 6 ) const ( DefaultStakedBalance = "0x8AC7230489E80000" // 10 ETH //nolint: lll - StakingSCBytecode = "0x60806040526004361061008a5760003560e01c806350d68ed81161005957806350d68ed8146101865780636a768705146101b1578063ca1e7819146101dc578063f90ecacc14610207578063facd743b14610244576100f8565b80632367f6b5146100fd5780632def66201461013a578063373d6132146101515780633a4b66f11461017c576100f8565b366100f8576100ae3373ffffffffffffffffffffffffffffffffffffffff16610281565b156100ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100e590610f1b565b60405180910390fd5b6100f6610294565b005b600080fd5b34801561010957600080fd5b50610124600480360381019061011f9190610cad565b61050f565b6040516101319190610f56565b60405180910390f35b34801561014657600080fd5b5061014f610558565b005b34801561015d57600080fd5b50610166610643565b6040516101739190610f56565b60405180910390f35b61018461064d565b005b34801561019257600080fd5b5061019b6106b6565b6040516101a89190610f3b565b60405180910390f35b3480156101bd57600080fd5b506101c66106c2565b6040516101d39190610f71565b60405180910390f35b3480156101e857600080fd5b506101f16106c7565b6040516101fe9190610e7e565b60405180910390f35b34801561021357600080fd5b5061022e60048036038101906102299190610cda565b610755565b60405161023b9190610e63565b60405180910390f35b34801561025057600080fd5b5061026b60048036038101906102669190610cad565b610794565b6040516102789190610ea0565b60405180910390f35b600080823b905060008111915050919050565b34600460008282546102a69190610fd6565b9250508190555034600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546102fc9190610fd6565b92505081905550600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156103b65750670de0b6b3a76400006fffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b156104bf5760018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600080549050600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b3373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d346040516105059190610f56565b60405180910390a2565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6105773373ffffffffffffffffffffffffffffffffffffffff16610281565b156105b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ae90610f1b565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411610639576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063090610edb565b60405180910390fd5b6106416107ea565b565b6000600454905090565b61066c3373ffffffffffffffffffffffffffffffffffffffff16610281565b156106ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a390610f1b565b60405180910390fd5b6106b4610294565b565b670de0b6b3a764000081565b600481565b6060600080548060200260200160405190810160405280929190818152602001828054801561074b57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610701575b5050505050905090565b6000818154811061076557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600463ffffffff1660008054905011610838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082f90610ebb565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156108d8576108d7336109ce565b5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806004600082825461092f919061102c565b925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561097c573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75826040516109c39190610f56565b60405180910390a250565b600080549050600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610a54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4b90610efb565b60405180910390fd5b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006001600080549050610aac919061102c565b9050808214610b9a576000808281548110610aca57610ac9611132565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060008481548110610b0c57610b0b611132565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000805480610c4957610c48611103565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055505050565b600081359050610c9281611256565b92915050565b600081359050610ca78161126d565b92915050565b600060208284031215610cc357610cc2611161565b5b6000610cd184828501610c83565b91505092915050565b600060208284031215610cf057610cef611161565b5b6000610cfe84828501610c98565b91505092915050565b6000610d138383610d1f565b60208301905092915050565b610d2881611060565b82525050565b610d3781611060565b82525050565b6000610d4882610f9c565b610d528185610fb4565b9350610d5d83610f8c565b8060005b83811015610d8e578151610d758882610d07565b9750610d8083610fa7565b925050600181019050610d61565b5085935050505092915050565b610da481611072565b82525050565b6000610db7604483610fc5565b9150610dc282611166565b606082019050919050565b6000610dda601d83610fc5565b9150610de5826111db565b602082019050919050565b6000610dfd601283610fc5565b9150610e0882611204565b602082019050919050565b6000610e20601a83610fc5565b9150610e2b8261122d565b602082019050919050565b610e3f8161107e565b82525050565b610e4e816110ba565b82525050565b610e5d816110c4565b82525050565b6000602082019050610e786000830184610d2e565b92915050565b60006020820190508181036000830152610e988184610d3d565b905092915050565b6000602082019050610eb56000830184610d9b565b92915050565b60006020820190508181036000830152610ed481610daa565b9050919050565b60006020820190508181036000830152610ef481610dcd565b9050919050565b60006020820190508181036000830152610f1481610df0565b9050919050565b60006020820190508181036000830152610f3481610e13565b9050919050565b6000602082019050610f506000830184610e36565b92915050565b6000602082019050610f6b6000830184610e45565b92915050565b6000602082019050610f866000830184610e54565b92915050565b6000819050602082019050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000610fe1826110ba565b9150610fec836110ba565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611021576110206110d4565b5b828201905092915050565b6000611037826110ba565b9150611042836110ba565b925082821015611055576110546110d4565b5b828203905092915050565b600061106b8261109a565b9050919050565b60008115159050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b7f4e756d626572206f662076616c696461746f72732063616e2774206265206c6560008201527f7373207468616e204d696e696d756d52657175697265644e756d56616c69646160208201527f746f727300000000000000000000000000000000000000000000000000000000604082015250565b7f4f6e6c79207374616b65722063616e2063616c6c2066756e6374696f6e000000600082015250565b7f696e646578206f7574206f662072616e67650000000000000000000000000000600082015250565b7f4f6e6c7920454f412063616e2063616c6c2066756e6374696f6e000000000000600082015250565b61125f81611060565b811461126a57600080fd5b50565b611276816110ba565b811461128157600080fd5b5056fea2646970667358221220ef563d387db47c10721dd290b05da6f0233130c28bebcd2b4be994914444b39164736f6c63430008070033" + StakingSCBytecode = "0x6080604052600436106100f75760003560e01c80637dceceb81161008a578063e387a7ed11610059578063e387a7ed14610381578063e804fbf6146103ac578063f90ecacc146103d7578063facd743b1461041457610165565b80637dceceb8146102c3578063af6da36e14610300578063c795c0771461032b578063ca1e78191461035657610165565b8063373d6132116100c6578063373d6132146102385780633a4b66f114610263578063714ff4251461026d5780637a6eea371461029857610165565b806302b751991461016a578063065ae171146101a75780632367f6b5146101e45780632def66201461022157610165565b366101655761011b3373ffffffffffffffffffffffffffffffffffffffff16610451565b1561015b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610152906111c0565b60405180910390fd5b610163610464565b005b600080fd5b34801561017657600080fd5b50610191600480360381019061018c9190610f3e565b61062e565b60405161019e919061121b565b60405180910390f35b3480156101b357600080fd5b506101ce60048036038101906101c99190610f3e565b610646565b6040516101db9190611145565b60405180910390f35b3480156101f057600080fd5b5061020b60048036038101906102069190610f3e565b610666565b604051610218919061121b565b60405180910390f35b34801561022d57600080fd5b506102366106af565b005b34801561024457600080fd5b5061024d61079a565b60405161025a919061121b565b60405180910390f35b61026b6107a4565b005b34801561027957600080fd5b5061028261080d565b60405161028f919061121b565b60405180910390f35b3480156102a457600080fd5b506102ad610817565b6040516102ba9190611200565b60405180910390f35b3480156102cf57600080fd5b506102ea60048036038101906102e59190610f3e565b610823565b6040516102f7919061121b565b60405180910390f35b34801561030c57600080fd5b5061031561083b565b604051610322919061121b565b60405180910390f35b34801561033757600080fd5b50610340610841565b60405161034d919061121b565b60405180910390f35b34801561036257600080fd5b5061036b610847565b6040516103789190611123565b60405180910390f35b34801561038d57600080fd5b506103966108d5565b6040516103a3919061121b565b60405180910390f35b3480156103b857600080fd5b506103c16108db565b6040516103ce919061121b565b60405180910390f35b3480156103e357600080fd5b506103fe60048036038101906103f99190610f6b565b6108e5565b60405161040b9190611108565b60405180910390f35b34801561042057600080fd5b5061043b60048036038101906104369190610f3e565b610924565b6040516104489190611145565b60405180910390f35b600080823b905060008111915050919050565b600654600080549050106104ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a490611180565b60405180910390fd5b34600460008282546104bf9190611280565b9250508190555034600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546105159190611280565b92505081905550600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156105cf5750670de0b6b3a76400006fffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b156105de576105dd3361097a565b5b3373ffffffffffffffffffffffffffffffffffffffff167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d34604051610624919061121b565b60405180910390a2565b60036020528060005260406000206000915090505481565b60016020528060005260406000206000915054906101000a900460ff1681565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6106ce3373ffffffffffffffffffffffffffffffffffffffff16610451565b1561070e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610705906111c0565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411610790576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078790611160565b60405180910390fd5b610798610a80565b565b6000600454905090565b6107c33373ffffffffffffffffffffffffffffffffffffffff16610451565b15610803576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fa906111c0565b60405180910390fd5b61080b610464565b565b6000600554905090565b670de0b6b3a764000081565b60026020528060005260406000206000915090505481565b60065481565b60055481565b606060008054806020026020016040519081016040528092919081815260200182805480156108cb57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610881575b5050505050905090565b60045481565b6000600654905090565b600081815481106108f557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600080549050600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60055460008054905011610ac9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac0906111e0565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610b6957610b6833610c5f565b5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508060046000828254610bc091906112d6565b925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610c0d573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f7582604051610c54919061121b565b60405180910390a250565b600080549050600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610ce5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cdc906111a0565b60405180910390fd5b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006001600080549050610d3d91906112d6565b9050808214610e2b576000808281548110610d5b57610d5a6113cc565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060008481548110610d9d57610d9c6113cc565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000805480610eda57610ed961139d565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055505050565b600081359050610f2381611519565b92915050565b600081359050610f3881611530565b92915050565b600060208284031215610f5457610f536113fb565b5b6000610f6284828501610f14565b91505092915050565b600060208284031215610f8157610f806113fb565b5b6000610f8f84828501610f29565b91505092915050565b6000610fa48383610fb0565b60208301905092915050565b610fb98161130a565b82525050565b610fc88161130a565b82525050565b6000610fd982611246565b610fe3818561125e565b9350610fee83611236565b8060005b8381101561101f5781516110068882610f98565b975061101183611251565b925050600181019050610ff2565b5085935050505092915050565b6110358161131c565b82525050565b6000611048601d8361126f565b915061105382611400565b602082019050919050565b600061106b60278361126f565b915061107682611429565b604082019050919050565b600061108e60128361126f565b915061109982611478565b602082019050919050565b60006110b1601a8361126f565b91506110bc826114a1565b602082019050919050565b60006110d460408361126f565b91506110df826114ca565b604082019050919050565b6110f381611328565b82525050565b61110281611364565b82525050565b600060208201905061111d6000830184610fbf565b92915050565b6000602082019050818103600083015261113d8184610fce565b905092915050565b600060208201905061115a600083018461102c565b92915050565b600060208201905081810360008301526111798161103b565b9050919050565b600060208201905081810360008301526111998161105e565b9050919050565b600060208201905081810360008301526111b981611081565b9050919050565b600060208201905081810360008301526111d9816110a4565b9050919050565b600060208201905081810360008301526111f9816110c7565b9050919050565b600060208201905061121560008301846110ea565b92915050565b600060208201905061123060008301846110f9565b92915050565b6000819050602082019050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600061128b82611364565b915061129683611364565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156112cb576112ca61136e565b5b828201905092915050565b60006112e182611364565b91506112ec83611364565b9250828210156112ff576112fe61136e565b5b828203905092915050565b600061131582611344565b9050919050565b60008115159050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b7f4f6e6c79207374616b65722063616e2063616c6c2066756e6374696f6e000000600082015250565b7f56616c696461746f72207365742068617320726561636865642066756c6c206360008201527f6170616369747900000000000000000000000000000000000000000000000000602082015250565b7f696e646578206f7574206f662072616e67650000000000000000000000000000600082015250565b7f4f6e6c7920454f412063616e2063616c6c2066756e6374696f6e000000000000600082015250565b7f56616c696461746f72732063616e2774206265206c657373207468616e20746860008201527f65206d696e696d756d2072657175697265642076616c696461746f72206e756d602082015250565b6115228161130a565b811461152d57600080fd5b50565b61153981611364565b811461154457600080fd5b5056fea2646970667358221220531eae5ca3c156b3603476dddb612597c51d357508806fc00ae15908bd887e1264736f6c63430008070033" ) // PredeployStakingSC is a helper method for setting up the staking smart contract account, -// using the passed in validators as prestaked validators +// using the passed in validators as pre-staked validators func PredeployStakingSC( validators []types.Address, + params PredeployParams, ) (*chain.GenesisAccount, error) { // Set the code for the staking smart contract // Code retrieved from https://github.com/0xPolygon/staking-contracts @@ -138,6 +135,8 @@ func PredeployStakingSC( storageMap := make(map[types.Hash]types.Hash) bigTrueValue := big.NewInt(1) stakedAmount := big.NewInt(0) + bigMinNumValidators := big.NewInt(int64(params.MinValidatorCount)) + bigMaxNumValidators := big.NewInt(int64(params.MaxValidatorCount)) for indx, validator := range validators { // Update the total staked amount @@ -173,6 +172,14 @@ func PredeployStakingSC( types.StringToHash(hex.EncodeUint64(uint64(indx + 1))) } + // Set the value for the minimum number of validators + storageMap[types.BytesToHash(big.NewInt(minNumValidatorSlot).Bytes())] = + types.BytesToHash(bigMinNumValidators.Bytes()) + + // Set the value for the maximum number of validators + storageMap[types.BytesToHash(big.NewInt(maxNumValidatorSlot).Bytes())] = + types.BytesToHash(bigMaxNumValidators.Bytes()) + // Save the storage map stakingAccount.Storage = storageMap diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index 721e7a2be6..f4885b168f 100644 --- a/jsonrpc/eth_state_test.go +++ b/jsonrpc/eth_state_test.go @@ -4,6 +4,9 @@ import ( "bytes" "errors" "fmt" + "math/big" + "testing" + "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/state" @@ -11,8 +14,6 @@ import ( "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/assert" "github.com/umbracle/fastrlp" - "math/big" - "testing" ) var ( diff --git a/protocol/service_v1.go b/protocol/service_v1.go index 6ebc452d84..92a5a15145 100644 --- a/protocol/service_v1.go +++ b/protocol/service_v1.go @@ -10,7 +10,7 @@ import ( "github.com/0xPolygon/polygon-edge/types" "github.com/hashicorp/go-hclog" "github.com/libp2p/go-libp2p-core/peer" - "google.golang.org/protobuf/types/known/anypb" + anypb "google.golang.org/protobuf/types/known/anypb" empty "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/protocol/syncer.go b/protocol/syncer.go index 2bdb170d6a..17b083c2fa 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -19,7 +19,7 @@ import ( "github.com/libp2p/go-libp2p-core/peer" "google.golang.org/grpc" "google.golang.org/grpc/connectivity" - "google.golang.org/protobuf/types/known/anypb" + anypb "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/state/executor.go b/state/executor.go index 4330749356..b15e25b21a 100644 --- a/state/executor.go +++ b/state/executor.go @@ -559,7 +559,8 @@ func (t *Transition) applyCall( } } - snapshot := t.state.Snapshot() //nolint:ifshort + //nolint:ifshort + snapshot := t.state.Snapshot() t.state.TouchAccount(c.Address) if callType == runtime.Call {