Skip to content

Commit

Permalink
EVM-713 Fork manager params (0xPolygon#1645)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorcrevar authored Jun 23, 2023
1 parent a152b79 commit 2df1b93
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 68 deletions.
45 changes: 32 additions & 13 deletions chain/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package chain

import (
"errors"
"math/big"
"sort"

"github.com/0xPolygon/polygon-edge/helper/common"
"github.com/0xPolygon/polygon-edge/types"
)

Expand Down Expand Up @@ -88,20 +88,24 @@ const (
)

// Forks is map which contains all forks and their starting blocks from genesis
type Forks map[string]*Fork
type Forks map[string]Fork

// IsActive returns true if fork defined by name exists and defined for the block
func (f *Forks) IsActive(name string, block uint64) bool {
ff := (*f)[name]
ff, exists := (*f)[name]

return ff != nil && ff.Active(block)
return exists && ff.Active(block)
}

// SetFork adds/updates fork defined by name
func (f *Forks) SetFork(name string, value *Fork) {
func (f *Forks) SetFork(name string, value Fork) {
(*f)[name] = value
}

func (f *Forks) RemoveFork(name string) {
delete(*f, name)
}

// At returns ForksInTime instance that shows which supported forks are enabled for the block
func (f *Forks) At(block uint64) ForksInTime {
return ForksInTime{
Expand All @@ -117,20 +121,35 @@ func (f *Forks) At(block uint64) ForksInTime {
}
}

type Fork uint64
// ForkParams hard-coded fork params
type ForkParams struct {
// MaxValidatorSetSize indicates the maximum size of validator set
MaxValidatorSetSize *uint64 `json:"maxValidatorSetSize,omitempty"`

// EpochSize is size of epoch
EpochSize *uint64 `json:"epochSize,omitempty"`

// SprintSize is size of sprint
SprintSize *uint64 `json:"sprintSize,omitempty"`

func NewFork(n uint64) *Fork {
f := Fork(n)
// BlockTime is target frequency of blocks production
BlockTime *common.Duration `json:"blockTime,omitempty"`

return &f
// BlockTimeDrift defines the time slot in which a new block can be created
BlockTimeDrift *uint64 `json:"blockTimeDrift,omitempty"`
}

func (f Fork) Active(block uint64) bool {
return block >= uint64(f)
type Fork struct {
Block uint64 `json:"block"`
Params *ForkParams `json:"params,omitempty"`
}

func NewFork(n uint64) Fork {
return Fork{Block: n}
}

func (f Fork) Int() *big.Int {
return big.NewInt(int64(f))
func (f Fork) Active(block uint64) bool {
return block >= f.Block
}

// ForksInTime should contain all supported forks by current edge version
Expand Down
2 changes: 1 addition & 1 deletion chain/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestParamsForks(t *testing.T) {
}{
{
input: `{
"homestead": 1000
"homestead": { "block": 1000 }
}`,
output: &Forks{
Homestead: NewFork(1000),
Expand Down
2 changes: 1 addition & 1 deletion command/genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ func (p *genesisParams) initGenesisConfig() error {
// Disable london hardfork if burn contract address is not provided
enabledForks := chain.AllForksEnabled
if len(p.burnContracts) == 0 {
enabledForks.SetFork(chain.London, nil)
enabledForks.RemoveFork(chain.London)
}

chainConfig := &chain.Chain{
Expand Down
7 changes: 1 addition & 6 deletions command/genesis/polybft_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi/artifact"
"github.com/0xPolygon/polygon-edge/consensus/polybft/validator"
"github.com/0xPolygon/polygon-edge/contracts"
"github.com/0xPolygon/polygon-edge/forkmanager"
"github.com/0xPolygon/polygon-edge/helper/common"
"github.com/0xPolygon/polygon-edge/server"
"github.com/0xPolygon/polygon-edge/types"
Expand Down Expand Up @@ -72,10 +71,6 @@ var (

// generatePolyBftChainConfig creates and persists polybft chain configuration to the provided file path
func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) error {
if err := forkmanager.ForkManagerInit(polybft.ForkManagerFactory, chain.AllForksEnabled); err != nil {
return err
}

// populate premine balance map
premineBalances := make(map[types.Address]*premineInfo, len(p.premine))

Expand Down Expand Up @@ -164,7 +159,7 @@ func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) er
// Disable london hardfork if burn contract address is not provided
enabledForks := chain.AllForksEnabled
if len(p.burnContracts) == 0 {
enabledForks.SetFork(chain.London, nil)
enabledForks.RemoveFork(chain.London)
}

chainConfig := &chain.Chain{
Expand Down
15 changes: 15 additions & 0 deletions consensus/polybft/polybft.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,21 @@ func (p *Polybft) Initialize() error {
return nil
}

func ForkManagerInitialParamsFactory(config *chain.Chain) (*chain.ForkParams, error) {
pbftConfig, err := GetPolyBFTConfig(config)
if err != nil {
return nil, err
}

return &chain.ForkParams{
MaxValidatorSetSize: &pbftConfig.MaxValidatorSetSize,
EpochSize: &pbftConfig.EpochSize,
SprintSize: &pbftConfig.SprintSize,
BlockTime: &pbftConfig.BlockTime,
BlockTimeDrift: &pbftConfig.BlockTimeDrift,
}, nil
}

// Start starts the consensus and servers
func (p *Polybft) Start() error {
p.logger.Info("starting polybft consensus", "signer", p.key.String())
Expand Down
33 changes: 21 additions & 12 deletions forkmanager/fork.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,34 @@ type Fork struct {
Name string
// after the fork is activated, `FromBlockNumber` shows from which block is enabled
FromBlockNumber uint64
// fork consensus parameters
Params *chain.ForkParams
// this value is false if fork is registered but not activated
IsActive bool
// map of all handlers registered for this fork
Handlers map[HandlerDesc]interface{}
}

// Handler defines one custom handler
type Handler struct {
// forkHandler defines one custom handler
type forkHandler struct {
// Handler should be active from block `FromBlockNumber``
FromBlockNumber uint64
// instance of some structure, function etc
Handler interface{}
}

func ForkManagerInit(factory func(*chain.Forks) error, forks *chain.Forks) error {
// forkParamsBlock encapsulates block and actual fork params
type forkParamsBlock struct {
// Params should be active from block `FromBlockNumber``
FromBlockNumber uint64
// pointer to fork params
Params *chain.ForkParams
}

func ForkManagerInit(
initialParams *chain.ForkParams,
factory func(*chain.Forks) error,
forks *chain.Forks) error {
if factory == nil {
return nil
}
Expand All @@ -41,16 +54,16 @@ func ForkManagerInit(factory func(*chain.Forks) error, forks *chain.Forks) error
fm.Clear()

// register initial fork
fm.RegisterFork(InitialFork)
fm.RegisterFork(InitialFork, initialParams)

// Register forks
for name := range *forks {
for name, f := range *forks {
// check if fork is not supported by current edge version
if _, found := (*chain.AllForksEnabled)[name]; !found {
return fmt.Errorf("fork is not available: %s", name)
}

fm.RegisterFork(name)
fm.RegisterFork(name, f.Params)
}

// Register handlers and additional forks here
Expand All @@ -64,12 +77,8 @@ func ForkManagerInit(factory func(*chain.Forks) error, forks *chain.Forks) error
}

// Activate forks
for name, blockNumber := range *forks {
if blockNumber == nil {
continue
}

if err := fm.ActivateFork(name, (uint64)(*blockNumber)); err != nil {
for name, f := range *forks {
if err := fm.ActivateFork(name, f.Block); err != nil {
return err
}
}
Expand Down
Loading

0 comments on commit 2df1b93

Please sign in to comment.