Skip to content

Commit

Permalink
Add GetGenesisGovBytes
Browse files Browse the repository at this point in the history
  • Loading branch information
ian0371 committed Dec 12, 2024
1 parent 685992c commit 519eabb
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 9 deletions.
11 changes: 2 additions & 9 deletions cmd/utils/nodecmd/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ import (
"github.com/kaiachain/kaia/blockchain/types"
"github.com/kaiachain/kaia/cmd/utils"
"github.com/kaiachain/kaia/governance"
headergov_impl "github.com/kaiachain/kaia/kaiax/gov/headergov/impl"
"github.com/kaiachain/kaia/log"
"github.com/kaiachain/kaia/params"
"github.com/kaiachain/kaia/rlp"
"github.com/kaiachain/kaia/storage/database"
"github.com/urfave/cli/v2"
)
Expand Down Expand Up @@ -128,14 +128,7 @@ func initGenesis(ctx *cli.Context) error {
}

// Set genesis.Governance and reward intervals
govSet := governance.GetGovernanceItemsFromChainConfig(genesis.Config)
govItemBytes, err := json.Marshal(govSet.Items())
if err != nil {
logger.Crit("Failed to json marshaling governance data", "err", err)
}
if genesis.Governance, err = rlp.EncodeToBytes(govItemBytes); err != nil {
logger.Crit("Failed to encode initial settings. Check your genesis.json", "err", err)
}
genesis.Governance = headergov_impl.GetGenesisGovBytes(genesis.Config)
params.SetStakingUpdateInterval(genesis.Config.Governance.Reward.StakingUpdateInterval)
params.SetProposerUpdateInterval(genesis.Config.Governance.Reward.ProposerUpdateInterval)

Expand Down
68 changes: 68 additions & 0 deletions kaiax/gov/headergov/impl/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,71 @@ func validateOpts(opts *InitOpts) error {

return nil
}

// GetGenesisGovBytes returns the genesis governance bytes for initGenesis().
// It panics if the given chain config is invalid.
func GetGenesisGovBytes(config *params.ChainConfig) headergov.GovBytes {
partialParamSet := make(gov.PartialParamSet)
genesisParamNames := getGenesisParamNames(config)
for _, name := range genesisParamNames {
param := gov.Params[name]
value, err := param.ChainConfigValue(config)
if err != nil {
panic(err)
}

err = partialParamSet.Add(string(name), value)
if err != nil {
panic(err)
}
}

govData := headergov.NewGovData(partialParamSet)
ret, err := govData.ToGovBytes()
if err != nil {
panic(err)
}

return ret
}

func getGenesisParamNames(config *params.ChainConfig) []gov.ParamName {
genesisParamNames := make([]gov.ParamName, 0)

if config.Governance != nil {
genesisParamNames = append(genesisParamNames, []gov.ParamName{
gov.GovernanceGovernanceMode, gov.GovernanceGoverningNode, gov.GovernanceUnitPrice,
gov.RewardMintingAmount, gov.RewardRatio, gov.RewardUseGiniCoeff,
gov.RewardDeferredTxFee, gov.RewardMinimumStake,
gov.RewardStakingUpdateInterval, gov.RewardProposerUpdateInterval,
}...)
}

if config.Istanbul != nil {
genesisParamNames = append(genesisParamNames, []gov.ParamName{
gov.IstanbulEpoch, gov.IstanbulPolicy, gov.IstanbulCommitteeSize,
}...)
}

if config.IsMagmaForkEnabled(common.Big0) &&
config.Governance.KIP71 != nil {
genesisParamNames = append(genesisParamNames, []gov.ParamName{
gov.Kip71LowerBoundBaseFee, gov.Kip71UpperBoundBaseFee, gov.Kip71GasTarget,
gov.Kip71BaseFeeDenominator, gov.Kip71MaxBlockGasUsedForBaseFee,
}...)
}

if config.IsKoreForkEnabled(common.Big0) &&
config.Governance != nil {
genesisParamNames = append(genesisParamNames, gov.GovernanceDeriveShaImpl)
if !common.EmptyAddress(config.Governance.GovParamContract) {
genesisParamNames = append(genesisParamNames, gov.GovernanceGovParamContract)
}
if config.Governance.Reward != nil &&
config.Governance.Reward.Kip82Ratio != "" {
genesisParamNames = append(genesisParamNames, gov.RewardKip82Ratio)
}
}

return genesisParamNames
}
123 changes: 123 additions & 0 deletions kaiax/gov/headergov/impl/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package impl

