Skip to content

Commit

Permalink
Base Fee Configs (#1890)
Browse files Browse the repository at this point in the history
* added genesis base fee flag

* cr fix

* typo

* cr fix

* edited flag comment

* made baseFeeEM as optional parameter

* fix linting error

* cr fix

* fix typo

* cr fix

* refactored baseFeeChangeDenom code

* linting fix

* cr fix

* cr fix

* Add BaseFeeChangeDenom to JSON marshalling logic

---------

Co-authored-by: Stefan Negovanović <stefan@ethernal.tech>
  • Loading branch information
rachit77 and Stefan-Ethernal authored Oct 4, 2023
1 parent b455131 commit 1f8c9c6
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 59 deletions.
2 changes: 1 addition & 1 deletion blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ func (b *Blockchain) CalculateBaseFee(parent *types.Header) uint64 {
func (b *Blockchain) calcBaseFeeDelta(gasUsedDelta, parentGasTarget, baseFee uint64) uint64 {
y := baseFee * gasUsedDelta / parentGasTarget

return y / b.config.Params.BaseFeeChangeDenom
return y / b.config.Genesis.BaseFeeChangeDenom
}

func (b *Blockchain) writeBatchAndUpdate(
Expand Down
4 changes: 2 additions & 2 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1396,10 +1396,10 @@ func TestBlockchain_CalculateBaseFee(t *testing.T) {
Forks: &chain.Forks{
chain.London: chain.NewFork(5),
},
BaseFeeChangeDenom: chain.BaseFeeChangeDenom,
},
Genesis: &chain.Genesis{
BaseFeeEM: test.elasticityMultiplier,
BaseFeeEM: test.elasticityMultiplier,
BaseFeeChangeDenom: chain.BaseFeeChangeDenom,
},
},
}
Expand Down
63 changes: 37 additions & 26 deletions chain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ type Genesis struct {
BaseFee uint64 `json:"baseFee"`
BaseFeeEM uint64 `json:"baseFeeEM"`

// BaseFeeChangeDenom is the value to bound the amount the base fee can change between blocks
BaseFeeChangeDenom uint64 `json:"baseFeeChangeDenom,omitempty"`

// Override
StateRoot types.Hash

Expand Down Expand Up @@ -113,19 +116,20 @@ func (g *Genesis) Hash() types.Hash {
// MarshalJSON implements the json interface
func (g *Genesis) MarshalJSON() ([]byte, error) {
type Genesis struct {
Nonce string `json:"nonce"`
Timestamp *string `json:"timestamp,omitempty"`
ExtraData *string `json:"extraData,omitempty"`
GasLimit *string `json:"gasLimit,omitempty"`
Difficulty *string `json:"difficulty,omitempty"`
Mixhash types.Hash `json:"mixHash"`
Coinbase types.Address `json:"coinbase"`
Alloc *map[string]*GenesisAccount `json:"alloc,omitempty"`
Number *string `json:"number,omitempty"`
GasUsed *string `json:"gasUsed,omitempty"`
ParentHash types.Hash `json:"parentHash"`
BaseFee *string `json:"baseFee"`
BaseFeeEM *string `json:"baseFeeEM"`
Nonce string `json:"nonce"`
Timestamp *string `json:"timestamp,omitempty"`
ExtraData *string `json:"extraData,omitempty"`
GasLimit *string `json:"gasLimit,omitempty"`
Difficulty *string `json:"difficulty,omitempty"`
Mixhash types.Hash `json:"mixHash"`
Coinbase types.Address `json:"coinbase"`
Alloc *map[string]*GenesisAccount `json:"alloc,omitempty"`
Number *string `json:"number,omitempty"`
GasUsed *string `json:"gasUsed,omitempty"`
ParentHash types.Hash `json:"parentHash"`
BaseFee *string `json:"baseFee"`
BaseFeeEM *string `json:"baseFeeEM"`
BaseFeeChangeDenom *string `json:"baseFeeChangeDenom"`
}

var enc Genesis
Expand All @@ -138,6 +142,7 @@ func (g *Genesis) MarshalJSON() ([]byte, error) {
enc.Difficulty = common.EncodeUint64(g.Difficulty)
enc.BaseFee = common.EncodeUint64(g.BaseFee)
enc.BaseFeeEM = common.EncodeUint64(g.BaseFeeEM)
enc.BaseFeeChangeDenom = common.EncodeUint64(g.BaseFeeChangeDenom)

enc.Mixhash = g.Mixhash
enc.Coinbase = g.Coinbase
Expand All @@ -161,19 +166,20 @@ func (g *Genesis) MarshalJSON() ([]byte, error) {
// UnmarshalJSON implements the json interface
func (g *Genesis) UnmarshalJSON(data []byte) error {
type Genesis struct {
Nonce *string `json:"nonce"`
Timestamp *string `json:"timestamp"`
ExtraData *string `json:"extraData"`
GasLimit *string `json:"gasLimit"`
Difficulty *string `json:"difficulty"`
Mixhash *types.Hash `json:"mixHash"`
Coinbase *types.Address `json:"coinbase"`
Alloc map[string]*GenesisAccount `json:"alloc"`
Number *string `json:"number"`
GasUsed *string `json:"gasUsed"`
ParentHash *types.Hash `json:"parentHash"`
BaseFee *string `json:"baseFee"`
BaseFeeEM *string `json:"baseFeeEM"`
Nonce *string `json:"nonce"`
Timestamp *string `json:"timestamp"`
ExtraData *string `json:"extraData"`
GasLimit *string `json:"gasLimit"`
Difficulty *string `json:"difficulty"`
Mixhash *types.Hash `json:"mixHash"`
Coinbase *types.Address `json:"coinbase"`
Alloc map[string]*GenesisAccount `json:"alloc"`
Number *string `json:"number"`
GasUsed *string `json:"gasUsed"`
ParentHash *types.Hash `json:"parentHash"`
BaseFee *string `json:"baseFee"`
BaseFeeEM *string `json:"baseFeeEM"`
BaseFeeChangeDenom *string `json:"baseFeeChangeDenom"`
}

var dec Genesis
Expand Down Expand Up @@ -230,6 +236,11 @@ func (g *Genesis) UnmarshalJSON(data []byte) error {
parseError("baseFeeEM", subErr)
}

g.BaseFeeChangeDenom, subErr = common.ParseUint64orHex(dec.BaseFeeChangeDenom)
if subErr != nil {
parseError("baseFeeChangeDenom", subErr)
}

if dec.Mixhash != nil {
g.Mixhash = *dec.Mixhash
}
Expand Down
3 changes: 0 additions & 3 deletions chain/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ type Params struct {
BurnContract map[uint64]types.Address `json:"burnContract"`
// Destination address to initialize default burn contract with
BurnContractDestinationAddress types.Address `json:"burnContractDestinationAddress,omitempty"`

// BaseFeeChangeDenom is the value to bound the amount the base fee can change between blocks
BaseFeeChangeDenom uint64 `json:"baseFeeChangeDenom,omitempty"`
}

type AddressListConfig struct {
Expand Down
14 changes: 11 additions & 3 deletions command/default.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package command

import (
"fmt"

"github.com/umbracle/ethgo"

"github.com/0xPolygon/polygon-edge/chain"
Expand All @@ -19,9 +21,15 @@ const (
)

var (
DefaultStake = ethgo.Ether(1e6)
DefaultPremineBalance = ethgo.Ether(1e6)
DefaultGenesisBaseFee = chain.GenesisBaseFee
DefaultStake = ethgo.Ether(1e6)
DefaultPremineBalance = ethgo.Ether(1e6)
DefaultGenesisBaseFee = chain.GenesisBaseFee
DefaultGenesisBaseFeeConfig = fmt.Sprintf(
"%d:%d:%d",
DefaultGenesisBaseFee,
DefaultGenesisBaseFeeEM,
DefaultGenesisBaseFeeChangeDenom,
)
)

const (
Expand Down
18 changes: 11 additions & 7 deletions command/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ func setFlags(cmd *cobra.Command) {
"the burn contract block and address (format: <block>:<address>[:<burn destination>])",
)

cmd.Flags().StringVar(
&params.baseFeeConfig,
genesisBaseFeeConfigFlag,
command.DefaultGenesisBaseFeeConfig,
`initial base fee(in wei), base fee elasticity multiplier, and base fee change denominator
(provided in the following format: [<baseFee>][:<baseFeeEM>][:<baseFeeChangeDenom>]).
BaseFeeChangeDenom represents the value to bound the amount the base fee can change between blocks.
Default BaseFee is 1 Gwei, BaseFeeEM is 2 and BaseFeeChangeDenom is 8.
Note: BaseFee, BaseFeeEM, and BaseFeeChangeDenom should be greater than 0.`,
)

cmd.Flags().StringArrayVar(
&params.bootnodes,
command.BootnodeFlag,
Expand Down Expand Up @@ -249,13 +260,6 @@ func setFlags(cmd *cobra.Command) {
defaultBlockTrackerPollInterval,
"interval (number of seconds) at which block tracker polls for latest block at rootchain",
)

cmd.Flags().Uint64Var(
&params.baseFeeChangeDenom,
baseFeeChangeDenomFlag,
command.DefaultGenesisBaseFeeChangeDenom,
"represents the value to bound the amount the base fee can change between blocks.",
)
}

// Access Control Lists
Expand Down
57 changes: 43 additions & 14 deletions command/genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
epochRewardFlag = "epoch-reward"
blockGasLimitFlag = "block-gas-limit"
burnContractFlag = "burn-contract"
genesisBaseFeeConfigFlag = "base-fee-config"
posFlag = "pos"
minValidatorCount = "min-validator-count"
maxValidatorCount = "max-validator-count"
Expand All @@ -42,7 +43,6 @@ const (
rewardWalletFlag = "reward-wallet"
blockTrackerPollIntervalFlag = "block-tracker-poll-interval"
proxyContractsAdminFlag = "proxy-contracts-admin"
baseFeeChangeDenomFlag = "base-fee-change-denom"

defaultNativeTokenName = "Polygon"
defaultNativeTokenSymbol = "MATIC"
Expand All @@ -69,6 +69,8 @@ var (
errReserveAccMustBePremined = errors.New("it is mandatory to premine reserve account (0x0 address)")
errBlockTrackerPollInterval = errors.New("block tracker poll interval must be greater than 0")
errBaseFeeChangeDenomZero = errors.New("base fee change denominator must be greater than 0")
errBaseFeeEMZero = errors.New("base fee elasticity multiplier must be greater than 0")
errBaseFeeZero = errors.New("base fee must be greater than 0")
)

type genesisParams struct {
Expand All @@ -88,7 +90,9 @@ type genesisParams struct {
blockGasLimit uint64
isPos bool

burnContract string
burnContract string
baseFeeConfig string
parsedBaseFeeConfig *baseFeeInfo

minNumValidators uint64
maxNumValidators uint64
Expand Down Expand Up @@ -140,8 +144,6 @@ type genesisParams struct {
blockTrackerPollInterval time.Duration

proxyContractsAdmin string

baseFeeChangeDenom uint64
}

func (p *genesisParams) validateFlags() error {
Expand All @@ -150,6 +152,10 @@ func (p *genesisParams) validateFlags() error {
return errUnsupportedConsensus
}

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

// Check if validator information is set at all
if p.isIBFTConsensus() &&
!p.areValidatorsSetManually() &&
Expand All @@ -161,10 +167,6 @@ func (p *genesisParams) validateFlags() error {
return err
}

if p.baseFeeChangeDenom == 0 {
return errBaseFeeChangeDenomZero
}

if p.isPolyBFTConsensus() {
if err := p.extractNativeTokenMetadata(); err != nil {
return err
Expand Down Expand Up @@ -417,18 +419,18 @@ func (p *genesisParams) initGenesisConfig() error {
GasUsed: command.DefaultGenesisGasUsed,
},
Params: &chain.Params{
ChainID: int64(p.chainID),
Forks: enabledForks,
Engine: p.consensusEngineConfig,
BaseFeeChangeDenom: p.baseFeeChangeDenom,
ChainID: int64(p.chainID),
Forks: enabledForks,
Engine: p.consensusEngineConfig,
},
Bootnodes: p.bootnodes,
}

// burn contract can be set only for non mintable native token
if p.isBurnContractEnabled() {
chainConfig.Genesis.BaseFee = command.DefaultGenesisBaseFee
chainConfig.Genesis.BaseFeeEM = command.DefaultGenesisBaseFeeEM
chainConfig.Genesis.BaseFee = p.parsedBaseFeeConfig.baseFee
chainConfig.Genesis.BaseFeeEM = p.parsedBaseFeeConfig.baseFeeEM
chainConfig.Genesis.BaseFeeChangeDenom = p.parsedBaseFeeConfig.baseFeeChangeDenom
chainConfig.Params.BurnContract = make(map[uint64]types.Address, 1)

burnContractInfo, err := parseBurnContractInfo(p.burnContract)
Expand Down Expand Up @@ -566,6 +568,33 @@ func (p *genesisParams) validateBurnContract() error {
return nil
}

func (p *genesisParams) validateGenesisBaseFeeConfig() error {
if p.baseFeeConfig == "" {
return errors.New("invalid input(empty string) for genesis base fee config flag")
}

baseFeeInfo, err := parseBaseFeeConfig(p.baseFeeConfig)
if err != nil {
return fmt.Errorf("failed to parse base fee config: %w, provided value %s", err, p.baseFeeConfig)
}

p.parsedBaseFeeConfig = baseFeeInfo

if baseFeeInfo.baseFee == 0 {
return errBaseFeeZero
}

if baseFeeInfo.baseFeeEM == 0 {
return errBaseFeeEMZero
}

if baseFeeInfo.baseFeeChangeDenom == 0 {
return errBaseFeeChangeDenomZero
}

return nil
}

func (p *genesisParams) validateProxyContractsAdmin() error {
if strings.TrimSpace(p.proxyContractsAdmin) == "" {
return errors.New("proxy contracts admin address must be set")
Expand Down
6 changes: 3 additions & 3 deletions command/genesis/polybft_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) er
Engine: map[string]interface{}{
string(server.PolyBFTConsensus): polyBftConfig,
},
BaseFeeChangeDenom: p.baseFeeChangeDenom,
},
Bootnodes: p.bootnodes,
}
Expand Down Expand Up @@ -308,8 +307,9 @@ func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) er
if p.isBurnContractEnabled() {
// only populate base fee and base fee multiplier values if burn contract(s)
// is provided
chainConfig.Genesis.BaseFee = command.DefaultGenesisBaseFee
chainConfig.Genesis.BaseFeeEM = command.DefaultGenesisBaseFeeEM
chainConfig.Genesis.BaseFee = p.parsedBaseFeeConfig.baseFee
chainConfig.Genesis.BaseFeeEM = p.parsedBaseFeeConfig.baseFeeEM
chainConfig.Genesis.BaseFeeChangeDenom = p.parsedBaseFeeConfig.baseFeeChangeDenom
}

return helper.WriteGenesisConfigToDisk(chainConfig, params.genesisPath)
Expand Down
50 changes: 50 additions & 0 deletions command/genesis/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package genesis

import (
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"math/big"
Expand Down Expand Up @@ -163,6 +164,55 @@ func parseBurnContractInfo(burnContractInfoRaw string) (*polybft.BurnContractInf
}, nil
}

type baseFeeInfo struct {
baseFee uint64
baseFeeEM uint64
baseFeeChangeDenom uint64
}

// parseBaseFeeConfig parses provided base fee configuration and returns baseFeeInfo
func parseBaseFeeConfig(baseFeeConfigRaw string) (*baseFeeInfo, error) {
baseFeeInfo := &baseFeeInfo{
command.DefaultGenesisBaseFee,
command.DefaultGenesisBaseFeeEM,
command.DefaultGenesisBaseFeeChangeDenom,
}

baseFeeConfig := strings.Split(baseFeeConfigRaw, ":")
if len(baseFeeConfig) > 3 {
return baseFeeInfo, errors.New("invalid number of arguments for base fee configuration")
}

if len(baseFeeConfig) >= 1 && baseFeeConfig[0] != "" {
baseFee, err := common.ParseUint64orHex(&baseFeeConfig[0])
if err != nil {
return baseFeeInfo, err
}

baseFeeInfo.baseFee = baseFee
}

if len(baseFeeConfig) >= 2 && baseFeeConfig[1] != "" {
baseFeeEM, err := common.ParseUint64orHex(&baseFeeConfig[1])
if err != nil {
return baseFeeInfo, err
}

baseFeeInfo.baseFeeEM = baseFeeEM
}

if len(baseFeeConfig) == 3 && baseFeeConfig[2] != "" {
baseFeeChangeDenom, err := common.ParseUint64orHex(&baseFeeConfig[2])
if err != nil {
return baseFeeInfo, err
}

baseFeeInfo.baseFeeChangeDenom = baseFeeChangeDenom
}

return baseFeeInfo, nil
}

// GetValidatorKeyFiles returns file names which has validator secrets
func GetValidatorKeyFiles(rootDir, filePrefix string) ([]string, error) {
if rootDir == "" {
Expand Down

0 comments on commit 1f8c9c6

Please sign in to comment.