import (
"math/big"
"reflect"
"strings"
"testing"

gomock "github.com/golang/mock/gomock"
"github.com/kaiachain/kaia/blockchain"
"github.com/kaiachain/kaia/blockchain/state"
"github.com/kaiachain/kaia/blockchain/types"
"github.com/kaiachain/kaia/common"
Expand Down Expand Up @@ -119,3 +122,123 @@ func TestInitialDB(t *testing.T) {
assert.Nil(t, StoredUint64Array(nil), ReadVoteDataBlockNums(h.ChainKv))
assert.Equal(t, uint64(0), *ReadLowestVoteScannedBlockNum(h.ChainKv))
}

func TestGetGenesisParamNames(t *testing.T) {
magmaGenesisConfig := params.MainnetChainConfig.Copy()
magmaGenesisConfig.MagmaCompatibleBlock = new(big.Int).SetUint64(0)
magmaGenesisConfig.Governance.KIP71 = params.GetDefaultKIP71Config()

koreGenesisConfig := magmaGenesisConfig.Copy()
koreGenesisConfig.KoreCompatibleBlock = new(big.Int).SetUint64(0)
koreGenesisConfig.Governance.GovParamContract = common.HexToAddress("0x123")
koreGenesisConfig.Governance.Reward.Kip82Ratio = "20/80"

testcases := []struct {
desc string
config *params.ChainConfig
expected []gov.ParamName
}{
{
desc: "Mainnet config",
config: params.MainnetChainConfig.Copy(),
expected: []gov.ParamName{
gov.GovernanceGovernanceMode, gov.GovernanceGoverningNode, gov.GovernanceUnitPrice,
gov.RewardMintingAmount, gov.RewardRatio, gov.RewardUseGiniCoeff,
gov.RewardDeferredTxFee, gov.RewardMinimumStake,
gov.RewardStakingUpdateInterval, gov.RewardProposerUpdateInterval,
gov.IstanbulEpoch, gov.IstanbulPolicy, gov.IstanbulCommitteeSize,
},
},
{
desc: "Kairos config",
config: params.KairosChainConfig.Copy(),
expected: []gov.ParamName{
gov.GovernanceGovernanceMode, gov.GovernanceGoverningNode, gov.GovernanceUnitPrice,
gov.RewardMintingAmount, gov.RewardRatio, gov.RewardUseGiniCoeff,
gov.RewardDeferredTxFee, gov.RewardMinimumStake,
gov.RewardStakingUpdateInterval, gov.RewardProposerUpdateInterval,
gov.IstanbulEpoch, gov.IstanbulPolicy, gov.IstanbulCommitteeSize,
},
},
{
desc: "Private net config - genesis is Magma",
config: magmaGenesisConfig,
expected: []gov.ParamName{
gov.GovernanceGovernanceMode, gov.GovernanceGoverningNode, gov.GovernanceUnitPrice,
gov.RewardMintingAmount, gov.RewardRatio, gov.RewardUseGiniCoeff,
gov.RewardDeferredTxFee, gov.RewardMinimumStake,
gov.RewardStakingUpdateInterval, gov.RewardProposerUpdateInterval,
gov.IstanbulEpoch, gov.IstanbulPolicy, gov.IstanbulCommitteeSize,
gov.Kip71LowerBoundBaseFee, gov.Kip71UpperBoundBaseFee, gov.Kip71GasTarget,
gov.Kip71BaseFeeDenominator, gov.Kip71MaxBlockGasUsedForBaseFee,
},
},
{
desc: "Private net config - genesis is Kore",
config: koreGenesisConfig,
expected: []gov.ParamName{
gov.GovernanceGovernanceMode, gov.GovernanceGoverningNode, gov.GovernanceUnitPrice,
gov.RewardMintingAmount, gov.RewardRatio, gov.RewardUseGiniCoeff,
gov.RewardDeferredTxFee, gov.RewardMinimumStake,
gov.RewardStakingUpdateInterval, gov.RewardProposerUpdateInterval,
gov.IstanbulEpoch, gov.IstanbulPolicy, gov.IstanbulCommitteeSize,
gov.Kip71LowerBoundBaseFee, gov.Kip71UpperBoundBaseFee, gov.Kip71GasTarget,
gov.Kip71BaseFeeDenominator, gov.Kip71MaxBlockGasUsedForBaseFee,
gov.GovernanceDeriveShaImpl, gov.GovernanceGovParamContract, gov.RewardKip82Ratio,
},
},
}

for _, tc := range testcases {
t.Run(tc.desc, func(t *testing.T) {
assert.Equal(t, tc.expected, getGenesisParamNames(tc.config))
})
}

// this prevents forgetting to update getGenesisParamNames after adding a new governance parameter
t.Run("getGenesisParamNames must include all governance parameters when all hardforks are enabled", func(t *testing.T) {
latestGenesisConfig := koreGenesisConfig.Copy()

// Set all *CompatibleBlock fields to zero.
configValue := reflect.ValueOf(latestGenesisConfig).Elem()
configType := configValue.Type()

for i := 0; i < configType.NumField(); i++ {
field := configType.Field(i)
if strings.HasSuffix(field.Name, "CompatibleBlock") {
fieldValue := configValue.Field(i)
if fieldValue.Type() == reflect.TypeOf((*big.Int)(nil)) {
fieldValue.Set(reflect.ValueOf(big.NewInt(0)))
}
}
}

assert.Equal(t, len(gov.Params), len(getGenesisParamNames(latestGenesisConfig)))
})
}

func TestKairosGenesisHash(t *testing.T) {
kairosHash := params.KairosGenesisHash
genesis := blockchain.DefaultKairosGenesisBlock()
genesis.Governance = blockchain.SetGenesisGovernance(genesis)
blockchain.InitDeriveSha(genesis.Config)

db := database.NewMemoryDBManager()
block, _ := genesis.Commit(common.Hash{}, db)
if block.Hash() != kairosHash {
t.Errorf("Generated hash is not equal to Kairos's hash. Want %v, Have %v", kairosHash.String(), block.Hash().String())
}
}

func TestMainnetGenesisHash(t *testing.T) {
mainnetHash := params.MainnetGenesisHash
genesis := blockchain.DefaultGenesisBlock()
genesis.Governance = blockchain.SetGenesisGovernance(genesis)
blockchain.InitDeriveSha(genesis.Config)

db := database.NewMemoryDBManager()
block, _ := genesis.Commit(common.Hash{}, db)
if block.Hash() != mainnetHash {
t.Errorf("Generated hash is not equal to Mainnet's hash. Want %v, Have %v", mainnetHash.String(), block.Hash().String())
}
}

0 comments on commit 519eabb

Please sign in to comment.